web09
1.访问url

这里burp还有查看源码都没有用信息,尝试查看是否有robots.txt
2.尝试访问
robots.txt
1 | curl -l https://ec66b6b9-7fe1-4de9-bef9-2dce69bfd269.challenge.ctf.show/robots.txt |
这明确提示了服务器上存在源码文件 index.phps。phps 后缀通常用于展示 PHP 源代码(PHP Source)。
index.phps
1 |
|
漏洞详解
代码中的关键漏洞在于 SQL 查询语句的拼接方式:
1 | $sql="select * from user where username ='admin' and password ='".md5($password,true)."'" |
这里使用了 md5($password, true)。
- 通常我们见到的
md5($str)默认返回 32 字符的十六进制字符串(例如e10adc3949...)。 - 当第二个参数为
true时,md5($str, true)返回 16 字节的原始二进制格式。
如果某个字符串的 MD5 原始二进制结果转换成字符串后,恰好包含 'or' 这样的字符序列,就可 以闭合前面的单引号,并构造出一个恒真的 SQL 条件,从而绕过密码验证。这就是所谓的 SQL 注入。
3. 漏洞利用
我们需要寻找一个字符串,满足以下条件:
- 长度 <= 10(源码限制)。
- 其 MD5 原始二进制值包含类似于
' or '...的结构。
攻击载荷 (Payload)
一个广为人知的字符串是 ffifdyop。(其他wp中这样写?)
它的 MD5 哈希(Hex)是:276f722736c95d99e921722cf9ed621c
将其转换为原始字符串(Raw Binary)时:
27->'(单引号)6f->o72->r27->'(单引号)36->6- …
转换过程 (Hex -> ASCII)
当代码调用 md5($password, true) 时,PHP
会把这串十六进制数每两个一组(即一个字节),转换成对应的原始字符:
27: 十六进制 0x27 等于十进制 39。在 ASCII 表中,39 对应的字符就是'(单引号)。6f: 十六进制 0x6f 等于十进制 111。在 ASCII 表中,111 对应的字符是o。72: 十六进制 0x72 等于十进制 114。在 ASCII 表中,114 对应的字符是r。27: 又是 0x27,再次得到'(单引号)。36: 十六进制 0x36 等于十进制 54。在 ASCII 表中,54 对应的字符是6。
转换后的字符串开头是 'or'6...。
将其代入 SQL 语句中:select * from user where username ='admin' and password =''or'6<乱码>...'
在 MySQL 中:
password = ''为假。OR后面的字符串'6...'会被转换为数字。由于以数字6开头,它会被转换成数字6。- 数字
6在布尔上下文中被视为TRUE。
因此,整个WHERE子句变为False OR True,结果为True,成功绕过认证。
4.开始攻击
发送post请求
1 | curl -X POST -d "username=admin&password=ffifdyop" https://ec66b6b9-7fe1-4de9-bef9-2dce69bfd269.challenge.ctf.show/index.php |
最终结果
服务器响应:
1 | curl -X POST -d "username=admin&password=ffifdyop" https://406c1283-1994-4509-a459-8cd55d5b6c5e.challenge.ctf.show/ |