URLDNS

URLDNS

摘要:DNSURL

0x01 链子

URLDNS1

1、URLNDS.java#getObject的57行,调用HashMap的put,跟进;

这个地方我回头看了下,链子应该是从readObject()开始的,这里图方便直接在荷载生成处直接上来调试了。

URLDNS2

2、put中调用hash方法跟进;URL3

3、hash中对key进行hashCode的计算,这里的key为URL对象,再跟进URL.hashCode;URLDNS4

4、URL.hashCode中调用自身handler属性的hashCode,其handler为URLStreamHandler,跟进其hashCode;URLDNS5

5、发现在java.net.URLStreamHandler#hashCode()中调用getHostAddress(u),这里的u即为我们构造payload传入的URL对象,其中包含了我们的DNSlog的地址,到此链子分析完毕。

0x02 PoC中一些比较有意思的点

首先,在URLNDS.java#getObject的53行的handler为自身新造的一个silentURLStreamHandler类,这个类将getHostAddress置空了,这使得我们在构造payload的过程中不会产生一次无意义的DNS请求。

这里还有一个点没太弄明白,这里使用了synchronized关键字使得线程独占了这个方法,估计是顺延了之前的实现。而之所以可以这样操作,是由于URL类中handler为transient关键字修饰的,其是不会被序列化的,故不影响我们的payload在目标机上的运行;

第二,由于之前的put操作使得hashCode字段不为-1故这里将hashCode置为-1以便在另一端可以触发(见第一幅图59行)。

0x03 一点思考

在调试完这个PoC的时候,我在思考一个问题,安全研究人员是如何挖掘到这条链子的呢?如果我是挖掘这条链子的安全人员我是怎样的一个思考方式呢?在这,我想大胆模拟下当初那名研究人员的思路:

我拿到URL的源码,查看到它的属性URLStreamHandler类的handler,进入发现其hashCode传入的参数正好是URL对象,而其中还对URL对象中的url发送DNS请求;那么下一步,我会考虑URL中是否调用了handler的hashCode且传入的对象是什么;然后就惊喜地发现,在URL的hashCode中调用了handler的hashCode传入的参数就是本身。

那么到这里,一条调用URL.hashCode()->URLStreamHandler.hashCode()->getHostName(URL)的链子就出来了。

然后需要思考的是,什么地方会调用URL的hashCode方法?很自然地在HashMap中找到hash会调用传入key的hashCode(),那哪里会调用HashMap的hash方法?这里我发现put,get等方法都会调用hash方法,而PoC中使用put只是需要将我们的恶意类放入其中。

到这,HashMap().put()->HashMap().hash()的链子接到上面去,我们的整个链子便构造完成了。


评论