未授权服务加固与泛解析字符绕过

面向公网资产多轮加固的业务、异常的业务,通过泛解析字符让服务抛出异常信息回显,定位到无需认证的位置,缩短未授权业务测试的日常时间成本。

前言

24年厂商把测试范围全部划到公网资产、IP

顿时压力暴增,公网资产已经23年已经测得七七八八了,未授权漏洞都少的可怜,开发作加固都做了好几轮。

公网资产,测试测着,每天都看着哪些服务容易出洞

很多服务测着测着,大半天过去了,最后发现是强认证,有的测着测着,关键位置上开发做了加固。

干了大半天白忙活,我做测试,最后变成测试牵着鼻子走。

要是能像审计代码一样,通过他的实现、回显筛选出脆弱的服务点就好了。就算没后续测试,也能点到为止

"跑路"转向下一处位置。

后续,观察到通过代码让服务抛出异常信息回显是很有效的,就能确认到这些服务点鉴权、调用、地址的方式。

通过几个季度的积累,完善了通过"泛解析字符"探测功能业务的场景,大幅缩短业务测试时间成本,所谓的无后续点到为止

树形图

泛解析服务探测

(案例涉及的场景均已修复,由于项目原因,严重厚码;场景更多面向服务功能的实现,以实用为主,请慢食用)

泛解析字符

通过代码让服务抛出异常信息回显的字符,根据服务string 值

  • string 原字符
  • string11、string1 相似字符
  • str1aing、straaing 混淆字符
  • 1aaa、222 垃圾字符
相似字符场景

目录地址,解析特性,回显相同

混淆字符场景

目录地址,回显异常,状态码通常404

探测功能类的回显和其父类回显

垃圾字符

常见为故障排查,无意义字符,看服务怎么回显

泛解析探测功能类实现

以常见的user类为例,每个具体实现的函数login、get函数、upload函数都归到user这个类下边

同级功能类,不同权值

上边两处实现都在同个功能类下边,查询都是

  • Api-Base+/user/getSymbolDetail
  • Api-Base+ /user/getReportDeal

getReportDeal鉴权了,需要提供一处token(required),这时候getReportDeal是否也需要提供一处token(required)?

但getReportDeal实现只需要一个Name值,虽然都是在同个父类user下面,但这不需要token值。

场景1

一个难啃的公网域名站,啃了两年

业务接入认证,业务只要请求就是401,需要token、返回用户未登录

能看到porjectApi/zuul有一处类实现,但zuul下边的实现跟上任何地址,一律返回401

Link到几个JS,

无对象参数,几处封装的函数z({url:"地址"}

直接喷洒到已有的父类: projectapi/zuul 、projectapi

projectapi/zuul+getfunction 401

projectapi+getfunction 401

贴图,需要先用泛解析字符获取到功能类实际地址

通过泛解析获取到XXxmobile这个类是在ProjectApi后边实现

无需认证的功能类

接着看他的子类实现

基本都和article这个子类实现有关,但这个子类上边测试过他的getfunction,是带鉴权的,(需要required token)

参数t值,简单测试,1、11、111、1111

通过泛解析获取他父类xmobile的地址、然后探测xmobile的功能类dept实现,dept的实现不需要认证,就得到一处未授权的功能未授权查询

场景2

陆续扩展

混淆的 data: t

怎么去处理这个t值?

这子类opi实现有一处pending值,

跟着这处pending值

params:{userId:L("uid"),pendingStatus:0,page:0,limit:20,type:"all",app:"na186"}

配合user/tree/1111 获取的userId值

场景3

功能类的键值混淆

做泛解析、分析子类权限最后还是要未授权查询,如果一些键值做了混淆,那应该怎么处理?

但找不到t值,提供任何参数都是返回200,同时后边得跟一处items,这处items是常量还是字符串?

通过泛解析处理掉这处值,现在只要跟到t值就能未授权

跟他的封装函数dt,跟到一处传参

在大类已知的情况下边,探测功能类地址,如下图,

泛解析探测布尔型回显

场景是公网一处域名,已获取到父类地址/project/api

父类回显

但通过泛解析字符处理,会得到

`project/api/pdf/extract_table 401 response "not login"

project/api/pd1f/extract_table 401 response "not login"

project/api1/pdf/extract_table 404 response "404"`

在project/api任意类实现,都需要认证,无认证返回401,login

在project任意实现,不存在返回404

往上走一层测试,看看

`project/pdf/extract_table 401 response "not login"

project/pd1f/extract_table 404 response "404"

project1/pdf/extract_table 404 response "404"`

上面已经通过泛解析字符得到在project任意实现,不存在返回404,

这里project/pd1f 返回404,project/pdf返回401,两处泛解析字符,异常的回显就拿到实际的

实现地址pdf-extract功能是通过/project+"/pdf/extract_table"调用

Snipaste_2025-04-02_00-17-13.png

场景2

在不知道大类的情况,探测功能类地址

是公网一处域名,前端异常。

每次加载都会又有一次初始化,请求service/dic/initDetailData,站点能看到的唯一调用实现

功能类地址

JS打包的地址里边有一处upload的地址,但需要确认他的父类地址,如下图, 这里做了加固,y.a的值跟不到

由于看到了站点初始化service/dic/ 这处是有调用实现的,拆分出两处测试点

  • service+upload的实现类
  • service/dic/+upload的实现类

两处都是500,布尔型回显,仍然无法确定upload实现的父类地址

从调用看,下边的DOMAIN_URL值就是之前加固的父类地址y.a

相邻功能类回显

还是把要确认login的实现类拼接到已有的实现上

  • service+login的实现类
  • service/dic/+login的实现类

302跳转,通过泛解析字符进一步确认地址,login11、log11in

回显的404确认login类实现在service后调用,要确认的父类地址在这为app-service,upload和login都是他的实现

泛解析探测目录路径

挑出来一处Java配tomcat场景,无js模块打包,只有必要的login加载

然后,不管怎么测试,他都会跳到watermark/login

在目录来说,watermark/login算路由,但跟到JS里又发现后面有get、update类实现

login在这处算路由地址还是功能实现的父类?

如果是路由地址,测试方向最多是跟上字典fuzz,没结果这条路线就可以断了,如果是功能父类,那就按功能实现的路线测试。

但他仍然可以按功能实现的路线测试

通过泛解析,看到login这个父类,实现出现异常会返回500

路径跳转

加入常见的路径跳转,是否能看到跳转可控呢?

大致能得到跳转不可控,login类对跳转按泛解析处理结果为异常,跳转可控会回到上边写死的路由,也就是/watermark/login,后续跳转测试路线可以断了

同样的路径跳转,login类会回到对应跳转路由,像下边的案例

加入路径跳转

跳转可控,后续测试再跳一层,有组件未授权

功能路径

挑出来一处插件性场景,探测已有poc的路径,观察泛解析字符路径跳转,找poc插件位置是否存在,探测路线是否可行,缩短后续测试成本

泛解析字符的结果看到,返回包的redirect_to参数未实际校验,单纯拼接。

后续通过路径跳转探测插件位置这条路线可以断了。

再挑出一处springboot的场景,文档插件


很明显的一处泛解析,功能地址在API,其他的api-docs 这类都是泛解析字符的结果,缩短测试成本

业务的挂钩场景

路由场景v2

去年业务未授权专题写了一版路由规则,基于#的测试,观察到一些重写的、遗漏的规则

挑出一处和路由相关的案例,资产是公网一处IP

观察到流量包,加载了打包的JS文件

实际上,要看前端的话,他是一处空白

观察到是index文件携带的link,引出的打包JS文件,那这儿就是入口文件,

根据他的路由写两处#/业务相关场景,index.html#/、index.html/#/ 跟上打包文件的路径

常用路由字符
  • page
  • pages
  • login
  • home
  • home/index
  • index.html

集成web路由

扩展路由规则的一些场景,

资产是一处公网域名地址,强认证,任意路由路径都会跳转到account,而account是重写的,没有这个类,

虽然路由上不可控,但拿到了JS打包的文件

这里有一处列表te很明显,plus、openplatform从名字看都是携带功能的地址

跟过来

泛解析处理路由

泛解析字符探测一下

是一处实打实的集成业务地址,不是后端的功能大类,根据他的路由写两处#/业务相关场景

openplatform#/、openplatform/#

新title、测试JS里边携带的功能路径

通过泛解析,拿到了集成地址,再通过路由规则发现了业务未授权,绕过加固做的强认证,分析薄弱的环节

查询类场景

公网域名功能看的见、摸得着的主要还是查询类,打包的JS文件携带了很多和业务相关的类,按业务回显,回显通常有三种

  • 参数缺失性字段
  • 布尔型字段
  • 认证性字段
参数缺失型字段

来看一处和id值实现相关的实现,通过泛解析提取到大类地址后,确认了monitor类实现grid的位置。

查询返回ProviceCode值不能为空

但跟上ProviceCode一处值后,依旧返回"ProviceCode值不能为空",说明required还需要其他参数

混淆的 data: t

怎么去处理这个t值?

跟着缺失的twoDigitProvinceCode值

和fourDigitCityCode封装在一个变量v里面,下图画框处发现两者有组合调用

构造后发现,不回显字段缺失了,回显为布尔型,Data数据没带过来,需要fourDigitCityCode具体值。

恰好数据包有get实现和fourDigitCityCode相关

查询成功,DATA列表携带数据返回

布尔型字段

开发修复后,再次看,异常的回显统一了,类似"服务繁忙,查询异常、502之类"

但仅从回显看,更像是把和id相关的类,这里的实现做了修复;因为回显还携带"DATA"接受数据字段。

测试,观察到了和他对应查询调用成功

相邻的父类地址

common和grid的父类monitor同目录,common的实现有数据

往下跟,也是"RSP_DESC":"系统未知错误", 布尔型,不再返回参数缺失。

上图,529处有一实现携带了?proviceCode值,看着是GET型,跟着看他的实现

拼接上缺失的值

GET型虽然统一了认证,但并不是完全的接入权限,通过其他类的实现,依旧能绕过到相关业务。

那么,POST型应该怎么来处理呢?

上边monitor父类做了限制,通过和他相邻的common类来GET型查询

common类的POST型如何处理

comon下边的query实现

混淆的 data: t

怎么去处理这个t值?

因为是business的实现,所以得先跟business,跟过来是两处键值key1:sendBusiness和key2:sendBusiness2

顺着sendBusiness()和sendBusiness2()往上走,

简单构造发包测试

{
"sendInterface":"1",
"staffName":"1",
"staffId":"11",
"provinceCode":"51",
"userId":"admin",
"businessList":"11"
}

强认证字段

强认证字段是识别度很低的回显,无论输入什么,都提示需要accesstoken、需要token、未登录。

既返回调用成功,又返回未获取Token,而且状态码也是200

很难确定功能类需要的required,先通过泛解析字符,获取不同的回显异常

通过两处泛解析字符,analysis和下边的实现类已经完全接入认证。

跟过来、或者往上跳

跟到一处policy父类,返回403

通过泛解析字符,返回包回显,policy这处类应该是可以后续测试的,和上边analysis类相隔开了。

强认证回显处理比较棘手,大多数功能类实现接入认证,通过泛解析字符确认相关类的权限情况后,后续测试路线可以断了,节省后续测试时间成本。

编辑器场景

打包的JS文件里调用的编辑器指纹,通常得归到业务指纹里边,但这里单独列出来,编辑器他通常是插件,大多数编辑器都是完善的,无需借助web,集成过来就能用。

指纹类发现,参考23年的https://forum.butian.net/share/2639

看JS打包的相关函数

相关函数

资产是一处公网域名地址,跟到JS里边,preView、View、pdf、upload相关的函数

常规的文件操作,读取、删除、上传

目录地址

资产是一处公网IP地址

存储桶场景

资源站点、展示功能居多,业务常涉及文章、图片、素材等功能,传参在文章id值、图片存储位置

异常页场景
中间件正常,服务异常

公网域名、IP常出现地址不通,无前端的问题,这大概是最棘手、最常见的情况

青一色的500,nginx有回显,服务异常、中间件正常(可能挂了、访问方式不对、限制)

nginx异常页的返回,状态码200,服务有问题(可能是端口方式),中间件正常

更改端口,401返回,nginx返回该401可能和web鉴权相关,走字典,探测相关资源

中间件挂了,服务挂了

nginx异常页的返回,状态码502,nginx挂了,服务也随nginx挂了

业务指纹场景

三无站点指纹

验证码处不可用,"无功能、无展示、无数据" 三无

观察站点的指纹,看着别扭,单独的域名、也没看到目录,直接把域名作为入口文件展示

目录测试,找他的目录业务

看着很有问题,入口文件没做泛解析字符跳转,测试出一处二级业务

功能插件指纹

访问是一处500

多f5几次,就会跳到开发重写的路由project/login

再过了一会,返回一处springboot的error,应该是404,但这404就不对,"error#/" ,是符合#/业务规则的

再次替换,到开发重写的路由login#/

验证相同,测试JS里边携带的功能路径

通过springboot的路由异常,观察到开发重写的路由login#/,后续功能路径测试。

域名指纹

业务域名和他资源域名

images域名只存放业务的资源文件,但开发运维到后期,观察到业务共用的情况

估计别的厂商测过,开发做过加固,关闭服务或者限制入口,比如下面的shzx子类

把业务喷洒到他资源域名,观察正常

对应shzx子类功能测试

实际是同套调用,用好可以处理一些加固站点。

JS文件指纹

多轮测试的站点,无JS文件打包,无登录地址、无前端展示,也是妥妥的三五站点

但访问有业务的JS文件加载

站点有统一的异常页面,跟到他的JS里边,有定义到列表

逐个访问,观察未授权页

  • 发表于 2025-04-22 16:44:26
  • 阅读 ( 607 )
  • 分类:渗透测试

0 条评论

请先 登录 后评论