include "stdafx.h"
include
include
include
define iPort 80//定义端口
define szSign "500 13\t\nServer:Microsoft-IIS/5.0"//根据此标志来检查目标是否有漏洞
pragma comment(lib,"ws2_32.lib")
//定义初始化全局变量
char *SendBuff="Get /NULL.printer\n",
CurrentTarget[52]={0},
turn[4][2]={"-","\","|","/"};
int SendBuffLen=strlen(SendBuff),
iConnTimeOut,//Tcp超时时间
ii=0,//Scan进度
iTotal;//服务器总数
HANDLE hSemaphore=NULL,//信标内核对象句柄线程控制
hStdout;//Console句柄显示进度
struct timeval timeout;//连接、发送和接收超时
DWORD SleepTime;//线程等待时间
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;
}
//得到的目标范围
int StartNet=inet_addr(argv[1]);
int StopNet=inet_addr(argv[2]);
int StartHost=ntohl(StartNet);
int StopHost=ntohl(StopNet);
//取得线程数量
MaxThread=atoi((char *)argv[3]);
//取得超时时间
iConnTimeOut=atoi((char *)argv[4]);
if ((iConnTimeOut>6)||(iConnTimeOut<2)||(MaxThread<1)|| (MaxThread>500) || (StopHost
{
Usage(argv[0]);
return 1;
}
SleepTime=1000*iConnTimeOut/MaxThread;
//设置超时时间
timeout.tv_sec=iConnTimeOut;
timeout.tv_usec=0;
__try
{
Start=clock();
if (WSAStartup(MAKEWORD(1,1),&Wsd)!=0)
{
ShowError("WSAStartup");
__leave;
}
hSemaphore=CreateSemaphore(NULL,MaxThread,MaxThread,NULL);
if (hSemaphore==NULL)
{
ShowError("CreateSemaphore");
__leave;
}
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);
//创建线程扫描
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(true)
{
WaitForSingleObject(hSemaphore,INFINITE);
if (!ReleaseSemaphore(hSemaphore,1,&PreviousCount))
{
ShowError("Main()ReleaseSemaphore");
Sleep(5000);
break;
}
if (PreviousCount==(MaxThread-1))
{
printf("\nAll Done");
break;
}
Sleep(500);
}
}//Try完
__finally
{
//计时结束
End=clock();
//转换时间格式
Duration=(double)(End-Start)/CLOCKS_PER_SEC;
//显示所用时间
printf("\n\n完成.扫描 %d 目标使用 %2.1f 秒.速度 %0.3g/s\n",iTotal,Duration,iTotal/Duration);
//关闭句柄
CloseHandle(hStdout);
CloseHandle(hSemaphore);
WSACleanup();
}
return 0;
}
//回显错误信息函数
void ShowError(char *msg)
{
MessageBox(NULL,(LPCWSTR)msg,(LPCWSTR)"Error",0);
}
//重置光标位置函数,以便扫描线程输出结果
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
{
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%% 等待 %d 秒结束\n",iConnTimeOut);
break;
}
else
{
k=j%4;
printf("%-15s %s [%d/%d] %s %%%0.3g",CurrentTarget,turn[k],ii,iTotal,turn[k],m);
}
}//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;
//创建套接字
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s==INVALID_SOCKET)
{
printf("\n创建套接字失败:%d",GetLastError());
ExitProcess(1);
}
//填写的地址结构
Server.sin_family=AF_INET;
Server.sin_port=htons(iPort);
Server.sin_addr.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);
}
//连接到目标
connect(s,(struct sockaddr *)&Server,sizeof(Server));
//设置Select参数
FD_ZERO(&w);
FD_SET(s,&w);
//等待Connect成功&Socket可写
iErr=select(0,0,&w,0,&timeout);
//等待返回后,socket仍不可写则退出
if ((iErr==SOCKET_ERROR)||(iErr==0))
{
__leave;
}
//Socket可写继续
else
{
//发送BUFF到目标
iErr=send(s,SendBuff,SendBuffLen,0);
if (iErr==SOCKET_ERROR)
{
__leave;
}
}
//等待Socket可读
FD_ZERO(&r);
FD_SET(s,&r);
iErr=select(0,&r,0,0,&timeout);
if ((iErr==SOCKET_ERROR)||(iErr==0))
{
__leave;
}
else
{
//接受目标Buff
iErr=recv(s,RecvBuff,RecvBuffLen,0);
if (iErr==SOCKET_ERROR)
{
__leave;
}
}
//验证BUFF
ptr=strstr(RecvBuff,szSign);
if (ptr!=NULL)
{
//线程输出前调用ResetCursor
ReSetCursor();
//输出信息加上\n
printf("[%-15s]有输出映射\n",inet_ntoa(Server.sin_addr));
}
}
__finally
{
if (!ReleaseSemaphore(hSemaphore,1,NULL))
{
ShowError("线程ReleaseSemaphore错误");
closesocket(s);
}
}
return 0;
}
void Usage(char *ProName)
{
printf("\n%s V1.0 只可找IIS5漏洞"
"\n\nUsage:%s < 结束IP> < 线程数量> < 超时时间>"
"\n\n参数说明:"
"\n 开始IP 结束IP-->开始IP要大于结束IP"
"\n 线程数量-->线程范围1-500"
"\n 超时时间-->TCP连接超时范围2-6"
"\n例子:"
"\n %s 192.168.0.0 192.168.255.255 200 2",ProName,ProName,ProName);
}