Packet Trasmission
A number of functions are available for transmitting packets. The following functions are the most noteworthy and useful.
send()
>>> packet = IP(dst="10.10.10.1")/TCP(dport=80)
>>> ans = send(packet)
.
Sent 1 packets.
>>> ans
>>>
Notice that no value is returned as a response to the sent packet so the result of printing the variable 'ans' is an empty one.
Let's use tcpdump to get a more detailed picture of what is happening on the network when we use the send() function.
sr()
>>> packet = IP(dst="10.10.10.1")/TCP(dport=80)/"Open Port"
>>> ans,unsans = sr(packet)
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
>>> ans
<Results: TCP:1 UDP:0 ICMP:0 Other:0>
>>> ans[0]
(<IP frag=0 proto=tcp dst=10.10.10.1 |<TCP dport=http |<Raw load='Open Port' |>>>,
<IP version=4L ihl=5L tos=0x0 len=40 id=31 flags= frag=0L ttl=64 proto=tcp
chksum=0x5a98 src=10.10.10.1 dst=10.0.2.15 options=[] |<TCP sport=http dport=ftp_data
seq=448001 ack=2 dataofs=5L reserved=0L flags=A window=65535 chksum=0xb94d
urgptr=0 |<Padding load='\x00\x00\x00\x00\x00\x00' |>>>)
>>> packet = IP(dst=["10.10.10.101","10.10.10.251"])/ICMP()/"Ping"
>>> ans,uans = sr(packet)
Begin emission:
.Finished to send 2 packets.
**
Received 3 packets, got 2 answers, remaining 0 packets
>>> ans
<Results: TCP:0 UDP:0 ICMP:2 Other:0>
>>> uans
<Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>
Now let's access the elements within this list. We would do this just like any other list in Python. The integer within the brackets represents the index of the stimuli/response pair we would like to access. In this example the first pair is an echo request (Type 8 Code 0) and the echo reply (Type 0) to the original request.
>>> ans[0]
(<IP frag=0 proto=icmp dst=10.10.10.101 |<ICMP |<Raw load='Ping' |>>>, <IP
version=4L ihl=5L tos=0x0 len=32 id=55 flags= frag=0L ttl=63 proto=icmp chksum=0x5b29
src=10.10.10.101 dst=10.0.2.15 options=[] |<ICMP type=echo-reply code=0 chksum=0x412f
id=0x0 seq=0x0 |<Raw load='Ping' |<Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00' |>>>>)
The second pair is the echo request and the ICMP destination unreachable/host unreachable from the gateway (Type 3 Code 1). The host 10.10.10.251 does not exist which is why this response is generated. We are only concerned with these responses for this illustration so the IP and ICMP errors can be ignored at this time.
>>> ans[1]
(<IP frag=0 proto=icmp dst=10.10.10.251 |<ICMP |<Raw load='Ping' |>>>, <IP
version=4L ihl=5L tos=0xc0 len=60 id=56 flags= frag=0L ttl=63 proto=icmp
chksum=0x5a4c src=10.10.10.101 dst=10.0.2.15 options=[] |<ICMP type=dest-unreach
code=host-unreachable chksum=0xdd1f unused=0 |<IPerror version=4L ihl=5L tos=0x0
len=8192 id=256 flags= frag=0L ttl=63 proto=icmp chksum=0x59c9 src=10.0.2.15
dst=10.10.10.251 options=[]
|<ICMPerror type=echo-request code=0 chksum=0x392f id=0x0 seq=0x0 |<Raw load='Ping'
|>>>>>)
The list that is returned as a result of this function is actually multidimensional. We will only explore the first two dimensions but it should be noted that there are many more. Each dimension allows us to dive down deeper in to the packet. We will access the second dimension in the following example. This index relates to the particular transaction that we are interested in accessing within the pair. In this case we will be examining the second ICMP request that was sent to host 10.10.10.251.
>>> ans[1][0]
<IP frag=0 proto=icmp dst=10.10.10.251 |<ICMP |<Raw load='Ping' |>>>
>>> ans[1][0].type
8
>>> ans[1][0].code
0
sr1()
>>> packet = IP(dst="10.10.10.1")/TCP(dport=22,flags="S")
>>> ans = sr1(packet)
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
We define a packet that is destined for TCP port 22 (Secure Socket Layer) and has a TCP flag that is set to 'S' for SYN. This should initiate the beginning of the TCP handshake and elicit a SYN/ACK flag from the destination host if the port is open.
>>> ans
<IP version=4L ihl=5L tos=0x0 len=44 id=86 flags= frag=0L ttl=64 proto=tcp
chksum=0x5a5d src=10.10.10.1 dst=10.0.2.15 options=[] |<TCP sport=ssh dport=ftp_data
seq=10624001 ack=1 dataofs=6L reserved=0L flags=SA window=65535 chksum=0x5b2f
urgptr=0 options=[('MSS', 1460)] |<Padding load='\x00\x00' |>>>
>>> ans[0][1]
<TCP sport=ssh dport=ftp_data seq=10624001 ack=1 dataofs=6L reserved=0L flags=SA
window=65535 chksum=0x5b2f urgptr=0 options=[('MSS', 1460)] |<Padding load='\x00\x00'
|>>
>>> ans[0][1].flags
18L
Keep in mind that the variable 'ans' stores the response to the 'packet' that was sent. 'ans[0][1]' specifies the second layer in this response packet. In our case, this would be the TCP layer. When we request the 'flags' field we are presented with the integer '18'. This is the combined value of the TCP flags (ACK = 16, SYN = 2).
srp()
The srp() function is used when sending a layer 2 (data link layer) datagram packet and will listen for responses in much the same way as the previous function does.
>>> datagram =
Ether(src="00:00:00:12:34:ab",dst="14:da:e9:01:3e:23")/IP(dst="10.10.10.101")
>>> sendp(datagram)
.
Sent 1 packets.
This function must be used if the Ether() layer has been defined within a packet. If a function such as send() is used, a warning will be produced indicating that there is an issue.
>>> send(datagram)
WARNING: Mac address to reach destination not found. Using broadcast.
.
Sent 1 packets.
Now that we have a foundation for crafting and transmitting packets, we can look in to actually reading packets from a packet capture file. This is a tremendously helpful capability when attempting to reproduce activity such as an exploit or attack on a network. We will explore these techniques as well as a few other in next post.
The srp() function is used when sending a layer 2 (data link layer) datagram packet and will listen for responses in much the same way as the previous function does.
>>> datagram =
Ether(src="00:00:00:12:34:ab",dst="14:da:e9:01:3e:23")/IP(dst="10.10.10.101")
>>> sendp(datagram)
.
Sent 1 packets.
This function must be used if the Ether() layer has been defined within a packet. If a function such as send() is used, a warning will be produced indicating that there is an issue.
>>> send(datagram)
WARNING: Mac address to reach destination not found. Using broadcast.
.
Sent 1 packets.
Now that we have a foundation for crafting and transmitting packets, we can look in to actually reading packets from a packet capture file. This is a tremendously helpful capability when attempting to reproduce activity such as an exploit or attack on a network. We will explore these techniques as well as a few other in next post.
No comments:
Post a Comment