網路數據包的捕獲與分析
Packet Capturing Overview
- What is Packet Capturing
- How can it be used
- What is libpcap
- Debug Tools: tcpdump & WinPcap & snoop
- What is BPF
- What is gopacket
What is Packet Capturing
Packet capture is a computer networking term for intercepting a data packet that is crossing or moving over a specific computer network.Once a packet is captured, it is stored temporarily so that it can be analyzed. The packet is inspected to help diagnose and solve network problems and determine whether network security policies are being followed.
http://og2061b3n.bkt.clouddn.com/Packet_Capture_Overview.pngHow can it be used
Development
Testing & validating & Reverse engineer APP on API
Network Administration
Seeing what traffic goes on in background,Looking for malicious traffic on networkData capturing is used to identify security flaws and breaches by determining the point of intrusion.Troubleshooting
Managed through data capturing, troubleshooting detects the occurrence of undesired events over a network and helps solve them. If the network administrator has full access to a network resource, he can access it remotely and troubleshoot any issues.
Security
defcon Wall of Sheep.Hackers can also use packet capturing techniques to steal data that is being transmitted over a network, like Stealing credentials.When data is stolen, the network administrator can retrieve the stolen or lost information easily using data capturing techniques.Forensics
forensics for crime investigations.Whenever viruses, worms or other intrusions are detected in computers, the network administrator determines the extent of the problem. After initial analysis, she may block some segments and network traffic in order to save historical information and network data.
What is libpcap
libpcap flow involving data copy from kernel to user space.
//Compile with: gcc find_device.c -lpcapn#include <stdio.h>n#include <pcap.h>nnint main(int argc, char **argv) {n char *device;n char error_buffer[PCAP_ERRBUF_SIZE];n //Find a devicen device = pcap_lookupdev(error_buffer);n if (device == NULL) {n printf("Error finding device: %sn", error_buffer);n return 1;n }nn printf("Network device found: %sn", device);n return 0;n}n
#include <stdio.h>n#include <time.h>n#include <pcap.h>n#include <netinet/in.h>n#include <netinet/if_ether.h>nnvoid print_packet_info(const u_char *packet, struct pcap_pkthdr packet_header);nnint main(int argc, char *argv[]) {n char *device;n char error_buffer[PCAP_ERRBUF_SIZE];n pcap_t *handle;n const u_char *packet;n struct pcap_pkthdr packet_header;n int packet_count_limit = 1;n int timeout_limit = 10000; /*In milliseconds*/nn device = pcap_lookupdev(error_buffer);n if (device == NULL) {n printf("Error finding device: %sn", error_buffer);n return 1;n }nn /*Open device for live capture*/n handle = pcap_open_live(n device,n BUFSIZ,n packet_count_limit,n timeout_limit,n error_buffern );nn /*Attempt to capture one packet. If there is no network trafficn and the timeout is reached, it will return NULL*/n packet = pcap_next(handle, &packet_header);n if (packet == NULL) {n printf("No packet found.n");n return 2;n }nn /*Our function to output some info*/n print_packet_info(packet, packet_header);n return 0;n}nnvoid print_packet_info(const u_char *packet, struct pcap_pkthdr packet_header) {n printf("Packet capture length: %dn", packet_header.caplen);n printf("Packet total length %dn", packet_header.len);n}n
Debug Tools
#Older versions of tcpdump truncate packets to 68 or 96 bytes.n#If this is the case, use -s to capture full-sized packets:n$ tcpdump -i <interface> -s 65535 -w <some-file>n# A packet capturing tool similar to TcpDump for Solarisn$ snoop -r -o arp11.snoop -q -d nxge0 -c 150000n
tcpdump
tcpdump 是一個運行在命令行下的嗅探工具。它允許用戶攔截和顯示發送或收到過網路連接到該計算機的TCP/IP和其他數據包。它支持針對網路層、協議、主機、網路或埠的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的信息,從而使用戶能夠進一步找出問題的根源。可以使用BPF來限制tcpdump產生的數據包數量。
snoop
snoop uses both the network packet filter and streams buffer modules to provide efficient capture of packets from the network. Captured packets can be displayed as they are received, or saved to a file for later inspection.
promiscuous mode
抓包工具需要工作在promiscuous mode(混雜模式)(superuser), 指一台機器的網卡能夠接收所有經過它的數據流,而不論其目的地址是否是它。當網卡工作在混雜模式下時,網卡將來自介面的所有數據都捕獲並交給相應的驅動程序。一般在分析網路數據作為網路故障診斷手段時用到,同時這個模式也被網路黑客利用來作為網路數據竊聽的入口。
BPF
Berkeley Packet Filter,縮寫BPF,是類Unix系統上數據鏈路層的一種介面,提供原始鏈路層封包的收發。BPF支持「過濾」封包,這樣BPF會只把「感興趣」的封包到上層軟體,可以避免從操作系統內核向用戶態複製其他封包,降低抓包的CPU的負擔以及所需的緩衝區空間,從而減少丟包率。BPF的過濾功能是以BPF虛擬機機器語言的解釋器的形式實現的,這種語言的程序可以抓取封包數據,對封包中的數據採取算術操作,並將結果與常量或封包中的數據或結果中的測試位比較,根據比較的結果決定接受還是拒絕封包。
http://og2061b3n.bkt.clouddn.com/Packet_Capture_BPF.pngGo Packet
Find Devices
package mainnnimport (nt"fmt"nt"log"nt"github.com/google/gopacket"nt"github.com/google/gopacket/layers"nt"github.com/google/gopacket/pcap"n)nnfunc main() {ntfmt.Println("----------Find all devices---------n ")nntdevices, err := pcap.FindAllDevs()ntif err != nil {nttlog.Fatal(err)nt}nt// Print device informationntfor _, device := range devices {nttfor _, address := range device.Addresses {ntttfmt.Println("- IP address: ", address.IP)ntttfmt.Println("- Subnet mask: ", address.Netmask)ntt}nt}nt/*- IP address: 45.33.110.101nt - Subnet mask: ffffff00nt - IP address: 2600:3c01::f03c:91ff:fee5:45b6nt - Subnet mask: ffffffffffffffff0000000000000000nt - IP address: fe80::f03c:91ff:fee5:45b6nt - Subnet mask: ffffffffffffffff0000000000000000nt - IP address: 127.0.0.1nt - Subnet mask: ff000000nt - IP address: ::1nt - Subnet mask: ffffffffffffffffffffffffffffffffnt*/n
Decoding Packet Layers
package mainnnimport (nt"fmt"nt"log"nt"net"nt"github.com/google/gopacket"nt"github.com/google/gopacket/layers"nt"github.com/google/gopacket/pcap"n)nnfunc main(){nnthandle, err := pcap.OpenLive("eth0", 65536, true, pcap.BlockForever)ntif err != nil {nttfmt.Printf("Error: %sn", err)nttreturnnt}ntdefer handle.Close()nnt//Create a new PacketDataSourcentsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)nt//Packets returns a channel of packetsntin := src.Packets()nntfor {nttvar packet gopacket.Packetnttselect {ntt//case <-stop:ntt//returnnttcase packet = <-in:ntttarpLayer := packet.Layer(layers.LayerTypeARP)ntttif arpLayer == nil {nttttcontinuenttt}ntttarp := arpLayer.(*layers.ARP)nntttif net.HardwareAddr(arp.SourceHwAddress).String() == "abc" {ntttt//Do something or dontnttt}nnttttcpLayer := packet.Layer(layers.LayerTypeTCP)ntttif tcpLayer == nil {nttttcontinuenttt}nttttcp := tcpLayer.(*layers.TCP)nnttt//.......nntt}nt}n}n
Creating and Sending Packets
package mainnnimport (n "github.com/google/gopacket"n "github.com/google/gopacket/layers"n "github.com/google/gopacket/pcap"n "log"n "net"n "time"n)nnvar (n device string = "eth0"n snapshot_len int32 = 1024n promiscuous bool = falsen err errorn timeout time.Duration = 30 * time.Secondn handle *pcap.Handlen buffer gopacket.SerializeBuffern options gopacket.SerializeOptionsn)nnfunc main() {n // Open devicen handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)n if err != nil {log.Fatal(err) }n defer handle.Close()nn // Send raw bytes over wiren rawBytes := []byte{10, 20, 30}n err = handle.WritePacketData(rawBytes)n if err != nil {n log.Fatal(err)n }nn // Create a properly formed packet, just withn // empty details. Should fill out MAC addresses,n // IP addresses, etc.n buffer = gopacket.NewSerializeBuffer()n gopacket.SerializeLayers(buffer, options,n &layers.Ethernet{},n &layers.IPv4{},n &layers.TCP{},n gopacket.Payload(rawBytes),n )n outgoingPacket := buffer.Bytes()n // Send our packetn err = handle.WritePacketData(outgoingPacket)n if err != nil {n log.Fatal(err)n }nn // This time lets fill out some informationn ipLayer := &layers.IPv4{n SrcIP: net.IP{127, 0, 0, 1},n DstIP: net.IP{8, 8, 8, 8},n }n ethernetLayer := &layers.Ethernet{n SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA},n DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD},n }n tcpLayer := &layers.TCP{n SrcPort: layers.TCPPort(4321),n DstPort: layers.TCPPort(80),n }n // And create the packet with the layersn buffer = gopacket.NewSerializeBuffer()n gopacket.SerializeLayers(buffer, options,n ethernetLayer,n ipLayer,n tcpLayer,n gopacket.Payload(rawBytes),n )n outgoingPacket = buffer.Bytes()n}n
Capture Packet Workflow
- Getting a list of network devices
- Capturing packets from a network device
- Analyzing packet layers
- Using Berkeley Packet Filters
Application
qisniffhttps://github.com/zond/qisniff新一代Ntopng網路流量監控—可視化和架構分析
基於網路抓包實現kubernetes中微服務的應用級監控更多精彩內容掃碼關注公眾號,RiboseYims Blog:Ribose Yims Blog
推薦閱讀:
※同一網段內的兩台主機通信是否需要路由器?
※TCP網路編程,從socket到消息包,發送接收都是bit,傳輸中兩端怎麼知道哪些bit組成一個協議?
※TCP快速重傳為什麼是三次冗餘ack,這個三次是怎麼定下來的?
※學習網路編程,想寫個聊天伺服器練練,想實現客戶端之間的通信,但是卡殼了?
※1.1.1.1 是哪裡的 IP?