知识点
拿到源码后,就要考虑几个绕过的方法:==的弱比较:0e和“字符串”;php的伪协议;eregi的绕过:%00的截断(而\x00会将url后面的都截断,我们的目的是在执行到变量时实现截断)和*123123。
解题流程
打开网页如下
熟悉的?id=
看起来好像有sql注入,通过sqlmap跑一遍发现并没有
F12查看一下源代码
有注释!,1p.html.查看一下这个网址。
跳转到论坛了 ,Burp抓不到包因为跳转处理在服务器
F12查看网络
这里发现301重定向。
那要看1p.html,
通过burpsuite抓包了。
抓包后将网址改为/1p.html, Repeater
之间这串
JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF
明显是base64加密
http://ctf.ssleye.com/base64.html在线解密一下
%22%3Bif(!%24_GET%5B’id’%5D)%0A%7B%0A%09header(‘Location%3A%20hello.php%3Fid%3D1’)%3B%0A%09exit()%3B%0A%7D%0A%24id%3D%24_GET%5B’id’%5D%3B%0A%24a%3D%24_GET%5B’a’%5D%3B%0A%24b%3D%24_GET%5B’b’%5D%3B%0Aif(stripos(%24a%2C’.’))%0A%7B%0A%09echo%20’no%20no%20no%20no%20no%20no%20no’%3B%0A%09return%20%3B%0A%7D%0A%24data%20%3D%20%40file_get_contents(%24a%2C’r’)%3B%0Aif(%24data%3D%3D%22bugku%20is%20a%20nice%20plateform!%22%20and%20%24id%3D%3D0%20and%20strlen(%24b)%3E5%20and%20eregi(%22111%22.substr(%24b%2C0%2C1)%2C%221114%22)%20and%20substr(%24b%2C0%2C1)!%3D4)%0A%7B%0A%09%24flag%20%3D%20%22flag%7B***********%7D%22%0A%7D%0Aelse%0A%7B%0A%09print%20%22never%20never%20never%20give%20up%20!!!%22%3B%0A%7D%0A%0A%0A%3F%3E
根据%3C来看Words变量应该是url编码
这串有url码,看着有点乱
http://ctf.ssleye.com/url.html解一下
<?
if(!$_GET['id']) //如果无法通过get获得id变量 或者 id=0执行
{header('Location: hello.php?id=1'); //跳转到hello.php文件设置id=1exit(); //退出脚本。
}
$id=$_GET['id']; //通过get方式获得其他文件的id变量
$a=$_GET['a']; //通过get方式获得其他文件的a变量
$b=$_GET['b']; //通过get方式获得其他文件的b变量
if(stripos($a,'.')) //$a文件里不能有.,但当'.'号在第一位时,因为字符串是从0开始的,所以函数会返回0,就可以通过判断。
{echo 'no no no no no no no';return ;
}
$data = @file_get_contents($a,'r'); //将$a文件读入到data里
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{$flag = "flag{***********}"
}
else
{print "never never never give up !!!";
}
/*
id== 0与if(!GET(‘id’))有突,于是令id=0e12345绕过,id为其他也可以stripos(字符串a,字符串b) 函数查找字符串b在字符串a里第一次出现的位置(不区分大小写)。
stripos() 函数:查找字符串在另一字符串里第一次出现的位置(不区分大小写)。
这个函数应该是想过滤掉‘.’号,但是当'.'号在第一位时,因为字符串是从0开始的,所以函数会返回0,就可以通过判断。
返回值: 返回字符串在另一字符串里第一次出现的位置,如果没有找到字符串则返回 FALSE。
注释:字符串位置从 0 开始,不是从 1 开始。strlen() 函数返回字符串的长度file_get_contents 将整个文件读入一个字符串
file_get_contents()函数显然是用来读取文件的,但是我们并不知道网站有哪些文件,但是$a参数可以控制,利用a=php://input来控制文件内容。
用$a=php://input通过php伪协议去绕过file_get_contents
源码里变量 $data 是由 file_get_contents() 函数读取变量 $a 的值而得,所以 $a 的值需为数据流。
在服务器里自定义一个内容为 bugku is a nice plateform! 文件,再把此文件路径赋值给 $a,显然不太现实。因此这里用伪协议 php:// 来访问输入输出的数据流,其内php://input 可以访问原始请求数据里的只读流。这里令 $a = “php://input”,并在请求主体里提交字符串 bugku is a nice plateform!。substr(string,start,length) 函数:返回字符串的一部分。
substr() 函数返回字符串的一部分。 substr(string,start,length) ,length参数可选。如substr($b,0,1) 就是在参数b里面 ,从0开始返回1个长度的字符串
substr($b,0,1)就是取b参数的第一个字符。ereg() 函数或 eregi() 函数存在空字符截断漏洞,即参数里的正则表达式或待匹配字符串遇到空字符则截断丢弃后面的数据。
eregi() 截断漏洞
CTF题做多了就知道 ereg() 函数或 eregi() 函数存在空字符截断漏洞,即参数里的正则表达式或待匹配字符串遇到空字符则截断丢弃后面的数据。
源码里待匹配字符串(第二个参数)已确定为 “1114”,正则表达式(第一个参数)由“111”连接b的第一个字符组成,若令substr(
b,0,1)=”\x00”,即满足“1114”与“111”匹配。因此,这里假设$b=”\x0012345”,才能满足以上的三个条件。eregi("111".substr($b,0,1),"1114") 就是判断"1114"这个字符串里面是否有符合"111".substr($b,0,1)这个规则的
字符串 1114 要与字符串 111 连接变量 $b 的第一个字符构成的正则表达式匹配
b的长度大于5,eregi("111".substr(b,0,1),“1114”)这个函数为b的正则匹配, substr(b的正则匹配,substr(b的正则匹配,substr(b,0,1)!=4这个说明$b开头不能为4,所以我可令
$b=*123456id参数为字符时,比较时会转为0在构造变量 b 里的空字符时,过早将空字符 \x00 放入,在提交请求时导致请求头截断,继而请求失败,得不到响应。
因为 b 是 URL 查询字符串里的变量,不应该在此放入空字符 \x00,而应该为空字符的 URL 编码 %00。注意,虽然 b=%0012345 实际字符串长度为 8 字节,但在后台脚本读入数据时,会将 URL 编码 %00 转换成 1 字节。所以说,空字符应该在后台脚本的变量里出现,而不是在 URL 查询字符串变量里出现。构造payload:
http://114.67.246.176:13629/hello.php?id=a&a=php://input&b=111111
*/?>
%00,?,*这三类特殊符号都可以用来绕过$b的判断,前者为截断空字符,后两者为通配符
构造payload:
http://114.67.246.176:13629/hello.php?id=a&a=1.1
构造payload:
http://114.67.246.176:13629/hello.php?id=a&a=php://input&b=%0012345
http://114.67.246.176:13629/hello.php?id=asd&a=php://input&b=*111111
http://114.67.246.176:13629/hello.php?id=0e123&a=php://input&b=%0011111
?id=0e123456&a=php://input&b=*123456