安洵杯 2019:easy_web
这道题还是不太难的嘿qwq记录一哈:
仔细观察url的img的参数,复制下来,两遍base64,一遍hex可以得到明文。
同理,我们将参数改为?img=TmprMlJUWTBOalUzT0RKRk56QTJPRGN3&cmd=(一次hex两次base64),然后查看源代码,可以得到index的源码。
<?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(echo `$cmd`; 反引号执行系统命令查看flag),需要满足如下条件:
1)以get形式传入的cmd参数的内容里不能出现ls/bash/tac/nl/more/less/head/wget/tail/vi/cat/od/grep/sed/bzmore/bzless/pcre/paste/diff/file/echo/sh等字符。
2)需要以post形式传入参数a和参数b,内容不能相等但是两个参数的值的md5要相等。而且这里用了strings和全等于,不能再利用数组和md5弱类型比较来绕过。
emm,也就是说,和img参数无关,我们基本可以无视掉它。
接下来,要想获得flag,需要执行cmd参数的值,题里把大部分的查看文件内容的linux命令都给过滤掉了,但是还没有全部过滤掉呢(w
参考大佬的文章,这个sort吸引了我的注意:
Linux 常用命令:文本查看篇 - 苏醒若蘅 - 博客园
别忘记 url里的空格用+号代替。
接下来就是关于post传参的问题了。我之前也记了笔记,利用工具生成a和b两个md5相同内容不同的文件,然后curl传过去。这里就不多说了:
关于PHP中md5比较绕过方式的总结 - 「配枪朱丽叶。」