WAF实战:SQL注入绕过宝塔面板的攻防博弈

📅 发布时间:2026/7/5 17:38:47 👁️ 浏览次数:
WAF实战:SQL注入绕过宝塔面板的攻防博弈
1. 从一次“被拒之门外”的测试说起大家好我是老张一个在安全圈摸爬滚打了十来年的老兵。今天想和大家聊一个非常接地气但又让很多新手朋友头疼的话题如何与宝塔面板的WAF“过招”特别是针对SQL注入的攻防博弈。你可能用过宝塔它确实是个好东西一键部署、可视化监控让服务器管理变得像搭积木一样简单。但它的WAFWeb应用防火墙有时候也挺“倔”一个简单的1‘ and 11测试可能就直接给你弹个拦截页面让人瞬间懵圈。这背后的场景其实是我们安全测试或日常运维中经常遇到的。你想验证一下自己的网站有没有SQL注入漏洞结果宝塔的防护规则先跳出来说“此路不通”。是网站真的固若金汤还是我们的“敲门”方式不对今天我们就抛开那些复杂的理论直接进入靶场实战。我会把自己在测试中踩过的坑、试出来的有效绕过方法以及宝塔WAF可能的工作逻辑掰开揉碎了讲给你听。目标很简单不是教你去攻击别人的网站而是让你彻底理解这套防护机制的“脾气”从而更好地加固自己的阵地或者在进行授权测试时能更精准地发现问题所在。我们这次的“战场”是一个经典的SQL注入靶场环境但上面部署了宝塔面板的WAF防护。你会发现很多教科书式的注入语句在这里直接失效。别急这恰恰是乐趣的开始。攻防的本质就是博弈是规则与绕过规则的智力游戏。通过一步步的试探、观察响应、调整Payload我们不仅能学会绕过技巧更能反向揣摩出WAF的过滤规则这种“知其然更知其所以然”的体验才是实战的精髓。2. 初探战场宝塔WAF的“第一道防线”当我们把经典的1‘ or 11、1‘ and 11甚至1‘ || 11提交上去时宝塔WAF几乎毫不犹豫地返回了拦截页面。这给我们传递了一个明确信号它对一些常见的SQL逻辑运算符和关键字如or,and,||建立了非常基础的“黑名单”匹配规则。这种规则通常基于简单的字符串匹配或正则表达式一旦发现请求参数中出现这些敏感词就直接阻断请求。这种防护思路直接有效能拦住绝大部分自动化扫描工具和初级的攻击尝试。但它的弱点也在于“简单”。SQL语言是灵活的同一种逻辑意图往往有多种表达方式。WAF的规则库不可能也无必要穷尽所有变形这就给我们留下了迂回的空间。我的第一个突破口是从一个看似不起眼的细节开始的运算符。在MySQL中和and是等价的逻辑与运算符。当我尝试id1 11时发现请求居然通过了但先别高兴太早直接这么写在HTTP请求中符号是参数分隔符会被解析。所以我们需要对它进行URL编码。编码后是%26因此完整的Payload变成了id1 %26%26 11。这次WAF放行了。这个成功的绕过说明了什么首先宝塔WAF的规则库可能没有将或其编码形式%26%26纳入对“AND”逻辑的拦截规则中。其次它提示我们一个非常重要的思路编码是绕过WAF的常见且有效的手段之一。不仅仅是URL编码还有十六进制编码、Unicode编码等等都可能用来混淆关键字符欺骗过滤规则。但这只是万里长征第一步。1 11只是一个布尔判断真正的注入攻击需要获取数据这就离不开select、from、where这些核心关键字。当我们尝试1 (select 1)1时拦截再次降临。这说明WAF的检测链条是分层的它不仅仅看孤立的单词还会看组合起来的“短语”或“语法片段”。3. 见招拆招绕过关键字过滤的“组合拳”面对select关键字被拦截我们有哪些武器实战中我试了几种常见方法第一招空白符干扰。这是最简单粗暴但往往有效的一招。在select前面加一个空格变成selectPayload1 ( select 1)1。成功了为什么一个空格就能救命这很可能是因为WAF的正则匹配规则是写死的比如它匹配的是\bselect\b或类似的模式旨在匹配完整的单词。当我们前置一个空格可能破坏了它预设的匹配边界条件。除了普通空格还可以尝试换行符%0a、制表符%09、注释符/**/等。这些空白符在SQL解析时通常被忽略但对字符串匹配规则可能是致命的干扰。第二招函数名混淆。当我们想用database()函数获取库名时1 (select database()security)被拦截了。这说明database()这个函数名本身也在黑名单里。我尝试了注释符分割函数名database/**/()但失败了。接着我尝试了注释符加换行database--%0a()。注意--是SQL的单行注释符%0a是换行符的URL编码。这个Payload1 (select database--%0a()security)竟然通过了这里的原理需要理解一下在MySQL中--注释掉其后的所有内容直到行尾。我们写database--%0a()意思是database后面开始注释然后换行%0a下一行的()会被执行吗实际上在一些上下文和MySQL版本中这种写法可能导致语法错误或行为不一致。但在这个靶场环境里它绕过了。我推测WAF的规则可能是匹配database()这个完整的字符串令牌。我们用--%0a将其从视觉和字符串匹配上“切断”了变成了database和()两部分而MySQL解释器在某种宽松模式下仍能将其识别为函数调用。这揭示了WAF的另一个潜在弱点语法分析与字符串匹配的鸿沟。WAF基于字符串或正则匹配而数据库引擎基于语法解析。利用两者之间的差异是高级绕过的核心。第三招寻找“替身”函数。宝塔可能拦截了database()、user()等常见信息函数但MySQL内置函数成百上千它不可能全部封禁。我们的任务就是找到那些“漏网之鱼”。我测试了多个函数后发现locate()函数可用。LOCATE(substr, str)函数返回子串substr在字符串str中第一次出现的位置如果不存在则返回0。这简直是为布尔盲注量身定做的“神器”我们可以构造这样的Payload来猜解数据库名第一个字符是否为‘s’id1 locate(s, (select database--%0a())) 11如果返回真即页面正常说明locate返回值大于0数据库名第一个字符是‘s’。通过不断变换子串从单个字符到多个字符我们就能一步步“拼”出完整的数据库名security。4. 深入腹地应对复杂查询与GET/POST的差异知道了库名下一步就是猜表名、字段名和具体数据。按照常规思路我们需要查询information_schema这个系统数据库。但当我们构造如下Payload时又被拦截了id1 locate(e, (select table_name from information_schema.tables where table_schemasecurity limit 0,1)) 11问题出在哪里通过反复测试和减法排查即逐步移除Payload中的部分进行测试我发现**from关键字**似乎是触发拦截的关键。单独select可能没事但select ... from ...这个组合模式被WAF盯上了。更有趣的现象出现了同样的Payload在GET请求参数在URL中中被拦截但改成POST请求参数在请求体中提交时竟然通过了这个差异非常值得深究。它可能揭示了宝塔WAF或某些规则集的检测策略对GET和POST请求应用了不同的检测严格度或规则集。通常GET请求的参数直接暴露在URL中更易被自动化工具扫描因此WAF可能会对GET参数施加更严格的检查。而POST请求体相对“隐蔽”规则可能稍松。这给我们一个实用提示在测试时如果GET型注入受阻不妨尝试将参数改为POST方式提交或许能打开新局面。那么对于GET请求如何绕过from的拦截呢我们无法在盲注中完全不用from。但我们可以利用之前“空白符干扰”和“编码变形”的思路进行组合尝试。例如对from进行各种编码变形如双URL编码、十六进制编码或者在from前后插入非常规空白符如%0b垂直制表符。另一个思路是利用MySQL的“无列名”注入或子查询技巧有时可以避免直接使用from information_schema。不过在我们的靶场案例中既然POST方式可行我们可以直接切换到POST注入点例如靶场的Less-11继续测试这更高效。在POST请求中我们顺利猜解出第一个表名为emails第一个字段为id。但在最终读取数据时又遇到了新麻烦1 locate(1, (select id from emails limit 0,1)) 11被拦截。1 (select locate(1,id) from emails limit 0,1) 11也被拦截。看来select ... from ...这个结构在数据提取阶段依然被重点关照。我尝试了加注释换行1 (select--%0alocate(1,id) from emails limit 0,1) 11还是不行。最后在select关键字前再加一个空格成功了1 ( select--%0alocate(1,id) from emails limit 0,1) 11。这再次印证了空格这个最简单的字符在对抗基于模式匹配的WAF时常常有奇效。它可能不断调整我们的策略从单一技巧到组合拳从硬碰硬到迂回穿插。5. 攻防背后的思考WAF规则逻辑与防御建议通过这一系列的实战试探我们可以尝试反向勾勒出宝塔面板WAF或其中某套规则的一些过滤逻辑基于黑名单的关键字/词法匹配这是第一层也是最基础的防护。它对or,and,select,from,union,database()等明显的关键字和函数名进行直接匹配拦截。对特定语法结构的检测例如select ... from ...这种组合。单独的select可能放过但加上from形成查询结构就触发规则。这说明它有一定的“上下文”感知能力不止看单词还看“短语”。对标准化输入进行检测我们的绕过大量使用了URL编码、空白符、注释符。这说明WAF的规则可能是在对输入进行一定程度的规范化如URL解码之前或之后进行匹配的。如果它在解码前匹配那么%26%26就能绕过and的规则。如果它对空白符的处理不严谨那么加空格就能干扰匹配。请求方法差异GET和POST请求的检测强度可能不同这可能是出于性能和误报率的权衡。GET请求更频繁参数暴露检查更严POST请求体检查成本高规则可能略有不同。那么作为防御方服务器运维人员我们能从这场博弈中学到什么不要迷信单一防护WAF是重要的安全层但绝非银弹。它主要基于规则总有被绕过的可能。真正的安全应该建立在“最小权限原则”和“纵深防御”之上。确保应用程序本身没有SQL注入漏洞使用参数化查询/预编译语句才是治本之策。理解WAF的告警当WAF告警时不要只看“拦截”这个结果。要去分析告警日志看它匹配了哪条规则攻击载荷是什么。这能帮助你理解正在遭受何种攻击甚至发现WAF规则本身的盲点。自定义规则与学习模式宝塔等WAF通常允许用户自定义规则。如果你发现某种绕过手法对你的站点有效可以针对性地添加更严格的规则。同时可以开启WAF的学习模式如果有让它在一段时间内观察正常流量减少对合法请求的误报。定期更新与测试WAF的规则库需要定期更新以应对新出现的攻击手法。同时可以定期对自己的网站进行安全的渗透测试或在授权下请专业人员进行主动发现WAF可能遗漏的问题。6. 实战心得思维比工具更重要回顾整个绕过过程我最大的感触是自动化工具固然高效但手动的、基于理解的测试往往能发现更隐蔽的问题。一开始工具可能被WAF轻易挡住报告“无漏洞”。但通过我们一步步的手工构造、观察响应、分析拦截点、调整Payload最终找到了多条可行的路径。这个过程锻炼的是一种“对抗性思维”。你需要站在防御者WAF的角度去思考它会检查什么怎么检查它的检查逻辑可能存在哪些盲区然后你再作为攻击者去尝试利用这些盲区。这种思维不仅适用于SQL注入绕过也适用于其他类型的WAF绕过、漏洞挖掘。最后必须再次强调所有技术讨论仅限用于授权测试、安全研究和自身系统加固。未经授权对他人系统进行测试是违法行为。希望这篇文章能帮你更深入地理解Web应用防火墙的工作机制和SQL注入攻防的实质在保护自己系统的道路上走得更稳、更远。安全是一场持续的动态博弈保持学习保持敬畏。