一个包含详细注释的扫描器C源代码

#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]={"-","   _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<ey4s@21cn.com> 2001.5.20"
  "/nhttp://www.patching.net"
  "/n/nUsage:%s <StartIP> <EndIP> <ThreadNum> <CONNTIMEO>"
  "/n/nNotice"
  "/nStartIP StopIP ==>Don't forgot StopIP must large than StartIP "
  "/nThreadNum ==>Thread number,please input between 1-500"
  "/nCONNTIMEO ==>TCP connect timeout,please input between 2-6"
  "/n/nExample"
  "/n%s 192.168.0.0 192.168.255.255 200 2/n",proname,proname,proname);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值