最近狂補基礎,猛看TCP/IP協議。不過,書上的東西太抽象了,沒有什麼資料執行個體,看了不 久就忘了。於是,搬來一個sniffer,抓了資料包來看,呵呵,結合書裡面得講解,理解得 比較快。我就來灌點基礎知識。 開始吧,先介紹IP協議。 IP協議(Internet Protocol)是網路層協議,用在網際網路上,TCP,UDP,ICMP,IGMP資料都是按照IP資料格式發送得。IP協議提供的是不可靠無串連得服 務。IP資料包由一個頭部和一個本文部分構成。本文主要是傳輸的資料,我們主要來理解頭部資料,可以從其理解到IP協議。 IP資料包頭部格式(RFC791) Example Internet Datagram Header 上面的就是IP資料的頭部格式,這裡大概地介紹一下。 IP頭部由20位元組的固定長度和一個可選任意長度部分構成,以大段點機次序傳送,從左到 右。 TCP協議 TCP協議(TRANSMISSION CONTROL PROTOCOL)是傳輸層協議,為應用程式層提供服務,和UDP不同的是,TCP協議提供的可靠的連線導向的服務。在RFC793中是基本的TCP描述。關於TCP協議的頭部格式內容的說明: TCP Header FORMat TCP Header FORMat 跟IP頭部差不多,基本的長度也是20位元組。TCP資料包是包含在一個IP資料報文中的。 好了,簡單介紹到此為止。來看看我捕獲的例子吧。這是一次FTP的串連,呵呵,是cuteftp預設的cuteftp的FTP網站,IP地址 是:216.3.226.21。我的IP地址假設為:192.168.1.1。下面的資料就是TCO/IP串連過程中的資料轉送。我們可以分析TCP /IP協議資料格式以及TCP/IP串連的三向交握(ThreeWay-Handshake)情況。下面的這些十六進位資料只是TCP/IP協議的資料, 不是完整的網路通訊資料。 第一次,我向FTP網站發送串連請求(我把TCP資料的可選部分去掉了) 192.168.1.1->216.3.226.21 IP頭部: 45 00 00 30 52 52 40 00 80 06 2c 23 c0 a8 01 01 d8 03 e2 15 TCP頭部:0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00 來看看IP頭部的資料是些什麼。 第一位元組,“45”,其中“4”是IP協議的版本(Version),說明是IP4。“5”是IHL位,表示IP頭部的長度,是一個4bit欄位,最大 就是1111了,值為12,IP頭部的最大長度就是60位元組。而這裡為“5”,說明是20位元組,這是標準的IP頭部長度,頭部報文中沒有發送可選部分數 據。 接下來的一個位元組“00”是服務類型(Type of Service)。這個8bit欄位由3bit的優先權子欄位(現在已經被忽略),4 bit的TOS子欄位以及1 bit的未用欄位(現在為0)構成.4 bit的TOS子欄位包含:最小延時、最大輸送量、最高可靠性以及最小費用構成,這四個1bit位最多隻能有一個為1,本例中都為0,表示是一般服務。 接著的兩個位元組“00 30”是IP資料報文總長,包含頭部以及資料,這裡表示48位元組。這48位元組由20位元組的IP頭部以及28位元組的TCP頭構成(本來截取的TCP頭應該是 28位元組的,其中8位元組為可選部分,被我省去了)。因此目前最大的IP資料包長度是65535位元組。 再是兩個位元組的標誌位(Identification):“5252”,轉換為十進位就是21074。這個是讓目的主機來判斷新來的分段屬於哪個分組。 下一個位元組“40”,轉換為二進位就是“0100 0000”,其中第一位是IP協議目前沒有用上的,為0。接著的是兩個標誌DF和MF。DF為1表示不要分段,MF為1表示還有進一步的分段(本例為 0)。然後的“0 0000”是分段便移(Fragment Offset)。 “80”這個位元組就是 TTL(Time To Live)了,表示一個IP資料流的生命週期,用Ping顯示的結果,能得到TTL的值,很多文章就說通過TTL位來判別主控件類型。因為一般主機都有預設 的TTL值,不同系統的預設值不一樣。比如WINDOWS為128。不過,一般Ping得到的都不是預設值,這是因為每次IP資料包經過一個路由器的時候 TTL就減一,當減到0時,這個資料包就消亡了。這也時Tracert的原理。本例中為“80”,轉換為十進位就是128了,我用的WIN2000。 繼續下來的是“06”,這個位元組表示傳輸層的協議類型(Protocol)。在RFC790中有定義,6表示傳輸層是TCP協議。 “2c 23”這個16bit是頭校正和(Header Checksum)。 接下來“c0 a8 01 01”,這個就是源地址(Source Address)了,也就是我的IP地址。 轉換為十進位的IP地址就是:192.168.1.1,同樣,繼續下來的32位“d8 03 e2 15”是目標地址,216.3.226.21 好了,真累啊,終於看完基本的20位元組的IP資料前序了。繼續看TCP的頭部吧,這個是作為IP資料包的資料部分傳輸的。 TCP頭部:0d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00 一來就是一個兩位元組段“0d 28”,表示本地連接埠號碼,轉換為十進位就是3368。第二個兩位元組段“00 15”表示目標連接埠,因為我是串連FTP網站,所以,這個就是21啦,十六進位當然就是“00 15”。 接下來的四個位元組“50 5f a9 06”是順序號(Sequence Number),簡寫為SEQ,SEQ=1348446470下面的四個位元組“00 00 00 00”是確認號(Acknowledgment Number),簡寫為ACKNUM。 繼續兩個位元組,“70 02”,轉換為二進位吧,“0111 0000 0000 0010”。這兩個位元組,總共16bit,有好多東西呢。第一個4bit“0111”,是TCP頭長,十進位為7,表示28個位元組(剛才說了,我省略了8 位元組的option資料,所以你只看見了20位元組)。接著的6bit現在TCP協議沒有用上,都為0。最後的6bit“00 0010”是六個重要的標誌。這是兩個電腦資料交流的資訊標誌。接收和發送斷根據這些標誌來確定資訊流的種類。下面是一些介紹: URG:(Urgent Pointer field significant)緊急指標。用到的時候值為1,用來處理避免TCP資料流中斷 ACK:(Acknowledgment fieldsignificant)置1時表示確認號(AcknowledgmentNumber)為合法,為0的時候表示資料區段不包含確認資訊,確認號被忽略。 PSH:(Push Function),PUSH標誌的資料,置1時請求的資料區段在接收方得到後就可直接送到應用程式,而不必等到緩衝區滿時才傳送。 RST:(Reset the connection)用於複位因某種原因引起出現的錯誤串連,也用來拒絕非法資料和請求。如果接收到RST位時候,通常發生了某些錯誤。 SYN:(Synchronize sequence numbers)用來建立串連,在串連請求中,SYN=1,ACK=0,串連響應時,SYN=1,ACK=1。即,SYN和ACK來區分 Connection Request和Connection Accepted。 FIN:(No more data from sender)用來釋放串連,表明發送方已經沒有資料發送了。 這6個標誌位,你們自己對號入座吧。本例中SYN=1,ACK=0,當然就是表示串連請求了。我們可以注意下面兩個過程的這兩位的變換。 後面的“40 00 c0 29 00 00”不講了,呵呵,偷懶了。後面兩次通訊的資料,自己分開看吧。我們看看串連的過程,一些重要地方的變化。 第二次,FTP網站返回一個可以串連的訊號。 216.3.226.21->192.168.1.1 IP頭部: 45 00 00 2c c6 be 40 00 6a 06 cd ba d8 03 e2 15 c0 a8 01 01 TCP頭部:00 15 0d 28 4b 4f 45 c1 50 5f a9 07 60 12 20 58 64 07 00 00 第三次,我確認串連。TCP串連建立起來。 192.168.1.1->216.3.226.21 IP頭部: 45 00 00 28 52 53 40 00 80 06 2c 2a c0 a8 01 01 d8 03 e2 15 TCP頭部:0d 28 00 15 50 5f a9 07 4b 4f 45 c2 50 10 40 b0 5b 1c 00 00 好,我們看看整個Threeway_handshake過程。 第一步,我發出串連請求,TCP資料為:SEQ=50 5f a9 06,ACKNUM=00 00 00 00,SYN=1,ACK=0。 第二步,對方確認可以串連,TCP資料為:SEQ=4b 4f 45 c1,ACKNUM=50 5f a9 07,SYN=1,ACK=1。 第三步,我確認建立串連。SEQ=50 5f a9 07, ACKNUM=4b 4f45c2,SYN=0,ACK=1。 可以看出什麼變化嗎?正式建立串連了呢,這些東西是什麼值? 我接收從216.3.226.21->192.168.1.1的下一個資料包中: SEQ=4b 4f 45 c2,ACKNUM=50 5f a9 07,SYN=0,ACK=1這些都是很基礎的東西,對於編寫sniffer這樣的東西是必須非常熟悉的。這裡只講解了TCP/IP協議的一點點東西,主要是頭部資料的格式。(T002) |