什么是抓包?
簡單說抓包就是截取網絡中傳輸的數據包,然后對數據包進行重發、編輯、轉存等操作。在此基礎上可以對數據包進行安全分析安全檢查等等,如果數據不安全,則可能被利用。
Fiddler的介紹
fiddler是常用的抓包工具之一。當瀏覽器訪問服務器會形成一個請求,此時,fiddler就相當於一個中間商,當瀏覽器發送請求,會先經過fiddler,然后在轉給服務器;當服務器有返回數據給瀏覽器顯示時,也會先經過fiddler,然后再把數據返滬給客戶端,在這樣一個過程,fiddler就可以截取請求和響應。主要用來截取http和https請求。
1、 查看fiddler的界面,講解說明
接下來我們實際操作下看看fiddler的界面
主要分為六塊地方:
l 第一塊區域是設置菜單
l 第二塊區域是一些工具菜單,點下就能看到對應的功能
l 第三塊左邊是抓捕的請求會話列表,這里的會話指一次請求
l 四塊右邊上方區域是request請求的詳細信息,可以查看Headers、Cookies、Raw、JSON等
l 第五塊右邊下方區域就是response信息,可以查看服務端返回的json數據或其它信息
l 第六塊區域左下角黑色的那塊小地方,雖然很不起眼,容易被忽略掉,這地方是命令行模式,可以輸入簡單的指令如:cls,執行清屏的作用等
常用頁標簽工具欄
看看右側的標簽頁,通過Statistic可以看到請求和響應的字節數,以及時間消耗信息等等
Inspeactors檢查標簽,它提供headers、textview、hexview,Raw等多種方式查看單條http請求的請求報文的信息,它分為上下兩部分:上部分為HTTP Request(請求)展示,下部分為HTTPResponse(響應)展示。
Auto Response自動響應標簽,我覺得這個對前端用處更大些,它可以對服務端返回的數據進行修改,方便我們調試。
Composer標簽
它跟我們熟悉的postman非常一樣。支持手動構建和發送請求, 我們還可以從web session列表中拖曳session, 把它放到composer選項卡中, 當我們點擊Execute按鈕, 就可以把請求發送到服務器端。
Filters過濾標簽
過濾器可以對左側的數據流列表進行過濾, 我們可以標記、 修改或隱藏某些特征的數據流。
Fiddler命令行工具
1、 命令行清空
2、 命令行篩選
3、 打斷點等等
打斷點
斷點的兩種方式
Bpu
Bpafter
全局斷點
單個斷點
攔截網站的所有請求
其他命令
https://docs.telerik.com/fiddler/knowledge-base/quickexec
當然,我這里只是列舉了比較基礎常用的功能,還有更多的功能值得大家有興趣去學習下,接下來我們看看wireshark工具。
Wireshark
Wireshark跟fiddler的主要區別就是,Wireshark主要用來幫助用戶對網絡行為有一個了解,而不能對網絡內容做更改或是提示,也就是說只能查看不能修改或轉發。
三次握手、四次揮手
在講之前,我們先回顧下上學時學過的三次握手、四次揮手。
小寫的ack代表的是頭部的確認號Acknowledge number, 縮寫ack,是對上一個包的序號進行確認的號,ack=seq+1。
大寫的ACK,則是我們上面說的TCP首部的標志位,用於標志的TCP包是否對上一個包進行了確認操作,如果確認了,則把ACK標志位設置成1。
標志位(Flags):共 6 個,即 URG、ACK、PSH、RST、SYN、FIN 等。
六個標志位具體含義如下:
SYN:簡寫為S,同步標志位,用於建立會話連接,同步序列號;
ACK:簡寫為.,確認標志位,對已接收的數據包進行確認;
FIN:簡寫為F,完成標志位,表示我已經沒有數據要發送了,即將關閉連接;
PSH:簡寫為P,推送標志位,表示該數據包被對方接收后應立即交給上層應用,而不在緩沖區排隊;
RST:簡寫為R,重置標志位,用於連接復位、拒絕錯誤和非法的數據包;
URG:簡寫為U,緊急標志位,表示數據包的緊急指針域有效,用來保證連接不被阻斷,並督促中間設備盡快處理;
需要注意的是:
- 不要將確認序號 Ack 與標志位中的 ACK 搞混了。
- 確認方 Ack=發起方 Seq+1,兩端配對。
為什么需要三次握手?
我們假設client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。
假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。
所以,采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。
TCP 三次握手跟現實生活中的人與人打電話是很類似的:
- 三次握手:
- “喂,你聽得到嗎?”
- “我聽得到呀,你聽得到我嗎?”
- “我能聽到你,今天 balabala……“
經過三次的互相確認,大家就會認為對方對聽的到自己說話,並且願意下一步溝通,否則,對話就不一定能正常下去了。
揮手請求可以是Client端,也可以是Server端發起的,我們假設是Client端發起:
第一次揮手: Client端發起揮手請求,向Server端發送標志位是FIN報文段,設置序列號seq,此時,Client端進入FIN_WAIT_1狀態,這表示Client端沒有數據要發送給Server端了。
第二次揮手:Server端收到了Client端發送的FIN報文段,向Client端返回一個標志位是ACK的報文段,ack設為seq加1,Client端進入FIN_WAIT_2狀態,Server端告訴Client端,我確認並同意你的關閉請求。
第三次揮手: Server端向Client端發送標志位是FIN的報文段,請求關閉連接,同時Client端進入LAST_ACK狀態。
第四次揮手 : Client端收到Server端發送的FIN報文段,向Server端發送標志位是ACK的報文段,然后Client端進入TIME_WAIT狀態。Server端收到Client端的ACK報文段以后,就關閉連接。此時,Client端等待2MSL的時間后依然沒有收到回復,則證明Server端已正常關閉,那好,Client端也可以關閉連接了。
為什么連接的時候是三次握手,關閉的時候卻是四次揮手?
建立連接時因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。所以建立連接只需要三次握手。
由於TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議,TCP是全雙工模式。這就意味着,關閉連接時,當Client端發出FIN報文段時,只是表示Client端告訴Server端數據已經發送完畢了。當Server端收到FIN報文並返回ACK報文段,表示它已經知道Client端沒有數據發送了,但是Server端還是可以發送數據到Client端的,所以Server很可能並不會立即關閉SOCKET,直到Server端把數據也發送完畢。當Server端也發送了FIN報文段時,這個時候就表示Server端也沒有數據要發送了,就會告訴Client端,我也沒有數據要發送了,之后彼此就會愉快的中斷這次TCP連接。
為什么要等待2MSL?
MSL:報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間。有以下兩個原因:
第一點:保證TCP協議的全雙工連接能夠可靠關閉:
由於IP協議的不可靠性或者是其它網絡原因,導致了Server端沒有收到Client端的ACK報文,那么Server端就會在超時之后重新發送FIN,如果此時Client端的連接已經關閉處於CLOESD狀態,那么重發的FIN就找不到對應的連接了,從而導致連接錯亂,所以,Client端發送完最后的ACK不能直接進入CLOSED狀態,而要保持TIME_WAIT,當再次收到FIN的時候,能夠保證對方收到ACK,最后正確關閉連接。
第二點:保證這次連接的重復數據段從網絡中消失
如果Client端發送最后的ACK直接進入CLOSED狀態,然后又再向Server端發起一個新連接,這時不能保證新連接的與剛關閉的連接的端口號是不同的,也就是新連接和老連接的端口號可能一樣了,那么就可能出現問題:如果前一次的連接某些數據滯留在網絡中,這些延遲數據在建立新連接后到達Client端,由於新老連接的端口號和IP都一樣,TCP協議就認為延遲數據是屬於新連接的,新連接就會接收到臟數據,這樣就會導致數據包混亂。所以TCP連接需要在TIME_WAIT狀態等待2倍MSL,才能保證本次連接的所有數據在網絡中消失。
實際演示
接下來我們用wireshark來看看理論是不是符合實際情況。
我們打開wireshark分析,然后我篩選了ip地址跟端口號,得到了如圖數據,這個其實就是一條完整的請求。我們可以很清楚的看到網絡七層協議中的四層,如果是http請求的話,還會出現一層應用層的信息。
經過數據的攔截我們看看前三條數據,跟后四條數據。
首先是三次握手
首先是發送端發送給服務端,一個SYN同步標志,以及一個隨機的序列號
然后服務端接收到了,將發送端的序列號加1變成確認號,然后將自己的序列號,確認號,以及大寫的ACK確認標志位發回給客戶端
客戶端接收到了,又將服務端的序列號加1,變為自己的確認號,然后將確認號,序列號,確認標志位置1,發給服務端,至此就完成了三次握手的過程。
然后是四次揮手過程
服務端收到后,首先將確認位置1,ack=seq+1,以及一個隨機的序列號發回給發起端
然后再發揮一個FIN標志位,ack確認號,ACK確認位,序列號,發回去,表示我也要結束了
最后發起端確認收到,再發回一個確認位給到服務端,同時等待兩個生存時間就自動關閉連接,然后四次揮手就結束了。