Lxj616 · 2014/07/17 14:07
0 x00: an overview
This article explains Python’s role in network security analysis from example code, and shows the reader how Python can parse, send, and sniff packet systems on the network with basic examples: Kali also has SCAPY, because it involves low-level network operations, the sample code in this article is available under Linux and cannot be copied directly to Windows
0x01: Parsing TCP packets using Python
Take the following code as an example
First import socket (for network programming), struct (for unpacking and parsing packet structure), binASCII (convenient format conversion)
Specify socket.sock_RAW when creating the socket to receive raw packets
Pkt is the received packet
Eth_hdr is the Ethernet header obtained by unpacking and unpacked (see Ethernet frame format below).
Ethernet frame structure:
We can see that the first part of the solution (destination address) is 080027bc6ecc. We can see that the second part (source address) is 525400123502. We can see that the third part (length \ type) is 0800
MAC (eth1) = 080027BC6ecc
Understand the source IP and destination IP in the IP packet header, as shown in the first figure
IP header structure:
The code used in this section is as follows:
#! python #! /usr/bin/python import socket import struct import binascii s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800)) pkt = s.recvfrom(2048); ethernetHeader=pkt[0][0:14] eth_hdr = struct.unpack("! 6s6s2s",ethernetHeader) binascii.hexlify(eth_hdr[0]) binascii.hexlify(eth_hdr[1]) binascii.hexlify(eth_hdr[2]) ipHeader = pkt[0][14:34] ip_hdr = struct.unpack("! 12s4s4s",ipHeader) print "Source IP address:"+socket.inet_ntoa(ip_hdr[1]) print "Destination IP address:"+socket.inet_ntoa(ip_hdr[2]) tcpHeader = pkt[0][34:54] tcp_hdr = struct.unpack("! HH16s",tcpHeader)Copy the code
The following is an example output of this section:
#! bash[email protected]:~/Desktop/wooyunPython#./0x01.py Source IP address:123.125.125.99 Destination IP address:10.0.3.15[email protected]:~/Desktop/wooyunPython# python python 2.7.3 (default, Jan 2 2013, 13:56:14) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import socket >>> import struct >>> import binascii >>> s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800)) >>> pkt = s.recvfrom(2048); >>> ethernetHeader=pkt[0][0:14] >>> eth_hdr = struct.unpack("! 6s6s2s",ethernetHeader) >>> binascii.hexlify(eth_hdr[0]) '080027bc6ecc' >>> binascii.hexlify(eth_hdr[1]) '525400123502' >>> binascii.hexlify(eth_hdr[2]) '0800' >>> ipHeader = pkt[0][14:34] >>> ip_hdr = struct.unpack("! >>> print "Source IP address:"+socket.inet_ntoa(ip_hdr[1]) Source IP address:123.125.125.99 >>> print "+socket.inet_ntoa(IP_hdr [2]) Destination IP address:10.0.3.15 >>> tcpHeader = PKT [0][34:54] >>> tcp_hdr = struct.unpack("! HH16s",tcpHeader)Copy the code
0x02: Sends TCP packets using Python
The code used in this article is as follows:
#! python #! /usr/bin/python import socket import struct rawSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800)) rawSocket.bind(("eth0",socket.htons(0x0800))) packet = struct.pack("! 6s6s2s",'\xaa\xaa\xaa\xaa\xaa\xaa','\xbb\xbb\xbb\xbb\xbb\xbb','\x08\x00') rawSocket.send(packet+"Hello there")Copy the code
The socket type is raw, and then bind an interface to send packets. The packets need to be wrapped by struct.pack
0x03: Sniffing packets using Python+Scapy
#! bash[email protected]:~# scapy INFO: Can't import python gnuplot wrapper . Won't be able to plot. WARNING: No route found for IPv6 destination :: (no default route?) Welcome to Scapy (2.2.0) >>> ls() ARP: ARPCopy the code
There are a lot of introductions listed here, but I won’t list them
#! bash >>> pkts = sniff(iface="eth1",count=3)Copy the code
Use sniffing to listen to three data packets on the eth1 interface
#! bash >>> pkts <Sniffed: TCP:3 UDP:0 ICMP:0 Other:0>Copy the code
Entering PKTS directly shows the sniffing profile
#! bash >>> pkts[0] <Ether dst=52:54:00:12:35:02 src=08:00:27:bc:6e:cc type=0x800 |<IP version=4L ihl=5L tos=0x0 len=116 Id = 30377 flags = DF frag TTL = 64 proto = = 0 l TCP chksum = 0 xbdeb SRC = 10.0.3.15 DST = 123.125.125.99 options = [] | < TCP sport = 49157 dport=http seq=2358039370 ack=1044674792 dataofs=5L reserved=0L flags=PA window=24120 chksum=0x656 urgptr=0 options=[] | < Raw load = 'GET/web_ime/patch. HTTP / 1.1 PHP \ r \ nHost: web.pinyin.sogou.com \ r \ nAccept: */*\r\n\r\n' |>>>> >>> pkts[0].show()Copy the code
Use show to show more details
#! bash ###[ Ethernet ]### dst= 52:54:00:12:35:02 src= 08:00:27:bc:6e:cc type= 0x800 ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 116 ID = 30377 flags= DF frag= 0L TTL = 64 proto= TCP chksum= 0xBdeb SRC = 10.0.3.15 DST = 123.125.125.99 \options\ ###[ TCP ]### sport= 49157 dport= http seq= 2358039370 ack= 1044674792 dataofs= 5L reserved= 0L flags= PA window= 24120 Chksum = 0x656 urgptr= 0 options= [] ###[Raw]### load= 'GET /web_ime/patch.php HTTP/1.1\r\nHost: web.pinyin.sogou.com\r\nAccept: */*\r\n\r\n' >>> >>> hexdump(pkts[1])Copy the code
Converting to hexadecimal form is much friendlier
#! bash 0000 08 00 27 BC 6E CC 52 54 00 12 35 02 08 00 45 00 .. '.n.RT.. 5... E. 0010 00 28 82 39 00 00 40 06 F2 A7 7B 7D 7D 63 0A 00 .(.9.. @... {}}c.. 0020 03 0F 00 50 C0 05 3E 44 78 E8 8C 8C D3 96 50 10 ... P.. >Dx..... P. 0030 FF FF D2 3F 00 00 00 00 00 00 00 00 ... ? . >>> >>> wrpcap("demo.pcap",pkts)Copy the code
Write to the PCAP file
#! bash >>> read_pkts=rdpcap("demo.pcap")Copy the code
Read from the PCAP file
#! bash >>> read_pkts <demo.pcap: TCP:3 UDP:0 ICMP:0 Other:0>Copy the code
Check that the read and write are consistent
#! bash >>> >>> pkts=sniff(iface="eth1",filter="icmp",count=3)Copy the code
Use filter to filter the type of packet you want to capture
Note that I also opened another shell and did a ping to send icmp packets
#! bash[email protected]:~# ping www.wooyun.org ping wooyun.sinaapp.com (220.181.136.24) 56(84) bytes of data.64 bytes from 220.181.136.24: Icmp_req =1 TTL =54 time=17.1 ms 64 bytes from 220.181.136.24: Icmp_req =3 TTL =54 time=11.8 ms 64 bytes from 220.181.136.24: Icmp_req =4 TTL =54 time=23.8 ms 64 bytes from 220.181.136.24: Icmp_req =5 TTL =54 time=17.1 ms 64 bytes from 220.181.136.24: Icmp_req =6 TTL =54 time= 5.463 ms ^C -- packets transmitted, 5 received 16% packet loss, time 5013 RTT min/avg/Max/ms mdev 23.824/6.086 = 5.636/15.135 / ms > > > PKTS < Sniffed: TCP:0 UDP:0 ICMP:3 Other:0>Copy the code
It is found that all the captured filter packets are ICMP packets
#! bash >>> >>> pkts[0] <Ether dst=52:54:00:12:35:02 src=08:00:27:bc:6e:cc type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 Id = 0 flags = DF frag TTL = 64 proto = = 0 l icmp chksum = 0 xc8cc SRC = 10.0.3.15 DST = 220.181.136.24 options = [] | < icmp type=echo-request code=0 chksum=0xd856 id=0x218e seq=0x1 |<Raw load='\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x 1e\x1f !" #$%&\'()*+,-./01234567' |>>>> >>> pkts[1] <Ether dst=08:00:27:bc:6e:cc src=52:54:00:12:35:02 type=0x800 |<IP version=4L Ihl =5L TOS =0x1 Len =84 ID =33433 FLAGS = FRAG =0L TTL =54 PROto =icmp CHksum =0x9032 SRC =220.181.136.24 DST =10.0.3.15 options=[] |<ICMP type=echo-reply code=0 chksum=0xe056 id=0x218e seq=0x1 |<Raw load='\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x 1e\x1f !" #$%&\'()*+,-./01234567' |>>>> >>> >>> icmp_str=str(pkts[0])Copy the code
Into the STR
#! bash >>> icmp_str 'RT\x00\x125\x02\x08\x00\'\xbcn\xcc\x08\x00E\x00\x00T\x00\x00@\x00@\x01\xc8\xcc\n\x00\x03\x0f\xdc\xb5\x88\x18\x08\x00\xd 8V! \x8e\x00\x01\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c \x1d\x1e\x1f !" #$%&\'()*+,-./01234567' >>> recon=Ether(icmp_str)Copy the code
Reconstructs the packet from STR
#! bash >>> recon <Ether dst=52:54:00:12:35:02 src=08:00:27:bc:6e:cc type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 Flags = DF frag TTL = 64 proto = = 0 l icmp chksum = 0 xc8cc SRC = 10.0.3.15 DST = 220.181.136.24 options = [] | < icmp type = echo request code=0 chksum=0xd856 id=0x218e seq=0x1 |<Raw load='\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x 1e\x1f !" #$%&\'()*+,-./01234567' |>>>> >>> export_object(icmp_str) eNprYApNCgphEDJl4mBQ35N3hoPBlYEhhIHBgcGB8cQZLgZm/jtbOyQ4GG6EKfYxMJ5ZfjiYAQgW efOCKAYBQSFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTS1tHV09fQNDI2MTUzPzQkY9AMQIFOY=Copy the code
Export a readable Base64 object
#! bash >>> newPkt=import_object() eNprYApNCgphEDJl4mBQ35N3hoPBlYEhhIHBgcGB8cQZLgZm/jtbOyQ4GG6EKfYxMJ5ZfjiYAQgW efOCKAYBQSFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTS1tHV09fQNDI2MTUzPzQkY9AMQIFOY=Copy the code
Press (CTRL +D) to finish typing and read objects back from Base64
#! bash >>> newPkt 'RT\x00\x125\x02\x08\x00\'\xbcn\xcc\x08\x00E\x00\x00T\x00\x00@\x00@\x01\xc8\xcc\n\x00\x03\x0f\xdc\xb5\x88\x18\x08\x00\xd 8V! \x8e\x00\x01\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c \x1d\x1e\x1f !" #$%&\'()*+,-./01234567' >>> Ether(newPkt) <Ether dst=52:54:00:12:35:02 src=08:00:27:bc:6e:cc type=0x800 |<IP version=4L Ihl =5L tos=0x0 Len =84 ID =0 Flags =DF FRAg =0L TTL =64 PROto =icmp CHksum = 0xC8cc SRC =10.0.3.15 DST =220.181.136.24 options=[] |<ICMP type=echo-request code=0 chksum=0xd856 id=0x218e seq=0x1 |<Raw load='\xcc\xa7\xc3S\x00\x00\x00\x00\xa2K\r\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x 1e\x1f !" # $% & \ '() *, +, -, / 01234567' | > > > >Copy the code
At this point we have successfully returned the exported packet the original way
>>>
Copy the code
The next step is to send packets using SCAPY
First, Ether/ARP constructs an ARP packet, and then srP1 sends the packet. From the Wireshark, it is found that the packet has been successfully sent, but the response can be received theoretically
#! bash[email protected]:~# scapy INFO: Can't import python gnuplot wrapper . Won't be able to plot. WARNING: No route found for IPv6 destination :: (no default route?) Welcome to Scapy (2.2.0) >>> from scapy.all import * >>> > PKT = Mr (DST = "ff: ff ff ff: ff: ff")/ARP (PDST = '192.168.1.3', HWDST = "ff: ff ff ff: ff: ff") > > > PKT < Mr DST = ff: ff ff ff: ff: ff type = 0 x806 | < ARP HWDST = ff: ff: ff: ff: ff: ff PDST = 192.168.1.3 | > > > > > PKT. The show () # # # # # # [Ethernet] dst= ff:ff:ff:ff:ff:ff src= 00:00:00:00:00:00 type= 0x806 ###[ ARP ]### hwtype= 0x1 ptype= 0x800 hwlen= 6 plen= 4 op= Who-has HWSRC = 00:00:00:00:Psrc = 192.168.1.3 HWDST = FF :ff:ff:ff PDST = 192.168.1.3 >>> SRP1 (PKT) Begin emission: Finished to send 1 packets. .............................................................................. ^C Received 78 packets, got 0 answers, remaining 1 packets >>>Copy the code