分析一下蚁剑的流量特点
AntSword
虚拟终端 / 命令执行
在打开蚁剑的虚拟终端时,会执行 cd [path]
指令,
发出的包如下
1 | POST /1.php HTTP/1.1 |
返回包:
1 | HTTP/1.1 200 OK |
将 cmd
的值进行 url 解码之后写入 phpstorm 中,可得到执行的 php 代码
1 |
|
初步分析
首先关闭了报错信息,并将脚本执行之间设置为无限制,避免因为各种原因导致脚本运行超时而返回错误,而后开启缓冲区
1 |
|
try
语句内的是重头戏。
解密参数,参数由一串随机字符串组成(上文中为
v1f656c7c99039
、x44aab141531de
、u6af8538cd4c2e
)1
2
3$p = base64_decode(substr($_POST["v1f656c7c99039"], 2));
$s = base64_decode(substr($_POST["x44aab141531de"], 2));
$envstr = @base64_decode(substr($_POST["u6af8538cd4c2e"], 2));根据请求包,解密出这些参数
$envstr
: (空)$p
:/bin/sh
$s
:cd "/var/www/html";cd /var/www/html/;echo [S];pwd;echo [E]
$p 为执行命令用到的解释器(在 Windows 中为 cmd, 在 Linux 中为 /bin/sh
$s 为需要执行的命令
判断操作系统(Windows / Linux),并以此加入环境变量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$d = dirname($_SERVER["SCRIPT_FILENAME"]);
$c = substr($d, 0, 1) == "/" ? "-c \"{$s}\"" : "/c \"{$s}\"";
if (substr($d, 0, 1) == "/") {
@putenv("PATH=" . getenv("PATH") . ":/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
} else {
@putenv("PATH=" . getenv("PATH") . ";C:/Windows/system32;C:/Windows/SysWOW64;C:/Windows;C:/Windows/System32/WindowsPowerShell/v1.0/;");
}
if (!empty($envstr)) {
$envarr = explode("|||asline|||", $envstr);
foreach ($envarr as $v) {
if (!empty($v)) {
@putenv(str_replace("|||askey|||", "=", $v));
}
}
}这里判断操作系统使用的方法是判断路径的第一个字符是否为
/
。此处的
$envstr
为空,所以进入不到 if 中,暂时不做分析拼接解释器与命令,并执行命令
1
2
3
4$r = "{$p} {$c}";
// $r = /bin/sh -c cd "/var/www/html";cd /var/www/html/;echo [S];pwd;echo [E]
$ret = @runcmd($r . " 2>&1");
print ($ret != 0) ? "ret={$ret}" : "";;回显命令执行的结果
1
2asoutput();
die();
下面着重分析一下runcmd
函数
在分析 runcmd
之前,先看一下 fe
函数
fe
fe 函数可以理解为 function_exists
函数的扩展,用于判断是否可以使用某个函数。
1 | // function fe |
它先把 disabled_functions
转化成了数组,然后进行了三个判断:
- 函数是否存在
function_exists
- 函数是否可调用
is_callable
- 函数是否在禁用列表中
in_array($f, $d)
综合以上三点返回函数是否可用
runcmd
runcmd 函数会以此判断各种执行系统命令函数,寻找能用的函数,也会尝试绕过禁用函数。
1 | function runcmd($c) |
依次判断了
- system
- passthru
- shell_exec
- exec
- popen
- proc_open
- antsystem (猜测是蚁剑自己实现的函数)
如果这些函数都被禁用,则会使用 runshellshock
函数或 COM
类
可以说是面面俱到了
runshellshock
什么是 shellshock
参考文章: https://zhuanlan.zhihu.com/p/35579956
简单的理解就是一种利用 unix 漏洞 bypass disabled_functions 的方法
如何使用
1 | function runshellshock($d, $c) |
从代码中可以看出用到三个函数
- putenv
- error_log
其中 error_log 与 mail 函数只是起到执行 bash 的效果
COM
详见:https://www.php.net/manual/zh/faq.com.php
而 WScript.shell 这个对象在 asp shell 中常用,不做扩展
命令执行
此后的命令执行都是在上面的基础上做
执行 ls 命令时,编码后的指令如下
cd "/var/www/html";ls;echo [S];pwd;echo [E]
,可以看到每一次都会切换目录(命令执行时的 cd,在下一次就会失效),而后执行命令。
返回结果如下:
对此有不解——我理解的 [S] == Start, [E] == End 那命令执行的结果为什么不在这之中而在外面呢?或许需要分析源码才能明白(所以蚁剑的 loader 什么时候开源)
文件管理
目录
蚁剑在访问目录时使用的核心代码为
1 | try { |
简单的遍历目录下的所有文件/文件夹,并回显
文件
创建文件/写文件
1 | try { |
默认写入的数据为 #Halo AntSword!
打开文件/读取文件
1 | try { |
总结
蚁剑会将 PHP 代码传入密码参数(上面为 cmd) 中,并且将需要用到的参数以随机字符串的变量名、base64 加密,并在前面加入两个字节的垃圾数据传入,由此来绕过一些 waf(在base64 这一层解码不出来)
但是为什么 PHP 代码明文传输仍然存在一定的疑惑