#include <stdio.h> #include <winsock2.h> #include <time.h> #define iPort 80//目標Web Server端口 .#define szSign "500 13\r\nServer: Microsoft-IIS/5.0"//根據此標誌來檢查目標是否有漏洞 #pragma comment(lib,"ws2_32.lib") /////////////////////////////////////////////////////////////////////////// // //定義&初始化全局變量 char *SendBuff="GET /NULL.printer\n",//發送的請求buff CurrentTarget[52]={0},//存放最後一個線程將掃瞄的目標 turn[4][2]={"-","\\","|","/"};//顯示進度時的字符 int SendBuffLen=strlen(SendBuff),//發送的buff長度 iConnTimeout,//TCP Connect TimeOut ii=0,//掃瞄進度 iTotal;//服務器總數 HANDLE hSemaphore=NULL,//信標內核對象句柄,用來控制線程數量 hStdout;//console標準輸出句柄,做進度顯示的時候用的 struct timeval timeout;//連接、發送和接收的超時值 DWORD SleepTime;//每個一個線程後等待的時間 /* SleepTime值根據用戶輸入的線程數量[ThreadNum]和TCP ConnectTimeOut[CONNTIMEO]來計算。確保在CONNTIMEO時間左右開ThreadNum個線程。這樣在CONNTIMEO時間後,所開的線程開始陸續超時退出,可以繼續穩定的開線程,可以有效的保證同時有ThreadNum個線程在運行。 */ /////////////////////////////////////////////////////////////////////////// void ShowError(char *);//顯示出錯信息函數 BOOL ResetCursor(void);//重置光標位置,線程輸出的時候調用的 DWORD WINAPI ShowProInfo(LPVOID);//顯示進度信息 DWORD WINAPI scan(LPVOID);//掃瞄函數 void usage(char *);//幫助函數 /////////////////////////////////////////////////////////////////////////// int main(int argc,char **argv) { HANDLE hThread=NULL;//線程句柄 DWORD dwThreadID;//線程ID struct sockaddr_in sa; int i, MaxThread;//最大線程數量 WSADATA wsd; long PreviousCount; clock_t start,end;//程序運行的起始和結束時間 double duration; //檢查用戶輸入參數 if(argc!=5) { usage(argv[0]); return 1; } //get target range int StartNet=inet_addr(argv[1]); int StopNet=inet_addr(argv[2]); int StartHost=ntohl(StartNet); int StopHost=ntohl(StopNet); //取得線程數量 MaxThread=atoi(argv[3]); //取得conn超時時間 iConnTimeout=atoi(argv[4]); //檢查參數合法性 if((iConnTimeout>6) || (iConnTimeout<2) || (MaxThread<1) || (MaxThread>500) || (StopHost<StartHost)) { usage(argv[0]); return 1; } //計算時間 SleepTime=1000*iConnTimeout/MaxThread; //設置連接超時值 timeout.tv_sec = iConnTimeout; timeout.tv_usec =0; __try { //開始計時 start=clock(); //加載winsock庫 if (WSAStartup(MAKEWORD(1,1), &wsd) != 0) { ShowError("WSAStartup"); __leave; } //創建信標內核對象句柄 hSemaphore=CreateSemaphore(NULL,MaxThread,MaxThread,NULL); if(hSemaphore==NULL) { ShowError("CreateSemaphore"); __leave; } //取得console標準輸出句柄 hStdout=GetStdHandle(STD_OUTPUT_HANDLE); if(hStdout==INVALID_HANDLE_VALUE) { ShowError("GetStdHandle"); __leave; } //設置目標總數 iTotal=StopHost-StartHost; //創建進度顯示線程 hThread=CreateThread(NULL,0,ShowProInfo,NULL,0,&dwThreadID); if(hThread==NULL) { ShowError("1 CreateThread"); __leave; } //關閉句柄 CloseHandle(hThread); //循環創建掃瞄線程 for(i=StartHost;i<=StopHost;i++) { //等待信標內核對象通知 WaitForSingleObject(hSemaphore,INFINITE); //create thread to scan hThread=CreateThread(NULL,0,scan,(LPVOID)i,0,&dwThreadID); if(hThread==NULL) { ShowError("2 CreateThread"); break; } //進度自加1 ii++; //重設最後一個線程掃瞄的目標 sa.sin_addr.s_addr=htonl(i); strncpy(CurrentTarget,inet_ntoa(sa.sin_addr),sizeof(CurrentTarget)); //休息一會兒 ) Sleep(SleepTime); //關閉線程句柄 CloseHandle(hThread); } //等待所有線程結束 while(1) { WaitForSingleObject(hSemaphore,INFINITE); if(!ReleaseSemaphore(hSemaphore,1,&PreviousCount)) { ShowError("main() ReleaseSemaphore"); Sleep(5000); break; } if(PreviousCount==(MaxThread-1)) { printf("\nAll done."); break; } Sleep(500); } }//end of try //搞定,清場,收工 __finally { //計時結束 end=clock(); //轉換時間格式 duration = (double)(end - start) / CLOCKS_PER_SEC; //顯示所用時間 printf("\n\nComplete.Scan %d targets use %2.1f seconds.Speed %0.3g/s\n",iTotal,duration,iTotal/duration); //關閉句柄 CloseHandle(hStdout); CloseHandle(hSemaphore); WSACleanup(); } return 0; } /////////////////////////////////////////////////////////////////////////// // //回顯錯誤信息函數 // void ShowError(char *msg) { MessageBox(NULL,msg,"ERROR",0); //printf("\n%s failed:%d",GetLastError()); } ////////////////////////////////////////////////////////////////////////// // //重置光標位置函數,以便掃瞄線程輸出結果 // BOOL ResetCursor() { CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; //取得當前光標位置 if(!GetConsoleScreenBufferInfo(hStdout,&ConsoleScreenBufferInfo)) { ShowError("GetConsoleScreenBufferInfo"); return FALSE; } //設置光標X坐標為0 ConsoleScreenBufferInfo.dwCursorPosition.X=0; //設置當前光標位置 SetConsoleCursorPosition(hStdout,ConsoleScreenBufferInfo.dwCursorPosition); return TRUE; } /////////////////////////////////////////////////////////////////////////// // //顯示進度信息函數 // DWORD WINAPI ShowProInfo(LPVOID lp) { int j,k; CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; float m; for(j=0;ii<iTotal;j++) { //休息一會兒 )) Sleep(SleepTime); //取得當前光標位置 if(!GetConsoleScreenBufferInfo(hStdout,&ConsoleScreenBufferInfo)) { ShowError("GetConsoleScreenBufferInfo"); return 1; } //設置百分比進度顯示的X坐標 ConsoleScreenBufferInfo.dwCursorPosition.X=0; //設置當前光標位置 SetConsoleCursorPosition(hStdout,ConsoleScreenBufferInfo.dwCursorPosition); //已經完成的百分比 m=(ii+1)*100.00/iTotal; //顯示進度 if(ii==iTotal) { printf("******** 100%% Wait %d seconds to exit ******** \n",iConnTimeout); break; } else { k=j%4; printf("%-15s %s [%d/%d] %s %%%0.3g",CurrentTarget,turn[k],ii,iTotal,turn[k],m); } }//end of for return 0; } /////////////////////////////////////////////////////////////////////////// // //掃瞄函數 // DWORD WINAPI scan(LPVOID lp) { int i=(int)lp,iErr; struct sockaddr_in server; SOCKET s=INVALID_SOCKET; char RecvBuff[1024]={0},*ptr; int RecvBuffLen=sizeof(RecvBuff); u_long ul=1;//初始化為為非0值 fd_set r,w; //create socket s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s==INVALID_SOCKET) { printf("\nCreate socket failed:%d",GetLastError()); ExitProcess(1); } //fill the addr struct server.sin_family=AF_INET; server.sin_port=htons(iPort); server.sin_addr.S_un.S_addr=htonl(i); __try { //設置socket為非鎖定模式,ul為0值的話,那麼soocket將被設置為鎖定模式 iErr=ioctlsocket(s,FIONBIO,(unsigned long*)&ul); if(iErr==SOCKET_ERROR ) { ResetCursor(); ShowError("ioctlsocket"); ExitProcess(1); } //printf("\n%X ioctl ok.strat conn",i); //connect to target connect(s,(struct sockaddr *)&server,sizeof(server)); //printf("\n%X conn return,start select w",i); //設置select參數 FD_ZERO(&w); FD_SET(s, &w); //等待connect成功&socket可寫 iErr=select(0, 0, &w, 0, &timeout); //printf("\n%X select w return %d",i,iErr); //等待返回後,socket仍不可寫則退出 if((iErr==SOCKET_ERROR) || (iErr==0)) { //printf("\n%X select return w err,exit",i); __leave; } //socket可寫則繼續 else { //send buff to target //printf("\n%X send",i); iErr=send(s,SendBuff,SendBuffLen,0); //printf("\n%X send return",i); if(iErr==SOCKET_ERROR) __leave; } //等待socket可讀 FD_ZERO(&r); FD_SET(s, &r); //printf("\n%X start select r",i); iErr=select(0, &r, 0, 0, &timeout); //printf("\n%X select r return %d",i,iErr); if((iErr==SOCKET_ERROR) || (iErr==0)) { //printf("\n%X select r err,exit",i); __leave; } else { //recv buff from target //printf("\n%X start recv",i); iErr=recv(s,RecvBuff,RecvBuffLen,0); //printf("\n%X recv ret",i); if(iErr==SOCKET_ERROR) __leave; } //verify buff ptr=strstr(RecvBuff,szSign); if(ptr!=NULL) { //線程輸出前要先調用ResetCursor函數 ResetCursor(); //輸出信息後務必加一個以上換行符號,輸出前請別加換行符號,以免顯示混亂 printf("[%-15s] has .printer mapped. \n",inet_ntoa(server.sin_addr)); } } __finally { if(!ReleaseSemaphore(hSemaphore,1,NULL)) ShowError("thread ReleaseSemaphore failed"); closesocket(s); } return 0; } /////////////////////////////////////////////////////////////////////////// void usage(char *proname) { printf("\n%s v0.1 only can find IIS5 .Printer mapped" "\nPower by ey4s<[email]ey4s@21cn.com[/email]> 2001.5.20" "\nhttp://www.patching.net" "\n\nUsage:%s <StartIP> <EndIP> <ThreadNum> <CONNTIMEO>" "\n\nNotice" "\n StartIP StopIP ==>Don『t forgot StopIP must large than StartIP " "\n ThreadNum ==>Thread number,please input between 1-500" "\n CONNTIMEO ==>TCP connect timeout,please input between 2-6" "\n\nExample" "\n %s 192.168.0.0 192.168.255.255 200 2",proname,proname,proname); }
註: 本文轉載自網路 非原創
轉載自 ey4s@21cn.com