SHA2017 CTF两道web

只做出来两道

Web 100

一道本地文件包含

存在/log.sh,里面是:

可以发现有/var/www/html/logs/${HOST}.log,猜测host是本机ip,直接访问可以发现日志记录。

于是直接请求一个带有一句话的url再包含即可拿到flag。(包含shell的时候要用file://包含)

Web 200

//更新:

看了别人的wp之后发现用group_concat可以直接取出所有的数据,因为平常在mysql环境下group_concat有默认长度限制所以我在做题的时候没有考虑使用,后来想想sqlite的group_concat函数是没有长度限制的,所以可以不用脚本一条一条数据的跑,而是直接用group_concat取完,这样看来这道题并不蠢,还是自己的视线太狭隘了一点。

 

一个带了验证码的sql注入,以及最后还要跑一万多条数据,实在是体验比较差的一道题,如果去掉最后一步的话会是一道非常棒的200分题目。

整个思路是

绕过FILTER_VALIDATE_EMAIL对mail参数的限制 -> 构造payload进行sql注入 -> 自动识别验证码dump数据库 -> 根据取得的数据拼成图片拿到flag

首先是第一步,提示在当你输入的mail格式错误时会显示

test@+test.com is not a valid email address according FILTER_VALIDATE_EMAIL

会知道这道题一定和FILTER_VALIDATE_EMAIL这个函数有关,这个函数广泛用于需要验证mail格式的情况下,在正常情况下@前面的字符串长度被限制为64个字节,联想到去年的phpmailer RCE,提到了绕过这个函数的一个方法,类似于test.""@test.com这样的构造会绕过FILTER_VALIDATE_EMAIL函数对于@前面字符串的长度限制,于是可以构造足够长度的payload。

然后是sql注入,提示在当你用’闭合mail的时候会显示database error

于是可以成功确定题目的考点,本地搭建一个环境测试FILTER_VALIDATE_EMAIL拦截的字符,发现()空格等被拦截,于是用/**/代替空格,接着发现#不能注释,确定不是mysql,构造'union/**/select/**/123--.""@test.com成功返回123,再然后发现是sqlite,整个注入探测过程到此为止。

然后需要脚本去注出数据,首先考虑的是识别验证码的问题,用python的pytesseract和PIL库可以非常快速的识别简单验证码,配合BytesIO可以直接导入BASE64编码的图片格式。

到此为止整道题的体验非常好,每一步都有较为明显的提示,同时也可以让没有复现过PHPmailer漏洞的人学到东西。然而此时一血仍然没有出现,所以肯定有其他的坑点。

发现数据库里没有任何flag,但是有一个image表储存了14767条数据,每条数据有一个小于16字节的base64,于是猜测是吧所有的base64拼接起来合成一张有flag的图片,根据表中另一个字段Line排序:
'/**/union/**/select/**/line||'AU1'||base64/**/from/**/image/**/where/**/line=14767--.""@test.com

跑完所有的数据后转换为图片即可

这最后一步确实很蠢,既然要跑数据,为什么不直接弄为盲注然后直接跑flag,要这样强行浪费做题人的时间,看不懂。

最后的exp: