埠和CGI的掃瞄實現

2021-03-31 14:15:12 字數 4783 閱讀 6508

埠和cgi的掃瞄實現

《首發於2023年黑客防線11期》

一. diy乙個埠掃瞄器之-高階技術

埠的掃瞄技術到現在大致分為兩種,一種就是低階傳統的掃瞄器,還有就是高階技術的。今天我們就來講講高階技術的原理及其實現在基本**。

經過測試我們知道正在listen的埠,如果接收在乙個syn包(就是tcp握手的第一次)那麼它就會返回乙個syn|ack(0x12)包,如果乙個 關閉的埠接收到syn包就會返回乙個psh|rst|syn(0x14)的包並且syn序列號為0。如果遠端主機不存在,那麼不返回任何資料報。

根據上面的分析我們就可以構造乙個掃瞄器了。

如果我們對目標機器發乙個syn包,如果接收到乙個syn|ack(0x12)的包我們就知道遠端埠是存活的。如果接收到psh|rst|syn(0x14)那麼就確定那個埠沒有開放。

好的那麼我們在發包前就需要建立乙個偵聽執行緒來接收返回的資料報,並加一分析。

1.定義偵聽執行緒:

dword   winapi  listeningfunc(lpvoid lpvoid) ;

gethostname(name, 100);

phostent=gethostbyname(name);

把本機ip位址複製到addr_in.sin_addr.s_un.s_addr中。

memcpy(&addr_in.sin_addr.s_un.s_addr, phostent->h_addr_list[0], phostent->h_length);

繫結。

int ret=bind(rawsock, (struct sockaddr *)&addr_in, sizeof(addr_in));

設定sio_rcvall 接收所有的資料報

dword lpvbuffer = 1;

dword lpcbbytesreturned = 0;

wsaioctl(rawsock, sio_rcvall, &lpvbuffer, sizeof(lpvbuffer), null, 0, &lpcbbytesreturned, null, null);

然後剩下的就是對資料報的捕獲分析了。用乙個死迴圈來不斷的捕獲接收到的資料報,分析如果是存活埠返回的包就打出來,不是的話就放棄,不做任何處理,繼續捕獲下乙個資料報。

while (true) ;

int  size=sizeof(from);

char recvbuf[256]=;

//接收資料報

ret=recvfrom(rawsock,recvbuf,sizeof(recvbuf),0,(struct sockaddr*)&from,&size);

char* sourceip=i***_ntoa(* (struct in_addr *)&from.sin_addr);

if(ret!=socket_error)

} }

}     // end while

}  一上就是我們要建立的偵聽分析執行緒。

ipheader 和 tcpheader的定義分別如下。

typedef struct ip_head      //定義ip首部

ipheader;

typedef struct tcp_head //定義tcp首部

tcpheader;

偵聽搞定了,剩下的問題就是怎麼構造syn 包傳送了。一般syn包的傳送都是自己構造ip頭和tcp頭部,然後用乙個tcp偽頭來計算效驗和,一般情況下這樣打造的。這樣自己造syn也是可以的, 但是我們的程式效率就會大大降低,我們用另外乙個高效率方法。怎麼才可以發出乙個syn包而不用自己構造呢?知道有個connect()api嗎?本來那 是用來建立聯接用的。它裡面就隱藏了tcp的三次握手,如果我們在發出乙個syn包後就關閉套結字,是不是就能起到發乙個syn包的功效了啊?所以就必須 設定套結字為非阻塞的。

2. 發syn包的實現如下。

dword  winapi  scan(lpvoid lp)

infor;

socket sock=null;

sockaddr_in addr_in=;

tchar      sendbuf[256]=;

infor*     lpinfor=(infor*)lp;

int    ierr;

ulong     ul=1; 

ushort port=lpinfor->port;

addr_in.sin_family=af_i***;

addr_in.sin_port=htons(port);

addr_in.sin_addr.s_un.s_addr=lpinfor->ip;

if ((sock=socket(af_i***,sock_stream,ipproto_tcp))==invalid_socket)

printf("socket setup error!/n");

ierr=ioctlsocket(sock,fionbio,(unsigned long*)&ul); //設定sock為非阻塞

connect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in));  //傳送syn包

closesocket(sock);

return 0; }

最主要的偵聽和傳送執行緒都完成了,剩下的就只是,怎麼提取ip位址和埠然後傳給傳送函式了

int main(int argc, char* argv) ;

ulong startip=0, endip=0;

int   number=0;

if ( wsastartup(makeword(2,2), &wsadata)!=0 )

//建立乙個嗅包的執行緒分析接收到的包。

createthread(null,0,listeningfunc,&tempnum,null,null);

sleep(500); //等待執行緒的初始化完成

ulong startip=0, endip=0;

startip=ntohl(i***_addr(argv[1]));

endip  =ntohl(i***_addr(argv[2]));

for ( ; startip <= endip ; startip++)   //從第乙個ip到最後乙個ip

} //end for

sleep(2000);  //最後等待2s,等最後發出的包返回。

printf("scan ***pletely.");

return 1;

} //主線程返回  程式結束。

以上全部**基本上就是乙個掃瞄器了。根據實際測試上面的這種掃瞄方法速度是相當快的。

二. cgi的掃瞄器

cgi 的掃瞄前提是開放了80(web服務)才可以利用的。首先我們必須和遠端的80埠建立聯接。然後通過提交get請求,再根據返回的資訊加以判斷的。例如 返回的200代表成功,一切正常。404代表無法找到指定位置的資源。403代表資源不可用等。然後我們偵聽返回的資料是不是有"http/1.1 200"這樣的子串。有代表請求成功,否則請求失敗。

大致的實現如下:

int main(int argc, char* argv)

;

// infor  結構用來傳遞cgi資訊和ip資訊

// 定義如下:

// typedef  struct

// infor;

if (argc !=2 ) return 0;

memcpy (infor.ip,argv[1],strlen(argv[1]));

printf("scan start......./n");

// 從檔案中讀取要掃瞄的cgi資訊

while ( fgets(infor.sendbuf,100,fp) !=null )

printf("scan ***pletely./n");

}// end main

scan執行緒定義如下:

dword  winapi  scan(lpvoid lp) ;

int   error=0;

char  buf[256]=;

char* p=null;

infor* lpinfor =(infor*)lp;

if ( (sock=socket(af_i***,sock_stream,ipproto_tcp))==invalid_socket)

target.sin_family=af_i***;

target.sin_port=htons(80);

target.sin_addr.s_un.s_addr=i***_addr(lpinfor->ip);

error=connect (sock, (struct sockaddr* )&target, sizeof(target)); //連線

if (error == socket_error)

send(sock,lpinfor->sendbuf,100,0);  //傳送get請求

recv(sock,buf,256,0);       //接收返回的資訊

p=strstr(buf,"http/1.1 200");  //查詢返回的資訊中有有沒有http/1.1 200子串。

if ( p!=null)   //200的意思是一切正常,對get和post請求的應答文件跟在後面

closesocket(sock);

return 1; }

python實現埠掃瞄

一 import socket import multiprocessing def ports ports service 獲取常用埠對應的服務名稱 for port in list range 1,100 143,145,113,443,445,3389,8080 try ports servi...

實現多執行緒埠掃瞄

實驗要求 能至少掃瞄5個ip位址 針對每個ip位址,開設100個執行緒同時對其進行掃瞄 如果埠開啟,使用函式getservbyport獲取其服務名,在螢幕上列印 ip port servername,如果是未知服務,則螢幕顯示 ip port unkonown 實驗環境 red hat 9 thre...

使用python實現掃瞄埠示例

python最簡潔易懂的掃瞄埠 執行絕對會很有驚奇感 複製 如下 from threading import thread,activecount import socket import os def test port dstwww.cppcns.com,port os.system title...