某學生粉絲發來問題:
這個題目一看就知道這位同學是網絡安全相關專業。
很多粉絲以為彭老師知識搞驅動的,
(資料圖片僅供參考)
但是其實作為一個擁有多篇網絡協議專利的老鳥,
網絡知識還是比較擅長的!
應用層套接字、組網、網卡驅動都有所涉獵,
目前還缺Linux內核協議棧這塊沒深入研究,后期會補上。
一、題目總結題目要求是掃描所有TCP半連接的端口,需要實現的功能如下:
攻擊方啟動任務1,循環向指定服務器端+端口發送SYN數據包,(端口從0開始遞增)如果該服務器上有服務打開了這個端口,就會回復SYN+ACK,此時服務端進入SYN_RCVD狀態,攻擊方啟動任務2,掃描收到的所有SYN+ACK數據包,如果客戶端收到SYN+ACK,那么說明服務器改端口打開,任務2就可以將所有打開的端口信息打印出來任務1使用socket API任務2使用pcap庫二、TCP基礎知識點解決這個問題必須掌握以下幾個知識點:
什么是TCPTCP3次握手什么是半連接TCP、IP協議頭如何使用Libpcap庫線程、進程整體來說對網絡知識的基本功要求還是很高的。關于TCP/IP協議棧這些基礎知識點的本文就不列舉了。
下面主要強化下這個題目涉及的TCP的知識點。
1.TCP首先就是我們必須了解TCP協議頭:
序列號:在建立連接時由計算機生成的隨機數作為其初始值,通過 SYN 包傳給接收端主機,每發送一次數據,就「累加」一次該「數據字節數」的大小。用來解決網絡包亂序問題確認應答號:指下一次「期望」收到的數據的序列號,發送端收到這個確認應答以后可以認為在這個序號以前的數據都已經被正常接收。用來解決不丟包的問題控制位:ACK:該位為 1 時,「確認應答」的字段變為有效,TCP 規定除了最初建立連接時的 SYN 包之外該位必須設置為 1 RST:該位為 1 時,表示 TCP 連接中出現異常必須強制斷開連接 SYN:該位為 1 時,表示希望建立連接,并在其「序列號」的字段進行序列號初始值的設定 FIN:該位為 1 時,表示今后不會再有數據發送,希望斷開連接。當通信結束希望斷開連接時,通信雙方的主機之間就可以相互交換 FIN 位置為 1 的 TCP 段與本題目相關的是最主要字段是控制位,控制位的操作最主要體現在3次握手和4次握手。
2. tcp三次握手開始客戶端和服務器都處于CLOSED狀態,然后服務端開始監聽某個端口,進入LISTEN狀態:
第一次握手(SYN=1, seq=x),發送完畢后,客戶端進入 SYN_SENT 狀態第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1), 發送完畢后,服務器端進入 SYN_RCVD 狀態第三次握手(ACK=1,ACKnum=y+1),發送完畢后,客戶端進入 ESTABLISHED 狀態,當服務器端接收到這個包時,也進入 ESTABLISHED 狀態,TCP 握手,即可以開始數據傳輸3. tcp四次揮手四次揮手過程:
客戶端打算關閉連接,此時會發送一個 TCP 首部 FIN 標志位被置為 1 的報文,也即 FIN 報文,之后客戶端進入 FIN_WAIT_1 狀態服務端收到該報文后,就向客戶端發送 ACK 應答報文,接著服務端進入 CLOSED_WAIT 狀態客戶端收到服務端的 ACK 應答報文后,之后進入 FIN_WAIT_2 狀態等待服務端處理完數據后,也向客戶端發送 FIN 報文,之后服務端進入 LAST_ACK 狀態客戶端收到服務端的 FIN 報文后,回一個 ACK 應答報文,之后進入 TIME_WAIT 狀態服務器收到了 ACK 應答報文后,就進入了 CLOSE 狀態,至此服務端已經完成連接的關閉客戶端在經過 2MSL 一段時間后,自動進入 CLOSE 狀態,至此客戶端也完成連接的關閉4.TCP狀態TCP協議狀態遷移圖如下:
CLOSED:表示初始狀態LISTEN:表示服務器端的某個SOCKET處于監聽狀態,可以接受連接了SYN_RCVD:表示接收到了SYN報文SYN_SENT:表示客戶端已發送SYN報文ESTABLISHED:表示連接已經建立了TIME_WAIT:表示收到了對方的FIN報文,并發送出了ACK報文,就等2MSL后即可回到CLOSED可用狀態了CLOSING:表示你發送FIN報文后,并沒有收到對方的ACK報文,反而卻也收到了對方的FIN報文。如果雙方幾乎在同時* close一個SOCKET的話,那么就出現了雙方同時發送FIN報 文的情況,也即會出現CLOSING狀態,表示雙方都正在關閉SOCKET連接CLOSE_WAIT:表示在等待關閉5. 半連接/全連接TCP半連接及全連接狀態,在服務器的性能分析中,起著重要的作用,它通常是反應服務端的處理能力
1)半連接隊列(syn queue)客戶端發送SYN包,服務端收到后回復SYN+ACK后,服務端進入SYN_RCVD狀態,這個時候的socket會放到半連接隊列。
2)全連接隊列(accept queue)當服務端收到客戶端的ACK后,socket會從半連接隊列移出到全連接隊列。當調用accpet函數的時候,會從全連接隊列的頭部返回可用socket給用戶進程。
全連接隊列中存放的是已完成TCP三次握手的過程,等待被處理的連接,在客戶端及服務端的狀態均為 ESTABLISHED
三、 抓包舉例要想學好網絡,抓包工具是必須掌握的。
下圖是一口君通過抓包工具抓取的一個完整的 tcp3次握手 + HTTP GET請求 + 4次握手的完整通信數據包。
https://www.bilibili.com/video/BV1xr4y1T7cT/?vd_source=07570058a62e0e8a6cf489efac35cfec
四、 socket關于socket API內容,大家可以的參考下面這篇文章《??socket到底是什么???》
五、libpcaplibpcap是一個網絡數據包捕獲函數庫,功能非常強大,Linux下著名的tcpdump就是以它為基礎的。
libpcap主要由兩部分組成:網絡分接頭(network tap)和數據過濾器(packet filter)。
網絡分接頭從網絡設備驅動程序中收集數據進行拷貝,過濾器決定是否接收該數據包。
libpcap利用BSD packet filter(BPF)算法對網卡接收到的鏈路層數據包進行過濾。
libpcap的包捕獲機制就是在數據鏈路層加一個旁路處理。當一個數據包到達網絡接口時,libpcap首先利用已經創建的套接字從鏈路層驅動程序中獲得該數據包的拷貝,再通過Tap函數將數據包發給BPF過濾器。
BPF過濾器根據用戶已經定義好的過濾規則對數據包進行逐一匹配,匹配成功則放入內核緩沖區,并傳遞給用戶緩沖區,匹配失敗則直接丟棄。
如果沒有設置過濾規則,所有數據包都將放入內核緩沖區,并傳遞給用戶層緩沖區。
1. libpcap安裝在線安裝sudo apt-get install libpcap-dev
這種適合有網絡的朋友
如何無法安裝嘗試更新下源:
sudo apt-get update
離線編譯安裝http://www.tcpdump.org/#latest-release
然后解壓tar zxvf libpcap-1.10.3.tar.gz cd libpcap-1.10.3./configuresudo makesudo make install
2. Libpcap的抓包流程:查找網絡設備:目的是發現可用的網卡,實現的函數為pcap_lookupdev(),如果當前有多個網卡,函數就會返回一個網絡設備名的指針列表。打開網絡設備:利用上一步中的返回值,可以決定使用哪個網卡,通過函數pcap_open_live()打開網卡,返回用于捕捉網絡數據包的秒數字。獲得網絡參數:這里是利用函數pcap_lookupnet(),可以獲得指定網絡設備的IP地址和子網掩碼。編譯過濾策略:Lipcap的主要功能就是提供數據包的過濾,函數pcap_compile()來實現。設置過濾器:在上一步的基礎上利用pcap_setfilter()函數來設置。利用回調函數,捕獲數據包:函數pcap_loop()和pcap_dispatch()來抓去數據包,也可以利用函數pcap_next()和pcap_next_ex()來完成同樣的工作。關閉網絡設備:pcap_close()函數關系設備,釋放資源。3. 數據結構說明:struct pcap_pkthdr { struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* 抓到的數據包實際長度 */ bpf_u_int32 len; /*數據包的長度 */};
4. libcap庫函數關于libcap的詳細講解,后續會出文章,
本文只講幾個重要的函數。
打開網絡接口//這個函數會返回指定接口的pcap_t類型指針,后面的所有操作都要使用這個指針。pcap_t * pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)device:網絡接口字符串,可以直接使用硬編碼,比如eth0。snaplen:對于每個數據包,從開頭要抓多少個字節,我們可以設置這個值來只抓每個數據包的頭部,而不關心具體的內容。典型的以太網幀長度是1518字節,但其他的某些協議的數據包會更長一點,但任何一個協議的一個數據包長度都必然小于65535個字節。promisc:指定是否打開混雜模式(Promiscuous Mode),0表示非混雜模式,任何其他值表示混合模式。如果要打開混雜模式,那么網卡必須也要打開混雜模式,可以使用如下的命令打開eth0混雜模式:ifconfig eth0 to_ms:抓包時長單位為毫秒,0標示一直等待。errbuf: 輸出參數,打開網絡接口失敗原因。
打開離線的pcap文件pcap_t * pcap_open_offline (const char *fname, char *errbuf)fname :文件名稱。errbuf :打開失敗的錯誤信息。
抓包函數int pcap_loop(pcap_t * p, int cnt, pcap_handler callback, u_char * user)p: 打開的pcap_t類型指針。cnt:一共抓多少個包,如果為負數就一直循環。callback:回調函數指針user:傳遞給回調函數的參數。
void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)userarg:是pcap_loop的最后一個參數,當收到足夠數量的包后pcap_loop會調用callback回調函數,同時將pcap_loop()的user參數傳遞給它pkthdr: 抓到的報文頭信息。packet:收到的包的數據。
過濾函數編譯int pcap_compile(pcap_t * p, struct bpf_program * fp, char * str, int optimize, bpf_u_int32 netmask)//fp:這是一個傳出參數,存放編譯后的bpf//str:過濾表達式//optimize:是否需要優化過濾表達式//metmask:簡單設置為0即可
設置過濾函數int pcap_setfilter(pcap_t * p, struct bpf_program * fp)//參數fp就是pcap_compile()的第二個參數,存放編譯后的bpf
釋放網絡接口void pcap_close(pcap_t * p)//該函數用于關閉pcap_open_live()獲取的pcap_t的網絡接口對象并釋放相關資源。
打開網絡包保存文件pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname) //p:是我們已經打開的網絡設備,從這個設備接收數據包。 // fname:是我們要寫入的文件名,隨便起。 //return: 如果出錯,會返回NULL??梢越璐藱z查這個文件有沒有打開。
將網絡包寫入文件void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)user:就是文件描述符dumpfp,只不過要做一下類型轉換。由于這個函數一般在pcap_loop()的函數指針所指向的packet_handler中使用,所以packet_handler中的user就是這里的user。 h:就是pkt_header
網絡包文件關閉pcap_dump_close(pcap_dumper_t * t);
5. libcap過濾規則一些過濾表達式的例子如下:
只接收源ip地址是192.168.1.177的數據包src host 192.168.1.177
只接收tcp/udp的目的端口是80的數據包dst port 80
只接收不使用tcp協議的數據包not tcp
只接收SYN標志位置位且目標端口是22或23的數據包(tcp首部開始的第13個字節)tcp[13] == 0x02 and (dst port 22 or dst port 23)
只接收icmp的ping請求和ping響應的數據包icmp[icmptype] == icmp-echoreply or icmp[icmptype] == icmp-echo
只接收以太網mac地址是00:e0:09:c1:0e:82的數據包ether dst 00:e0:09:c1:0e:82
只接收ip的ttl=5的數據包(ip首部開始的第8個字節)
ip[8] == 5
本例只抓取ip地址為本地IP的數據包,然后程序再對數據包協議頭進行解析:
host 192.168.0.113
六、設計方案實現原理:atach、cap進程運行在ubuntu中,要攻擊的目的終端可以使網絡中任意設備,只需要能ping通即可。本例在windows上測試,采用橋接模式將ubuntu的網口和windows的網口橋接起來。
atach進程主要功能:
創建tcp套接字設置需要攻擊的終端的ip+port,然后執行connect函數connect成功,說明對方該端口可以使用修改port值,重復前面3個步驟cap進程主要功能:
通過eth0,抓取指定規則:host 192.168.0.116數據包解析出以太頭、tcp頭,ip頭、tcp頭,判斷tcp頭中sync+ack位為1的所有數據包打印出步驟2過濾出來的數據包代碼流程:七、測試1. 環境:windows ip:192.168.0.116ubuntu ip:192.168.0.113
2. 文件:peng@ubuntu:~/work/test/pcap$ lsatach header.c libpcap-1.10.3.tar.gz cap.ccap libpcap-1.10.3 atach.c protocol.h
其中atach是上攻擊方,用于向指定ip發送sync包 cap 用于檢測所有網卡收到的sync+ack數據包 程序運行在ubuntu中。
3. 啟動網絡調試助手在windows上啟動網絡調試助手,
建立幾個Tcp Server,端口號分別為55、56、57
在這里插入圖片描述
4. 啟動程序1)首先啟動cappeng@ubuntu:~/work/test/pcap$ sudo ./cap 192.168.0.116found device: eth0netaddr:0000a8c0try to open device eth0filter:host 192.168.0.116
2)啟動攻擊程序atach需要新開啟一個終端。
peng@ubuntu:~/work/test/pcap$ ./atach 192.168.0.116
5. 運行截圖如下:右邊log可見,列舉出了所有可以訪問的端口,包括55、56、57。
注意:那個單詞atach故意少了一個t,否則編譯不過去:
大家可以試試你們的編譯器,刑不刑!
八、代碼代碼已經同步到gitee,地址如下:
https://gitee.com/yikoulinux/pcap.git
關鍵詞:
X 關閉
X 關閉
- 15G資費不大降!三大運營商誰提供的5G網速最快?中國信通院給出答案
- 2聯想拯救者Y70發布最新預告:售價2970元起 迄今最便宜的驍龍8+旗艦
- 3亞馬遜開始大規模推廣掌紋支付技術 顧客可使用“揮手付”結賬
- 4現代和起亞上半年出口20萬輛新能源汽車同比增長30.6%
- 5如何讓居民5分鐘使用到各種設施?沙特“線性城市”來了
- 6AMD實現連續8個季度的增長 季度營收首次突破60億美元利潤更是翻倍
- 7轉轉集團發布2022年二季度手機行情報告:二手市場“飄香”
- 8充電寶100Wh等于多少毫安?鐵路旅客禁止、限制攜帶和托運物品目錄
- 9好消息!京東與騰訊續簽三年戰略合作協議 加強技術創新與供應鏈服務
- 10名創優品擬通過香港IPO全球發售4100萬股 全球發售所得款項有什么用處?