S扫描器源代码

#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< xuehai008@163.com > 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); 
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
S扫描器是一个简单的使用两种常用的扫描方式进行端口扫描的端口扫描器程序. 可实现的功能是: 1.两种不同的扫描方式(SYN扫描和一般的connect扫描) 2.可以扫描单个IP或IP段所有端口 3.可以扫描单个IP或IP段单个端口 4.可以扫描单个IP或IP段用户定义的端口 5.可以显示打开端口的banner 6.可将结果写入文件 7.TCP扫描可自定义线程数 用法:scanner TCP/SYN StartIP [EndIP] Ports [Threads] [/Banner] [/Save] 参数说明: TCP/SYN -> TCP方式扫描或SYN方式扫描(SYN扫描需要在win 2k或以上系统才行),SYN扫描对本机无效 StartIP -> 起始扫描的IP EndIP -> 结束扫描的IP,可选项,如果这一项没有,就只是对单个IP扫描 Ports -> 可以是单个端口,连续的一段端口或非连续的端口 Threads -> 使用最大线程数去扫描(SYN扫描不需要加这一项),不能超过1024线程 /Banner -> 扫描端口时一并将Banner显示出来,这一选项只对TCP扫描有效 /Save -> 将结果写入当前目录的Result.txt文件中去 我们先点击开始菜单--->运行--->CMD.EXE,因为我把扫描器放在F盘,你们的扫描器放哪你们就进哪里, 打开S扫描器,下面我举几个例子演示下S扫描器的主要几个作用。 例子一: S TCP 218.80.12.1 218.80.12.123 80 512 TCP扫描218.80.12.1到218.80.12.123这IP段中的80端口,最大并发线程是512 例子二: S TCP 218.80.12.1 218.80.12.123 21,5631 512 /Banner TCP扫描218.80.12.1到218.80.12.123这IP段中的21和5631端口,最大并发线程是512,并显示Banner 例子三: S TCP 218.80.12.1 218.80.12.12 1-200 512 TCP扫描218.80.12.1到218.80.12.12这IP段中的1到200端口,最大并发线程是512 例子四: S TCP 218.80.12.7 1-200 512 TCP扫描218.80.12.7这IP中的1到200端口,最大并发线程是512 例子五: S SYN 218.80.12.7 1-65535 /Save SYN扫描218.80.12.7这IP中的1到65535端口,将结果写入Result.txt 扫描结束后Result.txt就存放在你的S扫描器所在的硬盘里,就是这个文档。刚才扫描的东西都在里面。 例子六: S SYN 218.80.12.1 218.80.12.255 21 /Save TCP扫描218.80.12.1到218.80.12.255这IP段中的21端口,将结果写入Result.txt 这个我重点说明一下,因为这条命令就是专门用来找肉鸡的,扫描一个IP段有没有开3389的或1433的 我示范下:S SYN 218.80.1.1 218.80.255.255 3389 /Save (找开放3389肉鸡的指令,矮鸟要牢记哦) 我晕哦,好多开了3389的,大家只要利用这指令扫到开3389的IP,再用别工具继续扫开了3389的肉鸡的弱口令 找到了马上建立管理员,登陆进去,你就算得到一个肉鸡了,由于本动画不是教找肉鸡的,我也不进行操作了 注意: 1.SYN扫描是很依赖于扫描者和被扫描者的网速的,如果你是内网的系统,那你不一定可以使用SYN扫描的 ,因为你的网关的类型会决定内网系统是否能进行SYN扫描.如果你的配置较低的话,我也不推荐使用 SYN扫描.SYN扫描速度是比TCP扫描的速度快很多的,但在稳定性方面却不是太好,所以自己决定使用 哪种模式进行扫描。 2.SYN扫描不需要线程那个参数,请看上面例子5和6 3.TCP扫描的最大并发线程不能超过1024. 4.使用SYN模式扫描,不能扫描Banner,具体为什么不能,请查看有关SYN的资料。 对于有些朋友说XP-SP2不能用S扫描器,有的说可以使用,本人就不大清楚了,懂得人请说明下XP-SP2能不能使用

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值