• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    CGI掃描器的原理和實現過程

    發布: 2007-7-04 20:04 | 作者: admin | 來源:  網友評論 | 查看: 13次 | 進入軟件測試論壇討論

    領測軟件測試網


    有很多網站為了安全起見,在WEB Server前面架了防火墻,或者做了TCP/IP過濾,對外只開放TCP 80 端口。從入侵者角度來看,要入侵那么從80上跑的CGI入手是比較可行的,當然也可以用別的辦法,例如旁敲側擊,呵呵。從網管角度來看,一是要保證CGI的安全性,另外網絡的整體安全性也是很重要的。針對基于80端口入侵、防范而出的CGI掃描器數不勝數,但基本上原理都一樣。


        CGI掃描器原理說起來其實非常簡單,可以用四句話來概括:<1>連接目標WEB SERVER;<2>發送一個特殊的請求;<3>接收目標服務器返回數據;<4>根據返回數據判斷目標服務器是否有此CGI漏洞。


       當管理的服務器達到一定數量的時候,手工檢測自己的服務器是否存在各種各樣的CGI漏洞,那就太消耗時間和精力了,所以一個網管手上有個比較好用的CGI漏洞掃描器還是必要的。OK!今天我們就自己來動手用C寫一個簡單的CGI掃描器,幫助自己在日常工作中檢測服務器:))


       源代碼如下,很多地方我都加了注釋,別嫌我煩哦:))編譯好的程序可以從http://eyas.3322.net/program/cgicheck.exe下載。


    /*************************************************************************


    Module:CGICheck.cpp


    Author:ey4s<ey4s@21cn.com>


    Date:2001/5/16


    說明:這是一個Console下多線程,帶有進度顯示的CGI掃描器的模板,更改一下szSign和SendBuff就可以掃描其他CGI漏洞,設置了連接、發送、接收超時,速度還可以哦。希望可以幫助到admins檢測自己的服務器:))


    *************************************************************************/


    #include <stdio.h>


    #include <winsock2.h>


    #include <time.h>


     


    #define iPort 80//目標Web Server端口


    #define szSign "500 13\r\nServer: Microsoft-IIS/5.0"http://根據此標志來檢查目標是否有漏洞


     


    #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<ey4s@21cn.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);


    }


       程序在VC++6.0上編譯通過,在windows2000上運行良好:)

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>