来自船山院士网络安全团队核心成员SRC大佬:月 的原创。

渗透测试中当页面功能点过少无处可测,或者攻防、SRC场景下开局一个登录框尝试弱口令、爆破、注入无果后针对JS接口寻找未授权信息泄露成为了得分关键。

前端Webpack接口

Vue框架并且使用Webpack打包更容易产生未授权,不是框架本身未授权而是开发者大多使用前后端分离,接口较多更容易出现不鉴权情况。

反编译js.map

Vue使用webpack(静态资源打包器)的时候,如果未进行正确配置,会产生一个app.js.map文件,而这个js.map可以通过Node.js环境安装reverse-sourcemap工具来反编译还原Vue源代码。

Webpack源码泄露反编译教程

reverse-sourcemap -o aaa -v app.9fbea7c7.js.map

还原源代码JS文件中,直接找关键的api目录、config目录从中提取出新的接口进行拼接测试未授权漏洞。

Python脚本提取JS接口

import re

# 读取文件内容
file_path = '1.js'
with open(file_path, 'r', encoding='utf-8'as file:
    js_code = file.read()

# 使用正则表达式提取路径
# 匹配 GET 或 POST 请求的路径,支持单引号或双引号
pattern = r'''(D.post|D.get)(['']([^'']+)['']'''
matches = re.findall(pattern, js_code)

# 打印匹配到的路径
if matches:
print('Matched paths:')
formatch in matches:
        method, path = match
print(f'{method.upper()}: {path}')
else:
print('No paths matched.')

Packer-Fuzzer寻找新接口API

Webpack打包站点手工审计JS寻找接口往往慢人一步,生成的JS文件数量异常之多并且总JS代码量异常庞大(多达上万行),这给我们的手工测试带来了极大的不便,利用此工具可以很好解决此问题。

Packer-FuzzerGithub地址

工具会对Webpack 打包站点自动API模糊匹配与漏洞检测,扫描所有JS文件存在的接口并拼接访问测试未授权等漏洞。 结束后会生成报告文件参考。

// -t adv 代表使用高级版进行扫描

python3 PackerFuzzer.py -t adv -u http://baidu.com  

根据报告审查是否有未授权接口或其他漏洞产生。

JS接口构造

插件工具

熊猫头

熊猫头插件针对前端显示到的接口或者其他铭感信息进行捕获显示,复制粘贴到BP爆破器GET POST 两种请求方式都测试,接口未鉴权就可以发现一些信息泄露以及未授权漏洞,包括内网的IP等。

但是插件显示是不完整的,针对熊猫头提取出的接口可以手工筛选一遍,例如:findsomething显示接口。

第一个接口应该将冒号去掉添加个数据,第二个接口也应该加入参数,一般也都是这样处理将 ,杂乱参数去除需要值的参数就赋值。

/user/getInfo/:uid  -----> 修改  /user/getInfo/uid

/user/getInfo?uid  -----> 修改  /user/getInfo?uid=xxxx

URLFinder

URLFinder工具地址

相比熊猫头插件提取更加全面,会深入页面JS文件做二层深度扫描不会局限当前页面JS文件,会对JS文件中引入的JS文件做三次的扫描接口拼接,寻找未授权接口或未授权功能点。

baidu.com

app.js                            confif.js                  url.js
app.xxx.js                        config.xxxxxx.js           url.xxxxxx.js
app.sdqew2324.js                  config.jkjk767.js           url.vcbvcj213.js    
api/user/info                     /api/getSharingJson         /api/custommap/

baidu.com/api/user/info
baidu.com/api/getSharingJson 
baidu.com/api/custommap/

如遇到站点铭感无法利用使用扫描器, 利用-t 参数减少线程或者利用二开URLFinder规避。

https://github.com/N-Next/URLFinder-x

//扫描域名并指定输出200状态和403状态码接口 -m 安全深入抓取

URLFinder.exe -u https://baidu.com/ -s 200,403 -m 3

// 线程20

URLFinder.exe -u https://baidu.com/ -s 200,403 -m 3 -t 20

经典开局登录框并且插件也没有探测出有效接口,可以利用工具深度扫描页面JS文件。

通过二层探测JS拼接接口size大小判断是否有新的数据产生,如果size大小跟未登录状态一致那肯定是页面没有变化也不需要额外去看, size数字非常大那么响应出的内容更丰富。

使用URLFinder可以很好的发现隐藏的未授权页面,那么进入功能点了就可以到处点点点,测试是否可以未授权增删改查。

  • 案例

SRC信息泄露

开局登录框,功能点无法利用URLFinder深入抓取JS拼接,找到一处下载接口,访问下载xls泄露网站部门人员工号+姓名,简单快速寻找未授权漏洞。

https://xxxxx/index.php/c/core_user_export/json?__request_data=

文件上传接口XSS

同样开局登录框,熊猫头短暂测试没有效果使用此工具二次对JS深度抓取接口拼接。

探测到隐藏文件上传功能点,成功利用收获文件上传XSS。

Fuzz功能接口

构造功能

如果网站功能点只能允许查看 info 那么在查询接口功能抓包构造其他参数, 因为常见业务接口格式如果js文件中只有查询的接口,那么自己可以尝试一下构造添加、修改和删除接口多观察接口,推测其功能,然后根据功能去FUZZ,毕竟你要实现一个web功能,基本都要有对应的增删改查接口。

api/info?id=1// 正常查询接口

api/ delete ?id=1//   构造删除接口 

/api/v1/api-docs 

//  尝试替换数字

/api/ v2 /api-docs  
/api/ v3 /api-docs

-----------------------------------------------------

查询(获取信息)
search list select query get find

删除(删除某个数据)
del Delete  remove

编辑(更新某个信息)
Update Up edit Change

添加(增加某个信息)
add create new

// 查询接口

GET /api/模块名/list

/api/模块名/all

注意

增删改在实际Fuzz中尽可能不携带参数测试,这些操作涉及到业务,万一误打误撞影响到了真实用户就脱离了测试安全的意义了,携带参数也是利用小号的值。

// 添加
【攻防实战】渗透测试JS接口Fuzz场景研究
POST /api/模块名/add   

// 删除接口

DELETE /api/模块名/id 

GET /api/模块名/del?id=

POST /api/模块名/

// 修改接口

POST /api/模块名/modify

POST /api/模块名/

接口信息泄露

除了构造增删改查外,泄露点更多是在查询处,查询处没有做好鉴权及易导致查询不当全站信息泄露,针对查询功能只要是查询的地方记住删除全部参数以及置空参数或者输入% 。

GET /api/demo/query=xxxxxx

GET /api/demo/ or querylist orlist# 删除查询参数构造list列表

GET /api/demo/query=  # 置空

GET /api/demo/query=%/*  # 模糊查询

假设一个接口是,如下,正常肯定是回显自己的,我们可以自行构造多余的功能,按照语义输出列表,并且前置的信息需要删除 small)翻译也是微小意思推断一下就是只输出小部分的,那么可以尝试这个参数删除发包测试,

/prod-api/system/info/small/userId  ------> 个人信息

/prod-api/system/info/small/userId/list   ------>  报错

/prod-api/system/info/userId/list   ------>  全站用户信息

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

微信文章学习到的思路功能点Fuzz出来后但是无权限利用此方法进行绕过。SRC挖掘-URL混淆的利用

https://mp.weixin.qq.com/s/PoXSeckX0iwBSkIr02zYoQ

URL混淆漏洞是指服务器和解析URL时,由于不同组件或系统的解析规则不一致,可以利用这种不一致来绕过安全控制或获取敏感信息,对路径进行编码添加后缀的方式从而进行绕过。

正常接口无权限。

对最后的接口后面添加混淆,利用字典去Fuzz 添加.json绕过,测试鉴权相关的漏洞时,可以尝试url混淆,接口多个位置fuzz 资源文件。

/api/user ----> 未授权403
/api/user.json/css/png --- 200 ok

白名单../绕过权限接口

社区师傅文章关于绕权限

 基于未授权的渗透测试技巧总结

接口未授权测试,提示了未授权的状态尝试添加../ 使得权限过滤器认为我们当前访问的接⼝为白名单接口前置的接口,需要是正常的白名单接口比如/login ,因为登录不需要权限校验,前面用正常的白名单后面接入未授权的接口。

/login/ ----> 200 ok
/system/user ----->  403 未授权
/system/**logn**/../user ------>  添加白名单接口未授权成功

利用分隔符 ; 让后端以为文明访问的接口不是业务接口,和上面添加 .json 差不多一致切割分隔符绕过。

有些像之前学习的shiro权限绕过 但shiro是 ../;

Fuzz接口参数

无论是熊猫头还是其他工具得到的接口Path其实是不完整的,直接拼接的话缺少参数是无法访问接口会报错,需要构造参数, 如果响应包直接提示缺少哪些参数对攻击者是很友好的,请求包构造发包就可以测试。

/api/demo/test HTTP2   -------->     '缺少deviceId'

提示缺少参数我们拼接

/api/demo/test? deviceId =xxx HTTP2   ------>   {最好情况直接显示数据} 

但更多的情况下是直接提示缺少参数也不说什么参数,那么需要可以JS源码里面找一下它的调用代码,找到请求中用到的参数进行构造, 先是找接口找到,没有办法Fuzz参数是最后的底牌。

BP搜索参数

BURP作为挖洞小伙伴善加利用功能点可以事倍功半,站点功能会自动记录加载过的所有JS文件,我们只需要做的是进入网站后点击一切能点击处让BP加载更多,避免缓存影响浏览器需要关闭缓存,这样可以保证JS文件被BP加载。

加载页面JS后点击站点地图的过滤,输入框输入提示缺少参数的Path 左侧目录,就会过滤出不存在此接口的文件,保留存在此接口的文件。

/api/

再从下面搜索框搜索对应缺少参数的的Path找到它的调用位置。

找到接口了,但是不懂参数如何构造可以提交给AI 给予明确的指示就会构造好示例的请求反馈给我们。

我从js里面找到了这个请求 请帮我构造好原本的请求参数是如何放置的,构造好请求参数值反馈给我

$.getJSON('/getLineLocalPromotion/demo/',{

lineIdstr:a,sid:b,rand:(new Date()).getTime()
},

/getLineLocalPromotion/demo?lineIdstr=123&sid=456&rand=1642678901234

BP站点地图寻找参数的方法和浏览器全局搜索大差不差,但浏览器查找如果相似的接口匹配行数过多,不利于查找,BP会首先进行一次过滤减少了范围,那个容易达到目的使用哪个方式。

字典Fuzz参数

缺少参数响应包更多的情况是模糊提示, 只会提示缺少参数,也不会说是什么参数,我们首先是可以按照上面的手法全局找接口,看看构造的是什么参数,找不到接口构造参数那么可以上字典Fuzz参数。

/api/demo/getuserinfo------>  Missing parameter // 无提示

/api/demo/getuserinfo? {fuzz} =

后端无提示,那么根据请求的语义,我们虽然不知道参数的具体值,但是能很大程度上缩小范围的,请求是获取用户的信息,那么代表传入的参数是用户参数,搜集常见的用户参数作为字典,根据接口需要实现什么功能,在这个思路基础上推断出参数。

id userid
user_id
uid
userId
google_nid 

文件上传参数名肯定是file files filesname,查询接口参数肯定也会是query q ,根据接口语义推断。

如果想不出合理的参数名毕竟我们不是开发出身,日常没有足够接口参数积累,可以以一个开发者的视角询问ai通过此接口可以传递哪些参数,有些情况参数存在多个,这个需要依照功能点来进行填充,显示功能点的可能需要pageSize pageNum 上传功能点需要时间戳、文件名等等,思路也是找不到就Fuzz

/api/demo/upload?{ file/files/filesname }= 

/api/demo/query?{ q/name/id }= 

接口语义参数拼接

原理是Web开发的思路和习惯,尤其是大部分MVC框架,我们对功能点操作实际上是对后端进行增删改查,MVC存在映射关系,根据面向对象思想,为了提供代码的复用性, 增删改查虽然不同功能但实际上操作的还是一个类中的参数,类中的属性肯定是高度类似,很多情况是还是完全相等。


在一个接口缺少参数,响应不出数据,可以回过头找到其他**’输出’**功能点显示的参数 拼接到请求包。

假设需要构造接口语义是edit编辑,那么肯定需要的是编辑的信息,ID、名称这些参数信息,根据这一点可以找**’输出’** info信息的功能点。

/api/demo/edit/  -----------> 缺少参数

/api/demo/edit

找到输出info 功能点 ,把数据体复制到edit编辑请求使用修改,GET POST JSON 均提交。

存在用户ID 编号的参数值最好有两个账户进行测试,是否可以达到越权或未授权目的!结合此方法在上文Fuzz功能接口的地方,找到隐藏功能二次根据语义判断隐藏参数做拼接测试。

Fuzz功能点和Fuzz参数原理都是一样的,推测出开发的语义化,因为他们的命名肯定是会有规律的,增删改查功能和和需要的参数都是这样,寻找 输入 输出 方法只是也是站在开发思维寻找参数。

功能点Fuzz 增删改查即可,参数寻找有响应包有提示直接拼接,无提示全局找,找不到根据请求语义找其他功能点输出参数位置拼接猜测,渗透测试讲究一个测,有可能性的话就测一下。

Fuzz JS文件

攻防有时会遇到比较古老的站点PHP/ASP.NET,同样是开局一个登录框 JS都是直接引入的,提取不到可以利用的接口,并且没有Webpack打包技术这个时候可以尝试Fuzz JS文件, 这些比较古老的站点的JS目录一般就是/js /script /plugins /content等等,很容易找到 JS的名字也比较简单,不像用Webpack打包的JS,名字中可能会带有随机字符。遇到这种还是能去FUZZ一下JS文件的。

尝试对JS文件名Fuzz 有些情况下JS文件并没有显示在当前目录 但确实是用到了这些文件,利用好字典对JS文件名进行爆破,如果响应了新的JS文件再从响应包中审计提取新的接口进行二次测试未授权

总结

文中借鉴了一些其他师傅的文章思路结合Fuzz场景,如能为师傅们提供一些新的思路那最好不过,不足之处还请批评指出,希望各位大佬日日出0day!!!

扫码进群,别打广告,发任何和技术无关,立马送飞机票。
纯技术交流,欢迎加入船山网安战神宗!