逆向工程恶意软件 |
|
文档编号: |
S002-F026 |
原作者: |
Lenny Zeltser |
译者: |
月中人 [PTG] |
审校: |
|
发布时间: |
2007-01-11 |
原文: |
Reverse Engineering Malware |
关键词: |
逆向工程,可控环境,恶意软件,木马,保护 |
原文链接:http://www.zeltser.com/reverse-malware-paper/reverse-malware.pdf May 2001 |
摘要:本文讨论在了解恶意软件如病毒、蠕虫和木马内部工作的时候使用的一些工具和技术。我们描述了一种方法,使用虚拟工作站软件如VMware建立廉价而且灵活的实验室环境;并示范了使用多种系统监视工具协同反汇编器和调试器一起逆向工程一个木马的过程。本文某些部分是以我们提交给GIAC的论文为基础,该论文是作为获取GCIH证书的一个实习作业部分。要了解更多信息请访问http://www.zeltser.com
目录
第 1 部分:介绍............................................2
1.1 概述..................................................2
1.2 背景信息...........................................2
第 2 部分:方法学.........................................4
2.1 可控环境...........................................4
2.2 行为模式...........................................5
2.3 代码分析...........................................6
第 3 部分:特洛伊木马的结构.......................8
3.1 本地系统交互....................................8
3.2 通信协议...........................................9
3.3 程序代码.........................................13
第 4 部分:保护措施...................................20
4.1 传播机制.........................................20
4.2 特洛伊木马的变种...........................20
4.3 特洛伊木马的签名...........................21
第 5 部分:参考书目...................................23
第1部分 介绍
1.1 概述
本论文试图评述逆向工程恶意软件的一种方法。突出该过程本身,而非仅仅关注程序的特点,是有双重原因的。首先,对于在这篇捧场文章中讨论的这个特定的木马(srvcp.exe),仍有许多未解决的问题;如将我们的调查结果定位于全面分析充其量会产生误导。其次,通过开发一种了解恶意软件内部工作的结构化方法,也就是可重复的剖解步骤,可以帮助防卫社区成员。
在分析木马过程中,我们对于攻击者在程序设计上所下的功夫已经留有深刻印象,攻击者乐于费尽心思地创建有弹性的、灵活的恶意软件。因此,逆向工程该木马程序的过程耗费不少时间、但终究还是达到我们的目的了。希望我们的讨论将会鼓励安全专业人士改进本文所建议的方法学,并可能弥补我们对这个特定木马理解上的遗漏之处。
我们要感谢Joe Abrams对这个木马汇编代码的见解以及对它现实存在环境的阐述。非常感谢Slava Frid,他帮助我们走过程序代码的特别隐秘区域,而且让我们分享他的思想。同时,我们感谢Doug Kahler与我们分享这个木马还有他的观测记录。最后,感谢Jeremy Gaddis提醒防卫社区注意这个木马。
1.2 背景信息
在
认出6667是IRC服务器经常使用的端口,我启动了一个IRC客户端并连接到那个主机。它的确是一个IRC服务器。快速检查显示出4个在线用户,它们的“Real Name”域被置为“Im trojaned”,其中一个是我的IP地址。
有的读者可能不熟悉IRC,我们简单说一下,可以把IRC看作是一个服务器内联的网络,它让使用者可以维持实时在线会话。会话的参与者典型地加入一个热衷于特定主题或兴趣的频道。这是通过把使用者的IRC客户端连接到一个服务器来实现的,而这个服务器参与所需要的IRC对等网络。当使用者录入一个消息要让频道参与者看见的时候,这条消息由IRC服务器转发给参与讨论的客户端,就如评论请求(RFC)文档1459中说明的。[RFC1459]
在Jeremy最初消息发表后数天,在
005515 PRIVMSG %s :no more...
00552D PRIVMSG %s :ready and willing...
Brandon也指出,该程序在端口113监听识别请求,而且当它接收到没有遵守识别协议(Ident protocol)的请求时该程序崩溃。识别服务的协议在RFC 1413中定义[RFC1413],在某用户启动一个TCP连接到一个远程服务器,识别服务允许该服务器确认此用户的登录名字。由于试图控制系统滥用,许多IRC服务器不接受IRC连接,除非接入用户的身份能够通过使用识别协议的再确认。
两天后,
今天刚刚参加了该频道,那里有55个人,以随机字母和数字记号。我以为他们全部被传染。
Doug稍后会好意地搜索他的文档,并与我们共享他在分析的基础上建立的一个木马拷贝。这对我们的研究是个关键的帮助,因为在这个思路(thread)开始时发送到邮件列表的可执行程序被证明是一个良性拷贝,似乎是一个Windows屏幕保护程序。
就如Nick FitzGerald在
关于这个特定木马,杀毒厂商没有提供很多信息,而稍后的病毒数据库的检查发现关于该木马的能力缺乏详细文件证明,这或许归因于它相对低调的姿态。在2001年六月事件邮件列表上讨论之后,该木马似乎没有引起公众的注意,并且一直保持相对未经调查状态。然而,我们对这个程序的兴趣被Pete Schmitt最近于
第2部分 方法学
2.1 可控环境
恶意软件的逆向工程师必须使用灵活的、不张扬的可控实验室环境,以便容易形成有效率、廉价和可靠的研究过程。我们最后选定使用VMware公司的虚拟工作站软件建立研究环境。VMware藉由提供硬件仿真和虚拟网络服务实现虚拟环境,而且允许我们在一个单一机器上进行操作系统的完全独立安装。使用VMware可以让多重操作系统同时运行,而且每个虚拟机器“相当于一台PC机,因为它有一个完全的、未更改的操作系统,一个唯一的网络地址,和一套补充完整的硬件设备。”[VM1]
为建立我们的实验室环境,我们使用的一台500MHz膝上型电脑有20GB磁盘空间和256MB RAM(随机存储器),操作系统是Windows
2000 Professional,在上面我们安装了VMware。尽管同样定价的桌上型电脑机器会提供更多计算能力,但是为了让我们的实验室尽可能轻便易于携带,我们还是决定使用一台膝上型电脑。因为想为研究提供多种操作系统,我们在VMware里面创建了三个虚拟机器:红帽子Linux
7.0、Windows 98第二版和Windows
NT 4.0工作站服务包
图 2-1
每个客座操作系统能够相互独立地操作,VMware允许我们使用一个虚拟网络互连虚拟机器,这是完全封闭在主机机器里面,并没有能力沟通外部世界。当使用Windows 2000作为主机操作系统的时候,为了实现这个功能,我们必须按照VMware支持网站的指示[VM2],手工创建一个虚拟的主机专用适配器(连接装置)。适配器被指定在一个私用RFC 1918范围内的一个IP地址,以确保它不与我们任何一个现有连接相冲突。[RFC1918]
作为主机专用适配器安装的一部份,VMware也安装了一个DHCP服务器服务,专用于在虚拟网络上配置IP地址。为了确保虚拟网络真正地与膝上型电脑的物理界面隔离,我们在主机机器上安装了ZoneAlarm Pro,它给我们提供一个舒适的保护层,会在任何数据包试图离开实验室环境时发出警告。不过,这个预防措施不能够保证环境的完全隔离。理想地,VMware主机不应该被连接到生产网络,而且应该使得在那几个虚拟机器看来VMware主机同样不是必需的。下面图2-2举例说明安装在我们膝上型电脑里的虚拟网络基础结构。
图 2-2
使用VMware代替物理分离系统的好处之一是能够备份系统并能在大约几分钟内恢复完全系统。每个虚拟机器由使用位于VMware的VMs子目录中的一些自包含文件来实现。复制那些被VMware用来表现虚拟机器的文件就可以备份那个系统。在分析未知的恶意软件时这特别有用,因为此时反复与病毒或木马交互可能感染环境,你需要把系统恢复到一个已知状态。此外,虚拟机器易于复制让工程师们可以维持一个操作系统在不同修正标准上的若干实例。
尽管由VMware提供高度隔离,在客座操作系统和主机机器之间仍然有一些交互。尤其是,VMware提供了VMware工具驱动程序,当它们被安装在一个虚拟机器上的时候,将会允许用户在客座操作系统和主机机器之间移动鼠标指针。此外,驱动程序允许虚拟机器共享对主机机器剪贴板的存取。这些功能从虚拟机器内启用,而且主机系统似乎没有禁用它们的能力。这意味着有可能针对一个基于VMware的实验室用户巧妙地设计一个攻击,它将会从一个虚拟机器内实现在某些层次上访问主机系统。
2.2 行为模式
要了解与恶意软件样品相关联的威胁,其方法之一是在一个可控环境里从检查它的行为开始。这典型地包括在实验室里运行该代理,并且研究它与计算机资源如何交互以及如何响应各种不同的诱因。前文所述基于VMware的实验室环境允许我们使用一个单一屏幕从各个不同系统上监视恶意软件。
我们综合使用进程、磁盘、注册表和网络监视工具来研究在某个特定机器上该木马的活动率,以及它对其他系统的连接尝试。当它尝试与因特网上的系统沟通时,我们能够指引该木马到实验室机器,如此一旦我们完全掌握它与世界如何交互,我们就可以为该木马重复本地环境。
我们发现Systernals提供的免费软件工具在监听该木马的行为时非常有用。特别地,我们用Windows NT/9x下的Filemon观察该木马试图在本地系统上存取哪些文件[SI1]。同样,Windows NT/9x下的Regmon让我们能够监视注册表相关的读写操作[SI2]。此外,售价$69的TCPView pro实用工具让我们可以获得系统上所有TCP和UDP连接的详细列表,并将这些网络端点与建立连接的进程捆绑。[WI]
我们使用了Winalysis,这个程序是SFullerton.com出品[SF],用于检测该木马造成的系统变化。Winalysis让我们可以创建一个原系统基准状态,并用它和木马运行后的系统状态相比较。配合Systernals的监视工具,使用Winalysis让我们可以通过检测相对地确定该木马对文件系统的影响。Windows 98/ME下的Winalysis售价每拷贝$25,Windows NT/2000下的每拷贝$35,能够发现对系统注册表和文件系统的改变。与一个更常用的剖解工具Tripwire相比[TR],Winalysis提供较少的细节和稳健性,但由于它的低价格和容易使用,所以我们还是把它作为一个有用的附加工具。
恶意软件在运行的时候会创建临时文件并在程序退出前删除它们。在这样的情况下,Winalysis不可能报告即将消失的暂时文件的存在,而Filemon将会报告文件被建立和删除,但是不会恢复文件的内容。为了应付这种可能性,我们使用Undelete实用工具,可从Executive Software公司买到,售价约$45 [ES]。Undelete工具用一个Recovery Bin代替本地的Windows的资源回收站,它能够捕获所有被删除的文件,甚至是那些被非GUI进程删除的文件。在写作本文的时候Undelete还只有支持Windows NT/2000的,真遗憾。
我们依赖Snort监视实验室网络上的流量,这是个免费分发的轻量级侵入检测系统[SN]。尽管Snort典型地是被用于自动检测基于网络的攻击,我们只是利用它内建的嗅探(sniffing)能力来获得有关网络通信的细节:我们使用“snort -v -d”命令启动该程序,这个命令告诉它进入冗长模式并且获取数据包的数据净荷。因为Snort可以支持Windows和UNIX操作系统,还有它宽大的配置基础,以及基于文本的日志和控制,所以相比其他的网络捕获工具程序,我们更喜欢使用基于Snort的嗅探器。
VMware带有一个名为vmnetsniffer的工具,它能在主机操作系统上运行,而且能显示在虚拟机器之间、主机机器与它的客座之间的网络流量。不过,对于详细的剖解分析来说,该程序所提供的信息范围还不够充分。即便使用“/ e”开关运行,vmnetsniffer也仅仅适当地记录数据包的大小、源的IP和MAC地址、传输协议类型、以及ARP和ICMP消息类型。这没有Snort所提供的信息那么详尽,而且最重要的是缺乏数据包的数据净荷。
出于网络监听的目的,VMware虚拟实验室网络可以被看作是基于集线器的,因为当它处于混杂的网络接口模式时,网络上的每个机器都能够看见所有的网络流量。不过,这个规则的例外是主机操作系统只能看到出入它本身的流量。你只有使用vmnetsniffer工具才能从主机机器上看见所有的虚拟网络流量。为了获得所需要的数据包细节,我们在虚拟Linux的实验室机器上运行Snort监视网络,从这个机器上我们可以看见所有的虚拟网络流量。
2.3 代码分析
本文前面部分所描述的行为分析集中在恶意软件的外部方面,即它与环境的交互,而没有让我们对该程序内部的工作有足够的了解。我们联合使用一个调试器和一个反汇编器,尝试逆向工程该木马的可执行文件,因为我们没有办法读到它的源程序码。这个过程依赖反汇编器了解该程序的基本结构,进而使用调试器单步调试它研究木马的工作流、并最终取得它运行时内存数据。
我们使用DataRescue的IDA Pro反汇编器把该木马反组合成汇编指令。IDA Pro标准版[DR1]能够从公司网站按$299的售价购买。在购买程序之前,你可利用它有限制的评估版本[DR2],它可以免费使用而且能证明在分析的早期它是十分有用的。DataRescue也提供IDA Pro免费软件[DR3],实际上那是该软件的3.85B版本、没有基于Windows的GUI,而我们发现图形化用户界面是非常有用的,这只有在该程序更新的版本中才有。在我们的分析过程中,由于需要解释我们不熟悉的的汇编指令,我们还要依靠‘英特尔体系结构软件开发者手册’(the Intel Architecture Software Developer's Manual)[IN]。
因为汇编是一个低级语言,若不使用SoftICE单步调试该木马,我们难以理解其代码流;SoftICE是一个强大的调试器[NM],它是适用于Windows 9x/NT/2000的NuMega SoftICE Driver Suite的组成部分,套装售价$999。我们让这个调试器在实验室系统的后台作业中运行,并且在同一个系统中启动木马。从该木马的反汇编代码和Systernals截取的系统调用、注册表调用,我们了解了它的总体结构,所以知道怎样在看上去特别重要的代码段中设置SoftICE断点。断点使得我们可以在特定的工作流分支上自动呼出调试器,不必单步调试该木马程序中的每一条指令。
SoftICE一旦启动,它就在后台作业中运行,直到按下“Ctrl-D”组合键把它呼出或者直到某程序触发一个先前设置的断点[C4N]。我们通常通过提供一个API函数名或指令地址作为参数,在SoftICE命令行执行“bpx”命令设置断点。我们在SoftICE中单步调试程序[MT]:按一次F10键前进一步,这里把执行函数调用作为一个单步;按F8键则把每一条指令作为一个单独步执行。最后,“d”命令也是我们的最常使用的SoftICE命令之一,通过直接指定一个特别的地址,或者储存在某个特定寄存器的值指示一个存储单元,该命令能显示那里的数据内容。
我们在Windows NT 4.0和Windows 98实验室机器上安装了SoftICE。最初,我们担心SoftICE在VMware环境中运行的稳定性。尤其当SoftICE被启动的时候,虚拟机器有时会当机而无法启动。不过,我们从这些虚拟机器上移除VMware视频驱动程序,并安装16色640x480模式的Windows标准的VGA驱动程序,大部分的问题立刻就不存在了。在Windows NT下我们使用“net start ntice”命令手工启动SoftICE。在Windows 98下我们试图手工启动SoftICE时遇到了问题,后来我们让系统在引导后自动启动SoftICE。
我们的装备中另一个有用的工具是“Strings”程序,在大多数UNIX分发版本中可以找到它。这个实用工具能够从可执行文件里面提取文本字符串,这对于评估一个程序的目的和结构常常是有帮助的。恶意软件的字符串快照比起它的反汇编代码完全列表要短得相当多,当然它也就不那么完全。在Windows上实现相似功能的程序是BinText程序,它是由Foundstone免费分发的[FS]。比起它在UNIX中的另一选择,BinText更灵活一点而且它支持多种高级过滤选项。
最后,为了自动化与分析有关的一些小任务,我们使用Perl作为脚本引擎。例如,我们能够使用Perl实现一个灵活的例程根据该木马的汇编代码建造解密片断的模型。大多数UNIX发布版本内包括了Perl,而且从ActiveState公司可以免费得到适于Windows平台的Perl版本,这个分发版本贴上了ActivePerl标签。[AS]
第3部分 特洛伊木马的结构
3.1 本地系统交互
在我们的Windows NT 4.0实验室机器上启动srvcp.exe这个木马之前,我们启用所拥有的全部监视工具。我们把 srvcp.exe这个文件放在本地文件系统中任意选择的位置上并且运行该程序。它安静地进入后台作业,而且除了把“srvcp.exe”进程加入进程列表之外,肉眼观察不到它有任何行动。我们可以看到通过监视工具程序记录下来的、与之有关的活动,然后我们大约在10秒钟之后杀死这个srvcp.exe进程。活动记录的检查显示,其行为与事件邮件列表上“未知木马”这个思路(thread)里讨论的相一致,具体情况我们在‘背景信息’小节中已详述。
在该木马被杀死之后,我们使用Winalysis扫描系统中文件系统和注册表的变化。该程序标示出涉及正常Windows活动的几个修改,并明确指出键值“srvcp.exe”创建了这个注册表键:“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Service Profiler” 。该配置使得每次Windows启动时系统都将尝试启动该木马。注意,它没有指定该木马的完全路径,这表明木马作者假定srvcp.exe会在(环境变量)path的某个路径中。间接说明我们没有掌握该木马的分布机制,或许它已经修改了系统路径,或许它把srvcp.exe拷贝到path默认的某个目录里,比如C:\WINNT。我们的案例中,这个可执行文件仍保留在C:\Download中,而且没有新的文件被创建,这意谓该木马不会在系统引导后启动。Filemon日志和Regmon日志证实了Winalysis的调查结果。
下面图3-1举例说明Regmon记录下该木马创建它的注册表键。(为了突出,我们在屏幕截图上手工标明有关的行)。后来实验证实该木马每一次运行时设置这个键,即使它早先已经被创建。注意,Regmon不显示该注册表键的数值–为了获得这个信息,我们必须使用regedit.exe工具查看注册表或者使用Winalysis比较系统状态。据Regmon记录,该木马也查询注册表的\Services\WinSock2键和Services\Tcp键,这是可执行文件利用TCP/IP进行网络通信的典型动作。
图 3-1
如下面图3-2所示,Filemon报告该木马试图存取C:\WINNT\System32\gus.ini文件,但在这个系统上没有找到该文件。在Windows NT下这个请求使用带“Open”选项的“IRP_MJ_CREATE”调用,而稍后在Windows 98下Filemon只是把该请求标示为“Read”。即使没有找到这个文件,在这两个系统中该木马都会继续运行。本文稍后我们将讨论gus.ini文件充当什么角色。而且,Filemon捕获到对C:\WINNT\System32\crtdll.dll的存取尝试,这个DLL提供诸如fopen、fclose和fscanf等函数调用。此外,该木马读取msafd.dll、wshtcpip.dll和rnr20.dll。最后,该木马读主机文件,或许这是我们曾经使用Snort看到的域名(domain name)解析过程的一部分,见下一节讨论。
图 3-2
3.2 通信协议
我们在某一个实验室机器上启动该木马之前,先配置Linux机器让Snort以冗长模式以监视网络通信。因为VMware虚拟网络有类似集线器的特性,所以这个系统能够捕获实验室网络上传送的所有数据包。下面图3-3举例说明,由运行srvcp.exe的Windows NT机器发出的一个域名服务(Domain Name Service, DNS)请求。我们配置Windows NT机器,让它把VMware主机系统172.16.198.1作为DNS服务器,尽管主机系统并没有运行DNS软件。发现试图解析irc.mcs.net,这与Filemon报告的行为相一致,Filemon记录了该木马要读本地主机文件的请求。
Domain Name Resolution Request 03/16-06:19:46.414790
172.16.198.131:1046 -> 172.16.198.1:53 UDP TTL:128 TOS:0x0
ID:4354 IpLen:20 DgmLen:57 Len: 37 00
01 01 00 00 01 00 00 00 00 00 00 03 69 72 63 .............irc 03
6D 63 73 03 6E 65 74 00 00 01 00 01 .mcs.net..... |
图 3-3
我们不愿在实验室网络上架设一个DNS服务器,而是添加一个项目到受感染机器的主机文件,使之解析irc.mcs.net为172.16.198.129。这个配置步骤的目的是重定向木马到在我们控制下的一个服务器,以便我们可以观察该程序与它正在解析名字的这个系统的连接的性质。这里在实验室环境下操纵DNS记录比较麻烦;万一该木马作者硬编码一个IP地址放进程序里面,我们必须配置本地的路由选择表和网络参数才能重定向流量到我们的系统。
如下面图3-4所示,该木马尝试连接到它认为是irc.mcs.net的那个系统上6667端口。这不奇怪,因为端口6667通常用于IRC通信,这与irc.mcs.net的主机名字和性质相一致,它是一个常用的EFnet网IRC服务器。注意,因为我们的服务器没有在端口6667上监听,所以我们的服务器用一个RST数据包回应该木马请求连接的SYN数据包。
Failed IRC Connection Attempt 03/16-06:44:10.522728
172.16.198.131:1060 -> 172.16.198.129:6667 TCP TTL:128 TOS:0x0
ID:47106 IpLen:20 DgmLen:44 DF ******S* Seq: 0x2D492
Ack: 0x0 Win: 0x2000 TcpLen: 24 TCP Options (1) => MSS: 1460 03/16-6:44:10.536857
172.16.198.129:6667 -> 172.16.198.131:1060 TCP TTL:255 TOS:0x0
ID:3 IpLen:20 DgmLen:40 ***A*R**
Seq: 0x0 Ack: 0x2D493 Win: 0x0 TcpLen: 20 |
图 3-4
为了响应观察到的行为,我们在Linux机器172.16.198.129上安装并配置ircd-hybrid软件[IS]给该木马提供IRC服务。再次启动该木马后,我们能够监视它和我们IRC服务器的会话。如下面图3-5所示,该木马试图使用昵称“mikey”登录到IRC频道“#daFuck”。在这里,“JOIN”命令前面的句点等于十六进制表示“0A”,这个字符表示新行。
Successful IRC Connection 03/16-07:59:47.630767
172.16.198.131:1030 -> 172.16.198.129:6667 TCP TTL:128 TOS:0x0
ID:18433 IpLen:20 DgmLen:102 DF ***AP*** Seq: 0x11B0D
Ack: 0xB1B0E8B2 Win: 0x2238 TcpLen: 20 4E 49 43 4B 20 20 55 79 58 63 20 55 79 58 63 20 55 79 58 63 20 UyXc UyXc UyXc. |
图 3-5
该木马连接到IRC的方式稍微有点不同于早先在本文‘背景信息’小节中所讨论的那些报告。尤其,Jeremy报告,在那个频道上该木马的真实名字是“Im trojaned”,而在我们这里其真实名字被设置为“fight me, pussy”。这两个实例中这些名字都暗示滥用,而且有可能我们现在看到的是该程序的一个变异版本。此外,Doug观察到该木马加入“#mikag”频道。我们这里发现在Doug的频道名字“#mikag”和我们的昵称“mikey”之间可能有某种联系,尽管我们的样品加入一个不同频道。在本文中将做更多讨论,稍后的分析在频道名字和gus.ini文件的内容之间建立一个联系。
从该木马连接IRC服务器后的一些数据包当中,我们注意到从服务器向运行该木马的工作站发出的一个识别请求。识别机制典型地被UNIX系统用来获取初始化TCP连接的用户名字。在受感染机器上运行的TCPView报告,该木马正在监听典型地被识别服务使用的TCP端口113,下面图3-6中显示该程序的识别响应。在这个交换之后,该木马登录到IRC服务器内,在我们的IRC服务器上运行“/who #daFuck”命令得到如下回应:
“#daFuck mikey H@
CaTiRk@172.16.198.131 (fight me, pussy)”
Trojan’s Ident Response 03/16-07:59:47.701560
172.16.198.131:113 -> 172.16.198.129:1078 TCP TTL:128 TOS:0x0
ID:18945 IpLen:20 DgmLen:78 DF ***AP*** Seq: 0x11B21
Ack: 0xB1EAA1B9 Win: 0x222B TcpLen: 20 31
30 33 30 20 45
52 49 44 20 54
69 52 6B 0D |
图 3-6
该木马内建立识别功能,极有可能是为了提高与IRC服务器连接的成功可能性,因为许多IRC服务器不接受那些不能通过识别机制确认身份的连接。一旦该木马回答了识别请求,它停止在TCP端口113监听,或许是为了逃避端口扫描器的远程检测,以及简化程序代码流。我们重复启动该木马,看到它以伪随机方式生成用户名经由识别机制提交。例如,生成的其他名字有“MdSxJy”、“HsSdLhG”、“IyKw”、“FgX”和“Ce”。加入需要的频道之后,该木马以大约每3秒钟的间隔连续地发出“NICK mikey”命令。见下面图3-7中所示。(为了表示清楚,图中没有包括来自IRC服务器的对应的ACK数据包)。
Trojan’s Nickname Requests 03/16-09:01:30.651137
172.16.198.131:1030 -> 172.16.198.129:6667 TCP TTL:128 TOS:0x0
ID:21761 IpLen:20 DgmLen:51 DF ***AP*** Seq: 0x11B79
Ack: 0xB1B0EE89 Win: 0x2238 TcpLen: 20 4E
49 43 4B 20 6D 69 6B 65 79 03/16-09:01:33.818259
172.16.198.131:1030 -> 172.16.198.129:6667 TCP TTL:128 TOS:0x0
ID:22017 IpLen:20 DgmLen:51 DF ***AP*** Seq: 0x11B84
Ack: 0xB1B0EE89 Win: 0x2238 TcpLen: 20 4E
49 43 4B 20 6D 69 6B 65 79 |
图 3-7
一旦该木马加入IRC频道,它保持连接,大概是等待它的操作者经由交谈会话发来的命令。这些通信的性质将在本文的‘代码分析’小节中进一步讨论。该程序也参与IRC协议所定义的周期性“PING”-“PONG”消息交换,这用来确定IRC客户端是活动的。
我们在一个实验中同时启动该木马两个实例,一个在Windows NT实验室机器上运行,而另一个在Windows 98系统上运行。连接到IRC服务器的第一个实例获得昵称“mikey”。然而,当第二个实例连接的时候,它没有被允许使用相同的名字,因为IRC协议要求在相同的IRC网络上昵称是唯一的。如下面图3-8示例,这迫使该木马以伪随机方式为自己生成一个不同的昵称。(在这个网络跟踪记录里,“irc.ticklabs.com”这个名称是我们分配给Linux实验室机器的主机名)。在这个情形下,该木马的两个实例都继续通过每隔3秒发出“NICK mikey”命令试图获得相同的昵称。
Nickname Conflict Resolution 03/16-09:19:48.633843
172.16.198.129:6667 -> 172.16.198.130:1025 TCP TTL:64 TOS:0x0 ID:233
IpLen:20 DgmLen:147 DF ***AP*** Seq: 0x3FCD1E87
Ack: 0x 6D
20 34 33 33 20 69
63 6B 6E 61 6D 65 20 69 73 20 61 64
79 20 69 6E 20 75 73 65 2E 0D 2E 74 69 63 6B 31 20 65 72 20 66 69 72 73
74 2E 0D 03/16-09:19:48.651467
172.16.198.130:1025 -> 172.16.198.129:6667 TCP TTL:128 TOS:0x0
ID:7936 IpLen:20 DgmLen:61 DF ***AP*** Seq: 0x 4E
49 43 4B 20 59 76 46
75 63 6B |
图 3-8
该木马似乎有意地确保至少多个实例之一持有“mikey”这个名字。如果持有该名字的那个木马实例从IRC服务器断开连接,程序的另一个实例最多会在3秒钟内获取这个名字。该木马连接上网的实例越多,它们当中被冠于“mikey”之名的可能性就越大。Doug Kahler在他与我们联系的e-mail中建议,该木马的目的之一可能是为它的操作者保留昵称或者阻止有人得到它。可能该程序的作者能够通过IRC消息与它通信、命令该木马释放这个名字以便那个人可能获得它。
我们有一个实验针对,检验在一个潜在攻击者和该木马多个实例之间通信的性质。IRC是用来中心控制一大群分布式攻击代理的一个极好的频道,这是该木马比如srvcp.exe经常被人猜测具有分布式拒绝服务能力的原因之一。通过在IRC频道上发出一个单一命令,攻击者能够与该木马多个实例通信,由该服务器决定转播消息给已连接上网的木马。IRC通信的这个性质使得很难追溯攻击来源。此外,IRC提供通过私人消息单独与该木马每个实例沟通的能力。
实现一对多和一对一的IRC消息都是使用下层IRC协议的“PRIVMSG”命令,如下面图3-9所示范。(为了表示清楚,我们从跟踪记录里删掉无关数据包)。开始两个数据包携带一个消息有意让所有的频道参与者见到;发送这个消息只要在IRC客户端提示符下输入“hi
all”。我们的昵称被设置为“attacker”,我们的真实名字是“lzeltser”,而且我们从“127.0.
Relaying Messages to IRC Clients 03/16-09:43:15.650781
172.16.198.129:6667 -> 172.16.198.130:1025 TCP TTL:64 TOS:0x0 ID:962
IpLen:20 DgmLen:94 DF ***AP*** Seq: 0x 65
72 40 31 32 37 2E 30 2E 30 2E 31 20 50 52 49 er@127.0.0.1 PRI 56
4D 53 47 20 23 64 61 46 75 63 6B 20 20
61 03/16-09:43:15.651144
172.16.198.129:6667 -> 172.16.198.131:1030 TCP TTL:64 TOS:0x0 ID:963
IpLen:20 DgmLen:94 DF ***AP*** Seq: 0x3498DF73
Ack: 0xFF37 Win: 0x7D78 TcpLen: 20 65
72 40 31 32 37 2E 30 2E 30 2E 31 20 50 52 49 er@127.0.0.1 PRI 56
4D 53 47 20 23 64 61 46 75 63 6B 20 20
61 03/16-09:43:49.946018
172.16.198.129:6667 -> 172.16.198.131:1030 TCP TTL:64 TOS:0x0 ID:989
IpLen:20 DgmLen:98 DF ***AP*** Seq: 0x3498DFE1
Ack: 0xFFB0 Win: 0x7D78 TcpLen: 20 65
72 40 31 32 37 2E 30 2E 30 2E 31 20 50 52 49 er@127.0.0.1 PRI 56
4D 53 47 20 6D 69 6B 65 79 20 20
66 |
图 3-9
本文前面说过,该木马试图在启动后从系统目录读gus.ini文件。当我们把gus.ini文件放进系统目录内的时候,Filemon显示该木马成功地打开并读文件。使用正运行在Linux实验室机器上的Snort,我们能够观察到该木马尝试连接到IRC服务器上的TCP端口6666,而非先前使用的TCP端口6667。因为我们的服务器没有在这个端口上监听,所以这个连接尝试失败。如下面图3-10所示,我们观察到该木马随后尝试解析一些IRC服务器的主机名字。(为了表示清楚,我们从跟踪记录上删掉TCP重试数据包)。该木马继续尝试解析其他一些似乎与IRC有关的主机名直到我们杀死该进程。
Resolving IRC Server Names 03/16-10:29:11.319877
172.16.198.131:1040 -> 172.16.198.1:53 UDP TTL:128 TOS:0x0
ID:63756 IpLen:20 DgmLen:61 Len: 41 00
01 01 00 00 01 00 00 00 00 00 00 05 65 66 6E .............efn 65
74 02 63 73 03 68 75 74 02 66 69 00 00 01 00 et.cs.hut.fi.... 01 . 03/16-10:29:44.423230
172.16.198.131:1042 -> 172.16.198.1:53 UDP TTL:128 TOS:0x0
ID:1037 IpLen:20 DgmLen:63 Len: 43 00
03 01 00 00 01 00 00 00 00 00 00 05 65 66 6E .............efn 65
74 05 64 65 6D 01 00 01 ... 03/16-10:30:15.667072
172.16.198.131:1044 -> 172.16.198.1:53 UDP TTL:128 TOS:0x0
ID:3341 IpLen:20 DgmLen:64 Len: 44 00
05 01 00 00 01 00 00 00 00 00 00 03 69 72 63 .............irc 00
01 00 01 .... |
图 3-10
为了响应观察到的行为,我们在我们的服务器上配置IRC精灵(daemon)以监听TCP端口6666。一旦该木马被重新启动,Snort日志显示该程序连接到IRC服务器TCP端口6666。然而,如下面图3-11示例,该木马现在使用键“soup”加入频道“#mikag”。我们还来不及使该木马可用gus.ini,它就使用了一个不同的频道名字,而且没有提供频道键。(在IRC上这个键有时被用来限制对一个频道的存取)。事实上,该木马现在的行为与Doug报告的观察结果相符,这在本文的‘背景信息’小节中先已描述过。
Connecting to a Different IRC Channel 03/16-11:07:12.816149
172.16.198.131:1032 -> 172.16.198.129:6666 TCP TTL:128 TOS:0x0
ID:34304 IpLen:20 DgmLen:112 DF ***AP*** Seq: 0xF 4E 49 43 4B 20 20 49 66 66 20
70 75 73 73 79 61
67 20 73 |
图 3-11
3.3 程序代码
在环球网上搜索srvcp.exe这个木马相关信息的时候,我们偶然看到Joe Abrams的一篇文章,其中他分析了该木马某个变种的几个代码段。Joe指出在该木马可执行文件中嵌入的许多加密字符串而且叙述了一个解密方法,这些字符串是用一个基于异或(XOR)的算法加密的[JA1]。虽然在我们这个木马版本的可执行文件中没有发现该文提到的大部份字符串,但是Joe解密的字符串中有一个文本值明显地是“gus.ini”。此外有个解密后值为“joeblow”,这间接说明Joe的木马版本与本文‘背景信息’中施密特报告提到的那个相似。
为了弄清解密算法,以便可以解密在我们的srvcp.exe拷贝中嵌入的字符串,我们把这个可执行文件装入IDA Pro反汇编器。(读者若想查阅该程序的反汇编代码,可在http://www.zeltser.com上查看我们反汇编这个程序结果的Adobe Acrobat打印输出)。遵循Joe的分析,我们搜索字符串“nhl*pwf”,据他说这是“gus.ini”的加密值。这引领我们来到一个代码段,见下面图3-12中所示。在这个段中该程序反复地把一个好象已加密的字符串推入栈,而且调用相同的例程,这暗示“sub_
Probable Calls to String Decryption Routine .text:0040141D
push offset aNhlPwf ; "nhl*pwf" .text:00401422
call sub_ .text:00401427 push offset aAhkl ; "|ahkli" .text: .text:00401431 push offset aWtwgr ; "wtwgr" .text:00401436 call sub_ .text:0040143B push offset aCdkk ; "|cdkk" .text:00401440 call sub_ .text:00401445 push offset aMfqece ; "mfqEce" .text: |
图 3-12
遵循Joe对解密过程的分析并在IDA
Pro中查看它的汇编码,我们可以创建一个基于Perl的例程来模仿该木马代码的相应部分。汇编例程在IDA
Pro中被标示为“sub_
Decrypting Embedded Strings sub decryptEmbeddedString
{ my($encrypted) = @_; my(@encrypted) = split(//, $encrypted); my($length) = $#encrypted; my($plain) = ""; my($counter); for ($counter=0; $counter<=$length;
$counter++) { $plain .= chr(ord($encrypted[$length-$counter])
^ ($counter+1)); } return($plain); } |
图 3-13
要获得嵌入字符串的明文译文,其方法之一是调用我们Perl例程处理每一个需要经过该程序“sub_
Embedded Strings Decrypted |
|
Encrypted Value |
Decrypted Value |
nhl*pwf |
gus.ini |
|ahkl |
mikey |
Wtwgr |
Setpr |
|cdkk |
Jiggy |
mfqEce |
daFuck |
~h`PmfqEce |
daFuckWhat |
v}~y{*%mj&qldkg |
fight
me, pussy |
og&teh*`ph |
irc.mcs.ne |
O_ATU@VDE@ |
AGGRESSIVE |
5|3u1v/k-h+i)j'g%JLQH |
ISON a b c d e f g h |
图 3-14
我们解密的嵌入字符串有些已经在我们的分析中见到,本文前面章节已讨论过。特别地,“gus.ini”是文件名,该木马尝试在启动后用这个初始化设置文件改变它某些方面的行为。“mikey”字符串相配在连接到一个IRC服务器时使用的昵称。“daFuck”字符串加上前缀“#”,是该木马所参加的IRC频道的名字。“fight me, pussy”字符串相配该木马在IRC服务器上所具有的IRC用户真实名字特性。最后,“irc.mcs.ne”,紧加上“t”字符,就是该木马尝试连接的IRC服务器的主机名字;嵌入字符串缺失最后一个字符或许是由于我们的字符串程序不能完全提取它。在我们分析了gus.ini文件的内容之后,其他字符串的用途变得更清楚一点。
我们得到的那个gus.ini文件拷贝,它使用的加密算法似乎与嵌入srvcp.exe的字符串使用的加密算法不一样。基于我们的观察,我们猜测该木马在运行时期间解密这个文件。为了译解这个文件,我们摸索着理解解密过程。在IDA Pro中查看该木马的汇编码,我们发现了几个fopen函数调用,它典型地是用来存取磁盘上的文件。其中只有一个调用被指定“r”属性,即只读模式打开一个文件,如下面图3-15所示。这是程序启动后的第一次fopen调用,这个事实结合先前讨论过的Filemon日志,暗示我们这是尝试读gus.ini文件。在调用fopen之前入栈的“arg_0”参数表示将要打开的文件名,在这里它应该是“gus.ini”。
Opening gus.ini File .text:00403662
push offset aR ; "r" .text:00403667 push [ebp+arg_0] .text: |
图 3-15
为了确保我们对于gus.ini文件如何被打开的理解是正确的,我们使用SoftICE调查程序运行时间什么时候fopen被调用。实现如下,启动SoftICE,然后按“Ctrl-D”进入SoftICE命令行。在命令提示符上我们输入“bpx CRTDLL!fopen”命令,在fopen函数被调用处设置断点。然后我们在命令行上输入“x”命令把SoftICE置于后台作业,而且启动srvcp.exe可执行文件。过1秒种左右,SoftICE拦截了一个对fopen的调用而且中断该程序的运行,把我们带回SoftICE命令行。然后我们用“F10”键单步调试一些汇编指令,从fopen函数返回。下面图3-16显示出该木马刚执行它的第一次fopen调用不久时SoftICE屏幕一部分。我们使用“d *(EBP+08)”命令显示fopen第一个参数的内存内容,和我们期望的一样,它是“C:\WINNT\System32\gus.ini”。
图 3-16
在IDA Pro中查看该木马的汇编码,我们看到唯一的一个对fscanf函数的调用带有参数“%[^\n]\n”,如下面图3-17所示。这是从文件读入一个整行的方式之一,也是该木马逐行读gus.ini文件的方法。继续在程序中探索,看到这个可执行文件使用“jnz loc_4036B
.text:00403738 push eax .text:00403739
push offset asc_4083D1 ; "%[^\n]\n" .text:0040373E push ebx .text: .text:00403744 add esp, 0Ch .text:00403747 cmp eax, 0FFFFFFFFh .text: |
图 3-17
该程序在4036B2偏移后面几行那里带“%[^=]=%[^”参数调用sscanf函数,通常用来解析字符串。此字串模式常常表示典型的.ini文件格式,即各行遵循“PARAMNAME=value”这种约定。因为加密的gus.ini文件没有遵循标准的.ini文件格式,即没有用等号分开参数名字和数值,所以该程序一定是在调用sscanf之前解密文件的每一行。如下面图3-18所示,在使用fscanf逐行读入并使用sscanf解析它之后,唯一被调用的例程是sub_405366,它或许是解密例程。
Parsing gus.ini Lines .text:004036B2 lea eax, [ebp+var_414] .text:004036B8 push eax .text:004036B9 push esi .text:004036BA
call sub_405366 .text:004036BF mov edi, eax .text: .text: .text: .text:004036CB push eax .text:004036CC
push offset asc_ .text:004036D1 push edi .text:004036D2
call sscanf |
图 3-18
为了调查在解密例程被调用时该木马的运行时环境,我们重新启动srvcp.exe进程,让SoftICE保留前面提到的CRTDLL!fopen断点。一旦SoftICE拦截到调用,我们就在SoftICE命令行输入“bpx 4036BA”,即在偏移4036BA处增加一个断点,这是sub_405366被调用的地方。然后我们使用“x”指令把SoftICE置于后台作业,并等待直到调试器在我们的断点上中断该木马。设置第二断点之前等待第一次fopen调用,这是为了让SoftICE参照该木马运行时栈为sub_405366调用的相对偏移计算绝对偏移。
在该程序调用解密例程之前它的状态见下面图3-19中所示。在SoftICE屏幕这个部分我们观察到这个可执行文件在调用sub_405366之前把两个数值推入栈,这跟先前IDA
Pro中见到的一样。EAX寄存器指向的内存单元中的数值是“JexO215WuK60H7HgI.j11vh
图 3-19
我们在SoftICE中用“F10”键让该木马执行sub_405366调用,之后我们再查看EAX寄存器关联的存储器内容。如下面图3-20所示,这个内存单元包含“NICK=mikey”,似乎是该木马处理gus.ini得出的一行已解密译文。
图 3-20
gus.ini中的其他行经这个过程处理后,我们证实了在sub_405366例程中的确进行文件解密。我们也能够通过监视EAX寄存器指向的存储器内容,在调用解密例程之后获得gus.ini文件的已解密译文,而不需要知道实际的解密算法。解密后gus.ini文件的内容见于下面图3-21中。为了更加清楚,我们精简了文件的内容。
Decrypted gus.ini File NICK=mikey MODE=AGGRESSIVE SETCOMMAND=setpr COMMAND=fuckedup CHANNEL=mikag soup SOUPCHANNEL=alphasoup
ah SERVER0=irc.mcs.net:6666 SERVER1=efnet.cs.hut.fi:6666 SERVER2=efnet.demon.co.uk:6666 SERVER3=irc.concentric.net:6666 SERVER4=irc.etsmtl.ca:6666 SERVER5=irc.fasti.net:6666 ...
cut for brevity ... |
图 3-21
gus.ini的内容似乎要覆盖在编译时间嵌入srvcp.exe内的缺省值。这个文件的解密译本除了提供参数数值之外也提供参数名字,这为我们了解以前见过的字符串的用途提供了有关线索。我们已经知道“NICK”参数定义了连接到IRC服务器时使用的昵称。虽然我们的gus.ini文件把这个名字设置为“mikey”,但是该木马的操作者似乎能够通过操纵gus.ini文件的内容把它设置为一个任意值。“CHANNEL”参数定义该木马参加频道的名字。我们的gus.ini覆盖该程序内建的频道名字,这与我们先前观察到的行为相一致。这个文件也给该木马提供服务器列表和端口数目,当加入一个IRC网络的时候,该程序将会使用它们,这些值覆盖缺省值----在irc.mcs.net上的端口6667。我们的gus.ini文件定义了34个这样的服务器,你可以从http://www.zeltser.com/下载这个文件的解密译本。这些主机名字与观察到的DNS解析请求相一致,在本文‘通信协议’小节中讨论过。
据参数名字判断,该木马能够加入一个替代频道,这是由gus.ini中“SOUPCHANNEL”参数定义了。这个参数的值与“CHANNEL”参数所定义的那个值是通过一个公共子串“soup”发生关系。内建的频道名字“daFuck”和具有“daFuckWhat”值的未知内建参数也是通过一个公共子串产生关联,这暗示“daFuckWhat”是内建的替代频道名字。在写作本文的时候我们还不清楚关于替代频道的使用细节。
在gus.ini中“SETCOMMAND”参数定义的值匹配这个可执行文件内嵌入的“setpr”字符串。这似乎是一个关键字----在IRC上认证该木马所使用的基准。这个假说得到Joe Abrams分析的支持,尽管在他的木马版本内嵌入的值与我们的不同[JA2]。Joe提出该木马有若干个访问层次,这表明我们这个木马的第二个口令是由gus.ini中的“COMMAND”参数设定,其值为“fuckedup”。我们认为对应这个参数的嵌入缺省值是“jiggy”,请注意它们不一样。
“MODE”参数在gus.ini文件中被设置为“AGGRESSIVE”,在本文写作的时候它和可执行文件中加密值的用途还是未知的。这可能是一个控制该木马攻击强度的方式,或者操作者是在IRC频道上微调它的行为。我们假定这个参数的替代值是“PASSIVE”,因为在可执行文件中这两个值都是用明文形式定义、在栈中又是紧挨着的。该程序比较这些值的明文译本和邻近代码段的一个变量;这可能是比较“MODE”参数的已解密值和某已知值的过程,而且可能会据此行动。
为了试图了解用来混淆gus.ini文件各行的那个算法,我们将注意力转向那传递给解密例程的第二个参数。这个字符串被设置为“EcbJer8\0dx.CJVJsAlmIZ”,而且在解密过程中似乎当作一个键使用,但是它没有在可执行文件中作为明文字符串嵌入。我们发现,这个键被存储为一个字符集合,在栈中从位置
Fragment of Embedded Decryption Key ... cut for brevity
... .data:00408110
db 6Dh ; m .data:00408111 db 0
; .data:00408112 db 0
; .data:00408113 db 0
; .data:00408114
db 49h ; I .data:00408115 db 0
; .data:00408116 db 0
; .data:00408117 db 0
; .data:00408118
db 5Ah ; Z .data:00408119 db 0
; .data: .data:0040811B db 0
; .data: .data:0040811D db 0
; .data:0040811E db 0
; .data: |
图 3-22
注意,每个有效字符后跟3个null字符。在启动后,该木马把键组合成一个单一字符串,实施的代码见下面图3-23中所示。该程序这个部分逐字符读入并在内存中相邻字节排列它们。
Assembling the Decryption Key .text:00403698 mov edx, dword_ .text: .text: .text: .text: .text: |
图 3-23
为了了解它的算法,我们尝试单步调试该木马的解密例程。虽然时间约束阻止我们完成这个过程,不过我们能够了解这个过程的一些潜在原则。作为解密过程的一部份,该程序使用null字符作为分隔符把上述的键分成两个字符串。我们跟随该程序的工作流,它变异了这个键的第一部分拷贝“EcbJer8” ----每个字符原始值加7。实现这个函数的汇编码见下面图3-24中所示。这个代码片断的结果是,这个键的最初部份被转换成“LjiQly?Ck”,跟着的一个不可打印字符十六进制数值表示为
Mutating the Decryption Subkey .text:00405401 mov eax,
edi .text:00405403 add eax,
[ebp+var_C] .text:00405406
add byte ptr [eax], 7 .text:00405409 inc edi .text: .text:0040540D lea ecx,
[eax] .text: .text:00405412 inc eax .text:00405413 cmp byte
ptr [ecx+eax], 0 .text:00405417 jnz short
loc_405412 .text:00405419 cmp edi,
eax .text:0040541B
jb short loc_405401 |
图 3-24
我们还注意到该木马处理了很多嵌入到可执行文件里面的字符值,在内存中该木马从偏移4086CC处开始将它们彼此紧靠着排成一行。在变异那个键的前缀之后不久,就在偏移405435处调用例程sub_404E78来执行这个任务。此时逻辑变得有点难以跟随,而且我们失去程序工作流的踪迹。若有兴趣追踪我们的步骤,可以在引用的偏移处设置一个断点并且单步调试这个代码。(具体实现办法可以是,首先在SoftICE中使用“bpx CRTDLL!fopen”命令在fopen调用上中断,然后在需要的偏移处用命令制造一新断点,比如“bpx 405435”)。
在建立环境之后(具体如何设置我们还不太清楚),解密过程继续进行,循环处理加密行开头部分的一个字符子集并且从偏移405473处调用例程sub_
据Joe Abrams说,通过IRC发送给该木马的命令也被使用相似的加密技术加了密。命令必须被适当地加密,该程序才能解释它们。Joe观察到在该木马的IRC频道上被使用的一些加密命令,通过重放这些命令,他能够以一种有限方式控制他那个版本的木马。这间接表明,用来加密命令和gus.ini文件的算法不考虑与该木马实例相关的特有特性。
为了一个适当加密命令能被该木马兑现,在每个通信尝试中,这个命令需要被加上一个适当的口令作为前缀。这意味着,试图控制该木马的操作者需要以“password command”(口令+命令)形式发送消息给IRC频道。就如我们前面讨论的,该程序内至少有两个硬编码的口令。这些口令可以使用gus.ini文件中的“SETCOMMAND”和“COMMAND”参数覆盖,这或许给操作者提供不同的访问层次。
如Joe在他的报告中所述,这个口令必须使用它自己的算法适当地加密。这个算法通过查验试图控制该程序的主机IP地址来保护该木马免于受到重放攻击。Joe在他的报告中描述了口令加密过程,而且指出有些组成加密口令的字符可能是不可打印的。需要适当地加密口令和命令字符串,这暗示存在着某个控制木马程序在外面操作,或者同时配以标准的IRC客户端。
srvcp.exe这个木马提供给攻击者什么功能我们还不清楚。就如我们在本文的‘背景信息’小节中提到的,若干FTP相关的字符串嵌入到程序里面,这暗示,它的操作者有能力把文件传入和传出受感染系统。如图3-25所示,该木马似乎依赖Windows内建的ftp.exe程序来进行基于FTP的文件传输。
Embedded FTP Messages .data:004084B9 db 'PRIVMSG
%s :successfully spawned ftp.exe',0Ah,0 .data:004084E3
db 'PRIVMSG %s :couldn',27h,'t spawn ftp.exe',0Ah,0 |
图 3-25
在srvcp.exe内嵌入的几个字符串间接表明,该木马能够进行拒绝服务攻击。如下面图3-26所示,“sacker”和“jacker”可能是对这些攻击的引用。注意,“sacker”把时间和端口数目作为参数,这可能让攻击者可以在某一个特定时间段内使用网络流量充斥某一个目标。“spawn”命令可能让攻击者可以在受感染机器上启动任意一个程序。
Possible Network Flood Commands .data:00408541 db 'PRIVMSG
%s :ctcp <nick> .data:00408541 db 'getnick <nick>, getnonick, rnick <nick>!!, ' .data:00408541
db 'sacker
time low_port high_port addy, jacker' .data:00408541
db ' time ip ip ip etc, stopsack, stopjack, spa' .data:00408541
db 'wn
filename, ftpget EVERYTHING, randnick, c' .data:00408541
db 'lone, clonedie',0Ah,0 |
图 3-26
第4部分 保护措施
4.1 传播机制
我们没有证据证明srvcp.exe不需要一个外部程序帮助就能够传播或复制。如本文‘本地系统交互’小节所提到的,这个可执行文件假定它位于一个被包含在系统路径中的目录里面,比如C:\WINNT,但是它实际上没有在启动后把自己复制或移动到那些目录。这暗示我们遗漏了实际负责把srvcp.exe放进适当目录内的另外一个程序。受害者可能通过e-mail消息收到一个受感染的载体文件,或者从因特网下载了受感染的程序。
从日期为2000年六月、有关srvcp.exe的一个HackFix主页上,我们发现这样的信息:该木马一直是用DivX_e3.exe程序传播的,该程序声称是DivX视频译码器一个注册版[HF]。另外据传,该木马正通过serials.2000.v6.0.zip、CDRWin3.8.zip和PSXCopy.v6.0.zip这些文件传播。在本文‘背景信息’小节中提到过,Pete Schmitt最近提交的一份事件报告证实,该木马正在继续传播;然而,在写作本文的时候我们还不知道目前载体文件的名字。一旦机器被感染,攻击者能够通过该木马的文件传输能力在受害者的系统上安装其他恶意软件。
载体程序是否连同srvcp.exe一起也安装了一个gus.ini文件拷贝,这还不能肯定。既然该木马没有gus.ini也能运转,所以这个文件可能是在最初感染之后被创建的。攻击者能够通过IRC文件传输和FTP能力上传gus.ini到受感染的机器。注意,这些连接多数是由受感染的机器初始化,因此它们不大可能被防火墙阻止。也可能是攻击者能够通过IRC控制频道发送适当命令指示该木马创建gus.ini文件。
4.2 特洛伊木马的变种
浏览杀毒产品厂商的公众数据库,我们发现有关srvcp.exe木马变种的许多记录。然而,厂商似乎对于该木马的命名有分歧。Symantec软件公司称之为“IRC.SRVCP.木马”,但是除了描述该木马特征为“wild”没有提供任何关于它的信息[SY]。Trend Micro提供该木马的简短描述,其行为特性和文件尺寸与我们木马变种相符;他们称之为“TROJ_SRVCP”[TM1]。Computer Associates提供了关于该木马的充分信息,这些信息表明他们变种与本文所述的这个可执行文件紧密地相符;他们称该程序为“Tasmer.B”和“Win32.Tasmer.B”[CA1]。
Computer Associates还描述了该木马另一个变种,其可执行文件名为tskmngr.exe,而它的注册表键是“Task Manager”;他们称这个程序为“Tasmer.A”、“Win32.Tasmer.A”、“Backdoor.Tasmer”和“Troj/Narnar”,而且说最早在2000年4月发现它。Trend Micro也描述了该木马的一个tskmngr.exe变种,但称它为“TROJ_TASMER.B”[TM2]。Sophos也命名tskmngr.exe变种为“Troj/Narnar”;他们指出,该木马连接一个DALnet的IRC服务器,这是我们这个木马版本所使用的EFnet网络的一个替代网络[SP]。Network Associates也讨论了这个变种,称之为“IRC/Randy”[NA]。
明显地,该木马至少有两个变种:一个在EFnet上操作,另一个在DALnet上操作。据Joe Abrams说,该木马的EFnet版本比在DALnet上运转的那个年轻许多。在Joe的文章中,凭借对DALnet频道上受感染用户的数目判断,EFnet版木马变种不象DALnet版的那么流行。Joe的木马版本加入DALnet上的“#KimmiTheB”频道,该频道由该组的成员控制,自成一“派”。
Joe也指出,他偶然碰到到过该木马的一个新版本,它被使用NeoLite工具程序加壳/压缩了。NeoLite封装Windows可执行文件及其资源以保护它们不被反编译器逆向工程[NL]。被NeoLite压缩以后的可执行文件启动后自解压到内存里面。绕过这种保护的办法是使用SoftICE在NeoLite解密例程上设置一个断点,让程序解压缩自己,然后使用SoftICE研究内存里的已解密程序。
4.3 特洛伊木马的签名
如下面图4-1所例,诺顿杀毒软件能自动检测我们的srvcp.exe木马版本。通过检查受感染机器手动检测该木马也相对容易:在文件系统上查找有无srvcp.exe可执行文件,检查有无注册表键“HKLM\software\Microsoft\Windows\CurrentVersion\Run\Service Profiler”,并检查在机器的系统目录中有无gus.ini文件。我们没有发现除了srvcp.exe之外哪个程序有这三个特征之一,但不排除有假阳性的可能。
图 4-1
该木马甚至不需要存取它的源程序码就可以不费力地变异,这使得对它的检测更加困难。例如,即使该程序的文件名不是“srvcp.exe”,它也会继续运行。这个可执行文件也能用一个普通的文件编辑器编辑,让它改用一个不同的注册表键。类似地,也能修改这个可执行文件让它使用“gus.ini”之外的资源文件名。
作为一个观念性证明,我们使用一个明文编辑程序修改那个已编译的可执行文件中的“gus.ini”文件名:由于这个文件名以加密格式储存,所以需要搜索字符串“nhl*pwf”。然后我们修改加密字符串中的一个字母,把新字符串变成“nhl*pwg”。使用IDA Pro反汇编修改后的可执行文件,结果的数据栈见下面图4-2中所示。运行该木马的修正版,结果它使用“fus.ini”这个名字作为它过去一直称为“gus.ini”的文件名。最令人不安的是,用这个简单方式修改可执行文件导致诺顿杀毒软件不再把它当作恶意软件。注意,通过逆向嵌入字符串的解密算法(在本文‘程序代码’小节描述过),我们发现这个算法能够给这个文件构造一个任意的文件名。
Modifying Name for Initialization File Before
modification: .data:00408034
db 'nhl*pwf',0 After
modification: .data:00408034
db 'nhl*pwg',0 |
图 4-2
发现该木马的方法之一是检测它的网络通信。例如,在受感染的系统上运行“netstat -a”命令将会显示系统在TCP端口113监听识别请求,即使该木马还没有连接到一个IRC服务器。扫描网络查找未经授权地运行识别请求的主机是远程检测这种状态木马的一个可能方法。一旦该木马成功连接到一个IRC服务器,“netstat -a”可能显示一个到某个外部服务器端口6667或6666的TCP连接。如果该组织的工作站不正常地使用IRC,这种通信可以用一个基于网络的侵入探测系统(Intrusion Detection System, IDS)检测到。
使用基于网络的IDS检测该木马,一个更加可靠的方法是扫描数据包内容、查找与该木马操作有关的字符串。通过在网络的流(stream)中查找“NICK mikey”之类字符串可以检测该木马的一般变种。遗憾的是,这个方法不可能比使用杀毒软件更有效,因为该木马的签名很容易改变。有关该木马活动更可靠的指标是每3秒左右出现专一一个IRC客户端发出昵称改变请求。遗憾的是,实现这种逻辑可能是资源密集的,因为它需要IDS维持跨多个数据包之间关于潜在攻击性流量的状态信息。替代办法是把IDS调整为扫描用来操作该木马的密码化命令字符串数据包,因为即使是加密的形式,在该木马的多个实例中这些命令还是保持相同,除非加密算法改变。为了获得这些命令字符串,需要对该木马进行一个更全面的分析。我们鼓励读者(他或她)参与这种探索、并和防卫社区共享调查结果。
第5部分 参考书目
[JLG] Jeremy L. Gaddis. 事件邮件列表文档. “未知木马(附件).” 8 June 2000. URL: http://www.securityfocus.com/archive/75/64241. 21 March 2001.
[RFC1459] Jarkko Oikarinen, Darren Reed. RFC 1459. “Internet多线交谈协议.” May 1993. URL: http://www.faqs.org/rfcs/rfc1459.html. 21 March 2001.
[BK] Brandon Kittler. 事件邮件列表文档. “回复:未知木马(附件).” 10 June 2000. URL: http://www.securityfocus.com/archive/75/64380. 21 March 2001.
[RFC1413] Michael St. Johns. RFC 1413. “身份认证协议.” February 1993. URL: http://www.faqs.org/rfcs/rfc1413.html. 21 March 2001.
[DK] Doug Kahler. 事件邮件列表文档. “回复:未知木马(附件).” 12 June 2000. URL: http://www.securityfocus.com/archive/75/64849. 21 March 2001.
[NF] Nick FitzGerald. 事件邮件列表文档. “回复:未知木马(附件).” 13 June 2000. URL: http://www.securityfocus.com/archive/75/64847. 22 March 2001.
[PS] Pete Schmitt. 事件邮件列表文档. “新的 (?) windows irc ddos 木马.” 10 March 2001. URL: http://www.securityfocus.com/archive/75/167985. 22 March 2001.
[VM1] VMware, Inc. “VMware工作站常见问题.” URL: http://www.vmware.com/products/desktop/ws_faqs.html. 22 March 2001.
[VM2] VMware, Inc. “用于Windows 2000主机的主机专用网络配置注意事项.” URL: http://www.vmware.com/support/ws2/doc/hostonly_w2k_ws_win.html. 4 April 2001.
[RFC1918] RFC 1918.URL: http://www.faqs.org/rfcs/rfc1918.html. 22 March 2001.
[SI1] Mark Russinovich, Bryce Cogswell. 用于Windows NT/9x的Filemon. 26 December 2000. URL: http://www.sysinternals.com/ntw2k/source/filemon.shtml. 22 March 2001.
[SI2] Mark Russinovich, Bryce Cogswell. 用于Windows NT/9x的Regmon. 7 November 2000. URL: http://www.sysinternals.com/ntw2k/source/regmon.shtml. 22 March 2001.
[WI] Winternals Software. TCPView专业版. URL: http://www.winternals.com/products/monitoringtools/tcpviewpro.shtml. 22 March 2001.
[SF] SFullerton.com. Winalysis 2.50版. 30 December 2000. URL: http://www.sfullerton.com/products.htm. 22 March 2001.
[TR] Tripwire 主页. URL: http://www.tripwire.com. 4 April 2001.
[ES] Executive Software. Undelete 2.0. URL: http://www.execsoft.com/undelete/undelete.asp. 22 March 2001.
[SN] Martin Roesch. Snort – 开放源码网络侵入检测系统. URL: http://www.snort.org. 22 March 2000.
[DR1] DataRescue. IDA Pro by Ilfak Guilfanov. URL: http://www.datarescue.com/idabase/idaorder.htm. 22 March 2001.
[DR2] DataRescue. IDA Pro 评估版下载. URL: http://www.datarescue.com/idabase/ida4down.htm. 22 March 2001.
[DR3] DataRescue. IDA Pro 免费软件.
URL: http://www.datarescue.be/downloadfreeware.htm.
22 March 2001.
[IN] Intel 公司. Intel体系结构软件开发者手册, 第2册: 指令集参考手册. 13 January 1997. URL: http://developer.intel.com/design/pentium/manuals/243191.htm. 22 March 2001.
[NM] Compuware NuMega. “我还可以单独买SoftICE吗?” URL: http://www.numega.com/drivercentral/FAQs/dsq29.shtml. 22 March 2001.
[C4N] CoRN2. “#Cracking4Newbies SoftIce 教程.” URL: http://whateverhosting.com/krobar/beginner/04.htm. 22 March 2001.
[MT] “Mammon_’s Tales to His Grandson” URL: http://newdata.box.sk/neworder/cracking/ice.html. 22 March 2001.
[FS] Foundstone. BinText v3.0. URL: http://www.foundstone.com/rdlabs/proddesc/bintext.html. 22 March 2001.
[AS] ActiveState 公司. ActivePerl. URL: http://www.activestate.com/Products/ActivePerl. 21 March 2001.
[IS] IRCD-Hybrid. URL: http://www.ircd-hybrid.net. 4 April 2001.
[JA1] Joe Abrams. “逆向一个木马.” 1 October 2001. URL: http://freeshell.org/~abrams/troj.txt. 22 March 2001.
[JA2] 在寄存器中篡改数据. Joe Abrams. “逆向一个木马.” 19 November 2001. URL: http://www.hackinthebox.org/article.php?sid=1138. 22March 2001.
[HF] HackFix. “srvcp.exe” June 2000. URL: http://www.hackfix.org/ircfix/srvcp.shtml. 22 March 2001.
[SY] Symantec 病毒百科全书. “IRC.SRVCP.Trojan.” URL: http://www.symantec.com/avcenter/cgi-bin/virauto.cgi?vid=18552. 22 March 2001.
[TM1] Trend Micro 病毒百科全书. “TROJ_SRVCP.” URL: http://antivirus.com/vinfo/virusencyclo/default5.asp?VName=TROJ_SRVCP&VSect=T. 4 April 2001.
[CA1] Computer Associates 病毒百科全书. “Tasmer.B.” URL: http://ca.com/virusinfo/encyclopedia/descriptions/tasmerb.htm. 22 March 2001.
[TM2] Trend Micro 病毒百科全书. “TROJ_TASMER.B” URL: http://antivirus.com/vinfo/virusencyclo/default5.asp?VName=TROJ_TASMER.B&VSect=T. 22 March 2001.
[SP] Sophos 病毒信息. “Troj/Narnar”. URL: http://www.sophos.com/virusinfo/analyses/trojnarnar.html. 22 March 2001.
[NA] Network Associates. “IRC/Randy”. 12 April 2000. URL: http://vil.nai.com/villib/dispVirus.asp?virus_k=98569&EY=y. 22 March 2001.
[NL] NeoWorks. “NeoLite:
为开发者程序加密与压缩.” URL: http://www.neoworx.com/products/neolite/default.asp.
4 April 2001.