您现在的位置是:网站首页> 编程资料编程资料
DoS系列--分布式拒绝服务攻击工具mstream _工具使用_网络安全_
2023-05-24
354人已围观
简介 DoS系列--分布式拒绝服务攻击工具mstream _工具使用_网络安全_
DoS系列--分布式拒绝服务攻击工具mstream ☆ 简介 分布式拒绝服务攻击工具mstream是基于stream2.c源码的。目前为止有七种公认的分 布式拒绝服务攻击 trinoo [03] Tribe Flood Network (TFN) [04] Tribe Flood Network 2000 (tfn2k) [06] stacheldraht/stacheldrahtV4 [05] stacheldraht v2.666 shaft [07] mstream 与其它DDoS工具相比,mstream显得粗糙多了。逆向工程还原出的C代码表明mstream 尚处在早期开发阶段,含有大量的BUGs以及未完成的特性。然而由于stream/stream2 攻击本身所具有的威力,即使参与的攻击机只有几台,也足以对victim(以及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所定义的外出过滤规则(参考资源[13]),在32bits 范围内伪造的源IP中,只有一小部分(匹配子网掩码的)能离开子网发送出去。然而, 此时出口路由器(内侧有18个子网)停止响应。这意味着做外出过滤规则的路由设备本 身将遭受攻击,尽管原来所定攻击目标只收到比攻击者预期要少得多的攻击报文。教 训是,对于DDoS,简单的包过滤机制并不是一个快速有效的解决方案。我们已经提醒 了路由厂商,希望他们能找出问题原因并修正之。 应用外出过滤规则后被拒绝外出的攻击报文无法到达下一跳路由器,下一跳路由器感 受不到攻击。这意味着基于IDS的边界路由器、DMZ上的IDS或者ISP方的监视设备无法 确认攻击发生。除非你正在监视路由器本身,而用户抱怨并暗示攻击来自你的子网。 这也使Sniffer抓包分析更加困难,只能在应用外出过滤规则的路由器内侧才能抓到 所有包。 2000年2月上旬一家电子商务网站遭受攻击,至今为止他们还不知道对方使用何种攻 击工具,只知道他们的路由器崩溃了,每次都依赖于他们的上级路由器阻断攻击、恢 复通讯。法律部门在缺乏证据的情况下无法介入,他们不能认定这是DoS、DDoS攻击 而非路由器、浏览器自身技术故障。针对Yahoo!的攻击描述在Packetstormsecurity 找到(参考资源[11]),并没有更多其它可用信息。 1999年trinoo、TFN和stacheldraht伴随着大量自动入侵行为,mstream则处在代码开 发的早期阶段,通常是手工入侵、安装(包括handler和agent),并用一个略微改动后 的Linux rootkit version 4 [10]保护自己。 附录D介绍了一次针对agent的入侵和踪迹隐藏。附录E介绍了一次针对handler的入侵 和踪迹隐藏。 ☆ mstream network: client(s)-->handler(s)-->agent(s)-->victim(s) 与trinoo和shaft一样,mstream network由一个或多个handlers(master.c)以及大量 的agents(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 (in published source) 15104/tcp ("in the wild") 12754/tcp (in recovered source) Agent -> Handler(s) : 9325/udp (in published source) 6838/udp ("in the wild") Handler -> Agent(s) : 7983/udp (in published source) 10498/udp ("in the wild") Attacker到Handler的远程控制是通过TCP连接完成的,端口号不定(很容易产生变体)。 Handler所等待的命令应该完整地位于单个TCP报文的数据区(PDU)中,而不是断续的 字节流。这意味着不能使用"telnet"控制Handler,netcat [19]可以胜任。Security Focus [20]中的源代码并未包含这样的客户端工具。 Attacker到Handler的传输未做加密处理,尽管stacheldraht表明增加Blowfish block cipher并不困难。命令行靠空格分隔参数。 与trinoo类似,Handler(s)与Agent(s)之间的通讯通过UDP报文完成。Agents命令行 靠斜杠(‘/‘)分隔参数,多项参数自身靠冒号(‘:‘)分隔。 我们所检查的代码中最多允许3个Attackers连接到一个Handler,或许这是一个保护 性措施,也可能是个多余的访问限制。 连接建立后,必须提交正确的口令,缺省值如下 Attacker -> Handler(s) : "sex" (in published source [20]) "N7%diApf!" (in recovered source) 如果口令不正确,所有目前已建立连接的用户被提醒有人正试图访问该Handler,然 后关闭这个未通过验证的连接。如果口令正确,所有目前已建立连接的用户被提醒产 生新的会话连接,通过验证的用户得到一个"> "提示符。 ☆ Handler命令 Handler命令行至多由3个空格分隔的参数组成(argv[0] - argv[2])。 如果攻击者建立连接后420秒内未输入一条命令,连接终止。 Handler命令集如下 help 显示如下信息 Available 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(s)与Agent(s)之间的命令串是明文字符串,在通讯报文中可见。 对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
