荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: michaelx (我有事不在), 信区: Security
标  题: 木马编程(2)
发信站: 荔园晨风BBS站 (Wed May 23 13:04:51 2001), 转信

揭开木马的神秘面纱(二)
作者:shotgun
 前言
   离冰河二的问世已经快一年了,大家对于木马这种远程控制软件也有了一定的认
识,比如:他会改注册表,他会监听端口等等,和一年前几乎没有人懂得木马是什么东

西相比,这是一个质的飞跃。但是,在这个连“菜鸟”都会用NETSTAT看端口,用
LOCKDOWN保护注册表的今天,难道木马就停步不前,等待我们的“杀戮”么?回答显然

是否定的。木马在这一年当中,同样也不断进步,不断发展,他们变得更加隐蔽,更加

灵活。本文试图通过分析近一年以来木马软件的发展,向大家介绍木马的最新攻防技
巧,从而使大家能够更加安全地畅游在Internet上。(本文中默认的操作系统为
Win2000,默认的编程环境是VC++6.0)
 在过去的一年当中,出过很多有名的木马,SUB7,BO2000,冰河等等,他们都有几个共
同的特点,比如:开TCP端口监听,写注册表等等,因此,针对这些特点,也涌现出了
不少查杀木马的工具,比如LockDown2000, Clean等,这些工具一般都是利用检查注册
表和端口来寻找木马(也有利用特征码来查找的,那种原始的思路我们就不说了,谁都

知道,只要源码稍微改改,特征码查询就毫无用处)甚至还出了一些号称能防范未来多

少年木马的软件。而在大家的不断宣传下,以下的木马法则已经妇孺皆知:
 1、 不要随便从不知名的网站上下载可执行文件,不要随便运行别人给的软件;
 2、不要过于相信别人,不要随便打开邮件的附件;
 3、经常检查自己的系统文件、注册表、端口、进程;
 4、经常去查看最新的木马公告,更新自己防火墙的木马库;
   这样看来,第一代木马的特性大家都已经耳熟能详,在这种情况下,作为一个地
下工作者,木马的日子会非常难过。那么,木马就这样甘受屠戮,坐以待毙么?人类就

这样灭绝了木马这个种族么?不是!木马为了生存,也在不断进化,在我们放松警惕,

庆祝胜利的时候,木马已经经历了几次质的突变,现在的木马比起他们的前辈要更加隐

蔽,更加巧妙,更难以发现,功能更强大。
   实际上在我们总结了老一辈木马的特征,并把它们写进杀马软件、编入防马教
程、挂在各个安全网站的首页的时候,木马们就意识到了自己的危险,为了自身的安
全,为了种族的延续,木马们认真地审视了自己的不足(没准也看了很多教程)觉得:

要想更好、更安全的发展下去,只有化缺点为优点,改短处为长处,否则只有死路一
条。于是,他们针对自己的不足,采取了以下的升级方案:
   一、关端口
 祸从口出,同样,端口也是木马的最大漏洞,经过大家的不断宣传,现在连一个刚刚
上网没有多久的“菜鸟”也知道用NETSTAT查看端口,木马的端口越做越高,越做越象
系统端口,被发现的概率却越来越大。但是端口是木马的生命之源,没有端口木马是无

法和外界进行通讯的,更不要说进行远程控制了。为了解决这个矛盾,木马们深入研究

了Richard Stevens的TCP/IP协议详解,决定:放弃原来他们赖以生存的端口,转而进
入地下。放弃了端口后木马怎么和控制端联络呢?对于这个问题,不同的木马采用了不

同的方法,大致分为以下两种方法:寄生、潜伏。
 1、 寄生就是找一个已经打开的端口,寄生其上,平时只是监听,遇到特殊的指令就
进行解释执行;因为木马实际上是寄生在已有的系统服务之上的,因此,你在扫描或查

看系统端口的时候是没有任何异常的。据我所知,在98下进行这样的操作是比较简单
的,但是对于Win2000 相对要麻烦得多。由于作者对这种技术没有很深的研究,在这里

就不赘述了,感兴趣的朋友可以去http://www.ahjmw.gov.cn/cit/或者西祠胡同的
WinSock版查看相关的资料。
 2、 潜伏是说使用IP协议族中的其它协议而非TCP/UDP来进行通讯,从而瞒过Netstat
和端口扫描软件。一种比较常见的潜伏手段是使用ICMP协议,ICMP(Internet控制报
文)是IP协议的附属协议,它是由内核或进程直接处理而不需要通过端口,一个最常见

的ICMP协议就是Ping,它利用了ICMP的回显请求和回显应答报文。一个普通的ICMP木马

会监听ICMP报文,当出现特殊的报文时(比如特殊大小的包、特殊的报文结构等)它会

打开TCP端口等待控制端的连接,这种木马在没有激活时是不可见的,但是一旦连接上
了控制端就和普通木马一样,本地可以看到状态为Established的链接(如果端口的最
大连接数设为1,在远程使用Connect方法进行端口扫描还是没有办法发现的);而一个

真正意义上的ICMP木马则会严格地使用ICMP协议来进行数据和控制命令的传递(数据放

在ICMP的报文中),在整个过程中,它都是不可见的。(除非使用嗅探软件分析网络流

量)
 3、 除了寄生和潜伏之外,木马还有其他更好的方法进行隐藏,比如直接针对网卡或
Modem进行底层的编程,这涉及到更高的编程技巧。
   二、隐藏进程。
   在win9x时代,简单的注册为系统进程就可以从任务栏中消失,可是在Window2000

盛行的今天,这种方法遭到了惨败,注册为系统进程不仅仅能在任务栏中看到,而且可

以直接在Services中直接控制停止、运行(太搞笑了,木马被客户端控制)。使用隐藏

窗体或控制台的方法也不能欺骗无所不见的ADMIN大人(要知道,在NT下,
Administrator是可以看见所有进程的)。在研究了其它软件的长处之后,木马发现,
Windows下的中文汉化软件采用的陷阱技术非常适合木马的使用。
   DLL陷阱技术是一种针对DLL(动态链接库)的高级编程技术,编程者用特洛伊DLL

替换已知的系统DLL,并对所有的函数调用进行过滤,对于正常的调用,使用函数转发
器直接转发给被替换的系统DLL,对于一些事先约定好的特殊情况,DLL会执行一些相对
应的操作,一个比较简单的方法是起一个进程,虽然所有的操作都在DLL中完成会更加
隐蔽,但是这大大增加了程序编写的难度,实际上这样的木马大多数只是使用DLL进行
监听,一旦发现控制端的连接请求就激活自身,起一个绑端口的进程进行正常的木马操

作。操作结束后关掉进程,继续进入休眠状况。
   因为大量特洛伊DLL的使用实际上已经危害到了Windows操作系统的安全和稳定
性,据说微软的下一代操作系统Window2001(海王星)已经使用了DLL数字签名、校验
技术,因此,特洛伊DLL的时代很快会结束。取代它的将会是强行嵌入代码技术(插入
DLL,挂接API,进程的动态替换等等),但是这种技术对于编写者的汇编功底要求很
高,涉及大量硬编码的机器指令,并不是一般的木马编写者可以涉足。(晕,我是门都

找不到,哪位高手可以指点我一下?)
   三、争夺系统控制权
 木马们并不甘于老是处于防守的地位,他们也会进攻,也会主动出击。WINNT下的溢出

型木马就是这样的积极者,他们不仅仅简单的加载、守候、完成命令,而是利用种种系

统的漏洞设法使自己成为系统的拥有者-ADMIN,甚至系统的控制者-System。那么,木
马利用什么方法能一改过去到处逃亡的面目,从而成为系统的主宰呢?
 首当其冲的显然是注册表:多年驰骋注册表的历史使得木马非常熟悉注册表的构造和
特点(你呢,你能比木马更熟悉注册表么)Windows2000有几个注册表的权限漏洞,允
许非授权用户改写ADMIN的设置,从而强迫ADMIN执行木马程序,这个方法实现起来比较

容易,但是会被大多数的防火墙发现。
 其次是利用系统的权限漏洞,改写ADMIN的文件、配置等等,在ADMIN允许Active
Desktop的情况下这个方法非常好用,但是对于一个有经验的管理员,这个方法不是太
有效;
 第三个选择是系统的本地溢出漏洞,由于木马是在本地运行的,它可以通过本地溢出
的漏洞(比如IIS的本地溢出漏洞等),直接取得system的权限。这部分内容在袁哥和
很多汇编高手的文章中都有介绍,我就不再赘述了。(偷偷告诉你,其实是我说不出
来,我要是能写出那样的溢出程序我还用在这里......)
   四、防火墙攻防战
   现在,在个人防火墙如此之流行的今天,也许有人会说:我装个防火墙,不管你
用什么木马,在我系统上搞什么,防火墙设了只出不进,反正你没法连进来。同样,对

于局域网内的机器,原先的木马也不能有效的进行控制(难道指望网关会给你做NAT么
?)但是,城墙从来就挡不住木马:在古希腊的特洛伊战争中,人们是推倒了城墙来恭

迎木马的,而在这个互联网的时代,木马仍然以其隐蔽性和欺诈性使得防火墙被从内部

攻破。其中反弹端口型的木马非常清晰的体现了这一思路。
 反弹端口型木马分析了防火墙的特性后发现:防火墙对于连入的链接往往会进行非常
严格的过滤,但是对于连出的链接却疏于防范。于是,与一般的木马相反,反弹端口型

木马的服务端(被控制端)使用主动端口,客户端(控制端)使用被动端口,木马定时

监测控制端的存在,发现控制端上线立即弹出端口主动连结控制端打开的被动端口,为

了隐蔽起见,控制端的被动端口一般开在80,这样,即使用户使用端口扫描软件检查自

己的端口,发现的也是类似 TCP UserIP:1026 ControllerIP:80 ESTABLISHED的情
况,稍微疏忽一点你就会以为是自己在浏览网页。(防火墙也会这么认为的,我想大概

没有哪个防火墙会不给用户向外连接80端口吧,嘿嘿)看到这里,有人会问:那服务端

怎么能知道控制端的IP地址呢?难道控制端只能使用固定的IP地址?哈哈,那不是自己

找死么?一查就查到了。实际上,这种反弹端口的木马常常会采用固定IP的第三方存储

设备来进行IP地址的传递。举一个简单的例子:事先约定好一个个人主页的空间,在其

中放置一个文本文件,木马每分钟去GET一次这个文件,如果文件内容为空,就什么都
不做,如果有内容就按照文本文件中的数据计算出控制端的IP和端口,反弹一个TCP链
接回去,这样每次控制者上线只需要FTP一个INI文件就可以告诉木马自己的位置,为了

保险起见,这个IP地址甚至可以经过一定的加密,除了服务和控制端,其他的人就算拿

到了也没有任何的意义。对于一些能够分析报文、过滤TCP/UDP的防火墙,反弹端口型
木马同样有办法对付,简单的来说,控制端使用80端口的木马完全可以真的使用HTTP协

议,将传送的数据包含在HTTP的报文中,难道防火墙真的精明到可以分辨通过HTTP协议

传送的究竟是网页还是控制命令和数据?
   五、更加隐蔽的加载方式:
   记得一年前,大家觉得通过所谓图片传播的木马非常神秘,其实现在几乎人人都
知道那只是一个后缀名的小把戏,而绑定EXE文件的木马也随着“不要轻易执行可执行
文件”的警告变得越来越不可行,和过去不同是,现在木马的入侵方式更加的隐蔽,在

揉合了宏病毒的特性后,木马已经不仅仅通过欺骗来传播了,随着网站互动化进程的不

断进步,越来越多的东西可以成为木马传播的介质,JavaScript,VBScript, ActiveX,
XML......几乎WWW每一个新出来的功能都会导致木马的快速进化,曾几何时,邮件木马

从附件走向了正文,简单的浏览也会中毒,而一个Guest用户也可以很容易的通过修改
管理员的文件夹设置给管理员吃上一点耗子药。当我们小心翼翼地穿行在互联网森林中

的时候,也许正有无数双木马的眼睛在黑暗中窥视,他们在等待你的一次疏忽,一个小

小的疏忽,这将给他们一个完美的机会......
   一点点感想:
 入侵高手可能会对于木马的编写和防御不屑一顾,但是,许多入侵事件多多少少会有
木马的参与(这个时候,木马程序往往被叫做后门)在最近的微软被黑事件中,入侵者

使用的就是一种叫QAZ的木马,实际上,这种木马并不非常高级,甚至不能算是第二代
木马(只是一种通过共享传播的蠕虫木马),而正是一只小小的木马,让强大的微软丢

尽了脸。要知道:入侵者和黑客不同,对于入侵者来说,入侵是最终的目的,任何手
段,只要能最快最简单的进入,就是最好的手段,由于被入侵的用户大多数并不是专业

人员,所以木马往往是一个很好的选择。
 在撰写本文的过程中,曾经有朋友和我戏言:危言耸听。其实,事实并非如此,在本
文中描述的木马,虽然看起来匪夷所思,但是在互联网上大多已经有了样品出现,而
且,我相信,一定还有技术含量远远超过上述木马的软件正在开发中。
   编后说明:
 本文的撰写,并不是为了发展木马技术,扰乱互联网,而是为了能深入探讨木马的攻
击和防御技术,引起人们对木马的关注,尽量减小木马传播可能造成的危害。
 本文的撰写得到了Lion Hook、无影猫、李逍遥、Yagami、 Quack以及Glacier的指导
和帮助,在此向他们表示感谢。
在揭开木马的神秘面纱(二)发表后,有很多朋友来信询问新型木马的详细情况,本文
会详细的分析Win2000下一种新型木马的内部构造和防御方法。(本文默认的操作系统为
Win2000,开发环境为VC++6.0。)
  大家知道,一般的"古典"型木马都是通过建立TCP连接来进行命令和数据的传递的,
但是这种方法有一个致命的漏洞,就是木马在等待和运行的过程中,始终有一个和外界
联系的端口打开着,这是木马的阿喀琉斯之踵(参看希腊神话《特洛伊战纪》),也是
高手们查找木马的杀手锏之一(Netstat大法)。所谓道高一尺,魔高一丈,木马也是在
斗争中不断进步不断成长的,其中一种ICMP木马就彻底摆脱了端口的束缚,成为黑客入
侵后门工具中的佼佼者。
  什么是ICMP呢?ICMP全称是Internet Control Message Protocol(互联网控制报文
协议)它是IP协议的附属协议,用来传递差错报文以及其他需要注意的消息报文,这个
协议常常为TCP或UDP协议服务,但是也可以单独使用,例如著名的工具Ping(向Mike
Muuss致敬),就是通过发送接收ICMP_ECHO和ICMP_ECHOREPLY报文来进行网络诊断的。

  实际上,ICMP木马的出现正是得到了Ping程序的启发,由于ICMP报文是由系统内核
或进程直接处理而不是通过端口,这就给木马一个摆脱端口的绝好机会,木马将自己伪
装成一个Ping的进程,系统就会将ICMP_ECHOREPLY(Ping的回包)的监听、处理权交给
木马进程,一旦事先约定好的ICMP_ECHOREPLY包出现(可以判断包大小、ICMP_SEQ等特
征),木马就会接受、分析并从报文中解码出命令和数据。
  ICMP_ECHOREPLY包还有对于防火墙和网关的穿透能力。对于防火墙来说,ICMP报文
是被列为危险的一类:从Ping of Death到ICMP风暴到ICMP碎片攻击,构造ICMP报文一向
是攻击主机的最好方法之一,因此一般的防火墙都会对ICMP报文进行过滤;但是ICMP_E
CHOREPLY报文却往往不会在过滤策略中出现,这是因为一旦不允许ICMP_ECHOREPLY报文
通过就意味着主机没有办法对外进行Ping的操作,这样对于用户是极其不友好的。如果
设置正确,ICMP_ECHOREPLY报文也能穿过网关,进入局域网。
为了实现发送/监听ICMP报文,必须建立SOCK_RAW(原始套接口),首先,我们需要定义
一个IP首部:
typedef struct iphdr {
 unsigned int version:4; // IP版本号,4表示IPV4
 unsigned int h_len:4; // 4位首部长度
 unsigned char tos; // 8位服务类型TOS
 unsigned short total_len; // 16位总长度(字节)
 unsigned short ident; file://16位标识
 unsigned short frag_and_flags; // 3位标志位
 unsigned char ttl; file://8位生存时间 TTL
 unsigned char proto; // 8位协议 (TCP, UDP 或其他)
 unsigned short checksum; // 16位IP首部校验和
 unsigned int sourceIP; file://32位源IP地址
 unsigned int destIP; file://32位目的IP地址
}IpHeader;
  然后定义一个ICMP首部:
typedef struct _ihdr {
 BYTE i_type; file://8位类型
 BYTE i_code; file://8位代码
 USHORT i_cksum; file://16位校验和
 USHORT i_id; file://识别号(一般用进程号作为识别号)
 USHORT i_seq; file://报文序列号
 ULONG timestamp; file://时间戳
}IcmpHeader;
  这时可以同过WSASocket建立一个原始套接口:
SockRaw=WSASocket(
          AF_INET, file://协议族
          SOCK_RAW, file://协议类型,SOCK_RAW表示是原始套接口
          IPPROTO_ICMP, file://协议,IPPROTO_ICMP表示ICMP数据报
          NULL, file://WSAPROTOCOL_INFO置空
          0, file://保留字,永远置为0
          WSA_FLAG_OVERLAPPED file://标志位
          );
  注:为了使用发送接收超时设置(设置SO_RCVTIMEO, SO_SNDTIMEO),必须将标志
位置为WSA_FLAG_OVERLAPPED
随后你可以使用fill_icmp_data子程序填充ICMP报文段:
fill_icmp_data函数:
void fill_icmp_data(char * icmp_data, int datasize)
{
 IcmpHeader *icmp_hdr;
 char *datapart;
 icmp_hdr = (IcmpHeader*)icmp_data;
 icmp_hdr->i_type = ICMP_ECHOREPLY; file://类型为ICMP_ECHOREPLY
 icmp_hdr->i_code = 0;
 icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); file://识别号为进程号
 icmp_hdr->i_cksum = 0; file://校验和初始化
 icmp_hdr->i_seq = 0; file://序列号初始化
 datapart = icmp_data + sizeof(IcmpHeader); file://数据端的地址为icmp报文
                        地址加上ICMP的首部长度
 memset(datapart,"A", datasize - sizeof(IcmpHeader)); file://这里我填充的数

                全部为"A",你可以填充任何代码和数据,实际上
                木马和控制端之间就是通过数据段传递数据的。
}
  再使用CheckSum子程序计算ICMP校验和:
  调用方法:
((IcmpHeader*)icmp_data)->i_cksum
= checksum((USHORT*)icmp_data, datasize);
CheckSum函数:
USHORT CheckSum (USHORT *buffer, int size)
{
 unsigned long cksum=0;
 while(size >1)
  {
    cksum+=*buffer++;
    size -=sizeof(USHORT);
  }
  if(size ) cksum += *(UCHAR*)buffer;
  cksum = (cksum >> 16) + (cksum & 0xffff);
  cksum += (cksum >>16);
  return (USHORT)(~cksum);
}// CheckSum函数是标准的校验和函数,你也可以用优化过的任何校验和函数来代替它

  随后,就可以通过sendto函数发送ICMP_ECHOREPLY报文:
  sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest)
);
  作为服务端的监听程序,基本的操作相同,只是需要使用recvfrm函数接收ICMP_EC
HOREPLY报文并用decoder函数将接收来的报文解码为数据和命令:
recv_icmp=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct
sockaddr*)&from,&fromlen);
decode_resp(recvbuf,recv_icmp,&from);
decoder函数:
void decoder(char *buf, int bytes,struct sockaddr_in *from)
{
 IpHeader *iphdr;
 IcmpHeader *icmphdr;
 unsigned short iphdrlen;
 iphdr = (IpHeader *)buf; file://IP首部的地址就等于buf的地址
 iphdrlen = iphdr->h_len * 4 ; // 因为h_len是32位word,要转换成bytes必须*4
 icmphdr = (IcmpHeader*)(buf + iphdrlen); file://ICMP首部的地址等于IP首部长
度加buf
 printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr));
file://取出源地址
 printf(" icmp_id=%d. ",icmphdr->i_id); file://取出进程号
 printf(" icmp_seq=%d. ",icmphdr->i_seq); file://取出序列号
 printf(" icmp_type=%d",icmphdr->i_type); file://取出类型
 printf(" icmp_code=%d",icmphdr->i_code); file://取出代码
 for(i=0;ifile://取出数据段
}
  注:在WIN2000下使用SOCK_RAW需要管理员的权限。
  对于ICMP木马,除非你使用嗅探器或者监视windows的SockAPI调用,否则从网络上
是很难发现木马的行踪的(关于进程的隐藏及破解会在下一篇文章中进行讨论),那么
,有什么可以补救的方法呢?有的,就是过滤ICMP报文,对于win2000可以使用系统自带
的路由功能对ICMP协议进行过滤,win2000的Routing
& Remote Access功能十分强大,其中之一就是建立一个TCP/IP协议过滤器:打开Routi
ng & Remote Access,选中机器名,在IP路由->General->网卡属性中有两个过滤器-输
入过滤和输出过滤,只要在这里将你想过滤的协议制定为策略,ICMP木马就英雄无用武
之地了;不过值得注意的是,一旦在输入过滤器中禁止了ICMP_ECHOREPLY报文,你就别
想再用Ping这个工具了;如果过滤了所有的ICMP报文,你就收不到任何错误报文,当你
使用IE访问一个并不存在的网站时,往往要花数倍的时间才能知道结果(嘿嘿,网络不
可达、主机不可达、端口不可达报文你一个都收不到),而且基于ICMP协议的tracert工
具也会失效,这也是方便和安全之间的矛盾统一了吧。
  本文的撰写是为了深入地研究Win2000的入侵和防御技术,探讨TCP/IP协议和Windo
ws编程技巧,请不要将文中的内容用于任何违法的目的,文中所附为试验性的ICMP通讯
程序,仅仅提供通过ICMP_ECHOREPLY进行通讯交换数据的功能以供研究;如果你对本文
中的内容或代码有疑问,请Mail
to:Shotgun@xici.net,但是出于网络安全的考虑,本人不会提供任何木马软件及代码。


--
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.28.10]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店