记录一个 Java 系统的漏洞挖掘,系统的主要的问题是没有做越权防护,其他漏洞暂时没有挖到,有点菜,先记录着吧,每天进步一点,总会变强的。

系统介绍

系统是一个 Java 写的自动化测试系统,不同角色之间做不同的事情,领导申请任务,审核同意,领导把任务派发给下属,下属执行测试任务,同时也有一些下载报告,上传文件之类的操作,但是由于国光我比较菜,这些功能点并没有挖到什么漏洞,所以这里就不再赘述了。

系统本身需要登录才可以进去使用,使用的是统一认证的登录界面,登录成功然后跳转到对应系统的,所以这里给了测试账号来进行测试,下面是本次测试所使用的3个测试账号信息:

角色 用户名 密码
测试人员 a P@ssw0rd
中层领导 b P@ssw0rd
审核人员 c P@ssw0rd

为了保证客户系统的安全性,这些账号信息是经过国光二次修改的。下面国光这里大概解释一下这 3 个角色的作用:

测试人员

主要发起一些测试任务,有上传压缩包、APK 等功能,同样也可以下载测试报告,有账户余额,一些功能操作会积分,可以用余额去购买积分。

中层领导

可以发起申请给自己团队添加人员,可以删除和恢复自己的下属成员,可以申请团队经费用于分配给下属成员进行测试使用

审核人员

主要负责处理一些领导层那边发起的审核,类似于 HR,也可以将集团成员划分到某某部门,分配不同的职责

当然功能比我叙述的还要多一点,国光只能够叙述个大概,这里做了解一下就好。

测试弯路

以下都是国光测试中走的弯路,实际上都没有研究出什么成果,还是太菜了,但是还是记录一下吧:

任意文件上传

在使用测试人员在进行功能测试的时候是可以指定上传zip或者apk的格式的,当然只是前段限制了上传的格式,抓包替换还是可以轻松过掉这个限制的,但是上传啥后缀的文件都不解析,点击直接就下载了,jsp 的测试文件也是如此,感觉没有什么作用就放弃了继续测试上传。

任意文件下载

点击之前上传的附件是可以任意文件下载的,浏览器复制下载链接发现是通过指定模块来实现下载功能的,尝试../../../../../index.jsp没有成功,应该是做了些过滤,所有的下载功能点都是使用的同一个模块,所以最后也就放弃了,没有测试成功。

Tomcat PUT

Burpsuite 查看网站返回包,发现存在apache-coyote/1.1字段,说明网站是 Toomcat 搭建的,于是想尝试一下 Tomcat CVE-2017-12615 PUT 写文件 漏洞,首先使用 OPTIONS 方法检测网站是否支持 PUT 方法,结果返回包里面居然真的显示 PUT 方法,有点小激动,感觉可以直接 getshell了,尝试 PUT 方法截断:

PUT /test.jsp/ HTTP/1.1
PUT /test.jsp%20 HTTP/1.1            
PUT /test.jsp::$DATA HTTP/1.1            
evil.jsp%20 evil.jsp::$DATA evil.jsp/

但是返回403,并不是想象中的201 Created,GG,果断访问去看下 Tomcat 的 404 报错页面,发现版本为:7.09x吐血 这个版本恰好修复了这个漏洞了,逃 感觉测试其他漏洞去,再这样下去今天就是 0 个漏洞了。

SQL注入

测试了很多功能点,很多 URL 解码后查看内容类似如下:

tableName=taskname&data={"columns":"id","user_name","task_name";"filter":"测试数据","start_time","stop_time"} 

可以看到思路是先直接查出所有的结果,然后再使用过滤条件来讲用户需要的结果给用户,查询所有数据没有可交互的点,而用户的输入数据在filter过滤器这边,这边相当于从静态结果数据中抽出数据显示给前端用户查看。基本上涉及到查询的语句都是如此,国光这里测试了好多无果,SQLmap 也尝试跑了起来,也是 GG,又浪费了很多时间,看来今天真的的要 0 洞了。

XSS

XSS 前端过滤了不让输入敏感字符,但是 Burpsuite 改包还是可以很容易绕过的,但是查看改包后端 返回包,指定了 JSON 格式:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
P3P: CP=CAO PSA OUR
Content-Type: application/json;charset=UTF-8

这样就导致了 XSS 语句无法直接触发,虽然通过古老的IE浏览器,配置一些安全策略可以让 XSS 在 JSON 中触发,这样也太水了吧。前端基本上所有界面都是如下的样子,通过类似表格一样的界面输出来,虽然显示了XSS攻击语句完好,但是实际审查元素发现,所以的标签都被实体化输出

吐血,时间已经过去一大半了,看样子今天真的要 0 洞了

漏洞记录

天无绝人之路,有时候多点耐心,注意一些细节还是有希望的,接着沉下心来,带着我的 SONY 头戴降噪耳机,打开手机听着国光的渗透测试代码审计必备歌单 果然下面漏洞就一个个挖到了。

XSS 1

利用类似历史记录下拉框的操作可以实现 XSS,虽然 XSS 前端都被实体化输出了,但是历史记录的下拉框这里没有实体化输出,还是可以成功执行 JS 的,有点类似于 Self-XSS 的感觉,但是我换了不同的浏览器登录测试了,这个下拉框 XSS 居然还存在,很迷,说明历史记录也存入到数据库中了,然后点击搜索框的时候会从数据库中调用数据,造成 XSS 漏洞的产生,这里又有点类似于存储型 XSS了,只是攻击的是自己~~ 不管了 这个就算是一个漏洞吧。

测试使用的账号如下:

角色 用户名 密码
测试人员 a P@ssw0rd

测试人员工作台中选择系统新增,添加一个系统基本信息,正常添加的话,系统名称这里是不允许使用一些非法字符的:

前端依然过滤不让输入敏感字符,然后BP直接改包插入 XSS Payload,我使用的 Payload 如下:

{"items":[{"mxVirtualId":"C8BC3B43-C06A-AEBF-7848-5A4BADCC36A7","appname":<img src=x onerror=prompt(1)>","versionname":"1"}]}

为什么使用冷门的prompt来弹窗呢,是因为 居然有XSS过滤,过滤掉了alert,吓了我一跳,还好过滤规则不严格,否则我可能真的得尝试好久了,最后插入成功后,点击系统名称的 input 窗口,就会弹窗,类似于存储 XSS 效果一样,无法被关掉:

实际上这种 XSS 还是比较多的,很容易被开发者忽视,几个月前挖过中国移动的一个对外开放的外网资产也存在这种 XSS。

XSS 2

b 可以故意在 xls 表格里面插入带有攻击的语句,当 c 审核的时候可以成功触发 XSS 跨站脚本漏洞。

测试使用的账号如下:

角色 用户名 密码
中层领导 b P@ssw0rd
审核人员 c P@ssw0rd

中层领导注册子账号的时候需要将要注册的账号填入表格中,然后发起申请,首先构造一个用户名是一个 XSS 攻击验证语句的表格内容:

我这里使用的 XSS Payload 如下:

xsspayload<img src=x onerror=confirm(1)>

这里用confirm来代替被过滤的alert

然后 c 这边看到了 b 的申请后,然后填写一些基本信息,点击审核,即可成功触发 b 故意留下的 XSS 攻击语句:

可以看到上方的1已经弹出了,最后来看一下这个 XSS 为什么可以成功触发,关键在于提示用户不存在的这个弹窗没有对 XSS 进行转义就直接输出来了:

越权 1

b 提交注册子账号申请的时候,可以不经过 c 的审核操作,直接自己给自己审核通过。

测试使用的账号如下:

角色 用户名 密码
中层领导 b P@ssw0rd
审核人员 c P@ssw0rd

b 注册子账号提交申请,提交申请后提示信息已经发送,b 此时的查看刚刚提交申请状态为:待审核状态。

c 账号登录,这边查看到刚刚 b 发起的申请了,状态也是为待审核。这个功能没有啥问题,继续测试,发现 b 有一个催办的功能,抓包看看:

POST /xxx/xxxService/rest/batchRegistration/updateButton?rnd=0.9688799541603235 HTTP/1.1
Host: 10.85.222.221
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.85.222.221/xxx/xxxService/main/index.jsp
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 22
Cookie: JSESSIONID=bbbbbbbbbbbbbbbbbbbbbbbbbbb; 
Connection: close

{"id":358,"state":"4"}

可以看到关键的信息如下:

{"id":358,"state":"4"}

state这个参数为4,结合上面泄露的state信息(某一个返回包泄露的):

符合我们的猜测,尝试手动修改为:

{"id":358,"state":"2"}

b 这边已经可以看到审核通过了:

c 这边查看待审核的列表中,之前的待审核的申请已经消失了,表名审核已经成功了。

越权 2

a 用自己的权限可以直接把b的下属成员直接删掉

b 登录后台,首先来看下下属账号管理的情况:

账号均正常。

a 用户登录,抓取测试人员的 Cookie 如下:

Cookie: JSESSIONID=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

利用这个 Cookie 身份,Burp 抓包构造一个删除下属成员的请求,具体的数据报如下:

POST /xxx/xxxService/rest/xxxpmainsub/updateFlag?rnd=0.6873779200540744 HTTP/1.1
Host: 10.85.222.221
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.85.222.221/xxx/xxxService/main/index.jsp
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Cookie: SESSIONID=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Content-Length: 99
Connection: close

{"mainId":"8ad55e5d6dde8910016e6cba05370368","subId":"8ad55e5d6dde8910016e6e0b00ed0378","flag":"1"}

返回包里面显示删除成功了:

使用 b 进后台查看下是否成功删掉,可以看到的确下属成员被直接删掉了:

目前状态为待恢复状态,表明a越权做了b该做的事情,成功将单位负责人的下属成员删掉了。

小结

其他还有类似的越权漏洞以及一些特定的返回包中泄露服务器物理路径信息等我这里就不在赘述了,本文实际上没有啥技术含量,以后再测试这种类似的系统的时候,可以多尝试下越权,越权可以用同一个 Cookie 身份去测试其他角色可以执行的操作,如果可以成功执行,基本上是存在垂直越权漏洞的,很多系统的 SQL 注入这类的攻击基本上都防御的差不多得了,但是由于开发混乱,越权这块不一定都解决的很好,也算是是一个思路吧。

支持一下

本文可能实际上也没有啥技术含量,但是写起来还是比较浪费时间的,在这个喧嚣浮躁的时代,个人博客越来越没有人看了,写博客感觉一直是用爱发电的状态。如果你恰巧财力雄厚,感觉本文对你有所帮助的话,可以考虑打赏一下本文,用以维持高昂的服务器运营费用(域名费用、服务器费用、CDN费用等)

微信
支付宝

没想到文章加入打赏列表没几天 就有热心网友打赏了 于是国光我用 Bootstrap 重写了一个页面用以感谢支持我的朋友,详情请看 打赏列表 | 国光