mstream分布式拒绝服务攻击工具解析
作者:云端旅人
时间:2026-07-27
转载
DoS系列--分布式拒绝服务攻击工具mstream 简介 分布式拒绝服务攻击工具mstream,其核心代码源自stream2 c。到目前为止,业界公认的分布式拒绝服务攻击工具有七种:trinoo、Tribe Flood Network (TFN)、Tribe Flood Network 2
# DoS系列--分布式拒绝服务攻击工具mstream
## 简介
分布式拒绝服务攻击工具mstream,其核心代码源自stream2.c。到目前为止,业界公认的分布式拒绝服务攻击工具有七种:trinoo、Tribe Flood Network (TFN)、Tribe Flood Network 2000 (tfn2k)、stacheldraht/stacheldrahtV4、stacheldraht v2.666、shaft,以及我们今天要聊的mstream。
跟其他DDoS工具相比,mstream显得粗糙得多。通过逆向工程还原出的C代码可以看出,它明显还处在早期开发阶段,里面充斥着大量BUG以及未完成的特性。不过话说回来,由于stream/stream2攻击本身具备的威力,哪怕只有几台攻击机参与,也足以对目标(以及agent所在网络)产生极大的影响。
mstream的源代码是在2000年4月29日被人匿名发布到vuln-dev@securityfocus.com以及BugTraq邮件列表上的。因此这篇分析做了少许修正,希望紧急事件响应小组和各厂商能花点时间提出自己的应对方案。文中可能还残留着一些错误,正是这次匆忙赶制修正所致。需要提醒读者的是,对源代码的修改必然导致与本文分析细节不符——比如提示信息、口令、命令、TCP/UDP端口号、所支持的攻击方式、签名、特性等等。事实上,外面流传的代码所用的通讯端口已经与本文分析中的不同。
本文使用了CERT Distributed System Intruder Tools workshop于1999年11月发布的术语标准。强烈建议先阅读以下链接作为背景知识:
- http://www.cert.org/reports/dsit_workshop.pdf
- http://staff.washington.edu/dittrich/misc/ddos/
2000年4月下旬,在某大学一台被入侵的Linux主机上发现了mstream agent。这台机器当时正以伪造的源IP对超过一打(12个)的目标主机进行flooding攻击。
这个子网的出口上应用了RFC 2267所定义的外出过滤规则。在32bits范围内伪造的源IP中,只有一小部分(匹配子网掩码的)能离开子网发送出去。然而,问题出现了:出口路由器(内侧有18个子网)停止了响应。这意味着做外出过滤规则的路由设备本身反而遭受了攻击,尽管原来设定的攻击目标只收到了比预期少得多的攻击报文。教训是,对于DDoS,简单的包过滤机制并不是一个快速有效的解决方案。我们已经提醒了路由厂商,希望他们能找出问题原因并修正。
应用外出过滤规则后被拒绝外出的攻击报文无法到达下一跳路由器,因此下一跳路由器感受不到攻击。这意味着基于IDS的边界路由器、DMZ上的IDS或者ISP方的监视设备无法确认攻击发生。除非你正在监视路由器本身,而用户抱怨并暗示攻击来自你的子网。这也让Sniffer抓包分析变得更加困难——只有在应用外出过滤规则的路由器内侧才能抓到所有包。
2000年2月上旬,一家电子商务网站遭受攻击,至今他们还不知道对方使用了何种攻击工具。只知道他们的路由器崩溃了,每次都依赖于上级路由器阻断攻击、恢复通讯。法律部门在缺乏证据的情况下无法介入,他们不能认定这是DoS或DDoS攻击,而非路由器、浏览器自身的技术故障。针对Yahoo!的攻击描述可以在Packetstormsecurity找到,但并没有更多其他可用信息。
1999年,trinoo、TFN和stacheldraht伴随着大量自动入侵行为出现。而mstream则处于代码开发的早期阶段,通常是手工入侵、安装(包括handler和agent),并用一个略微改动后的Linux rootkit version 4保护自己。
附录D介绍了一次针对agent的入侵和踪迹隐藏。附录E介绍了一次针对handler的入侵和踪迹隐藏。
## mstream network: client(s)→handler(s)→agent(s)→victim(s)
与trinoo和shaft一样,mstream network由一个或多个handler(master.c)以及大量的agent(server.c)组成。Attacker到handler之间的通讯是未加密的TCP传输,handler到agent之间的通讯是未加密的UDP传输。整个结构看上去像这个样子:
```
--------------------------------------------------------------------
---------- ----------
| attacker | | attacker |
---------- ----------
| | . . . -- ------ --------------- ------ ---------------- -- . . .
| | | | | |
----------- ----------- -----------
| handler | | handler | | handler |
----------- ----------- -----------
| | | | | |
| | . . . --- ------ ----- ------------ --- -------- ------------ - -- . . .
| | | | | | | | |
------- ------- ------- ------- -------
| agent | | agent | | agent | | agent | | agent |
------- ------- ------- ------- -------
图: mstream network
--------------------------------------------------------------------
```
## 通讯
- Attacker → Handler(s): 6723/tcp (published source), 15104/tcp ("in the wild"), 12754/tcp (recovered source)
- Agent → Handler(s): 9325/udp (published source), 6838/udp ("in the wild")
- Handler → Agent(s): 7983/udp (published source), 10498/udp ("in the wild")
Attacker到Handler的远程控制是通过TCP连接完成的,端口号不定(很容易产生变体)。Handler所等待的命令应该完整地位于单个TCP报文的数据区(PDU)中,而不是断续的字节流。这意味着不能使用telnet控制Handler,netcat可以胜任。Security Focus中的源代码并未包含这样的客户端工具。
Attacker到Handler的传输未做加密处理,尽管stacheldraht表明增加Blowfish block cipher并不困难。命令行靠空格分隔参数。
与trinoo类似,Handler与Agent之间的通讯通过UDP报文完成。Agent命令行靠斜杠(/)分隔参数,多项参数自身靠冒号(:)分隔。
我们所检查的代码中最多允许3个Attackers连接到一个Handler,这可能是一个保护性措施,也可能是个多余的访问限制。
连接建立后,必须提交正确的口令。缺省值如下:
- Attacker → Handler(s): "sex" (published source), "N7%diApf!" (recovered source)
如果口令不正确,所有目前已建立连接的用户会收到提醒:有人正试图访问该Handler,然后关闭这个未通过验证的连接。如果口令正确,所有目前已建立连接的用户会收到新会话连接的通知,通过验证的用户会得到一个 `>` 提示符。
## Handler命令
Handler命令行至多由3个空格分隔的参数组成(argv[0] - argv[2])。如果攻击者建立连接后420秒内未输入一条命令,连接终止。
Handler命令集如下:
- **help**:显示如下信息
```
A vailable commands:
stream stream attack !(进行stream攻击)
servers Prints all known servers.(显示所有已知servers/agents)
ping ping all servers.
who tells you the ips of the people logged in
mstream lets you stream more than one ip at a time
```
- **servers**:显示当前所有已知Agents
- **who**:显示当前已建立连接的用户
- **ping**:确认Agents的活动状态。对所有已知Agents发送"ping",每收到一个"pong"回应就报告用户。
- **stream **:针对单个主机攻击,seconds指定攻击持续时间。Handler将主机名解析成IP地址并发送命令"mstream/arg1:arg1/arg2"到所有Agents,这里arg1是victim目标IP地址,arg2是攻击持续时间。
- **mstream **:针对多台主机攻击,seconds指定攻击持续时间。Handler发送命令"mstream/arg1/arg2"到所有Agents,这里arg1是冒号分隔的victim目标IP地址列表,arg2是攻击持续时间。
- **quit**:终止Attacker到Handler的连接
## Agent命令
Handler到Agent的命令位于UDP报文的数据区(PDU)中,未做加密处理(尽管这很容易做到)。
目前仅有三条Agent命令。Agent命令行是一个靠斜杠(/)分隔参数的简单字符串。
- **ping**:对发送该命令的IP响应以"pong"。
- **stream/IP/seconds**:开始对指定IP进行攻击,seconds指定攻击持续时间。
- **mstream/IP1[:IP2[:IPN]]/seconds**:开始对指定IP列表进行攻击,seconds指定攻击持续时间。
尽管Agent可以接受stream和mstream两种命令,但实际只有mstream命令用于Handler与Agent之间。比如"stream 192.168.0.100 10"会被转换成"mstream/192.168.0.100:192.168.0.100/10",然后发送到Agent。不清楚为何要这样处理,或许这只是表明mstream的开发过程快速而凌乱。
## 口令保护
Handler受口令保护,以防止其被任意接管。口令未做加密处理,仅仅是明文字符串之间的比较。可以利用Sniffer获取口令明文。
这里需要再次提醒的是,mstream有一个特性是其他DDoS工具所不具有的:它会提醒所有已建立连接的用户有新的连接试图建立,无论成功与否。
令人惊奇的是Handler与Agent之间无口令保护。
## 指纹
前面提到过,Handler与Agent之间的命令串是明文字符串,在通讯报文中可见。
对Agent使用strings命令可以看到这样一些明文字符串(为了节省显示空间做了处理):
```
ELF mstream /lib/ld-linux.so.2 ping GNU pong __gmon_start__ fork libc.so.6 init.c random . . . getpid server.c perror strchr@@GLIBC_2.0 getuid packet malloc getpid@@GLIBC_2.0 recvfrom _DYNAMIC socket _etext bind __register_frame_info@@GLIBC_2.0 inet_addr recvfrom@@GLIBC_2.0 __deregister_frame_info _fp_hw setsockopt perror@@GLIBC_2.0 rand fork@@GLIBC_2.0 strncmp sock strncpy cksum sendto random@@GLIBC_2.0 strtok _init fork malloc@@GLIBC_2.0 memset getppid@@GLIBC_2.0 srand sendto@@GLIBC_2.0 getppid __deregister_frame_info@@GLIBC_2.0 time setsockopt@@GLIBC_2.0 htons time@@GLIBC_2.0 exit _start atoi forkbg _IO_stdin_used strlen@@GLIBC_2.0 __libc_start_main stream strlen strncmp@@GLIBC_2.0 strchr inet_addr@@GLIBC_2.0 __register_frame_info __bss_start free main GLIBC_2.0 __libc_start_main@@GLIBC_2.0 PTRh data_start QVh0 bind@@GLIBC_2.0 Ph% getuid@@GLIBC_2.0 PhG _fini WVS s_in [^_ srand@@GLIBC_2.0 WVS nlstr j(j exit@@GLIBC_2.0 j h atoi@@GLIBC_2.0 j(h _edata j h in_cksum j(h _GLOBAL_OFFSET_TABLE_ [^_ free@@GLIBC_2.0 131.247.208.191 _end 129.79.20.202 htons@@GLIBC_2.0 socket send2master bind memset@@GLIBC_2.0 setsockopt strncpy@@GLIBC_2.0 newserver _IO_stdin_used stream strtok@@GLIBC_2.0 __data_start __gmon_start__ socket@@GLIBC_2.0 rand@@GLIBC_2.0
```
对Handler使用strings命令可以看到这样一些明文字符串(做了处理):
```
% strings -n 3 master socket stream bind stream attack ! listen servers setsockopt Prints all known servers. fcntl ping You're too idle ! ping all servers. Connection from %s who newserver tells you the ips of the people log New server on %s. mstream pong lets you stream more than one ip at Got pong number %d from %s who %s has disconnected (not auth'd): %s Currently Online: Invalid password from %s. Socket number %d Password accepted for connection fr [%s] Lost connection to %s: %s ping stream Pinging all servers. Usage: stream mstream Unable to resolve %s. Usage: mstream 00000000:0000 st=07
rpc.wall 588 root 7r FIFO 0,0 648 pipe
rpc.wall 588 root 8u raw 30241 00000000:00FF->00000000:0000 st=07
rpc.wall 588 root 9u CHR 5,1 4952 /dev/console
rpc.wall 588 root 10u IPv4 30244 UDP *:1051
rpc.wall 588 root 11u raw 30245 00000000:00FF->00000000:0000 st=07
rpc.wall 588 root 21w FIFO 0,0 648 pipe
```
server.c和master.c都有BUG,结果Agent多出一些raw socket、UDP socket(在这个例子中各多出两个),而Handler会多出一些打开的文件句柄以及UDP socket(Andrew Korty曾经检查到数百个)。毫无疑问,mstream处在早期开发阶段,所以这些签名并不可靠。
当一个Agent第一次启动时,它向编译时固化进二进制文件的缺省Handlers列表发送"newserver"命令。用tcpdump可以看到如下内容:
```
00:04:38.530000 192.168.0.20.1081 > 192.168.0.100.6838: udp 9
0x0000 4500 0025 ef75 0000 4011 098a c0a8 0014 E..%.u..@.......
0x0010 c0a8 0064 0439 1ab6 0011 2b63 6e65 7773 ...d.9.... cnews
0x0020 6572 7665 7200 0000 0000 0000 0000 erver.........
```
如果发现rootkit存在(Handler和Agent上都会使用),你不能相信标准操作系统命令的输出,比如进程、网络连接等等。所有的系统管理员都应该花点时间看看参考资源[10]以了解rootkit。
前面提到了,如果一个Agent在10498/UDP上收到一个UDP报文,其数据区包含字符串"ping",如果这个Agent此时没有处在攻击状态中,则响应一个UDP报文,目标端口6838/UDP,数据区包含字符串"pong"。下面是tcpdump的输出,结尾的0是tcpdump自己增加的,实际负载只有4个字节。
```
00:05:16.457239 192.168.0.100.65364 > 192.168.0.20.10498: udp 5
0x0000 4500 0021 f412 0000 4011 04f1 c0a8 0064 E..!....@......d
0x0010 c0a8 0014 ff54 2902 000d 6ce3 7069 6e67 .....T)...l.ping
0x0020 0a .
00:05:16.458214 192.168.0.20.1083 > 192.168.0.100.6838: udp 4
0x0000 4500 0020 ef8c 0000 4011 0978 c0a8 0014 E.......@..x....
0x0010 c0a8 0064 043b 1ab6 000c 8045 706f 6e67 ...d.;.....Epong
0x0020 0000 0000 0000 0000 0000 0000 0000 ..............
```
可以用ngrep、snort(附录B介绍了snort规则)做签名匹配,或者用rid(附录C有一个RID模板)搜索空闲(未做攻击)Agents。
```
# ngrep "p[oi]ng" udp port 6838 or udp port 10498
```
如果攻击者修改了源代码,这条ngrep命令所用端口也要修改。
攻击报文固定在40字节大小,或许是规避某些IDS的大包检测规则。
stream2.c对victim做TCP ACK Flooding,源IP随机化(用random()产生),源端口和TCP序列号顺序递增。参看如下源代码:
```c
for ( i = 0; ; i++ ) {
cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
packet.ip.ip_id++;
packet.tcp.th_sport++;
packet.tcp.th_seq++;
if ( !dstport ) {
s_in.sin_port = packet.tcp.th_dport = rand();
}
...
}
```
由于源IP随机化,伪造得到的点分十进制源IP可能出现某些字节为0的情况。
用tcpdump抓取攻击报文:
```
01:39:24.701083 192.168.0.2.65527 > 192.168.0.20.10498: [bad udp cksum 3100!] udp 24 (ttl 64, id 886)
0x0000 4500 0034 0376 0000 4011 f5dc c0a8 0002 E..4.v..@.......
0x0010 c0a8 0014 fff7 2902 0020 556c 7374 7265 ......)...Ulstre
0x0020 616d 2f31 3932 2e31 3638 2e30 2e31 3030 am/192.168.0.100
0x0030 2f31 300a /10.
01:40:10.132724 192.168.0.2.65526 > 192.168.0.20.10498: [bad udp cksum 3100!] udp 24 (ttl 64, id 930)
0x0000 4500 0034 03a2 0000 4011 f5b0 c0a8 0002 E..4....@.......
0x0010 c0a8 0014 fff6 2902 0020 556d 7374 7265 ......)...Umstre
0x0020 616d 2f31 3932 2e31 3638 2e30 2e31 3030 am/192.168.0.100
0x0030 2f31 300a /10.
01:41:23.674796 192.168.0.2.65525 > 192.168.0.20.10498: [bad udp cksum 4a00!] udp 49 (ttl 64, id 1031)
0x0000 4500 004d 0407 0000 4011 f532 c0a8 0002 E..M....@..2....
0x0010 c0a8 0014 fff5 2902 0039 a9b4 6d73 7472 ......)..9..mstr
0x0020 6561 6d2f 3139 322e 3136 382e 302e 313a eam/192.168.0.1:
0x0030 3139 322e 3136 382e 302e 3130 303a 3139 192.168.0.100:19
0x0040 322e 3136 382e 302e 322f 3130 0a 2.168.0.2/10.
01:41:23.675771 arp who-has 192.168.0.1 tell 192.168.0.20
0x0000 0001 0800 0604 0001 0010 5a99 6544 c0a8 ..........Z.eD..
0x0010 0014 0000 0000 0000 c0a8 0001 0000 0000 ................
0x0020 0000 0000 0000 0000 0000 0000 0000 ..............
01:41:23.675772 arp who-has 192.168.0.100 tell 192.168.0.20
0x0000 0001 0800 0604 0001 0010 5a99 6544 c0a8 ..........Z.eD..
0x0010 0014 0000 0000 0000 c0a8 0064 0000 0000 ...........d....
0x0020 0000 0000 0000 0000 0000 0000 0000 ..............
01:41:23.675773 77.172.43.85.38444 > 192.168.0.2.26296: . [tcp sum ok] ack 0 win 16384 [tos 0x8] (ttl 255, id 50237)
0x0000 4508 0028 c43d 0000 ff06 bdde 4dac 2b55 E..(.=......M. U
0x0010 c0a8 0002 962c 66b8 ea97 d237 0000 0000 .....,f....7....
0x0020 5010 4000 7c74 0000 0000 0000 0000 P.@.|t........
01:41:23.675774 88.148.222.45.39212 > 192.168.0.2.10342: . [tcp sum ok] ack 0 win 16384 [tos 0x8] (ttl 255, id 51005)
...(后续近20行类似报文省略)
```
对Cisco Net Flows产生的日志使用如下命令(过滤点分十进制中含有0的IP地址)可以发现攻击的存在:
```
% grep "[ \.]0[ \.(]" ddos-000415
Apr 15 04:12:08 tcp 82.0.151.5(29497) -> 192.168.10.5(27072), 1 packet
Apr 15 04:12:18 tcp 207.0.149.32(21893) -> 192.168.10.5(3913), 1 packet
Apr 15 04:12:33 tcp 0.147.151.82(10473) -> 10.4.152.237(2810), 1 packet
...
(后续更多行省略)
```
需要提醒的是,某些伪造得到的源IP是广播地址、组播地址、子网地址,这将产生一些其他问题(参考资源[12])。
分析stream2.c的源代码,IP、TCP层的很多头部信息被随机化了,但还是有一些静态值:
```c
packet.ip.ip_id = rand();
...
packet.tcp.th_win = htons(16384);
...
packet.tcp.th_seq = random();
...
packet.tcp.th_sport = rand();
packet.tcp.th_dport = rand();
...
while ( time( 0 ) <= endtime ) {
if ( floodtype != 0 ) {
i = 0;
while ( arg4[i] != NULL ) {
if ( strchr( arg4[i], '.' ) != NULL ) {
packet.ip.ip_dst.s_addr = inet_addr(arg4[i]);
cksum.pseudo.daddr = inet_addr(arg4[i]);
s_sin.sin_addr.s_addr = inet_addr(arg4[i]);
cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
packet.ip.ip_id++;
packet.tcp.th_sport++;
packet.tcp.th_seq++;
s_in.sin_port = packet.tcp.th_dport = rand();
...
}
}
}
}
```
## 防御
我们没有时间完成这部分内容,任何针对stream/stream2或者其它DDoS工具的防御讨论都可一试。最后,归根结底,网管、系管们做好自身的安全防卫工作吧。
## 弱点
由于Attacker、Handler、Agent之间的通讯未加密,很容易被Sniffer、Hijack等等。Agent不对命令来源做任何验证,我们可以利用"ping/pong"特性找出那些当前未做攻击的Agent。
"pong"是Agent到Handler的唯一响应,"newserver"是Agent第一次启动时发给Handler的。附录D介绍了Agent的安装,每次系统重启都会启动Agent。这意味着在系统重启时可以抓到"newserver"包,不过我们不推荐这样去鉴别Agent的存在,至少不该是首选动作。参看附录D、附录E。
Agent接收到一个格式错误的命令串(比如"stream foo bar")时,将发生segmentation fault,导致Agent不可用,但是很可能在系统重启时恢复工作。
向Agent发送太多命令会导致打开的文件句柄过多而最终停止响应。
Agent进程是单线程的,意味着在攻击中它无法处理来自Handler的命令,一旦攻击开始,Agent将失去控制。
Agent工作在多种flood攻击模式下时,攻击列表中的所有主机遭受同样时间长度的攻击以及同样类型的攻击(比如ICMP主机不可达、TCP RST)。
## 可能的修正
1. Handler上针对到自己的连接请求做源端口过滤
2. 在Handler与Agent之间增加验证机制
3. 报文大小可选
4. 允许指定flood packets的TCP标志(ACK、RST、NUL、random等)
5. Attacker与Handler之间的通讯加密
6. 增加内置命令
## 致谢
- Halloween (trinoo)
- Thanksgiving (TFN)
- Christmas (stacheldraht)
- New Years (building/testing scanning tools for all three)
- Sven Dietrich & Neil Long (analyzing "shaft")
- Andrew Korty & investigators at Indiana University (forensic analysis and data gathering)
感谢那位匿名发布mstream源代码的朋友承认了早期的工作。
## 附录A - 参考资源
[00] TCP/IP Illustrated, Vol. I, II, and III. W. Richard Stevens and Gary R. Wright., Addison-Wesley
[01] CERT Distributed System Intruder Tools Workshop report http://www.cert.org/reports/dsit_workshop.pdf
[02] CERT Advisory CA-99-17 Denial-of-Service Tools http://www.cert.org/advisories/CA-99-17-denial-of-service-tools.html
[03] The DoS Project's "trinoo" distributed denial of service attack tool, Da vid Dittrich http://staff.washington.edu/dittrich/misc/trinoo.analysis
[04] The "Tribe Flood Network" distributed denial of service attack tool, Da vid Dittrich http://staff.washington.edu/dittrich/misc/tfn.analysis
[05] The "stacheldraht" distributed denial of service attack tool, Da vid Dittrich http://staff.washington.edu/dittrich/misc/stacheldraht.analysis
[06] TFN2K - An Analysis, Jason Barlow and Woody Thrower, Axent Security Team http://packetstorm.securify.com/distributed/TFN2k_Analysis-1.3.txt
[07] An analysis of the ``Shaft'' distributed denial of service tool, Sven Dietrich, Neil Long, and Da vid Dittrich http://netsec.gsfc.nasa.gov/~spock/shaft_analysis.txt
[08] Distributed Denial of Service (DDoS) Attack Tools, Da vid Dittrich http://staff.washington.edu/dittrich/misc/ddos/
[09] Distributed denial of service attack tools at Packet Storm Security http://packetstorm.securify.com/distributed/
[10] "Root Kits" and hiding files/directories/processes after a break-in, Da vid Dittrich http://staff.washington.edu/dittrich/misc/faqs/rootkits.faq
[11] Technical details of the attack on Yahoo! http://packetstorm.securify.com/distributed/yahoo.txt
[12] BUGTRAQ threads on the stream.c DoS attack and its fallout http://staff.washington.edu/dittrich/misc/ddos/stream.txt
[13] RFC 2267 -- Network Ingress Filtering: Defeating Denial of Service Attacks which employ IP Source Address Spoofing, Paul Fergussen and Daniel Senie ftp://ftp.isi.edu/in-notes/rfc2267.txt
[14] ngrep http://www.packetfactory.net/ngrep/
[15] rid http://theorygroup.com/Software/RID
[16] Dan Farmer & Wietse Venema's class on computer forensic analysis http://www.fish.com/security/forensics.html
[17] tcpdump ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
[18] snort http://www.clark.net/~roesch/security.html
[19] netcat ("nc"), Hobbit http://packetstorm.securify.com/UNIX/netcat/nc110.tgz
[20] Source code for mstream http://securityfocus.com/templates/archive.pike?list=82&date=2000-04-29&thread=200004291748.TAA13203@lobeda.jena.thur.de
## 附录B - 检测mstream的snort规则
```
alert UDP any any -> any 6838 (msg: "IDS100/ddos-mstream-agent-to-handler"; content: "newserver"; )
alert UDP any any -> any 10498 (msg: "IDS101/ddos-mstream-handler-to-agent"; content: "stream/"; )
alert UDP any any -> any 10498 (msg: "IDS102/ddos-mstream-handler-ping-to-agent"; content: "ping";)
alert UDP any any -> any 10498 (msg: "IDS103/ddos-mstream-agent-pong-to-handler"; content: "pong";)
alert TCP any any -> any 12754 (msg: "IDS109/ddos-mstream-client-to-handler"; flags: S;)
alert TCP any 12754 -> any any (msg: "IDS110/ddos-mstream-handler-to-client"; content: ">"; flags: AP;)
alert TCP any any -> any 15104 (msg: "IDS111/ddos-mstream-client-to-handler"; flags: S;)
alert TCP any 15104 -> any any (msg: "IDS112/ddos-mstream-handler-to-client"; content: ">"; flags: AP;)
```
## 附录C - 检测mstream的RID模板
```
start mstream-wild
send udp dport=10498 data="ping"
recv udp dport=6838 data="pong" nmatch=2
end mstream-wild
start mstream-published
send udp dport=7983 data="ping"
recv udp dport=9325 data="pong" nmatch=2
end mstream-published
```
注:这里错误地使用了减号'-',证明这个模板是未经验证的。
## 附录D - 最初的Agent系统的入侵和踪迹隐藏
通过检查Agent系统、询问管理员,确认发生过两次独立的入侵。第一个在2000年3月31之前,/etc/passwd中留下了"inertia"帐号,管理员于4月1号删除了该帐号。上载安装rootkit (lrk4)和DDoS Agent ("rpc.wall")是在4月13号16:02(所有时间均为美国/太平洋时间或GMT-0700时间),留有ADM named攻击的痕迹,4月15号05:55还登录了一次。系统日志被删除、擦除过,所以无法根据日志判断发生过什么。
Dan Farmer和Wietse Venema提供过一个"Coroner's Toolkit",利用其中的"mactime"还是可以看到入侵者的某些行为。下列输出中的年份100显然是Y2K问题。
```
Apr 13 100 16:02:42 12060 .aa -rwxr-xr-x root/www root /bin/chown
12660 m.m -r-sr-xr-x root/www bin /bin/login
Apr 13 100 16:02:43 2048 mcmc drwxr-xr-x root/www root /bin
12660 cc -r-sr-xr-x root/www bin /bin/login
168748 .a. -rwxr-xr-x root/www root /usr/bin/as
64796 .a. -rwxr-xr-x root/www root /usr/bin/egcs
64796 .a. -rwxr-xr-x root/www root /usr/bin/gcc
64796 .a. -rwxr-xr-x root/www root /usr/bin/i386-redhat-linux-gcc
168496 .a. -rwxr-xr-x root/www root /usr/bin/ld
12656 m.c -rws--x--x root/www root /usr/bin/old
12656 m.c -r-xr-xr-x root/www bin /usr/bin/xstat
2315 .a. -rw-r--r-- root/www root /usr/include/_G_config.h
1313 .a. -rw-r--r-- root/www root /usr/include/alloca.h
4090 .a. -rw-r--r-- root/www root /usr/include/arpa/inet.h
3451 .a. -rw-r--r-- root/www root /usr/include/bits/byteswap.h
13327 .a. -rw-r--r-- root/www root /usr/include/bits/confname.h
168 .a. -rw-r--r-- root/www root /usr/include/bits/endian.h
2283 .a. -rw-r--r-- root/www root /usr/include/bits/errno.h
5107 .a. -rw-r--r-- root/www root /usr/include/bits/fcntl.h
4647 .a. -rw-r--r-- root/www root /usr/include/bits/in.h
3406 .a. -rw-r--r-- root/www root /usr/include/bits/posix_opt.h
2842 .a. -rw-r--r-- root/www root /usr/include/bits/select.h
4673 .a. -rw-r--r-- root/www root /usr/include/bits/sigset.h
1716 .a. -rw-r--r-- root/www root /usr/include/bits/sockaddr.h
9033 .a. -rw-r--r-- root/www root /usr/include/bits/socket.h
1297 .a. -rw-r--r-- root/www root /usr/include/bits/stdio_lim.h
2015 .a. -rw-r--r-- root/www root /usr/include/bits/time.h
4673 .a. -rw-r--r-- root/www root /usr/include/bits/types.h
1781 .a. -rw-r--r-- root/www root /usr/include/bits/uio.h
1798 .a. -rw-r--r-- root/www root /usr/include/endian.h
2481 .a. -rw-r--r-- root/www root /usr/include/errno.h
4579 .a. -rw-r--r-- root/www root /usr/include/fcntl.h
9433 .a. -rw-r--r-- root/www root /usr/include/features.h
5861 .a. -rw-r--r-- root/www root /usr/include/getopt.h
973 .a. -rw-r--r-- root/www root /usr/include/gnu/stubs.h
10291 .a. -rw-r--r-- root/www root /usr/include/libio.h
17327 .a. -rw-r--r-- root/www root /usr/include/netdb.h
10779 .a. -rw-r--r-- root/www root /usr/include/netinet/in.h
1591 .a. -rw-r--r-- root/www root /usr/include/netinet/in_systm.h
9086 .a. -rw-r--r-- root/www root /usr/include/netinet/ip.h
4855 .a. -rw-r--r-- root/www root /usr/include/netinet/tcp.h
2550 .a. -rw-r--r-- root/www root /usr/include/rpc/netdb.h
6467 .a. -rw-r--r-- root/www root /usr/include/stdint.h
20816 .a. -rw-r--r-- root/www root /usr/include/stdio.h
27654 .a. -rw-r--r-- root/www root /usr/include/stdlib.h
13245 .a. -rw-r--r-- root/www root /usr/include/string.h
2104 .a. -rw-r--r-- root/www root /usr/include/strings.h
4932 .a. -rw-r--r-- root/www root /usr/include/sys/cdefs.h
3359 .a. -rw-r--r-- root/www root /usr/include/sys/select.h
7996 .a. -rw-r--r-- root/www root /usr/include/sys/socket.h
1577 .a. -rw-r--r-- root/www root /usr/include/sys/sysmacros.h
5337 .a. -rw-r--r-- root/www root /usr/include/sys/time.h
5299 .a. -rw-r--r-- root/www root /usr/include/sys/types.h
1907 .a. -rw-r--r-- root/www root /usr/include/sys/uio.h
9314 .a. -rw-r--r-- root/www root /usr/include/time.h
36708 .a. -rw-r--r-- root/www root /usr/include/unistd.h
874 .a. -rw-r--r-- root/www root /usr/lib/crtn.o
1446620 .a. -rwxr-xr-x root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cc1
46816 .a. -rwxr-xr-x root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/collect2
88444 .a. -rwxr-xr-x root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cpp
1424 .a. -rw-r--r-- root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtend.o
5794 .a. -rw-r--r-- root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h
9834 .a. -rw-r--r-- root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h
770000 .a. -rwxr-xr-x root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/libgcc.a
1957 .a. -rw-r--r-- root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
178 .a. -rw-r--r-- root/www root /usr/lib/libc.so
69638 .a. -rw-r--r-- root/www root /usr/lib/libc_nonshared.a
6162 .a. -rw-r--r-- 1046 squid /usr/src/linux/include/asm-i386/errno.h
1492 .a. -rw-r--r-- 1046 squid /usr/src/linux/include/asm-i386/socket.h
277 .a. -rw-r--r-- 1046 squid /usr/src/linux/include/asm-i386/sockios.h
305 .a. -rw-r--r-- 1046 squid /usr/src/linux/include/linux/errno.h
Apr 13 100 16:02:44 702 mcmc -rwxr-xr-x root/www root /etc/rc.d/rc.local
1024 mcmc drwxr-xr-x root/www root /root/.ncftp
9 mcmc lrwxrwxrwx root/www root /root/.ncftp/history
9 mcmc lrwxrwxrwx root/www root /root/.ncftp/log
9 mcmc lrwxrwxrwx root/www root /root/.ncftp/trace
29696 m.c drwxr-xr-x root/www root /usr/bin
17016 m.c -rwxr-xr-x root/www root /usr/bin/rpc.wall
8460 .a. -rw-r--r-- root/www root /usr/lib/crt1.o
1124 .a. -rw-r--r-- root/www root /usr/lib/crti.o
1892 .a. -rw-r--r-- root/www root /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o
...
Apr 15 100 05:55:09 1024 mcmc drwxr-xr-x root/www root /var/named
1024 mcmc drwxr-xr-x root/www root /var/named/ADMROCKS
Apr 15 100 05:56:19 20437 .a. -rwxr-xr-x root/www root /usr/sbin/tcpd
Apr 15 100 05:56:20 34 .aa -rw-r--r-- root/www root /usr/libexec/awk/addy.awk
35628 .a. -rwxr-xr-x root/www root /usr/sbin/in.telnetd
Apr 15 100 05:56:26 159576 .a. -rwxr-xr-x root/www root /usr/bin/pico
975 .a. -rw-r--r-- root/www root /usr/share/terminfo/v/vt200
975 .a. -rw-r--r-- root/www root /usr/share/terminfo/v/vt220
```
从这个输出中可以观察到如下信息:
- 2000年4月13号16:02创建/bin/login、运行/bin/chown。
- 与此同时,运行gcc/egcs进行编译,创建了/bin/old和/bin/xstat。.h文件的Access times表明被编译的程序使用了socket。
- 接下来/etc/rc.d/rc.local被修改,在最后增加了一行"/usr/bin/rpc.wall",于是每次重启系统时都会自动启动Agent。ncftp日志文件被修改(先删除,然后符号链接到/dev/null以阻止ncftp文件传输日志产生)。
- 程序/usr/bin/rpc.wall被修改,C运行时库被访问过,这意味着rpc.wall运行过。
- 4月15号05:55,似乎有一次针对本机的ADM named远程缓冲区溢出攻击,然后访问tcpd wrapped service激活in.telnetd。rootkit的配置文件/usr/libexec/awk/addy.awk也被访问过。不确定这是否仅仅碰巧是第三次入侵企图。
- 6秒后/usr/bin/pico被运行,vt200终端类型。既然被安装了特洛伊木马的login包含"vt200"字符串,可以确认远程root shell后门至少两天前就安装好了。
管理员只删除了/etc/passwd中的"inertia"帐号,并未删除/etc/shadow中的相应内容:
```
inertia:iUCNir1cd8pI2:::::::
```
不到1秒就破解出这个口令"hi"。
用strings命令观察/bin/login,带有典型的特洛伊木马特征,一个非标准命令(这里是/usr/bin/xstat)和一个嵌入式终端类型(vt200)用于激活远程root shell:
```
...
login
/bin/sh
/usr/bin/xstat
TERM
bcshjvmudzwxftejk
vt200
%s=%s
init.c
...
```
用strings命令观察/bin/ls和/bin/ps,显示rootkit配置文件分别是/usr/libexec/awk/files.awk和/usr/libexec/awk/ps.awk。另一个配置文件是前面提到的/usr/libexec/awk/addy.awk。
一个有用的窍门在于标准Linux rootkit编译时(由Makefile决定)保留了调试信息:
```
...
ls.c
/home/XXXXX/stuff/lrk4/fileutils-3.13/src/
gcc2_compiled.
int:t1=r1;-2147483648;2147483647;
char:t2=r2;0;127;
...
```
本机并未使用telnetd支持远程登录,而是SSH。入侵者在/etc/inetd.conf中增加了如下内容:
```
...
#finger stream tcp nowait root /usr/sbin/tcpd in.fingerd
#cfinger stream tcp nowait root /usr/sbin/tcpd in.cfingerd
#systat stream tcp nowait guest /usr/sbin/tcpd /bin/ps -auwwx
#netstat stream tcp nowait guest /usr/sbin/tcpd /bin/netstat -f inet
working stream tcp nowait root /usr/sbin/tcpd in.telnetd
...
```
然后在/etc/services中增加了如下内容:
```
working 1120/tcp # Kerberos working daemon
```
用lsof可以看到这个侦听端口:
```
inetd 353 root 4u IPv4 375 UDP *:talk
inetd 353 root 5u IPv4 376 UDP *:ntalk
inetd 353 root 6u IPv4 377 TCP *:working (LISTEN)
inetd 353 root 8u IPv4 378 TCP *:time (LISTEN)
inetd 353 root 10u IPv4 379 UDP *:time
inetd 353 root 11u IPv4 380 TCP *:auth (LISTEN)
inetd 353 root 12u IPv4 381 TCP *:linuxconf (LISTEN)
```
## 附录E - 对印第安纳大学Handler系统的分析
2000年4月20日,印第安纳大学IT安全办公室接到华盛顿大学Da ve Dittrich的通知(随后是Penn State),在华盛顿大学确认一台类似Trinoo Agent的主机正以伪造过的源IP进行DoS攻击,该Agent的二进制文件中固化有印第安纳大学所属IP。
首先我们阻断了与该IP相关的进出通讯,并记录一切入连接企图。主要意图是避免该IP引起更多麻烦,但不想惊动入侵者。没有重启主机或者其它针对网络的物理改变(比如拔掉网线),以免运行在主机上的程序监测到这些行为并删除自身。
一旦系统与网络其他部分隔离开来,就可以运行lsof,输出报告在后面。这个输出表明进程rpc.wall侦听好几个UDP端口,其中包括6838/UDP,Dittrich先生提到他那边的Agent进程向该端口发送报文。/usr/bin/...被打开读取了几百次,这个文件包含一个IP列表,做了点简单的ASCII变换加密。这些IP地址似乎是受该Handler控制的Agent地址。华盛顿大学那台Agent确实在这个列表里。我们发现一个类似的文件/dev/grab/...,想必为另一个master server所用。
这种文件中包含类似行:
```
ckd`chj`cc`jb<
```
ASCII变换加密仅仅是在每个字符上增加50,所以最终IP是(减去50即可得到):
```
192.168.11.80
```
可以用如下Unix命令一次性转换完毕:
```
tr 'b-j`' '0-9.' | sed 's/<$//'
```
我们得到76个IP地址,大概都是DDoS sla ve agents。
通过搜索原始设备(raw disk)找到了rpc.wall的源代码。入侵者很好地删除了原来的源代码,不仅释放了inode,也清除了内容本身。但是在编译过程中没有使用gcc -pipe,预编译代码被写入一个临时文件,最终传递给编译器。尽管这个临时文件由编译器删除了,但这种删除未能清除内容本身,通过读取原始设备可以还原出来。
分析这个源代码后,发现它能进行"stream"、"mstream"攻击。mstream攻击显然是多个IP同时进行stream攻击。这比先前所见更大范围的DDoS攻击。
还原出来的源代码附在报告尾部。
此刻意识到这是相当重要的证据,于是用dd将整个文件系统复制出来,通过网络传输到笔记本电脑上。然后可以只读mount这个文件继续检查。
在/bin/下发现名为flukek.tgz的rootkit。它替换了cron、in.timed、inetd、login、named、passwd、rshd、syslogd、tcpd等等。下列文件自系统安装以来被增加到/bin、/sbin、/usr/bin以及/usr/sbin中。似乎没有文件被增加到/usr/libexec或/usr/local中。列出的时间是inode change times,/usr/bin/old似乎是以前的login:
```
-rw-r--r-- 1 root wheel 2387704 Dec 18 16:37 bin/flukek.tgz
-r-sr-xr-x 1 root daemon 12656 Apr 13 23:39 bin/login
-rw-r--r-- 1 root wheel 1401 Apr 24 12:11 usr/bin/...
-rwsr-xr-x 1 root wheel 20164 Mar 31 14:50 usr/bin/old
-rwxr-xr-x 1 root wheel 33610 Apr 13 23:37 usr/bin/rpc.wall
-rwxr-xr-x 1 root wheel 32727 Apr 5 21:56 usr/bin/xfs
-r-xr-xr-x 1 root daemon 20164 Mar 31 14:50 usr/bin/xstat
-rwxr-xr-x 1 root wheel 111500 Mar 31 20:09 usr/sbin/dnskeygen
-rwxr-xr-x 1 root wheel 266712 Mar 31 20:09 usr/sbin/irpd
-rwxr-xr-x 1 root wheel 528612 Mar 31 20:09 usr/sbin/named
-rwxr-xr-x 1 root wheel 7166 Mar 31 20:09 usr/sbin/named-bootconf
-rwxr-xr-x 1 root wheel 285076 Mar 31 20:09 usr/sbin/named-xfer
-rwxr-xr-x 1 root wheel 37056 Mar 31 20:09 usr/sbin/ndc
```
似乎没有库文件、内核模块或PAM模块被替换。
/etc/passwd和/etc/shadow最近被修改过:
```
-rw-r--r-- 1 root wheel 849 Feb 17 00:57 /mnt/etc/passwd
-rw------- 1 root wheel 884 Feb 17 00:57 /mnt/etc/passwd-
-r-------- 1 root wheel 794 Feb 17 00:57 /mnt/etc/shadow
-r-------- 1 root wheel 658 Nov 15 10:07 /mnt/etc/shadow-
```
/etc/shadow的备份文件于11月5日创建,这给了我们一个何时增加帐号的线索:
```
www:MyjKA0KGHplq6:11004:0:99999:7:::
login1:MyjKA0KGHplq6:11004:0:99999:7:::
web:af47L/OTL7K6.:11004:0:99999:7:::
x::11004:0:99999:7:::
```
没有试图破解这些口令,仅仅试着以"x"登录,失败了。
/etc/services和/etc/inetd.conf被改变:
- /etc/services: a 1111/tcp
- /etc/inetd.conf: a stream tcp nowait root /usr/sbin/tcpd in.telnetd
同样,没有试图登录它。
下面三个文件是现在所能找到的惟一含有相关信息的日志文件:
- /.bash_history: nslookup cd /bin w ps x ftp 192.168.0.1 21 w
- /var/log/secure: 包含多次连接记录(略)
- /var/log/wtmp: 包含登录记录(略)
下面是lsof的输出,编辑过:
```
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
...
rpc.wall 29108 root cwd DIR 3,1 31744 59393 /usr/bin
rpc.wall 29108 root rtd DIR 3,1 1024 2 /
rpc.wall 29108 root txt REG 3,1 33610 61172 /usr/bin/rpc.wall
rpc.wall 29108 root mem REG 3,1 342206 30722 /lib/ld-2.1.1.so
rpc.wall 29108 root mem REG 3,1 65996 30758 /lib/libnss_dns-2.1.1.so
rpc.wall 29108 root mem REG 3,1 4016683 30729 /lib/libc-2.1.1.so
rpc.wall 29108 root mem REG 3,1 243964 30760 /lib/libnss_files-2.1.1.so
rpc.wall 29108 root mem REG 3,1 251436 30766 /lib/libnss_nisplus-2.1.1.so
rpc.wall 29108 root mem REG 3,1 364235 30742 /lib/libnsl-2.1.1.so
rpc.wall 29108 root mem REG 3,1 251787 30764 /lib/libnss_nis-2.1.1.so
rpc.wall 29108 root mem REG 3,1 164797 30770 /lib/libresolv-2.1.1.so
rpc.wall 29108 root 0r REG 3,1 1401 198670 /usr/bin/...
rpc.wall 29108 root 1u CHR 136,1 3 /dev/pts/1
rpc.wall 29108 root 2u CHR 136,1 3 /dev/pts/1
rpc.wall 29108 root 3u inet 36066 TCP *:15104 (LISTEN)
rpc.wall 29108 root 4u CHR 136,1 3 /dev/pts/1
rpc.wall 29108 root 5u inet 36067 UDP *:6838
rpc.wall 29108 root 6r REG 3,1 1401 198670 /usr/bin/...
...
(后续大量重复打开/usr/bin/...的文件描述符,以及多个UDP端口)
...
rpc.wall 29108 root 110r REG 3,1 1401 198670 /usr/bin/...
```
---
注:本文原始出处为互联网安全焦点(nsfocus.com),文中部分URL和参考链接已失效,仅作历史分析参考。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
DDoS攻击的三大主要形式:原理、特征与防御重点
DDoS攻击主要分为基于流量(Volume)、基于应用层(Application)和基于协议(Protocol)三种形式。流量型攻击通过海量数据淹没带宽;应用层攻击利用Web漏洞耗尽服务器资源;协议层攻击则利用TCP握手缺陷导致系统挂起。了解这些原理是制定针对性防御策略的基础。
如何有效预防和缓解DDoS攻击:5大核心策略详解
面对DDoS攻击,单纯增加带宽已非长久之计。本文详解5大核心防护策略:优化网络硬件配置、建立DNS冗余机制、部署透明缓解技术、引入负载平衡器及专用Anti-DDoS模块。通过合理组合这些技术手段,可有效抵御SYN泛洪、Slowloris等常见攻击,保障业务连续性与网站可用性。
DDoS防护四大误区:CDN、防火墙与黑名单的局限性解析
许多企业误以为CDN、防火墙或黑名单能完全抵御DDoS攻击。本文深入解析四大常见误区:CDN仅提供部分缓解、静态黑名单易失效、防火墙算力有限且可能成为目标、阈值警报仅具滞后性。了解这些局限性,有助于构建更立体的防御体系,避免在攻击发生时措手不及。
常见DDoS攻击类型详解:原理、特征与防御策略
本文详细解析四种常见DDoS攻击类型:SYN Flood利用TCP三次握手缺陷耗尽资源;UDP Flood通过海量数据包造成带宽拥塞;ICMP Flood利用Ping请求消耗系统算力;应用层Flood针对Web脚本进行高频请求。了解其原理是制定有效防御策略的基础。
如何有效抵御DDOS攻击:4种核心防护方案解析
面对DDOS攻击,企业需构建多层防护体系。本文详解四大核心策略:利用反向路由器查询进行流量清洗,通过GCDN智能分配节点隐藏源站IP,部署负载均衡硬件分担压力,以及接入高防机房抵御数百G恶意流量。掌握这些技术,可最大程度保障业务连续性。