对某大型企业的一次web漏洞挖掘过程

  • A+
所属分类:安全文章

注:本文相关漏洞均已报告SRC 并完成修复

 

对某大型企业的一次web漏洞挖掘过程

前言

近几年工作转型,已经很久没挖过漏洞,突然想检验一下自己当前是否还有挖洞能力。因此本次以挖到某个大型厂商一个中危级别以上漏洞作为目标,最终挖到了一个低危(存储 xss) + 一个高危 (任意文件读取),完成了本次目标。同时将整个过程较完整的思路记录下来,供大家参考。

 

 

对某大型企业的一次web漏洞挖掘过程

前期思路

 

该企业有着多年的自身安全建设及SRC 运营,如果以渗透测试的思路拿机器权限绝非易事(渗透测试思路请参考此前发到乌云drops 的一篇文章:渗透中寻找突破口的那些事https://blog.csdn.net/hrayha/article/details/104887524),且常见的反射xss,sql注入等问题估计早已被内部扫描器、自身及外部安全人员挖的差不多,我就以逻辑类漏洞作为主要挖掘方向。

 

 

对某大型企业的一次web漏洞挖掘过程

寻找目标

 

既然要寻找逻辑类漏洞,首先要寻找功能比较复杂的站点,通过搜索引擎搜索site:xxx.com,发现这么一个站点:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

通过域名git.xxx.com 可初步判断为是一个类似gitlab的代码托管平台,此类平台一般会涉及到用户管理、文件管理、项目管理等功能,可测试的种类多样,因此将目标定在这个系统上,深入测试每一个功能,直到挖到中危以上漏洞完成目标。

 

 

对某大型企业的一次web漏洞挖掘过程
测试过程

 

登录系统后可看到左侧功能菜单如下:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

可以看到功能还是比较丰富的,需要注意的一点是测试全程开启抓包工具,我这里使用的是fiddler,目的是可以抓取一些接口地址进行测试,以及方便改包重放。

我们顺着提示,先初始化git 账号,设置用户名时随便输入了test,提示用户名已存在,这里一定是调用了接口查询后端数据库或缓存,返回fiddler 看到如下请求:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

此时我们可以做一个基本的sql注入测试,此处属于字符型,一般我会直接在后面加单引号,因为在数据库查询中,如果引号带入的话会触发语法错误而造成页面的异常响应,我们通过页面响应是否异常即可初步判断是否存在sql 注入,结果如下:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

通过文案提示可发现后端对用户名格式做了判断,这里的返回结果,除了sql注入外,xss需要的引号,尖括号也无法带入,因此用户名的xss测试也省了,不过这也是符合预期的,如果这样就挖到漏洞,我估计一定是他们自身的扫描器挂了。后面对于大多数的接口测试思路基本如此,不做赘述。
来到"项目"功能,先创建项目,做如下填写:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

这里简单说明下,前面的aaaaa、bbbbb主要是方便对返回结果搜索来定位过滤情况,不同的功能用不同字母主要是为区分不同功能点的过滤情况,">用来判断目标系统对敏感字符的过滤情况,标签作为大部分白名单标签可观察目标系统是否支持白名单标签。

提交后出现如下提示:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

这里一般分为前端判断与后端判断两种情况:

1.前端判断的话我们可以通过改包重放来绕过限制;

2.后端判断可以忽略对相关功能点测试。

我这里看到了对应的请求包,所以可判断本处为后端判断,所以只进行描述字段的相关测试,提交请求后返回结果如下。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

这里我发现一个比较可喜的现象,那就是虽然过滤了尖括号,但是img 标签被正常解析,说明此处支持白名单,在接下来我又分别做了一些测试,结果如下:

测试payload

返回结果

说明情况

<img src=1 onerror1=alert(1)>

<img src="HRay2/aaaa/1">

对onerror属性过滤

<img src=1 aaa=1>

<img src="HRay2/aaaa/1">

对属性的过滤非黑名单而是白名单

<img/src=1/onerror=alert(1)>

&lt;img/src=1/onerror=alert(1)&gt;

以 / 分隔属性会直接转义尖括号

<bbbbbb>

非白名单标签过滤为空

<bb<bbb>bbbb>

&lt;bbbbbb&gt;

执行对非白名单标签过滤后会转义尖括号

<img src=javascript:xxxxx>

<img>

白名单属性内依然有过滤

<img src=javas<aaaa>cript:xxxxx>

&lt;img src=javascript:xxxxx&gt;

执行对非白名单标签过滤后转义尖括号动作无视黑白标签

<img src=jAvascript:xxxxx>

<img>

过滤无视大小写

<img src=aaaa:xxxxx>

<img>

非基于黑名单的过滤

这里的输出点我们需要依赖尖括号,且目前看来只能使用白名单标签+白名单属性,暂时无法利用,所以我们继续看其他功能点。
经过一些类似测试后,我们来到了项目组功能,在项目组的描述文件功能处又遇到了与刚才相同的过滤,不过这个时候我比刚才多做了一个尝试。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

目的是想深入看一下白名单属性内的过滤情况,结果如下:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

我们输入的内容被完整的输入,说明白名单属性内,对尖括号是没有做过滤的。

在html中,有些标签是可以优先闭合的,比如下面这段代码

<html><title><ahref="1</title><script>alert(1)</script>"></a></html>

这段代码在实际解析中会把<ahref="1作为<title>标签中的部分,从而完成无双引号的闭合。

本处无法在上面插入有效的title标签,理论上不可利用,但是当我直接测试如下payload 时:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

奇迹出现了:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

经过后端的逻辑处理后插入的script 标签竟然直接跳出了a 标签,到了这里大家可能以为把script 标签内容改为alert(1) 就解除了,事实并非如此,我发现script 标签内的符号都会被url 编码处理,比如:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

我们通过插入
aaaaaa<ahref="1<title><script>aa`[email protected]#$%^&*()-+=_[]{}|/?</script>"> 来测试符号的url 编码情况,结果如下:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

开始想通过<scriptsrc=xxx.js>的方法实现,且该站点本身就提供写文件的功能,可以天然绕过同源限制,不过被浏览器拦截

原创干货 | 对某大型企业的一次web漏洞挖掘过程

查了一下,大概是因为这里写入的js 以 raw格式查看返回的是 text格式,与 script标签内要求的 javascript类型不符导致,查找无url 编码符号的payload,最后找到这么一个:
aaaaaa<ahref="1<title><iframe/src=data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=>">
成功完成弹窗。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

不过后来这个被评为低危,因为poc 是在data:text 下执行的,无法获取用户信息,后来我又找到这么一段poc
aaaaaa<ahref="1<title><script>throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a[12]+[1337]+a[13]</script>">

原创干货 | 对某大型企业的一次web漏洞挖掘过程

说明:后面读了测试规范,发现官网其实是严禁弹窗测试的,希望大家后面注意,尽量使用console.log 来做测试。

不过这样停止总觉得有点勉强,那就继续再挖一下看看吧。
因为xss的价值比较低,所以后面的测试着重去找一些偏逻辑、水平权限或者敏感接口类的问题,以下思路为测试后没成功,但是我觉得对web 安全测试来说还是需要关注的点。

1.我们随便打开一个页面的时候,查看网页源代码,会发现有这么一段内容:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

这里面包含一个id,并且通过这段内容以及观察其他一些参数的格式,估计可能会存在一个参数名为user_id 的隐藏参数,之前发现过这么一个例子,就是站点本身的一系列操作都是解析session 内容来获取用户对应身份进行操作,但是当你主动去传递一个类似user_id 这么一个参数时,程序会去执行传递的user_id 对应用户的操作,这就导致了水平权限的问题,这种问题的成因有可能是早期程序逻辑就是根据传参的userid 去执行操作,后期改成session,但只是去掉了默认的参数传递,并没有完全从后端去掉这部分逻辑。

2.在cookie 中存在这么一个字段:

原创干货 | 对某大型企业的一次web漏洞挖掘过程

熟悉的小伙伴可能一眼就能认出这是一段base64 的密文。

这段密文解密后的内容格式为:
Username:毫秒级时间戳:32位md5。
其中md5 没有解密成功,不多做猜测,前面讲到程序一般从session 获取用户身份信息执行对应操作,当然也可能是从cookie 中某个字段去取值,所以可尝试将username 部分替换为其他用户信息(这里替换为自己小号用户名),替换后使用base64 加密并替换对应字段内容,同时也可以尝试将用户名后面加单引号,用来测试一些隐藏的sql 注入。

3.测试过程中抓到这么一个接口:
https://git.xxx.com/search/autocomplete/users/1xxxx.json

原创干货 | 对某大型企业的一次web漏洞挖掘过程

看起来可以获取一些基本信息,中间的users 这里,有可能会存在一些类似的隐藏接口可以获取一些敏感信息,比如把users 换成tokens 等。

经过一系列失败的测试后,我看到了一个让我眼前一亮的功能,在我们使用客户端提交commit 的时候,可以选择调用一个bash 脚本来检查commit 描述是否符合特定规范,比如必须要使用--bug=xxx类似的格式(由于很多图都是提交报告后补截的,这个功能在我报告后很快就下掉了,所以此处只能靠文字描述)。开始想着此处可能要出rce ,不过这个bash 脚本是官方写死的,无法更改。最后在查看fiddler 时被我抓到了一个读脚本内容的接口。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

本能的尝试读取/etc/passwd。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

哈哈,运气不错,抓到了一个文件读取,并且是root 权限,从root 的 history文件里读到了 log文件路径。

原创干货 | 对某大型企业的一次web漏洞挖掘过程

到这里足以证明危害,所以马上报告给了官方src,响应也很快,周末的时候也可以及时完成止损,下掉了对应功能,这个漏洞被官方评定为高危级别,因此本次测试目标达成,至此告一段落。

 

对某大型企业的一次web漏洞挖掘过程
后记

刚开始工作的时候,有幸跟0x557 的la0wang 在一起工作,当时做项目感觉老王总是能用很短的时间挖到可以getshell的漏洞,并且很多漏洞并没不复杂,自己也能看懂,就是挖不到,当时感觉是运气不好,随着工作年头的增加逐渐明白那是因为常年的积累,对各种系统、各种程序的逻辑了解的足够深刻,了解哪里容易出现问题才做到的。漏洞本身源于对外部可控因素的过滤或校验不严格,我们需要通过不断积累各种知识来深入理解哪些是我们可控的,可控的因素会带入到哪里,可能经过哪些地方,才能更多的挖掘到别人挖不到的漏洞。人工测试过程中,我们要多去思考程序可能的逻辑是怎样的,而不应该机械化的看到id=xx这种就加个单引号,看到输入框就往里加标签,这样人的效率自然拼不过机器。所以本文尽可能比较完整的描述了整个测试的思考流程,希望可以给大家带来参考价值。最后打个小广告,C轮融资的互联网企业,招一枚渗透测试工程师,大家可以把简历发送至[email protected]感谢大家的阅读。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: