背景介紹:
通過一個issue引出:waf在向業務服務器轉發流量的時候,可以自定義添加http請求頭部字段;在向客戶端轉發流量時,可以自定義添加http響應頭部字段。
如何去驗證???
感覺tcpdump+Wireshark這種搭配,就目前看來,非常完美。
所有的網絡傳輸在這兩個工具搭配下,都無處遁形。
正文:
1、tcpdump與Wireshark介紹
在網絡問題的調試中,tcpdump應該說是一個必不可少的工具,和大部分linux下優秀工具一樣,它的特點就是簡單而強大。它是基於Unix系統的命令行式的數據包嗅探工具,可以抓取流動在網卡上的數據包。
默認情況下,tcpdump不會抓取本機內部通訊的報文。根據網絡協議棧的規定,對於報文,即使是目的地是本機,也需要經過本機的網絡協議層,所以本機通訊肯定是通過API進入了內核,並且完成了路由選擇。【比如本機的TCP通信,也必須要socket通信的基本要素:src ip port dst ip port】
如果要使用tcpdump抓取其他主機MAC地址的數據包,必須開啟網卡混雜模式,所謂混雜模式,用最簡單的語言就是讓網卡抓取任何經過它的數據包,不管這個數據包是不是發給它或者是它發出的。一般而言,Unix不會讓普通用戶設置混雜模式,因為這樣可以看到別人的信息,比如telnet的用戶名和密碼,這樣會引起一些安全上的問題,所以只有root用戶可以開啟混雜模式,開啟混雜模式的命令是:ifconfig en0 promisc, en0是你要打開混雜模式的網卡。
Linux抓包原理:
Linux抓包是通過注冊一種虛擬的底層網絡協議來完成對網絡報文(准確的說是網絡設備)消息的處理權。當網卡接收到一個網絡報文之后,它會遍歷系統中所有已經注冊的網絡協議,例如以太網協議、x25協議處理模塊來嘗試進行報文的解析處理,這一點和一些文件系統的掛載相似,就是讓系統中所有的已經注冊的文件系統來進行嘗試掛載,如果哪一個認為自己可以處理,那么就完成掛載。
當抓包模塊把自己偽裝成一個網絡協議的時候,系統在收到報文的時候就會給這個偽協議一次機會,讓它來對網卡收到的報文進行一次處理,此時該模塊就會趁機對報文進行窺探,也就是把這個報文完完整整的復制一份,假裝是自己接收到的報文,匯報給抓包模塊。
Wireshark介紹:
Wireshark是一個網絡協議檢測工具,支持Windows平台、Unix平台、Mac平台,一般只在圖形界面平台下使用Wireshark,如果是Linux的話,直接使用tcpdump了,因為一般而言Linux都自帶的tcpdump,或者用tcpdump抓包以后用Wireshark打開分析。在Mac平台下,Wireshark通過WinPcap進行抓包,封裝的很好,使用起來很方便,可以很容易的制定抓包過濾器或者顯示過濾器。
綜上所述:tcpdump是用來抓取數據非常方便,Wireshark則是用於分析抓取到的數據比較方便。
語法
tcpdump(選項)
選項
-a:嘗試將網絡和廣播地址轉換成名稱; -c<數據包數目>:收到指定的數據包數目后,就停止進行傾倒操作; -d:把編譯過的數據包編碼轉換成可閱讀的格式,並傾倒到標准輸出; -dd:把編譯過的數據包編碼轉換成C語言的格式,並傾倒到標准輸出; -ddd:把編譯過的數據包編碼轉換成十進制數字的格式,並傾倒到標准輸出; -e:在每列傾倒資料上顯示連接層級的文件頭; -f:用數字顯示網際網絡地址; -F<表達文件>:指定內含表達方式的文件; -i<網絡界面>:使用指定的網絡截面送出數據包; -l:使用標准輸出列的緩沖區; -n:不把主機的網絡地址轉換成名字; -N:不列出域名; -O:不將數據包編碼最佳化; -p:不讓網絡界面進入混雜模式; -q :快速輸出,僅列出少數的傳輸協議信息; -r<數據包文件>:從指定的文件讀取數據包數據; -s<數據包大小>:設置每個數據包的大小; -S:用絕對而非相對數值列出TCP關聯數; -t:在每列傾倒資料上不顯示時間戳記; -tt: 在每列傾倒資料上顯示未經格式化的時間戳記; -T<數據包類型>:強制將表達方式所指定的數據包轉譯成設置的數據包類型; -v:詳細顯示指令執行過程; -vv:更詳細顯示指令執行過程; -x:用十六進制字碼列出數據包資料; -w<數據包文件>:把數據包數據寫入指定的文件。
實例
1、直接啟動tcpdump將監視第一個網絡接口上所有流過的數據包
tcpdump
2、監視指定網絡接口的數據包
tcpdump -i eth0
如果不指定網卡,默認tcpdump只會監視第一個網絡接口,一般是eth0,下面的例子都沒有指定網絡接口。
3、監視指定主機的數據包
# 打印所有進入或離開sundown的數據包。 tcpdump host sundown # 也可以指定ip,例如截獲所有210.27.48.1 的主機收到的和發出的所有的數據包 tcpdump host 210.27.48.1 # 打印helios 與 hot 或者與 ace 之間通信的數據包 tcpdump host helios and \( hot or ace \) # 截獲主機210.27.48.1 和主機210.27.48.2 或210.27.48.3的通信 tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \) # 打印ace與任何其他主機之間通信的IP 數據包, 但不包括與helios之間的數據包. tcpdump ip host ace and not helios # 如果想要獲取主機210.27.48.1除了和主機210.27.48.2之外所有主機通信的ip包,使用命令: tcpdump ip host 210.27.48.1 and ! 210.27.48.2 # 抓取eth0網卡上的包,使用: sudo tcpdump -i eth0 # 截獲主機hostname發送的所有數據 tcpdump -i eth0 src host hostname # 監視所有送到主機hostname的數據包 tcpdump -i eth0 dst host hostname
4、監視指定主機和端口的數據包
# 如果想要獲取主機210.27.48.1接收或發出的telnet包,使用如下命令 tcpdump tcp port 23 and host 210.27.48.1 # 對本機的udp 123 端口進行監視 123 為ntp的服務端口 tcpdump udp port 123
5、監視指定網絡的數據包
# 打印本地主機與Berkeley網絡上的主機之間的所有通信數據包 tcpdump net ucb-ether # ucb-ether此處可理解為“Berkeley網絡”的網絡地址,此表達式最原始的含義可表達為:打印網絡地址為ucb-ether的所有數據包 ----------------------------------------------------------- #打印所有通過網關snup的ftp數據包 tcpdump 'gateway snup and (port ftp or ftp-data)' # 注意:表達式被單引號括起來了,這可以防止shell對其中的括號進行錯誤解析 ----------------------------------------------------------- # 打印所有源地址或目標地址是本地主機的IP數據包 tcpdump ip and not net localnet # 如果本地網絡通過網關連到了另一網絡,則另一網絡並不能算作本地網絡。 # 抓取80端口的HTTP報文,以文本形式展示: sudo tcpdump -i any port 80 -A
暫時就介紹上面這幾種常用的,更多的使用方法,自己去google。
----------------------------------------華-麗-分-割-線----------------------------------------
下面就issue中的需求,來舉個實際工作中抓包分析的例子。
首先通過tcpdump抓取未添加http請求頭前的報文
tcpdump -i eth2 -X -e -w test.cap
我習慣性把抓包結果(當然tcpdump搭配一定參數,直接在服務器上看http報文,也是可以的)保存成cap或者pcap文件,然后通過Wireshark分析查看.
將test.cap通過Wireshark打開,查看http報文部分的具體內容。
由上可知,未篡改http請求頭部內容時,默認是沒有Content-Type這行參數的。
接下來我通過waf在向業務服務器轉發流量的時候,自定義添加http請求頭部字段(這里拿Content-Type舉例)。
篡改http請求頭部內容后,再次抓包分析:
由上圖可知,驗證成功。