找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2786

积分

0

好友

374

主题
发表于 昨天 19:02 | 查看: 16| 回复: 0

前言

刚接触漏洞挖掘的朋友,常常会陷入一个误区:只对一些基础的功能点进行浅尝辄止的测试。为了拓宽大家的挖掘视角,本文将整合多位优秀师傅分享的思路,并结合笔者自身的实践经验,提炼出一些精华技巧。这些零散的优质想法之前缺乏系统的梳理,现在我将一部分优化思路汇总起来,希望能实现思路价值的叠加效应。

前置基础:请求、状态码与接口信息

在功能点测试无从下手时,未授权漏洞往往隐藏在你所忽略的请求和状态码信息中。很多人测试接口时,只测试最初发现的那一层,并不会仔细甄别接口的前置目录是否正确。他们常常盲目爆破得到一堆 404 响应,即使第一次找到的接口拼接后能够访问,也只是看一眼功能而已,并不会去观察响应字节大小的变化,并基于新加载的信息去尝试二次拼接和深度挖掘。

请求方法与状态码回顾

请求方法

GET:获取资源。GET请求用于从服务器获取指定的资源。它是最常见的请求方法,通常用于请求和读取服务器上的数据。

POST:提交数据。POST请求用于向服务器提交数据,通常用于创建新的资源或在服务器上执行某些操作。

PUT:更新资源。PUT请求用于向服务器更新指定的资源,通常用于修改或替换现有数据。

DELETE:删除资源。DELETE请求用于从服务器删除指定的资源。

HEAD:获取资源的元数据。HEAD请求与GET请求类似,但它只返回资源的响应头部信息,而不返回实际的资源内容。

OPTIONS:询问服务器可接受的请求方法。OPTIONS请求用于向服务器查询支持的请求方法。

PATCH:部分更新资源。PATCH请求用于对服务器上的资源进行局部更新,只修改指定的字段或属性。

TRACE:追踪请求的路径。TRACE请求用于在客户端和服务器之间进行往返检查,以查看请求在传输过程中是否被修改。

CONNECT:建立代理服务器隧道。CONNECT请求用于与代理服务器建立隧道连接,通常用于通过代理访问SSL加密的资源

常见状态码

200 OK: 请求成功。服务器已成功处理请求

301 Moved Permanently: 永久重定向。请求的资源已被永久移动到新的位置。

302 Found:临时重定向。请求的资源临时被移动到另一个URL

304 Not Modified:未修改。自从上次请求后,资源没有发生变化,可以使用缓存的版本

400 Bad Request:错误请求。服务器无法理解请求,通常是由于客户端错误,如缺少参数。

401 Unauthorized:未授权。请求要求用户的身份验证。

403 Forbidden:禁止访问。服务器理解请求但拒绝执行。可能是因为权限问题。

404 Not Found:未找到。服务器上没有找到请求的资源。

405 Method Not Allowed:方法不被允许。请求行中指定的请求方法不能被用于请求相应的资源。

408 Request Timeout:请求超时。服务器等待请求时发生了超时。

500 Internal Server Error:内部服务器错误。服务器遇到了阻止其完成请求的意外情况。

501 Not Implemented:未实现。服务器不支持请求的功能,无法完成请求。

502 Bad Gateway:错误网关。作为网关或代理工作的服务器从上游服务器收到了无效的响应。

405接口的挖掘与拼接

利用 GET 方法去拼接发现接口是比较常规的操作。这里的重点是当遇到 POST 方法以及状态码为 405 的情况。

Burp Suite 拦截到405状态码的请求列表

处理方法是:将请求方法修改为 POST,并在数据部分加入一个空的 JSON 请求体。因为某些时候,仅仅修改请求方法而没有提供请求体,后端可能不会返回有效的数据。这样做常常能带来意想不到的惊喜。之后,根据接口的响应(如果提示缺少某些参数),再去补充对应的参数。

POST

Content-Type: application/json

{
}

修改请求方法并添加空JSON体

正确跑出接口后,关键是根据字节长度 (size) 来筛选。字节长度较大的响应,通常意味着加载了新的内容或新的 JS 文件。然后,基于这个新接口,在浏览器中带着参数访问,逐步测试,层层深入。

根据响应长度筛选出加载了新内容的接口

403未授权与权限绕过技巧

对于希望进阶的测试者,强烈推荐关注接口测试及 JS 信息挖掘。通过细致的挖掘,往往能找到高质量的未授权访问漏洞。

“闪屏”后台页面的利用

有时在访问后台时,页面会瞬间闪现出后台界面,然后立即重定向到登录页面。这里提供两种测试方法,重点阐述第二种。

  1. 利用 Burp Suite 卡包:拦截进入后台的请求包不放行,然后在前台页面点击各个功能。点击结束后,再一个个地放行被拦截的包。这样可以测试未授权访问,但效率较慢,需要逐个功能点击,并且有时新加载的接口并不直接出现在页面源码中。
  2. 卡住登录包:在登录时拦截请求,等待片刻,浏览器可能会加载后台的 JS 文件。此时利用爬虫或扫描工具就能探测到这些后台接口,拿到后就可以直接批量测试未授权了。下图就是一个典型案例,卡住登录请求后,就不会收到重定向指令。

拦截登录请求后加载出的后台接口列表

如果后台页面不会一闪而过,而是直接显示登录框,可以尝试手动输入账户密码后拦截响应包,将登录成功的标志(如 success: false)修改为 true。如果前端校验不严格,可能会短暂进入后台,然后被重定向。如果这个方法可行,就可以继续用第二种方法去挖掘更多的未授权接口。这个思路是从一篇微信公众号文章中学到的。

通过修改登录响应包绕过前端校验

Type参数越权

当我们遇到编辑功能或权限分级(如管理员、编辑者、创作者、查看者)时,如果身份类型不一致,可以尝试修改决定用户类型的 type 参数,将自己的身份提升至高权限,从而执行越权操作。

type: 0 // 查看者
type: 1 // 编辑者 (可能代表管理员)

无权限URL添加资源后缀绕过

URL混淆漏洞是指由于服务器端不同组件解析 URL 的规则不一致,攻击者可以利用这种差异来绕过安全控制。一种常见的手法是在路径末尾添加 .json.css 等资源文件后缀。

URL混淆绕过示意图

正常接口返回无权限 403

正常请求返回401未授权

在接口末尾添加 .json 后缀后成功绕过

通过对接口路径进行混淆,利用字典对路径的不同位置进行 Fuzz,添加 .json 等后缀进行绕过。在测试鉴权相关的漏洞时,可以尝试 URL 混淆,在接口的多个位置 Fuzz 添加资源文件后缀。

/api/user      ----> 未授权 403
/api/user.json ----> 200 OK

添加.json后缀后成功访问并下载文件

我通常利用 Burp 插件 OneScan 来帮助我自动在接口的不同位置拼接后缀进行测试。在插件中设置好字典,遇到可疑的 403 接口就发送过去扫描,利用资源文件后缀在多个位置进行拼接尝试。

使用OneScan插件对403接口进行FUZZ

如果出现状态码为 200 且响应字节长度 (size) 很大,那么大概率加载出了新的内容,我们也就获得了更多的测试点。

FUZZ后找到状态码200且长度异常的接口

常用资源文件后缀/混淆字典

%09
%20
%23
%2e
%2f
/%2e/
//
/..;/
//..;/
/%20
/%09
/%00
/.json
/.css
/.html
/?
/??
/???
/?testparam
/#
/#test
//.
////
/.//./
~
.
..;
。
;%09
;%09..
;%09..;
;%2f..
*
.json
../
..;/
?a.css
?a.js
?a.jpg
?a.png
../admin
..%2f
./
.%2f
..%00/
..%0d/
..%5c
&
#
@
??
\..\.\
.././
/;/
.%2e/
..\
..%ff/
%2e%2e%2f
%3f
?.css
?.js
%3f.css
%3f.js
%26
%0a
%0d
%20
%0d%0a
%3b
\
.\

此外,Burp 插件 BypassPro 也可以用来处理 403 接口。

BypassPro插件界面

Vue框架带#未授权的二次拼接

Vue 等前端框架的路由前常有 #,这类路径在数据包中通常抓取不到。当爬虫工具找到一批带 # 的接口时,无法直接用 Burp Intruder 进行爆破测试。这里有几个方法可以尝试:

  1. 手动拼接与递归发现:首先,尝试手动拼接爬虫发现的路径。如果某个拼接后的接口可以访问(例如,显示出风险报告页面),那么就在这个有效接口的基础上,再次查看浏览器加载的新 JS 文件,获取更多接口,然后基于这些新接口再次进行未授权测试。如此循环往复。
https://example.com/rental/#/login

爬虫发现的Vue应用带#路由

手动拼接后可能得到一个有效路径:

https://example.com/paypage/#/riskReport?transld=

手动拼接后得到的有效功能页面

  1. URLFinder 等工具扫描:使用 URLFinder 等工具对目标进行扫描。注意观察响应字节 (size) 大小。当字节数发生变化时,代表加载了不同的数据或 JS 文件。此时,可以再次用爬虫工具基于新的 URL 去发现更多接口,然后在这些新接口的基础上进行二次拼接测试。

URLFinder扫描结果

URLFinder发现的高危隐藏路由

寻找前置接口的共性

有时,我们在 JS 文件中发现一个接口 /rebateBillSettlementList,但它的完整前置路径 /api/gw/rent/rebateBillSettlementList 却从未见过。这提示我们,站点可能使用了一个共用的接口前缀目录。我们可以尝试以这个目录 (/api/gw/rent/) 为前缀,去爆破其他发现的接口片段,或者将已发现的接口按这个结构重组。虽然不一定每次都成功,但值得尝试。

所以说,挖掘 SRC 最好专注于某一厂商,去“熟悉业务”。这里的“熟悉业务”概念可能比较模糊,新手的疑问是:为什么要熟悉业务?挖什么不是挖呢?我对“熟悉业务”的理解是:理解该厂商开发人员的代码习惯。同一批站点往往有很多相似之处。如果 Web 端和小程序端使用同一套代码,那么一个站点可以登录注册,另一个只有空白页面,token 是否可以通用?A 站点只有普通用户权限,B 站点有管理员权限,那么接口互换一下呢?这需要我们举一反三。当然,高手可能直接就能发现漏洞。但当我们还不能对漏洞信手拈来时,能做的就是认真分析每一个数据包,记录并实践每一条思路!坚持下去,发现漏洞只是时间问题。

在JS中发现某个接口,推测其完整路径

如果经常对同一厂商进行挖掘,可以积累该厂商的业务接口。有时,多套系统会部署相同的接口。A 站点的接口可能在 B 站点也能使用,将 A 和 B 站点的接口组合一下,又可能发现新的接口,从而扩大攻击面。

同一厂商不同业务系统的相似接口

越权查询与操作漏洞挖掘

各类功能点越权

任何交互处都可能存在越权,这是需要牢记的原则。

查询信息与日历接口

对于查询类功能,除了测试越权,还需要关注是否存在 XSS 或 SQL 注入。观察响应包是否有回显,可以尝试使用 % 等通配符测试模糊查询或注入。

深度挖掘的关键是:把所有能点击的地方全都点开看一看。

订单管理后台的复杂查询功能

弱鉴权参数(Cookie)

在个人信息交互的功能点,通过 Burp 抓包,找出决定用户身份的参数。常规方式是找 uid,但有时也可能是其他参数,比如手机号。尝试修改为别人的号码,看是否能越权查看。可以逐个删除 Cookie 中的字段并发包,直到响应报错,这样就能确定被删除的字段是关键鉴权信息。如果是 JWT 鉴权,可以尝试一系列针对 JWT 的攻击方法;如果是其他弱参数鉴权,则可以尝试爆破。

评论区越权

评论区是越权的重灾区。

  1. 越权删除评论:首先抓取删除自己评论的数据包,尝试替换成别人的用户 ID 或评论 ID。
  2. 回复模块越权:抓取回复别人的数据包,尝试替换用户 ID,实现“让别人回复别人”的效果。
  3. 注意新功能点:回复评论可能会触发新的接口或功能点,这些新的交互点也需要测试。
  4. CSRF 越权回复:测试是否存在 CSRF,可以诱使受害者越权回复他人。

另类URL编码汉字越权

决定用户身份的 ID 可能不再是简单的数字,而是经过编码的汉字(URL编码)。所以,并不是不存在修改 ID 越权的情况,只是明文数字 ID 已近乎绝迹,取而代之的是未经严格鉴权的编码 ID 或有规律的长 ID。测试越权时,最好同时打开两个不同权限的账户进行对比,这样既不影响正常用户业务,又能快速通过数据包差异找到突破口。利用文本对比工具可以迅速定位差异。下面的编码汉字只是其中一种形式,这里想传递的是举一反三的思路。

GET /XXX?id=%E4%B8%94%E4%B8%98%E4%B8%96%E4%B8%93 HTTP/1.1
Host: XXX
Accept: *
......
Connection: close

id=%E4%B8%94%E4%B8%98%E4%B8%96%E4%B8%93 解码后是:且丘世专

所以 且丘世专 这四个字的 URL 编码对应着我的用户 ID。

汉字与URL编码对应表

普通用户利用管理员接口升级权限

核心思路是:普通用户 A 获取到管理员 B 的“生成管理员”邀请接口,然后 A 自己调用这个接口生成一个邀请链接,再自己去点击,从而使自己成为管理员。

场景 A:

  1. 管理员 B 生成了一个“团队查看者”链接,A 点击后成为团队成员。
  2. 我们测试用的账户 B 是管理员。我们拿到 B 的“生成团队编辑者(即管理员)”接口。
  3. 普通用户 A 使用 B 的这个接口(替换身份参数为自己),生成了一个“编辑者”邀请链接。
  4. A 自己去点击这个链接,于是 A 就成为了和 B 一样的管理员。
  5. 简单说,A 使用了 B 的高权限功能接口,相当于“免费使用了付费功能”。

场景 B:
普通用户申请权限时,对比管理员账户 (admin) 和普通用户的数据包差异。尝试修改普通用户申请权限数据包中的角色参数,例如将 role: "user" 修改为 role: "admin"role: "root"。我们可以用字典来尝试这些可能的值。

role:"user"    修改为 role:"admin"

信息泄露类接口挖掘

查询类功能测试思路

有的接口参数使用斜杠 /,有的使用问号 ?,但有时效果是一样的。

URL参数中斜杠与问号效果相同的示例

信息泄露常常伴随着 JS 文件中的接口参数拼接。对于查询类功能,记住:删除所有查询参数、将参数值置空、或者输入 % 进行模糊查询,都是基本的测试手法。

GET /api/demo/query= xxxxxx    # 正常查询
GET /api/demo/                 # 删除查询参数
GET /api/demo/query=           # 置空参数值
GET /api/demo/query=%          # 模糊查询

特别是针对带有 id 等资源标识符的接口。

h5/qrCode.html/?id

测试方法:
h5/qrCode.html/?id=      # 置空
h5/qrCode.html/?id=%     # 模糊查询/%
h5/qrCode.html/?id=null  # 添加null
h5/qrCode.html/          # 删除参数

Authorization字段鉴权绕过

如果请求头中有 Authorization 字段,置空后通常返回 401。尝试修改其值为 1 或其他值,看是否会返回不同的信息。这个字段常与 JWT 同时出现用于鉴权。修改它可能类似于修改管理员参数或进行模糊查询 (%),可以举一反三进行测试。

Authorization: Bearer xxxxToken

任意功能点的返回包修改

只要后端没有在响应包中返回关键的权限校验标记(如特定的 token 字段),就代表这个功能的鉴权可能只在前端。在站点的其他业务中,类似的响应可能如下所示。结合业务点,如果响应包没有强鉴权信息,可以尝试修改返回包来短暂绕过限制。这种情况多出现在邀请码、代理商申请、管理员提交等有次数或身份限制的场景。绕过后出现的新功能点又可以继续测试。

success: true
code: 200
message: 成功
data: true

获取他人ID的场景

如果决定用户身份的参数只是一个 ID,而没有强后端 cookietoken 鉴权,那么首要任务就是找到别人的 ID。例如,在站点的关注列表、排行榜、社区评论区、投诉反馈等涉及用户间交互的功能中,常常会带出其他用户的 id

用户ID泄露的可能场景

信息查询:添加list接口

方法一:添加 list 并删除前置路径
原本查询个人信息的路径是 /prod-api/system/info/small/userId
尝试在后面加上 /list,虽然可能返回 404,但可以尝试删除前面的一些路径。

/prod-api/system/info/small/userId/list

在个人信息接口后添加list返回404

尝试删除前面的路径,例如 small,最终可能得到列出所有信息的接口。

/prod-api/system/info/list

方法二:添加 list/ 并以斜杠结束
将个人接口的单词修改为 list 并在末尾添加斜杠 /,有时会绕过某些中间件的解析,列出所有信息。

/api/user/ads/info?a=123456        // 只能看到自己的信息
/api/user/ads/list/?a=123456       // 更改参数并以斜杠结束,可能绕过

信息查询:将参数提升为路径的一部分

在个人信息接口中,如果参数(如用户ID)是以查询字符串(?id=xxx)的形式传递,可以尝试删除参数名和等号,直接将参数值当作路径的一部分来请求。首先需要找到别人的 id,然后进行替换尝试。有时这个值可能是用户的昵称或其他标识,需要多观察业务逻辑,对比自己的个人信息接口来判断。

GET /api/v1/user/info?id=@saber   # 正常写法
GET /api/v1/user/@saber           # 尝试将参数值作为路径一部分

将GET参数值直接作为路径一部分进行请求

个人信息响应数组为空

在个人信息或涉及敏感信息查询的地方,如果我们点击查询,响应包中出现了某个数组结构,但内容为空([]),那么存在越权的可能性就比较大。这意味着查询逻辑执行了,只是当前用户无权查看结果。此时可以尝试删除 token 等鉴权信息后重发请求,可能会回显所有人的信息。

data: []

个人信息JSON批量查询

涉及个人信息的模块,如果请求是 JSON 格式,并且正常只回显一条信息。

请求:

{
   uid: 100001
}

响应:

{
   xxxxx
   xxxxx
   xxxxx
}

尝试手动传入一个包含多个 UID 的 JSON 数组,如果后端没有严格校验,响应包也可能会回显出多个用户的信息,造成批量信息泄露。

请求:

[
  { uid: 100001 },
  { uid: 100002 },
  { uid: 100003 }
]

响应:

[
  { ...用户1信息... },
  { ...用户2信息... },
  { ...用户3信息... }
]

利用 page & size 参数

对于分页查询接口,尝试将查询参数置空或改为特殊值(如 %),然后将 pagesize 参数改为一个很大的数值(如 9999)。这可能绕过数据量限制,看到本不该看到的大量数据,造成信息泄露。其原理是前端传入了巨大的 size 值,而后端没有做好限制。

路径本身就是ID参数

如果接口的路径中直接包含了ID值,无论ID出现在路径的前面还是后面,都应该测试一下遍历和删除操作。删除ID部分后发送请求,有时会返回所有用户的信息列表。

GET /api/user/123456
GET /api/123456/user
GET /api/user/          # 删除ID后发送,可能回显所有用户信息

拼接新参数造成越权

记某src通过越权拿下高危漏洞

如果两个不同的接口返回的内容结构一致,那么一个地方存在越权,另一个地方也可能存在。如果 Userid 无法直接遍历获取,可以想办法从其他接口找到它,然后利用 & 符号将其拼接到目标请求中,实现越权。当全部个人信息都依赖 cookie 鉴权时,可以尝试这种方法。


文章案例
接口 GetUser 会显示用户敏感信息,但请求中只有 Version 参数可以修改,且修改它没用。修改 cookie 也无法越权。

/gateway/nuims/nuims?Action=GetUser&Version=2020-06-01

但是,通过其他接口获得了 UserId 参数后,可以将其用 & 连接到上述接口,从而越权查看其他用户的敏感信息。

/gateway/nuims/nuims?Action=GetUser&Version=2020-06-01&UserId=xxxxxxxxxxxxx

通过拼接UserId参数越权获取他人信息

原文还拓展了思路:第二个接口的正常返回值与第一个接口结构相同,那么第二个接口也可以进行同样的参数拼接,从而“一份漏洞,两份收益”。

第二个接口:/gw/nuims/api/v1/nuims/LcpGetUser
越权请求:/gw/nuims/api/v1/nuims/LcpGetUser?UserId=xxxxxxxxxxxxx

输入框XSS的进阶利用

客服聊天框:修改typehtml

文章实例
在咨询客服的输入框输入内容后抓包,如果看到 Content-Typetype 字段为 text,这意味着输入内容被当作纯文本处理。我们可以尝试将其修改为 html。由于是我们自己主动修改请求,这最初是一个 Self-XSS。需要结合文章中的技巧,将其转化为一个存储型 XSS。

搜索历史处的CSRF+XSS组合拳

抓取网站搜索功能的请求,将其制作成 CSRF PoC。当受害者点击这个 PoC 链接时,相当于在他的浏览器中执行了一次搜索(内容由你控制,比如是一个 XSS Payload)。那么,当受害者之后查看自己的搜索历史记录时,XSS 就会被触发,从而实现了一个存储于受害者“本地”的 XSS。可以利用 XSS 平台直接接收受害者的 Cookie

CSRF+XSS:
如果一个点存在XSS可以弹出Cookie,那么尝试
制作这个请求为CSRF,发送给受害者后它在本地弹窗,我们这里接收到Cookie就完成了攻击,如果是存储型的XSS危害更大。

寻找非常规输入点

文件夹/文件的重命名功能、修改字体设置、甚至某些配置项的名称,都可能是潜在的输入点。只要用户可以自定义内容,就可能有插入 XSS 的机会。核心思路是:尽可能多地找到用户可控制的输入框或文本区域,在小众或后台页面尝试插入测试Payload,如 test"><

Get参数型XSS的定位

URL 中出现 ?name=xxxx 这类参数时,我们输入测试值后,可以通过浏览器的开发者工具(F12)全局搜索(Ctrl+F)我们输入的内容。每次输入完都按 F12 搜索一下,看看内容被加载到了页面的哪个位置。为了避免被过滤,可以先输入一段正常的文字,等找到内容被带入的位置后,再想办法构造最终的 Payload。这个方法有点麻烦,但可以一试。

在地址栏参数中输入内容并在页面源码中搜索

Multipart请求格式绕过WAF

微信文章
将普通的 application/x-www-form-urlencodedJSON 格式的 POST 请求,更改为 multipart/form-data 格式,有时可以绕过后端的某些实体化解析规则或 WAF 的检测,从而成功注入 XSS 等Payload。

Multipart请求格式说明

希望这些在 云栈社区 分享的实战技巧,能帮助你在漏洞挖掘的道路上走得更远。安全测试需要耐心、细心和不断的实践总结,保持学习,持续精进。




上一篇:基于Java+Claude Code的多Agent股票分析系统搭建心得
下一篇:超越付费课程:5个高价值GitHub仓库助你突破开发瓶颈
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 16:54 , Processed in 0.792180 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表