SNIFF原理解析 |
|
jackkcg
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 SNIFF原理解析 SNIFF
原理解析 原創︰xundi(xundi)
來源︰http://www.xfocus.org2001-04-01.秋天的樹. 一 前言
SNIFF真是一個古老的話題,關于在網路上采用SNIFF來獲取敏感訊息已經不是什么新鮮事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢?
SNIFF就是嗅探器,就是竊聽器,SNIFF靜悄悄的工作在網路的底層,把你的秘密全部記錄下來。看過威爾史密斯演的《全民公敵》嗎?SNIFF就象裡面精巧的竊聽器一樣,讓你防不勝防。 SNIFF可以是軟體,也可以是硬體,既然是軟體那就要分平台,有WINDOWS下的、UNXI下的等,硬體的SNIFF稱為網路分析儀,反正不管硬體軟體,目標只有一個,就是獲取在網路上傳輸的各種訊息。本文僅僅介紹軟體的SNIFF。 當你舒適的坐在家裡,愜意的享受網路給你帶來的便利,收取你的EMAIL,購買你喜歡的物品的時候,你是否會想到你的朋友給你的信件,你的信用狀帳號變成了一個又一個的訊息包在網路上不停的傳送著,你是否曾經這些訊息包會透過網路流入別人的機器呢?你的擔憂不是沒有道理的,因為SNIFF可以讓你的擔憂變成實實在在的危險。就好象一個人躲在你身后偷看一樣。。。。。。
二 網路基礎知識 “網路基礎知識”,是不是聽起來有點跑題了?雖然聽起來這和我們要談的SNIFF沒什么關系,可是還是要說一說的,萬丈高樓平地起,如果連地基都沒打好,怎么蓋樓?﹗如果你對網路還不是十釐清楚的話,最好能靜下心來好好看看,要知道,這是基礎的基礎,在這裡我只是簡單的說一下,免得到時候有人迷糊,詳細的最好能夠自己去找書看看。
(1)TCP/IP體系架構 開放系統互連(OSI)模型將網路劃分為七層模型,分別用以在各層上實現不同的功能,這七層分別為︰應用層、表示層、會話層、傳輸層、網路層、數據鏈路層及物理層。而TCP/IP體系也同樣遵循這七層標準,只不過在某些OSI功能上進行了壓縮,將表示層及會話層合並入應用層中,所以實際上我們打交道的TCP/IP僅僅有5層而已,網路上的分層架構決定了在各層上的協議分布及功能實現,從而決定了各層上網路設備的使用。實際上很多成功的系統都是基于OSI模型的,如︰如幀中繼、ATM、ISDN等。
TCP/IP的網路體系架構(部分)
----------------------------------- | SMTP |
DNS | HTTP | FTP | TELNET| 應用層
----------------------------------- | TCP
| UDP | 傳輸層 ----------------------------------- |
IP | ICMP | ARP RARP | 網路層 ------------------------
| IEEE 802 以太網 SLIP/PPP PDN etc| 數據鏈路層
----------------------------------- | 網卡 電纜 雙絞線 etc
| 物理層 ----------------------------------- 從上面的圖中我們可以看出,第一層物理層和第二層數據鏈路層是TCP/IP的基礎,而TCP/IP本身並不十分關心低層,因為處在數據鏈路層的網路設備驅動程式將上層的協議和實際的物理界面隔離開來。網路設備驅動程式位于介質訪問子層(MAC)。
(2)網路上的設備 中繼器︰中繼器的主要功能是終結一個網段的信號並在另一個網段再生該信號,一句話,就是簡單的放大而已,工作在物理層上。
網 橋︰網橋使用MAC物理位址實現中繼功能,可以用來分隔網段或連接部分異種網路,工作在數據鏈路層。
路由器︰路由器使用網路層位址(ip,x.121,e.164等),主要負責數據包的路由尋徑,也能處理物理層和數據鏈路層上的工作。
網 關︰主要工作在網路第四層以上,主要實現收斂功能及協議轉換,不過很多時候通訊閘都被用來描述任何網路互連設備。
(3)TCP/IP與以太網 以太網和TCP/IP可以說是相互相成的,可以說兩者的關系幾乎是密不可分,以太網在一二層提供物理上的連線,而TCP/IP工作在上層,使用32位的IP位址,以太網則使用48位的MAC位址,兩者間使用ARP和RARP協議進行相互轉換。從我們上面TCP/IP的模型圖中可以清楚的看到兩者的關系。 載波監聽/沖突檢測(CSMA/CD)技術被普遍的使用在以太網中,所謂載波監聽是指在以太網中的每個站點都具有同等的權利,在傳輸自己的數據時,首先監聽信道是否空閑,如果空閑,就傳輸自己的數據,如果信道被占用,就等待信道空閑。而沖突檢測則是為了防止發生兩個站點同時監測到網路沒有被使用時而產生沖突。以太網采用廣播機製,所有與網路連接的工作站都可以看到網路上傳遞的數據。
為了加深你的理解,我們來看看下面的圖,一個典型的在以太網中客戶與伺服器使用TCP/IP協議的通信。
用戶進程 FTP客戶 <-------------------------> FTP伺服器
應用層 | | 內核中的協議棧 TCP
<-------------------------> TCP 傳輸層 | |
內核中的協議棧 IP <-------------------------> IP
網路層
| | 以太網驅動程式
<-------------------------> 以太網驅動程式 數據鏈路層 ──────-------------------------------
以太網
??唆唆了這么多,有人煩了吧?相信我,這是基礎的基礎,可以說是說得是很簡單拉,如果需要,拿出個幾十萬字來說上面的內容,我想也不嫌多,好了,讓我們進入下一節,sniff的原理。
三 SNIFF的原理 要知道在以太網中,所有的通訊都是廣播的,也就是說通常在同一個網段的所有網路界面都可以訪問在物理媒體上傳輸的所有數據,而每一個網路界面都有一個唯一的硬體位址,這個硬體位址也就是網卡的MAC位址,大多數系統使用48比特的位址,這個位址用來表示網路中的每一個設備,一般來說每一塊網卡上的MFC位址都是不同的,每個網卡廠家得到一段位址,然后用這段位址分發給其生產的每個網卡一個位址。在硬體位址和IP位址間使用ARP和RARP協議進行相互轉換。
在正常的情況下,一個網路界面應該只附應這樣的兩種數據幀︰ 1.與自己硬體位址相匹配的數據幀。 2.發向所有機器的廣播數據幀。 在一個實際的系統中,數據的收發是由網卡來完成的,網卡接收到傳輸來的數據,網卡內的單片程式接收數據幀的目的MAC位址,根據計算機上的網卡驅動程式設置的接收模式判斷該不該接收,認為該接收就接收后產生中斷信號通知CPU,認為不該接收就丟掉不管,所以不該接收的數據網卡就截斷了,計算機根本就不知道。CPU得到中斷信號產生中斷,作業系統就根據網卡的驅動程式設置的網卡中斷程式位址調用驅動程式接收數據,驅動程式接收數據后放入信號堆棧讓作業系統處理。而對于網卡來說一般有四種接收模式︰
廣播模式︰該模式下的網卡能夠接收網路中的廣播訊息。 組播模式︰設置在該模式下的網卡能夠接收組播數據。 直接模式︰在這種模式下,只有目的網卡才能接收該數據。 混雜模式︰在這種模式下的網卡能夠接收一切透過它的數據,而不管該數據是否是傳給它的。 好了,現下我們總結一下,首先,我們知道了在以太網中是基于廣播模式傳送數據的,也就是說,所有的物理信號都要經過我的機器,再次,網卡可以置于一種模式叫混雜模式(promiscuous),在這種模式下工作的網卡能夠接收到一切透過它的數據,而不管實際上數據的到達站址是不是他。這實際上就是我們SNIFF工作的基本原理︰讓網卡接收一切他所能接收的數據。
(圖一) 我們來看一個簡單的例子,如圖一所示,機器A、B、C與集線器HUB相連接,集線器HUB透過路由器Router訪問外部網路。這是一個很簡單也很常見的情況,比如說在公司大樓裡,我所在的網路部辦公室裡的幾台機器透過集線器連接,而網路部、開發部、市場部也是同樣如此,幾個部門的集線器透過路由器連接。還是回到我們的圖一上來,值得注意的一點是機器A、B、C使用一個普通的HUB連接的,不是用SWITCH,也不是用ROUTER,使用SWITCH和ROUTER的情況要比這複雜得多。 我們假設一下機器A上的管理員為了維護機器C,使用了一個FTP命令向機器C進行遠程登陸,那么在這個用HUB連接的網路裡數據走向過程是這樣的。首先機器A上的管理員輸入的登陸機器C的FTP口令經過應用層FTP協議、傳輸層TCP協議、網路層IP協議、數據鏈路層上的以太網驅動程式一層一層的包裹,最后送到了物理層,我們的網線上。接下來數據幀送到了HUB上,現下由HUB向每一個接點廣播由機器A發出的數據幀,機器B接收到由HUB廣播發出的數據幀,並檢查在數據幀中的位址是否和自己的位址相匹配,發現不是發向自己的后把這數據幀丟棄,不予理睬。而機器C也接收到了數據幀,並在比較之后發現是發現自己的,接下來他就對這數據幀進行分析處理。 在上面這個簡單的例子中,機器B上的管理員如果很好奇,他很想知道究竟登陸機器C上FTP口令是什么?那么他要做的很簡單,僅僅需要把自己機器上的網卡置于混雜模式,並對接收到的數據幀進行分析,從而找到包含在數據幀中的口令訊息。
四 做一個自己的sniff 在上一節裡,我們已經知道了SNIFF的基本原理是怎么一回事,這一節我們來親自動手做一個自己的sniff,畢竟,用程式代碼來說話比什么都要來得真實,也容易加深理解。
回頭想一想我們上面說的原理,我們要做的事情有幾件︰ 1. 把網卡置于混雜模式。 2. 捕獲數據包。 3.
分析數據包。 注︰下面的源代碼取至Chad Renfro的<< Basic Packet-Sniffer
Construction from the Ground Up>>一文中
/************************tcp_sniff_2.c********************/
1.#include 2.#include 3.#include 4.#include
5.#include 6.#include 7.#include 8.#include
9.#include "headers.h"
/*prototype area*/ 10.int
open_raw_socket(void); 11.int set_promisc(char *interface, int
sock); 12.int main() { 13.int sock, bytes_recieved,
fromlen; 14.char buffer[65535]; 15.struct sockaddr_in
from; 16.struct ip *ip; 17.struct tcp *tcp; 18.sock =
open_raw_socket(); 19. set_promisc(interface, sock);
20. while(1) 22. { 23. fromlen = sizeof from; 24.
bytes_recieved = recvfrom(sock, buffer, sizeof buffer, 0, (struct
sockaddr *)&from, &fromlen); 25. printf("\nbytes
received ::: ]\n",bytes_recieved); 26. printf("source address
::: %s\n",inet_ntoa(from.sin_addr)); 27. ip = (struct ip
*)buffer; /*see if this is a tcp packet*/ 28.
if(ip->ip_protocol == 6) { 29. printf("ip header length :::
%d\n",ip->ip_length); 30. printf("protocol :::
%d\n",ip->ip_protocol); 31. tcp = (struct tcp *)(buffer
(4*ip->ip_length)); 32. printf("source port :::
%d\n",ntohs(tcp->tcp_source_port)); 33. printf("dest port :::
%d\n",ntohs(tcp->tcp_dest_port)); 34. } 35. }
36.} 37.int open_raw_socket() { 38. int sock;
39. if((sock = socket(af_inet, sock_raw, ipproto_tcp)) < 0) {
/*Then the socket was not created properly and must die*/
40. perror("the raw socket was not created"); 41. exit(0);
42. }; 43. return(sock); 44. } 45.int
set_promisc(char *interface, int sock ) { 46. struct ifreq
ifr; 47. strncpy(ifr.ifr_name,
interface,strnlen(interface) 1); 48. if((ioctl(sock,
SIOCGIFFLAGS, &ifr) == -1)) { /*Could not retrieve flags
for the interface*/ 49. perror("could not retrive flags for the
interface"); 50. exit(0); 51. } 52. printf("the
interface is ::: %s\n", interface); 53. perror("retrieved
flags from interface successfully"); 54. ifr.ifr_flags |=
iff_promisc; 55. if (ioctl (sock, siocsifflags, &ifr) ==
-1 ) { /*could not set the flags on the interface */ 56.
perror("could not set the promisc flag:"); 57. exit(0); 58. } 59. printf("setting interface ::: %s ::: to promisc",
interface); 60. return(0); 61. }
/***********************EOF**********************************/
上面這段程式中有很詳細的注解,不過我想還是有必要說一說,首先第10行--int
open_raw_socket(void); 是我們的自定義函數,具體內容如下︰ 37.int
open_raw_socket() { 38. int sock; 39. if((sock =
socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { /*Then the
socket was not created properly and must die*/ 40. perror("the
raw socket was not created"); 41. exit(0); 42. }; 43.
return(sock); 44. } 第39行 if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) <
0) { 這裡我們調用了socket函數,使創建了了一個原始套界面,使之收到TCP/IP訊息包。
接下來第11行-int Set_Promisc(char *interface, int
sock),這也是我們的自定義函數,目的是把網卡置于混雜模式,具體內容如下︰ 45.int set_promisc(char
*interface, int sock ) { 46. struct ifreq ifr; 47.
strncpy(ifr.ifr_name, interface,strnlen(interface) 1); 48.
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { /*Could not
retrieve flags for the interface*/ 49. perror("could not retrive
flags for the interface"); 50. exit(0); 51. } 52.
printf("the interface is ::: %s\n", interface); 53.
perror("retrieved flags from interface successfully"); 54.
ifr.ifr_flags |= iff_promisc; 55. if (ioctl (sock,
SIOCSIFFLAGS, &ifr) == -1 ) { /*Could not set the flags on
the interface */ 56. perror("could not set the promisc
flag:"); 57. exit(0); 58. } 59. printf("setting
interface ::: %s ::: to promisc", interface); 60. return(0);
61. } 首先 struct ifreq ifr; 定一了一個ifrreg的架構ifr,接下來
strncpy(ifr.ifr_name,
interface,strnlen(interface) 1);,就是把我們網路設備的名字填充到ifr架構中,在這裡 #define
INTERFACE "eth0" ,讓我們再往下看,ioctl(sock, SIOCGIFFLAGS,
&ifr),siocgifflags請求表示需要獲取界面標志,現下到了第54行,在我們成功的獲取界面標志后把他設置成混雜模式,ifr.ifr_flags
|= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS,
&ifr)。OK,現下我們所說的第一步已經完成--------把網卡置于混雜模式。
現下進入第二步,捕獲數據包。從第20行開始,我們進入了一個死循環,while(1),在第24行,recvfrom(sock,
buffer, sizeof buffer, 0, (struct sockaddr *)&from,
&fromlen),這個函數要做的就是接收數據,冰把接收到的數據放入buffer中。就是這么簡單,已經完成了我們要捕獲數據包的任務。
到了第三步,分析數據包。27行,ip = (struct ip
*)buffer,使我們在頭文件中的IP架構對應于所接收到的數據,接下來判斷在網路層中是否使用的是TCP協議,if(ip->ip_protocol
== 6) ,如果答案是,tcp訊息包從整個IP/TCP包 buffer (4*ip->ip_length)
位址處開始,所以31行 tcp = (struct tcp *)(buffer
(4*ip->ip_length)),然后對應架構把你所需要的訊息輸出。
/*************************headers.h**************************/
/*structure of an ip header*/ struct ip { unsigned
int ip_length:4; /*little-endian*/ unsigned int ip_version:4;
unsigned char ip_tos; unsigned short ip_total_length;
unsigned short ip_id; unsigned short ip_flags;
unsigned char ip_ttl; unsigned char ip_protocol;
unsigned short ip_cksum; unsigned int ip_source; unsigned
int ip_dest; }; /* Structure of a TCP header */
struct tcp { unsigned short tcp_source_port; unsigned
short tcp_dest_port; unsigned int tcp_seqno; unsigned int
tcp_ackno; unsigned int tcp_res1:4, /*little-endian*/
tcp_hlen:4, tcp_fin:1, tcp_syn:1, tcp_rst:1,
tcp_psh:1, tcp_ack:1, tcp_urg:1, tcp_res2:2;
unsigned short tcp_winsize; unsigned short tcp_cksum;
unsigned short tcp_urgent; };
/*********************EOF***********************************/ 從上面的分析我們可以清楚的認識到,認識一個SNIFF需要對TCP/IP協議有著詳細的了解,否則你根本無法找到你需要的訊息。有了上面的基礎,你可以自己來做一個你需要的SNIFF了。
五 常用的SNIFF 很少有原因會讓你自己親自動手來做一個自己的SNIFF,除非你是想了解他的原理,或者是其他一些特別的原因,比如你要在某個特殊的環境攔截一些特殊的數據包。下面我們就來看看一些在網路上經常使用的SNIFF。
(1)windows環境下 windows環境下當然是大名鼎鼎的netxray以及sniffer
pro了,實際上很多人都是用他在windows環境下抓包來分析,不過我想很少有人笨到去在別人的機器上安裝一個圖形界面的sniff,除非他和管理員很熟悉........
netxray的使用就不多說了,反正windows下的東西就是click,click,click,非常的方便用戶。
(2)UNUX環境下
UNUX環境下的sniff可以說是百花齊放,一抓就是一大把,如sniffit,snoop,tcpdump,dsniff等都是比較常見的,他們都有一個好處就是發布源代碼,可以讓你研究,當然也都是免費的︰)
1. sniffit
sniffit可以營運在Solaris、SGI和Linux等平台上,由Lawrence Berkeley Laboratory
實驗室開發的一個免費的網路監聽軟體。最近sniffit 0.3.7也推出了nt版本,並也支持windows2000.
使用方法: -v 顯示版本訊息 -a 以ASCII形式將監聽的結果輸出。 -A
在進行記錄時,所有不可打印的字符都用代替 -b 等同于同時使用參數-t & -s。
-d
將監聽所得內容以十六進製模式顯示在當前終端 -p 記錄連接到的包,0為所有端口。缺省為0。
-P
protocol 選擇要檢查的協議,缺省為TCP。可能的選擇有IP、TCP、ICMP、UDP和他們的組合。 -s
指定sniffer 檢查從 發送的數據包。 -t 指定sniffer 檢查發送到的數據包。 -i 進入交互模式 -l 設定數據包大小,default是300位元組 注︰參數可以用@來表示一個IP范圍,比如 -t
192.168.@ -t和-s
只適用于TCP/UDP數據包,對于ICMP和IP也進行解釋。但如果只選擇了-p參數,則只用于TCP和UDP包。
舉例說明:
監聽流向機器xxx.xxx.xxx.xxx的21端口(ftp)的訊息,並以ascii顯示
監聽所有流出或流入機器xxx.xxx.xxx.xxx的23端口(telnet)的訊息,並以16進製顯示
你可以在這裡找到sniffit
http://reptile.rug.ac.be/~coder/sniffit/sniffit.html2.
snoop
snoop默認情況安裝在Solaris下,是一個用于顯示網路交通的程式,不過SNIFF是把雙刃劍,既然管理員能用他來監視自己的網路,當然一個心懷惡意的入侵者也可以用他來SNIFF自己感興趣的內容。值得一提的是,
SNOOP被發現存在一個緩沖區溢出漏洞,當以導致入侵者以營運snoop(通常為root)的身分遠程進入系統。這是題外話,暫且就此打住。
使用方法︰ [ -a ] # Listen to packets on audio [ -d
device ] # settable to le?, ie?, bf?, tr? [ -s snaplen ] #
Truncate packets [ -c count ] # Quit after count packets [
-P ] # Turn OFF promiscuous mode [ -D ] # Report dropped packets
[ -S ] # Report packet size [ -i file ] # Read previously
captured packets [ -o file ] # Capture packets in file [ -n
file ] # Load addr-to-name table from file [ -N ] # Create
addr-to-name table [ -t r|a|d ] # Time: Relative, Absolute or
Delta [ -v ] # Verbose packet display [ -V ] # Show all
summary lines [ -p first[,last] ] # Select packet(s) to display
[ -x offset[,length] ] # Hex dump from offset for length [
-C ] # Print packet filter code 例如︰
監聽機器a與b的談話,並把內容存儲于文件saved中 3.
tcpdump
tcpdmp也算是一個很有名氣的網路監聽軟體,FREEBSD還把他附帶在了系統上,是一個被很多UNIX高手認為是一個專業的網路管理工具。
使用方法: tcpdump采用命令行模式,它的命令格式為︰ tcpdump [
-adeflnNOpqStvx ][ -c 數量 ][ -F 文件名 ][ -i 網路界面 ][ -r 文件名][ -s snaplen
][ -t 類型 ][ -w 文件名 ][表達式 ] 1. tcpdump的選項介紹 -a
將網路位址和廣播位址轉變成名字; -d
將匹配訊息包的代碼以人們能夠理解的匯編格式給出; -dd 將匹配訊息包的代碼以c語言程式段的格式給出; -ddd
將匹配訊息包的代碼以十進製的形式給出; -e
在輸出行打印出數據鏈路層的頭部訊息; -f
將外部的Internet位址以數字的形式打印出來; -l
使標準輸出變為緩沖行形式; -n 不把網路位址轉換成名字; -t
在輸出的每一行不打印時間戳;
-v 輸出一個稍微詳細的訊息,例如在ip包中可以包括ttl和服務類型的訊息; -vv
輸出詳細的報文訊息;
-c 在收到指定的包的數目后,tcpdump就會停止; -F
從指定的文件中讀取表達式,忽略其它的表達式;
-i 指定監聽的網路界面; -r 從指定的文件中讀取包(這些包一般透過-w選項產生); -w
直接將包寫入文件中,並不分析和打印出來; -T
將監聽到的包直接解釋為指定的類型的報文,常見的類型有rpc和snmp
2. tcpdump的表達式介紹 表達式是一個正則表達式,tcpdump利用它作為過濾報文的條件,如果一個報文滿足表達式的條件,則這個報文將會被捕獲。如果沒有給出任何條件,則網路上所有的訊息包將會被截獲。
在表達式中一般如下幾種類型的關鍵字,一種是關于類型的關鍵字,主要包括host,net,port, 例如 host
210.27.48.2,指明 210.27.48.2是一台主機,net 202.0.0.0 指明
202.0.0.0是一個網路位址,port 23 指明端口號是23。如果沒有指定類型,缺省的類型是host. 第二種是確定傳輸方向的關鍵字,主要包括src , dst ,dst or src, dst and src ,這些關鍵字指明了
傳輸的方向。舉例說明,src 210.27.48.2 ,指明ip包中源位址是210.27.48.2 , dst net
202.0.0.0 指明目的網路位址是202.0.0.0 。如果沒有指明方向關鍵字,則缺省是src or dst關鍵字。 第三種是協議的關鍵字,主要包括fddi,ip
,arp,rarp,tcp,udp等類型。Fddi指明是在FDDI(分布式光纖數據界面網路)上的特定的網路協議,實際上它是"ether"的別名,fddi和ether具有類似的源位址和到達站址,所以可以將fddi協議包當作ether的包進行處理和分析。其他的幾個關鍵字就是指明了監聽的包的協議內容。如果沒有指定任何協議,則tcpdump將會監聽所有協議的訊息包。
除了這三種類型的關鍵字之外,其他重要的關鍵字如下︰gateway,
broadcast,less,greater,還有三種 邏輯運算,取非運算是 'not ' '! ',
與運算是'and','&&';或運算 是'or' ,'||'。 舉例使用:
將監聽ip位址為aaa.bbb.ccc.ddd的機器的通話
將監聽ip位址為aaa.bbb.ccc.ddd的機器的23端口的通話
4. dsniff 之所以要談談dsniff,是因為他不僅僅是一個sniff,在他的整個套件包中,包含了很多其它有用的工具,如arpspoof,dnsspoof,macof,tcpkill等等,SNIFF的手段更加的多樣和複雜化。dsniff是由DugSong開發的你可以在他的主頁上找到這個工具。
目前dsniff支持openbsd (i386), redhat linux (i386), 和solaris (sparc).
並且在FreeBSD, Debian Linux, Slackware Linux, AIX,
和HP-UX上也能運轉得很好。但是dsniff需要幾個其他的第三方軟體進行支持,他們分別是,Berkeley DB ,OpenSSL,
libpcap, libnet, libnids。如果條件允許的話,你最好能夠親自讀一讀dsniff的源代碼,你可以在
http://naughty.monkey.org/~dugsong/找到dsniff。 六 深入sniff 單純的sniff的功能始終是局限的,所以在大多數的情況下,sniff往往和其他手段結合起來使用,sniff和spoof已及其他技術手段結合在一起對網路構成的危害是巨大的。單純的sniff好比缺了一只腿,無法發揮大的作用,例如在sniff原理一節中我們討論的例子裡,我一再的強調我們使用的是一個普通的HUB進行連接是有原因的,如果我們把在圖一中的HUB用一個switch代替,那情況就要複雜一些了,如圖二所示︰
圖(二) 在圖二中,我們的機器A、B、C與Switch相連接,而Switch透過路由器Router訪問外部網路。我們先來了解Switch的工作原理︰
在我們圖一中的 HUB
只是簡單地把所接收到的信號透過所有端口(除了信號來的那個口)重複發送出去不同,而圖二中的Switch卻可以檢查每一個收到的數據包,並對數據包進行相應的處理。在Switch內保存著每一個網段上所有節點的物理位址,只允許必要的網路流量透過Switch。舉例來說,當Switch接收到一個數據包之后,根據自身保存的網路位址表檢查數據包內包含的發送和接收方位址。如果接收方位于發送方網段,該數據包就會被Switch丟棄,不能透過交換機傳送到其它的網段;如果接收方和發送方位于兩個不同的網段,該數據包就會被Switch轉發到目標網段。這樣,透過交換機的過濾和轉發,可以有效避免網路廣播風暴,減少誤包和錯包的出現。順便說一句,現下Switch和HUB的價格相去無幾,所以hub正逐漸被網路交換機取代。 現下回到我們的例子中來,在圖二中仍然和圖一一樣,我們假設機器A上的管理員為了維護機器C,使用了一個FTP命令向機器C進行遠程登陸,那么在這裡,數據是這樣走的︰首先機器A上的管理員輸入的登陸機器C的FTP口令經過應用層FTP協議、傳輸層TCP協議、網路層IP協議、數據鏈路層上的以太網驅動程式一層一層的包裹,最后送到了物理層,我們的網線上。接下來數據幀送到了Switch上,而Switch檢查數據幀中的到達站址,並在他自身保存的網路位址表中知道了他應該把這數據幀發到機器C那裡,于是,接下來機器C接收到了從A發來的訊息,發現他是發給自己的訊息,于是進行分析處理。 OK,現下我們機器B上的管理員的好奇心只能深深的埋藏在心裡了,因為數據包根本就沒有經過他,就算他把自己的網卡設置成混雜模式也是有力無處使。 在了解在一個Switch環境下原理后,我們結合一些手段去設法sniff,是的,我們可以做到這一點,有許多的手段可以讓管理員B滿足他的好奇心,在下面我會提出幾個辦法,當然只是其中的一些辦法而已。
1 ARP Spoof 在基于IP通信的內部網中,我們可以使用 ARP Spoof
的手段,了解什么是ARP
Spoof的前提你先要明白一下什么是ARP和RARP協議,什么是MAC位址,什么又是IP位址。ARP協議是位址轉換協議,RARP被稱為反向位址轉換協議,他們負責把IP位址和MAC位址進行相互轉換對應。
ARP Spoof 攻擊的根本原理是因為計算機中維護著一個 ARP 高速緩存,並且這個ARP
高速緩存是隨著計算機不斷的發出ARP請求和收到ARP附應而不斷的更新的,ARP
高速緩存的目的是把機器的IP位址和MAC位址相互映射。你可以使用 arp 命令來查看你自己的 ARP
高速緩存。現下設想一下,一個Switch工作在數據鏈路層,他根據MAC位址來轉發他所接收的數據包,而電算機維護的 ARP
高速緩存卻是動態的......你想到什么了嗎? 為了加深理解,現下給我們的機器編上號,機器a︰ip位址為
10.0.0.1 ,mac位址為 20-53-52-43-00-01 ,機器b︰ip位址為 10.0.0.2 ,mac位址為
20-53-52-43-00-02,機器c︰ip位址為 10.0.0.3 ,mac位址為 20-53-52-43-00-03
。現下機器B上的管理員是個聰明的家伙,他向機器A發出一個 ARP Reply (協議沒有規定一定要等ARP Request出現才
能發送ARP Reply,也沒有規定一定要發送過ARP Request才能接收ARP
reply),其中的目的ip位址為10.0.0.1,目的mac位址為 20-53-52-43-00-01
,而源ip位址為10.0.0.3,源mac位址為 20-53-52-43-00-02 ,好了,現下機器a更新了他的 arp
高速緩存,並相信了ip位址為10.0.0.3的機器的mac位址是 20-53-52-43-00-02
。當機器A上的管理員發出一條FTP命令時---ftp
10.0.0.3,數據包被送到了switch,switch查看數據包中的到達站址,發現mac為 20-53-52-43-00-02
,于是,他把數據包發到了機器B上。再設想一下,如果不想影響A和C之間的通信該怎么辦?你可以同時欺騙他們雙方,來一個
man-in-middle 。
當然,在實際的操作中你還需要考慮到一些其他的事,比如某些作業系統在會主動的發送ARP請求包來更新相應的ARP入口等。
2. mac flooding 在上面我們曾經提到過,Switch之所以能夠由數據包中目的MAC位址判斷出他應該把數據包發送到那一個端口上是根據他本身維護的一張位址表。這張位址表可能是動態的也可能是靜態的,這要看Switch的廠商和Switch的型號來定,對于某些Switch來說,他維護的是一張動態的位址表,並且位址表的大小是有上限的,比如 3com
superstack switch 3300 (3c16981 hardware v.1 software
v.2.10) 就是這樣一種switch,我們可以透過發送大量錯誤的位址訊息而使switch維護的位址表“溢出”,從而使他變成廣播模式來達到我們要
sniff 機器a與機器c之間的通信的目的。 3. fake the mac address
偽造MAC位址也是一個常用的辦法,不過這要基于你網路內的Switch是動態更新其位址表,這實際上和我們上面說到的
ARP Spoof
有些類似,只不過現下你是想要switch相信你,而不是要機器a相信你。因為switch是動態更新其位址表的,你要做的事情就是告訴switch︰hi,我是機器c。換成技術上的問題你只不過需要向switch發送偽造過的數據包,其中源mac位址對應的是機器c的mac位址,現下switch就把機器c和你的端口對應起來了。不過其中存在一個問題,現下機器c也會說了︰hi,switch老大,我才是機器c呢﹗,現下你該怎么辦?切,還用問﹗讓他說不了話就可以了,dos還是其他什么,隨便你了......
4. icmp router advertisements
這主要是由ICMP路由器發現協議(IRDP)的缺陷引起的,在Windows 95、98、2000及SunOS、Solaris
2.6等系統中,都使用了irdp協議,sunos系統只在某些特定的情況下使用該協議,而windows95 ,windows95b,
Windows98, Windows98se, 和 Windows2000都是默認的使用IRDP協議。
irdp協議的主要內容就是告訴人們誰是路由器,設想一下,一個hack利用irdp宣稱自己是路由器的情況會有多么的糟糕﹗所有相信hack的請求的機器把他們所有的數據都發送給hack所控製的機器.........
5. icmp redirect 所謂ICMP重定向,就是指告訴機器向另一個不同的路由發送他的數據包,ICMP重定向通常使用在這樣的場合下,假設A與B兩台機器分別位于同一個物理網段內的兩個邏輯子網內,而A和B都不知道這一點,只有路由器知道,當A發送給B的數據到達路由器的時候,路由器會向A送一個ICMP重定向包裹,告訴A︰HI,別再送數據給我轉交了,你就直接送到B那裡就可以了。設想一下,一個hack完全可以利用這一點,使得A發送給B的數據經過他。 上面提到的這些方法只不是其中的一些,為了配合sniff能夠工作得更有效率,還有其他許多的辦法,其實sniff的目的說穿了只有一個,就是抓包,從抓包這個概念上引伸下去,所有為了能夠抓到網路上的訊息包而采用的技術都可以歸入sniff,單純的sniff是沒有什么效率的。你還能想到什么嗎?進攻路由器,在路由器上放置sniff......,在系統內核中植入sniff......等等。
七 如何防止SNIFF 防止sniff最有效的手段就是進行合理的網路分段,並在網路中使用交換機和網橋,在理想的情況下使每一台機器都擁有自己的網路段,當然這會使你的網路建設費用增加很多,所以你可以盡量使相互信任的機器屬于同一個網段,使他們互相之間不必擔心sniff的存在。並在網段于網段間進行硬體屏障。你也可以使用加密技術對你在網路中傳送的敏感數據如戶ID或口令,你的銀行帳號,商業機密等進行加密,你可以選用SSH等加密手段。為了防止ARP欺騙,你可以使用永久的ARP緩存條目,反正上面的攻擊手段和原理你也看了,你就反過來想想該怎么辦好了。不過有盾必有矛,平時的安全意識才是最重要的。
(注︰以下關于AntiSniff的介紹取至backend翻譯整理的L0pht AntiSniff 技術文檔一文)
當你做做層層保護后,你還是懷疑自己的網路上存在sniff該怎么辦? L0pht
小組為了探測sniff專門發布了一個軟體 AntiSniff,當然這個軟體不是免費的︰),AntiSniff
工具用于檢測局域網中是否有機器處于混雜模式,AntiSniff Version
1.x被設計為營運在以太網的windows系統中,提供了簡單易用的圖形用戶界面,antisniff version
1.x 主要工作在非交換環境下的本地網段中,如果營運在交換環境下其功能將大打折扣。antisniff ver 2.0
將不但能在本地網段中,而且能夠穿過路由器和交換機進行工作。 ◆ 作業系統類特殊測試 Linux 內核測試 舊版本的Linux內核存在一個奇怪的特性,可被用于確定機器是否處于混雜模式。在正常情形下,網卡會過濾和丟棄那些目標位址不是本機MAC位址或以太網廣播位址的數據包。如果數據包的目標位址為本機以太網位址或廣播位址,將傳送給內核進行處理,因為其認為該以太網數據幀包含了本機的正確IP位址或該網路廣播位址。如果網卡處于混雜模式,則每個數據包都會傳遞給作業系統進行分析或處理。許多版本的
Linux內核只檢查數據包中的IP位址以確定是否存放到IP堆棧中進行處理。為了利用這一點,AntiSniff構造一個無效以太網位址而IP位址有效的數據包。對于使用了這些內核版本和處于混雜模式的Linux系統,由于只檢查到IP位址有效而將其接收並存放到相應堆棧中。透過在這個偽造的以太網數據幀中構造一個ICMP
ECHO請求,這些系統會返回附應包(如果處于混雜模式)或忽略(如果不處于混雜模式),從而暴露其工作模式。當偽造的以太網數據幀中的IP位址設置為網路廣播位址時這個測試非常有效。
AntiSniff的使用者可以修改偽造的以太網址,缺省值為66:66:66:66:66:66。 NetBSD
許多NetBSD內核具有與上述Linux內核相同的特性,不過偽造以太網數據幀中的 IP位址必須設為廣播位址。
Windows 95/98/NT 根據對網路驅動程式頭文件的了解,可以知道當處于混雜模式時,Microsoft的作業系統會確切地檢查每個包的以太網位址。如果與網卡的以太網位址匹配,將作為目標IP位址為本機的數據包存放到相應堆棧中處理。可以被利用的一點是系統對以太網廣播包的分析。在正常情形下,例如機器工作在非混雜模式下,網卡只向系統內核傳輸那些目標以太網址與其匹配或為以太網廣播位址(ff:ff:ff:ff:ff:ff)的數據包。如果機器處于混雜模式下,網路驅動程式仍然會檢查每個數據包的以太網位址,但檢查是否為廣播包時卻只檢查頭8位位址是否為0xff。因此,為了使處于混雜模式的系統返回附應訊息,AntiSniff構造以太網位址為ff:00:00:00:00:00且含有正確目標IP
位址的數據包,當Microsoft的作業系統接收到這個數據包時,將根據網路驅動程式檢查到的細微差別而返回附應包(如果處于混雜模式)或丟棄這個數據包(如果處于非混雜模式)。 需要注意的是,這個檢查與使用的網路驅動程式有關。Microsoft缺省的網路驅動程式具有以上特性,大多數的廠商為了保持兼容性也繼承了這些特性。不過有些網卡會在其硬體層中檢查以太網位址的頭8位,所以可能會無論系統真正的狀態是什么都總是返回正值。關于這類網卡和驅動程式請訪問AntiSniff
ver 1.x的web網站。 ◆ dns 測試
進行DNS測試的原因是許多攻擊者使用的網路數據收集工具都對IP位址進行反向
dns解析,因為他們希望根據域名尋找更有價值的主機。例如joepc1.foo.bar對攻擊者的吸引力往往不如payroll.foo.bar這種商業域名。此時這些工具就由被動型網路工具變為主動型網路工具了。而不監聽網路通訊的機器不會試圖反向解析數據包中的
IP位址。為了利用這一點,AntiSniff Ver
1.x使自身處于混雜模式下,向網路發送虛假目標ip位址的數據包,然后監聽是否有機器發送該虛假目標ip位址的反向dns查詢。偽造數據包的以太網位址、檢查目標、虛假目標ip位址可由用戶定製。
◆ 網路和主機附應時間測試 這種測試已被証明是最有效的。它能夠發現網路中處于混雜模式的機器,而不管其作業系統是什么。警告,這個測試會在很短的時間內產生巨大的網路通訊流量。進行這種測試的理由是不處于混雜模式的網卡提供了一定的硬體底層過濾機製。也就是說,目標位址非本地(廣播位址除外)的數據包將被網卡的固件丟棄。在這種情況下,驟然增加、但目標位址不是本地的網路通訊流量對作業系統的影響只會很小。而處于混雜模式下的機器則缺乏此類底層的過濾,驟然增加、但目標位址不是本地的網路通訊流量會對該機器造成較明顯的影響(不同的作業系統/內核/用戶模式會有不同)。這些變化可以透過網路通訊流量工具監視到。
根據以上要點,antisniff ver 1.x 首先利用icmp
ECHO請求及附應計算出需要檢測機器的附應時間基準和平均值。在得到這個數據后,立刻向本地網路發送大量的偽造數據包。與此同時再次發送測試數據包以確定平均附應時間的變化值。非混雜模式的機器的附應時間變化量會很小,而混雜模式的機器的附應時間變化量則通常會有
1-4個數量級。為了對付攻擊者和入侵者們最常用的多種工具,AntiSniff進行了三種網路飽和度測試︰SIXTYSIX、TCPSYN和THREEWAY。
*
SIXTYSIX測試構造的數據包數據全為0x66。這些數據包不會被非混雜模式的機器接收,同時方便使用常見的網路監聽/分析工具(如tcpdump和snoop等)記錄和捕獲。
* TCPSYN測試構造的數據包包含有效的TCP頭和IP頭,同時TCP標志域的SYN位被設置。
*
THREEWAY測試采取的原理基本上與TCPSYN一樣,但更複雜些。在這種測試中兩個實際不存在的機器間多次建立完整的TCP三方握手通訊。它能夠更好地欺騙那些駭客工具。
antisniff ver 1.x
中能夠透過以上三種數據包測試發現正處于混雜模式機器的測試方法最好周期性地進行和與以前的數據比較。附應時間測試第一次營運的數據還能夠用于分析一個大型網路在flooding和非flooding狀態時的性能,並幫助工程師調整網路性能。一旦確信本地網路已營運在正常(沒有未經允許而處于混雜模式的機器)
狀態,就應該設置AntiSniff工具周期性營運。只要發現某台機器性能(附應時間)發生數量級的變化,一般就能確定其正處于混雜模式。這種方法不需比較兩台獨立系統間的性能數據,而只需比較同一台機器不同時候的數據就能確定該機器是否處于混雜模式。
八 結尾 本文旨在向你描述sniff的基本原理,為的是要使你不僅僅能夠了解什么是sniff而已,而是要明白sniff運轉的根本原理,文章參考了大量的資料,牽涉到直接引用的已經注明出處和作者,非常的感謝他們。在此還要感謝
w.richhard.stevens,雖然其人已逝,但留下的tcp/ip三卷本真是造福了大家,文章的很多地方也是拜他老人家指點迷經才得以感悟。最后還要感謝雀巢咖啡,讓我得以熬夜把這篇文章寫完,呵呵,謝謝大家。 *********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together!
希望能大家敞開心胸,將知識寶庫結合一起 發表人 - jackkcg 於 2003/02/19 19:25:35
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |