首页 / 资讯中心 / 文章详情

基于Burpsuite的越权与未授权漏洞自动化检测插件实战解析

基于Burpsuite的越权与未授权漏洞自动化检测插件实战解析 ★ FEATURED ARTICLE
做安全测试的兄弟应该都有过这种体验测一个业务站点光越权漏洞就得手工注册两个账号来回切、改ID、比对返回包翻来覆去折腾半天最后还不一定把接口覆盖全。未授权漏洞也一样一个个接口去试全靠手工点脑子稍微一乱要么漏掉要么重复。我当年在测试一个后台管理系统的时候因为接口太多手工测越权测到凌晨结果第二天复盘才发现漏掉了两个风险点。也就是那时候下定决心必须搞一个能自动干这活的Burpsuite插件。陆陆续续写了不少版本最近把它更新到了适配新版Burpsuite的状态顺手把一些积累了挺久的想法也加了进去。这篇文章就把这款自动化检测越权、未授权漏洞的插件全貌拆开聊一聊包括设计思路、核心实现、使用教程和踩坑记录给需要做这类检测的朋友一个参考。1. 越权和未授权漏洞为什么会成为测试重点1.1 两种漏洞的定义和区别先说清楚一个容易混淆的点。越权漏洞指的是一个已经登录的普通用户通过修改请求参数、修改请求地址等手段访问到了本不该有权限访问的数据或功能。比如把购物订单号换掉查看别人的订单详情这种属于水平越权普通用户通过构造请求调用了管理员的删除接口这种属于垂直越权。未授权漏洞则不一样。它指的是完全不需要登录或者绕过登录校验就能直接访问到后台接口、敏感接口。最典型的就是管理后台的API接口没有任何鉴权中间件直接裸奔在公网上任何人拿个Http请求工具就能调。很多人把这两个混为一谈但检测思路差别挺大的。越权检测的关键在于身份切换后的访问结果对比而未授权检测的关键在于未携带身份信息时能否直接拿到有效响应。所以插件必须把这两套逻辑分开设计。1.2 它们为什么容易出现在实际业务中实战中碰到最多的两个场景一是前后端分离项目前端只做了按钮隐藏没有真正做权限控制二是接口文档管理混乱内网接口忘了加权限校验就部署到了生产环境。尤其是现在微服务架构流行一个网关后面挂几十个服务权限校验经常出现漏配的情况。我在测试一个跨平台系统某企业内部的OA系统这里就不提具体名字了的时候就发现他们的用户信息查询接口完全没有在网关层做鉴权任何人只要知道接口路径直接GET请求就能拉回一批用户手机号。这种问题光靠人工测试如果不知道路径就测不出来但有了自动化插件只要从历史请求里把路径捞出来再逐个去掉身份信息重放很快就能暴露。1.3 手工测试的难点在哪里手工测越权的痛点其实就三个第一个是账号切换成本高尤其遇到短信验证码登录的系统每注册一个测试账号都要收一次码来回倒腾非常崩溃第二个是请求量太大一个接口可能要测好几个ID、好几种角色单靠人在Burp里手动改包根本点不过来第三个是响应比对靠肉眼两个返回包若是只有某个字段不同肉眼很容易漏判。所以做这个插件的核心目标很明确把登录两个账号变成自动切换身份把肉眼比对响应变成算法算相似度把一个个试接口变成批量重放所有接口。这个思路就是整个插件的灵魂。2. 插件整体设计思路2.1 先确定功能边界写工具最怕的就是什么都想塞进去。最开始我想把更多检测能力都塞进这个插件里比如SQL注入检测、XSS检测但后来发现这样一来插件会变得特别臃肿而且不好维护。最后我砍掉了所有其他漏洞检测的模块只保留两个核心功能越权检测和未授权检测。明确了边界之后整个插件的架构其实就清晰了。它需要做的只有三件事收集流量、修改请求并重放、对比响应判断漏洞。收集流量这个动作依靠Burpsuite的代理日志来获取插件只需要把用户标记过的请求存起来就行。修改请求和重放是整个插件的核心工作需要设计好改包的逻辑。响应对比则需要选择合适的算法。2.2 核心模块划分插件的功能结构我分成了五个模块。第一个是流量收集模块负责把经过Burp代理的请求按照用户指定的作用域过滤出来同时去掉一些明显不需要测的静态资源请求比如图片、CSS、JS文件。第二个是策略配置模块用户在这里配置测试账号、目标接口、请求头的处理规则等等。第三个是重放引擎模块这是最重要的模块它负责根据策略生成新的请求用当前登录的Session发起重放。第四个是响应分析模块负责对比原始请求和重放请求的响应结果。第五个是报告生成模块把检测结果整理成表格方便导出。这五个模块之间互相独立通过接口通信。这样的好处是如果我想优化某个部分不用把整个插件重写一遍。2.3 为什么选择基于Burp扩展API开发其实在做这个插件之前我也想过用别的方案比如直接用Python写一个独立的扫描器。但仔细一想独立扫描器需要自己去处理代理、抓包、Session管理这一堆破事开发成本太高了。而Burpsuite本身已经解决了流量获取和中间人代理的问题我只需要把精力放在请求分析和改包重放上效率完全不同。另外还有一个重要的原因Burpsuite的扩展API里自带了Session处理机制和Cookies管理这意味着我可以直接复用Burp的会话能力不用自己去写登录态的获取和维持代码。这对一个个人开发者来说省下的工作量不是一点半点。新版Burpsuite的扩展API也做了不少调整比如Montoya API的要理清楚了。老版的IBurpExtender接口虽然还能用但官方已经越来越不推荐了所以我这次更新就是把这套旧的API全部换掉这在后面我会细说。3. 核心逻辑实现细节3.1 请求拦截与流量标记插件的入口是Burp的HTTP处理器HttpHandler。所有经过代理的请求都会被插件拦截到。但我不会对每一个请求都做处理那样性能会崩。我会先做一个筛选只处理用户配置的作用域内的请求并且Content-Type是JSON、表单、XML这类业务请求的才进入后续流程。筛选通过之后请求会进入一个滑动窗口缓存。我维护了一个请求队列每个请求记录下完整的URL、请求方法、请求头和请求体方便后续修改重放。同时在Burp的UI面板上我会给这些请求加一个高亮标记打上Potential标签方便用户在中转过程中直观地看到哪些请求已经被缓存。有几个细节要特别注意第一HTTPS请求一定要能正常处理证书信任问题要提前配好第二文件上传接口不要进重放池因为重放文件上传请求可能会产生一堆垃圾文件第三带Token的请求要把Token从请求头里剥离否则后续重放时可能会被服务端拒绝。这些都是我在实际测试中踩过的坑。3.2 水平越权测试逻辑水平越权的检测逻辑是插件最核心的部分。我这里的方法是两账号比对法用户需要至少配置两个测试账号A账号和B账号。首先用A账号正常访问目标接口拿到一个基准响应然后用A账号的Session去重放这个请求但把请求中与用户身份相关的参数替换成B账号的资源ID最后对比两次响应。什么是用户身份相关的参数这里我用了一套基于规则的提取方式。优先从路径中提取比如/api/user/{id}/info这种RESTful风格的接口路径参数就是身份标识。其次从查询参数中提取比如?userId123。再就是请求体中的字段比如JSON里的owner_id。用户可以在插件界面上手动指定要替换的参数名也可以让我自动提取。替换逻辑说穿了很简单把原始请求中的那个ID值替换成另外一个账号的资源ID。但难点在于如何构造第二个账号的资源ID。我是这样做的先用B账号登录然后让插件自动请求一个配置好的个人信息接口把B账号的资源ID从响应中提取出来存到内存里。替换的时候就拿这个ID去换A请求里的ID。响应对比用了两部分状态码和响应体。如果状态码相同响应体也长得差不多那基本可以判断存在水平越权。但如果状态码变化明显或者响应体出现了无权限之类的字眼那就说明没有越权。3.3 垂直越权测试逻辑垂直越权的逻辑和水平越权有点不一样。垂直越权关注的是低权限用户能不能调用高权限接口。所以我会让用户配置两个角色账号一般是一个普通用户和一个管理员。然后用普通用户的Session去重放管理员的请求看能不能成功。这里有两种情况需要区分。第一种是接口本身没有做权限控制普通用户直接访问管理员接口就成功了这种属于典型的水平权限提升。第二种是接口做了前端控制但后端没有校验这种情况往往请求还能通但返回数据不完整或者某些字段为空。我通过检测返回体中的字段数量差异来辅助判断如果返回体的JSON字段数比预期少了很多会标记为疑似垂直越权。垂直越权检测有个很大的坑在于管理员接口怎么找我采用的办法是从流量中智能识别。如果一个请求的URL里包含admin、manage、system、user-management等关键词我就会把它归入高权限接口池。用户也可以手动添加URL前缀来指定哪些接口算高权限接口。3.4 未授权访问检测逻辑未授权访问的检测思路相对直接但仍然需要考虑两个不同的方向。第一个方向是去认证重放取出原始请求把Cookie头、Authorization头等所有身份凭证信息全部剥掉直接重放。如果响应里还包含完整的业务数据那说明接口存在未授权访问。第二个方向是换无效Token重放把Authorization替换成InvalidToken之类的占位符看服务端会不会直接拒绝。如果返回200或者直接返回业务数据那就说明Token校验形同虚设。这里有一个关键是未授权检测不能简单粗暴地把所有请求头都删掉因为有些接口虽然不做权限校验但做了CSRF校验或者其他的非身份校验。如果直接把所有头删掉可能会因为缺少某些必要的头而返回400造成误报。所以我提供了一个配置项让用户决定哪些头要保留哪些头要删除。默认配置是只删除Cookie和Authorization保留其他所有的请求头。未授权访问的响应判定我采用了一个更保守的策略。只有同时满足以下三个条件才标记为未授权漏洞第一响应状态码与原始请求一致第二响应Content-Type是JSON等业务类型第三响应体长度大于某个阈值可配置默认500字节。这样做的目的是尽量降低误报率因为很多登录页本身也会返回一堆HTML代码但那些不是业务数据。3.5 响应对比与相似度计算响应对比是整个检测流程的最后一步也是最容易出问题的一步。一开始我用了最简单的方案两个响应体完全一致就判定为越权。但后来发现这个方案根本不行。因为很多动态接口会在响应中包含时间戳、随机数、当前用户昵称等动态字段导致服务端正常响应时两次返回的响应体也会不一样。后来我换成了基于Token的差异率计算。把两个响应体的文本进行分词然后计算不同的Token数量占总Token数量的比例。如果差异率低于用户设定的阈值默认10%就认为是基本一致即存在越权。如果差异率在10%到50%之间标记为疑似需要人工复核。如果差异率超过50%则认为是不同内容不存在越权。这个方法在实际测试中效果还不错。但有一个问题是一些动态字段如前端的随机ID会导致差异率虚高。所以我加了一个忽略字段的功能。用户可以把动态字段名加进去插件在对比时会把这些字段的值统一替换成固定占位符再进行Token比较。如果你对算法有更好的想法比如用SimHash或者向量化相似度我觉得也是完全可以的。对于个人插件而言这个基于Token差异率的方法已经能覆盖绝大多数场景了。4. 使用教程与配置参数4.1 安装与环境要求新版本插件基于最新的Burp Montoya API开发所以需要较新版本的Burpsuite才能跑起来。建议使用官方最新版。开发语言是Java你需要确保本地有Java 17以上环境不然插件在加载阶段就会报ClassNotFoundException。安装过程非常简单打开Burp - Extensions - Add - 选择插件Jar包 - Next。但要注意插件加载后会自动创建一个新的Tab页如果Burp界面没看到这个Tab说明加载失败了可以去Errors面板看报错信息。常见的原因是JDK版本不兼容以及Jar包缺依赖。我这次更新把依赖都打进了Fat Jar里所以一般情况下不需要额外装依赖。插件本身没有独立的下载热门链接因为直接把下载地址贴出来很容易被滥用。我建议你在自己用的代码托管平台里搜插件名称找发布版本的Release页面去下载。或者从源码自己编译也就一条命令的事。4.2 策略配置说明插件的配置界面设计得比较简洁。主界面上有几个核心配置项作用域Scope限定插件只处理哪些域名支持通配符。检测类型勾选要执行的检测可以单选或者全选。越权测试账号配置A账号和B账号的登录入口以及身份标识参数。未授权检测配置选择要剥离的请求头默认剥离Cookie和Authorization。响应判断阈值差异率阈值、最小响应长度阈值。忽略字段填写需要忽略的动态字段名多个用逗号分隔。这里特别强调一下账号配置。插件本身不负责登录你需要先在Burp里用A账号登录目标系统捕获登录后的请求然后右键发送到插件插件会自动提取当前的Cookie和Session标识保存为A账号Session。然后你再退出登录切B账号登录同样操作保存为B账号Session。之后插件在检测时就会自动切换这两个Session。4.3 实操流程演示我举个实际例子假设现在要对一个模拟业务系统某跨平台系统的订单管理模块做越权检测。第一步设置Scope为example.com检测类型勾选水平越权垂直越权未授权访问。第二步在Burp代理中正常操作A账号浏览订单列表、查看订单详情、修改个人资料等让插件缓存一批请求。这里要注意操作覆盖面尽量广把带ID参数的接口多触发几个。第三步切换到B账号在插件配置页里绑定B账号Session然后在越权测试页面点击开始检测。插件会自动遍历所有缓存的请求找到带身份参数的接口用B账号的资源ID替换并用A账号的Session重放。第四步等待跑完看结果列表。插件会把每个检测项标记为存在越权、疑似存在或未发现。点击每一项可以看到原始请求、重放请求和响应差异率的详情。第五步对于标记为存在的项我建议你在Burp的Repeater里手动复测一遍确认一下是否真的可以利用。自动化工具的作用是辅助你定位可能的问题最终的验证一定不能省。4.4 结果解读与报告输出检测结果的展示我做了分类和统计。除了列表之外还会生成一个简单的统计面板列出总共检测了多少个接口、发现多少高危、多少中危、多少疑似。报告可以导出成Markdown或者CSV格式方便直接贴进测试报告。我建议你按风险等级来处理高危的是那种响应体完全一致且包含完整业务数据的越权或未授权访问这种必须当天就提到缺陷系统里中危的是响应有一定差异但能访问到核心字段的需要进一步人工验证低危和疑似可以攒起来等下一次测试的时候一起复测。结果解读这块有一个很重要的原则漏洞判断要结合业务上下文。比如某些接口虽然没做权限控制但返回的数据本身就是公开信息那就算不上漏洞。所以插件的判定只能作为参考真正定性一定需要人工结合业务场景来判断。5. 新版本更新内容与优化5.1 适配新版API这次更新最大的变化就是彻底从老的IBurpExtender接口迁移到了Montoya API。老接口在最新版Burp上已经不能使用了而且官方也不太可能再做长期维护。Montoya API的设计更现代接口划分更清晰尤其在HTTP处理这块提供了更灵活的请求编辑能力。迁移过程其实挺痛苦的不少接口的调用方式变了。比如老的IExtensionHelpers变成了HttpService和RequestResponse的组合请求的修改也从字符串拼接变成了HttpRequest对象层面的操作。这让我重写了不少代码。不过换来的好处也很明显插件的稳定性和性能都提升了尤其是在处理HTTPS并发请求时明显感觉更顺畅。5.2 检测逻辑增强新版增加了两个比较实用的功能。第一个是级联ID提取针对那种资源ID不是一个而是多个参数的情况比如订单接口同时包含orderId和subOrderId插件会同时提取和替换而不是只处理第一个匹配项。第二个是动态路径感知针对路径参数不再是死板地把路径里的数字全换掉而会结合参数名来判断哪些数字更像资源ID。另外新版还优化了未授权检测的判定逻辑。老版本经常会把返回登录页误判为未授权访问因为登录页状态码也是200。这次我增加了内容指纹库把常见的登录页关键字如login、password、验证码等单独过滤掉误报率降了一半还不止。5.3 性能与稳定性优化性能方面之前老版本跑100个接口的检测可能要五分钟现在做了并发控制把线程数调到默认8并且设置了每个接口的超时时间默认10秒整个流程跑下来两三分钟就搞定了。同时缓存了一些DNS解析结果避免了频繁重复DNS查询带来的延迟。稳定性方面加了三个之前没考虑到的细节第一是内存保护请求缓存设置了最大条数超出上限会自动丢弃最旧的请求防止跑测试的时候Burp内存爆炸第二是异常重试机制网络超时或者连接重置时自动重试一次避免因为临时网络抖动产生误报第三是日志系统所有插件的关键操作都记录到文件方便排查问题。5.4 后续规划接下来我打算给插件加一个批量Target支持也就是同时检测多个域名而不是只限定一个Scope。另外还想加入对WebSocket接口的越权检测支持目前市面上对WebSocket的越权检测工具比较少这个方向也是不少朋友私下问过我的。说实话做一个自己够用的插件和做一个能让别人也顺手用的插件完全是两码事。后面我会继续维护如果有新的想法或者大家有需求也会持续更新下去。6. 常见问题与排查技巧6.1 插件加载失败的常见原因加载失败是最常见的问题。如果你在Extensions面板里看到插件报错我建议按这个顺序排查确认Burp版本是否够新Montoya API需要较新的版本。确认本地JDK版本Java 17以下会直接加载不了。看Error面板的最新报错如果是ClassNotFoundException大概率是依赖没有打包全如果是UnsupportedClassVersionError就是JDK版本问题。把插件Jar包下载完整不要用不稳定的网盘文件最好是从源码仓库的Release页面下载。6.2 检测结果大量误报的原因和对策误报率高的原因我总结了四种第一种响应体里有大量动态字段比如时间戳、随机数、当前用户ID导致相似度计算不准。这种情况就把这些字段名加入到忽略字段里重新检测。第二种接口本身返回的是固定页面比如统一异常页面不管有没有权限返回的内容都一样插件就会误判为越权。需要你把统一异常页面的特征加到过滤规则里。第三种账户配置有问题B账号和A账号的身份标识没有正确提取导致替换的时候替换了不相关的内容。第四种请求头里除了Cookie和Authorization还有其他的身份标识参数比如自定义的X-Token需要在配置里额外指定。如果你遇到的是漏报而不是误报常见原因则是接口的身份参数比较隐蔽比如藏在路径里的UUID插件可能没有识别出来需要替换的参数名这时候需要你在配置里手动添加身份参数名。6.3 检测速度慢怎么优化如果检测速度太慢优先做三件事第一把并发线程数调到16或者更高前提是你的带宽和服务端扛得住第二把超时时间从10秒调低到5秒太慢的接口直接跳过第三减少Scope里的访问量只保留真正需要检测的接口别把所有静态资源都带着。另外如果检测过程中Burp的CPU占用率居高不下通常是响应体太大导致的。可以加一个最大响应体大小的限制超过比如1MB的响应直接不参与比对这个问题会缓解很多。6.4 说一句掏心窝的话写了这个插件之后我自己最直观的感受是测越权和未授权漏洞的效率至少翻了三倍。以前一个项目要花一整天手工测现在插件先粗筛一轮把明显有问题的标出来我再针对性地做人工复验半天基本就够了。而且因为覆盖范围广漏测的概率也小了不少。不过我也想给用这个插件的朋友提个醒自动化工具做得再好也只是辅助。越权漏洞的最终确认一定要靠人去理解业务上下文。你调通的接口到底是不是越权得看这个资源到底应不应该被当前身份访问。这个判断目前没有任何工具能完全替代人去完成。最后再分享一个小技巧在做大规模检测之前先用两三个接口跑一次小测试确认插件行为符合预期再全量铺开。这样既不用反复修改配置也不用担心因为配置问题导致大量漏报的情况。这个习惯我保持了挺久实测下来能省很多事。
阅读完成 · 觉得有帮助?
咨询建站