WeChall - Addslashes
Challenge
MySQL/Exploit 类,难度 5.44,909 人解出。源码可见,使用
addslashes() 对用户输入转义,但数据库连接字符集设为
GBK。目标:以 admin 身份登录。密码字段会被 md5()
处理,无法注入。
Solution
经典宽字节注入(Wide Byte Injection)。
addslashes() 会在
'、"、\、NUL
前插入反斜杠 \(0x5c)。正常情况下这能防住简单的 SQL
注入,但 GBK 编码下,0x5c
是合法的多字节字符的第二字节。
GBK 编码范围:首字节 0x81-0xFE,尾字节
0x40-0xFE(不含 0x7F)。所以
0xBF 0x5C 是一个合法的 GBK 字符「縗」。
攻击流程:
表单使用 GET 方法提交,按钮值为「注册」。先确认正常登录行为:
1 | $ curl -s -b 'WC=...' \ |
直接注入单引号,被 addslashes() 拦截:
1 | $ curl -s -b 'WC=...' \ |
用 %bf 前缀构造宽字节。admin' 经过
addslashes() 变成 admin\',即
admin%5c%27。我们在前面加 %bf,使
%bf%5c 被 GBK
解码为一个字符,%27(单引号)就逃逸了:
1 | $ curl -s -b 'WC=...' \ |
%bf%5c 被 GBK 吃掉成为「縗」,后面的
' OR 1=1-- - 被解释为 SQL,绕过了转义。但
OR 1=1 只会返回表中第一条记录,不一定是 Admin。需要精确指定
Admin 用户名,用 hex 编码避免单引号被转义:
1 | $ curl -s -b 'WC=...' \ |
0x41646d696e 是 'Admin' 的 hex
编码,不包含单引号,不会被 addslashes() 干扰。
核心原理图示:
1 | 输入: ' OR username=0x41646d696e -- - |
OR 1=1
虽然能绕过密码检查,但只返回第一条记录。实际解题需要
OR username=0x41646d696e 精确匹配 Admin。密码字段会被
md5() 处理后再拼接,无法通过用户名注入绕过,所以必须用
-- 注释掉密码条件。