最近身边碎事比较多,也面临期末考试月,周末抽空做了这个难度不大的题目,在这个过程中转过了一些弯,也遇到了一些问题。
这道题比较实在,没有像有的题一样需要扫描,有的时候一点思路也没有了就得扫描目录,发现竟然是代码审计。
先是访问主页面,发现了url中比较吸引人眼球的地方:img参数,要敏感,应该是个base64编码之后的字符串,
一次解码之后,格式仍然很像,继续解码,直到最后一步直接就是hex的ascii码,得到555.png,一个正常的文件名,同时我们在源代码里也看到了base64编码过的png内容,
只能说怀疑有任意文件下载,不知人家后端是否做了过滤,做了什么过滤,只能先做个尝试,
在img里填入这个参数,结果发现成功返回了index.php的base64编码之后的文本,我们解码它,得到
index.php因为这里是任意文件读,所以我们可以认为preg_match('/flag/')处给了提示,flag在文件里,路径无非就是./或/,文件名可能有flag,flag.txt,flag.php,大概也就五六种可能,不是重点。
重点在于后面的echo `$cmd`,这个命令执行是我们的突破口,
稍微总结一下,简单的命令执行函数中,
exec(),返回值为输出的最后一行;
system(),返回值为输出值的最后一行,打印输出值;
passthru(),没有返回值,打印全部输出值;
shell_exec(),将输出值作为返回值,不打印任何信息,同``。
`$cmd`直接接触的这一层的md5判断已经不管用了,现在已经有了真正意义上的md5碰撞,网上也可以找到相关的字符串甚至是直接下载程序,我把一个txt拖进去,生成了一个新的txt,两个文件的md5真的相同,查看内容发现里面只有几位不一样。这里直接用之前记下的:
而`$cmd`前面这个超长的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))
,几乎把我们常用的文件读命令或者nc拿shell命令的道路都堵死了,想了想也没有想出什么法子(太菜了)。
网上有的大佬说,可以用sort命令:sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
在看了wp后,我也意识到自己思路受限了,或者说自己心急了,再或者说自己基础不够好。这里不是说有正则就能匹配一切,比如这里想要匹配反斜杠的|\\|写的不太好,可以绕过,我们传ca\t flag,竟然就可以绕过。一开始我以为ca\t中的\t会成为tab而绕过,但发现这个正则式里面是有\t的,根本匹配不到,又想到可能得用\\\\来匹配,发现正则式里也有。事情不简单,在本地试了一下。
传入ca\t时,\\, \\\\, \t,前面看到是匹配不上的,\\t, \\\t竟然也匹配不上,interesting
直到用了\\\\t才匹配上,既然\\\\t能匹配上,\\\\为什么匹配不上啊,求有知道的前辈明示。个人猜测,ca\t传进php脚本之后,以cat\\t存储,想要表示它,就得用\\\\,但显然\\\\并没有匹配上,不知真实原因。
克服了这一点,就可以get flag,
或
个人感觉是比较直接、实在的一道题,重点突出旗帜鲜明,不拐弯抹角,比较友好。
大胆应无惧,雄心誓不回
网友评论