sqli-labs这个靶场,前31关大多数人是笑着刷过去的,到了Less-32才开始真正怀疑人生。这一关的标题叫“Bypass custom filter adding escaped parameter”,翻译成人话就是:服务端明明给参数加了反斜杠转义,你却还得想办法把注入打进去。很多人卡在这里,不是不会写union select,而是搞不明白一个关键问题:单引号前面明明被加了反斜杠,为什么用%df+'组合一下,反斜杠就凭空消失了?
如果你也在刷sqli-labs,或者刚接触SQL注入想搞懂宽字节注入到底是什么,这篇文章就是给你准备的。我会从原理、源码、手工注入全流程到常见坑位,把Less-32这一关掰开揉碎讲清楚,保证你看完不仅能通关,还能顺手搞懂Less-33、Less-34那套兄弟关卡。
1. 关卡定位:为什么Less-32是sqli-labs的分水岭
1.1 这一关到底考什么
Less-32本身是一个基于GET传参的字符型注入点,SQL语句大概是SELECT * FROM users WHERE id='$id' LIMIT 0,1这种结构,参数外面套了单引号。如果你直接输入?id=1',服务端会调用一个类似addslashes的过滤函数,把单引号转义成\',于是SQL语句变成WHERE id='1\'',单引号被反斜杠“焊死”,注入直接失效。
但这一关特殊的地方在于,靶场把数据库连接字符集设置成了GBK。在GBK编码里,一个汉字占两个字节,而\的ASCII码是0x5c,单引号是0x27。如果你在'前面补上一个%df,经过过滤后原始输入变成了%df%5c%27,其中%df%5c在GBK字符集里会被解析成一个合法汉字,后面的%27就单独逃逸出来变成了真正的单引号。这就是宽字节注入的核心逻辑:不是绕过了过滤函数,而是利用编码差异让反斜杠“参与”到了前一个字符的编码里,从而失去转义作用。
这一关本质上考的是你对字符集、编码、转义这三个概念的理解深度。单纯会背payload没用,你得知道payload为什么长这样,换了编码环境为什么就不生效。
1.2 和前31关有什么区别、哪些关卡会延续这套玩法
在Less-32之前,你遇到的注入点大多能直接输入'闭合,比如Less-1是单引号闭合,Less-2是数字型,Less-3是单引号加括号。这些关卡不涉及任何输入过滤,你只需要关注SQL语句本身的拼接逻辑。
到了Less-32,靶场开始引入“过滤”概念。同一个',前面被强行加了一个\,原本的注入路径被堵死。但更阴险的是,这个过滤函数对GET、POST、Cookie的所有参数统一生效,意味着你没法通过更换传参方式来绕过。
Less-32、Less-33、Less-34三关是一套连续剧,它们的核心都是宽字节注入,只是传参方式不同:
| 关卡 | 传参方式 | 过滤函数 | 注入闭合类型 |
|---|---|---|---|
| Less-32 | GET型,id参数 | 自定义check_addslashes (addslashes) | 单引号字符型 |
| Less-33 | GET型,id参数 | mysql_real_escape_string | 单引号字符型 |
| Less-34 | POST型,uname/passwd | check_addslashes + mysql_real_escape_string | 单引号字符型 |
也就是说,Less-32你只要能手工打通,后面两关基本就是换汤不换药的复刻。Less-34的POST传参稍微改一下请求方式就行,payload思路完全一致。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 宽字节注入原理拆解:addslashes、GBK和“被吞掉的反斜杠”
2.1 addslashes做了什么:看起来滴水不漏的转义
`addslashes
