Python scapy arbitrary TCP stack

Source: Internet
Author: User
Tags ack iptables
1. Foreword


If you only need to study the TCP stack behavior of Linux, just use Packetdrill to meet all my requirements. Packetdrill is what makes me want to be the TCP stack. Packetdrill simple manual for use.



However, the tragedy is that, in addition to studying the TCP stack behavior of Linux, but also need to study the TCP stack of Windows behavior, Windows is not open source, feel that there should be quite a few unknown pits.



To be able to reproduce some of the network behavior of Windows TCP protocol stacks, the Python scapy is used to construct the TCP stack of Windows. Scapy has a bit of delay in TCP packet injection, a tool that cannot be used (or packetdrill, awkward) when it is required to defer a rigorous scenario. In view of the current situation encountered, barely usable, and then have been used to the python, easy to start up. 2. Basic Syntax installation scapy



Installed using Yum install directly in CentOS 7.2.

Help solves most of the problems
[Root@localhost ~]# scapy
info:can ' t import python gnuplot wrapper. Won ' t is able to plot.
Info:can ' t import PyX. Won ' t is able to use Psdump () or Pdfdump ().
Warning:no Route found for IPv6 destination:: (No default route?)
Welcome to Scapy (2.2.0)
>>> Help (send)


Most of the time, if you see something you don't understand, please use help. The second is the official reference manual.



Basic Syntax ip/tcp/http packet manipulation


>>> IP ()
<IP |>
>>>> IP () / TCP ()
<IP frag = 0 proto = tcp | <TCP | >>
>>>> IP (proto = 55) / TCP ()
<IP frag = 0 proto = 55 | <TCP >>

>>>> Ether () / IP () / TCP ()
<Ether type = IPv4 | <IP frag = 0 proto = tcp | <TCP | >>>
>>>> IP () / TCP () / "GET /HTTP/1.0\r\n\r\n" The data part can use string directly
<IP frag = 0 proto = tcp | <TCP | <Raw load = 'GET /HTTP/1.0\r\n\r\n' | >>>
>>>> Ether () / IP () / UDP ()
<Ether type = IPv4 | <IP frag = 0 proto = udp | <UDP | >>>
>>>> Ether () / IP () / IP () / UDP ()
<Ether type = IPv4 | <IP frag = 0 proto = ipencap | <IP frag = 0 proto = udp | <UDP | >>>>


>>> str (IP ())
'E \ x00 \ x00 \ x14 \ x00 \ x01 \ x00 \ x00 @ \ x00 | \ xe7 \ x7f \ x00 \ x00 \ x01 \ x7f \ x00 \ x00 \ x01'
>>> IP (_)
<IP version = 4L ihl = 5L tos = 0x0 len = 20 id = 1 flags = frag = 0L ttl = 64 proto = hopopt

chksum = 0x7ce7 src = 127.0.0.1 dst = 127.0.0.1 |>
>>> a = Ether () / IP (dst = "www.baidu.com") / TCP () / "GET /index.html HTTP / 1.0 \ n \ n"
>>> hexdump (a)
0000 00 03 0F 19 6A 49 08 00 27 FE D8 12 08 00 45 00 .... jI ..'..... E.
0010 00 43 00 01 00 00 40 06 70 78 C0 A8 73 C6 B4 61 .C .... @. Px..s..a
0020 21 6C 00 14 00 50 00 00 00 00 00 00 00 00 50 02! L ... P ........ P.
0030 20 00 B3 75 00 00 47 45 54 20 2F 69 6E 64 65 78 ..u..GET / index
0040 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP / 1.0.
0050 0A.
>>> b = str (a)
>>> b
"\ x00 \ x03 \ x0f \ x19jI \ x08 \ x00 '\ xfe \ xd8 \ x12 \ x08 \ x00E \ x00 \ x00C \ x00 \ x01 \ x00 \ x00 @ \ x06px

\ xc0 \ xa8s \ xc6 \ xb4a! l \ x00 \ x14 \ x00P \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00P \ x02 \ x00 \ xb3u

\ x00 \ x00GET /index.html HTTP / 1.0 \ n \ n "
Packet sending


Packet delivery mainly includes the following functions SEND/SENDP/SR/SR1/SRP The main differences are:



The Send function works on the third floor


Send (IP (dst= "192.168.115.188")/icmp ())


SENDP function in the second layer, you can select the network card and protocol


SENDP (ether ()/IP (dst= "192.168.115.188", Ttl= (1,4)), iface= "eth0")


The role of the fuzz function: You can change some default values that cannot be computed (such as checksums and checksums), and the changed values are random, but the type matches the value of the field.


Send (IP (dst= "www.baidu.com")/udp ()/ntp (version=4), loop=2)  #未使用fuzz ()
 Send (IP (dst= "www.baidu.com")/fuzz (UDP ()/ntp (version=4)), loop=2) #使用fuzz ()  


The SR () function is used to send packets and receive responses. The function returns the packet with the response and the packet that has no response; The function is also the core of Scapy, he will return two list data, one is answer list and the other is unanswered


>>> sr (IP (dst = "192.168.115.1") / TCP (dport = [21,22,23]))
Begin emission:
Finished to send 3 packets.
***
Received 3 packets, got 3 answers, remaining 0 packets
Results: TCP: 3 UDP: 0 ICMP: 0 Other: 0>, Unanswered: TCP: 0 UDP: 0 ICMP: 0 Other: 0

>>> ans, unans = _ This is also the core of scapy
>>> ans.show ()
0000 IP / TCP 192.168.115.198:ftp_data> 192.168.115.1:ftp S ==> IP / TCP 192.168.115.1:ftp> 192.168.115.198:ftp_data RA / Padding
0001 IP / TCP 192.168.115.198:ftp_data> 192.168.115.1:ssh S ==> IP / TCP 192.168.115.1:ssh> 192.168.115.198:ftp_data RA / Padding
0002 IP / TCP 192.168.115.198:ftp_data> 192.168.115.1:telnet S ==> IP / TCP 192.168.115.1:telnet> 192.168.115.198:ftp_data SA / Padding
>>> sr (IP (dst = "192.168.115.1") / TCP (dport = [21,22,23]), inter = 0.5, retry = -2, timeout = 1) When the network environment is not good, you can also Add additional information such as inter retry timeout,

The

Function SR1 () is a variant of the SR () that returns only the grouping (or grouping sets) that the answer sends. The packets sent by these two functions must be layer 3rd packets (IP,ARP, etc.). The function SRP () is located on layer 2nd (Ethernet, 802.3, etc.).


>>> p=sr1(IP(dst="192.168.115.188")/ICMP()/"test")
Begin emission:
.....Finished to send 1 packets.
.*
Received 7 packets, got 1 answers, remaining 0 packets
>>> p
<IP  version=4L ihl=5L tos=0x0 len=32 id=26000 flags= frag=0L ttl=128 proto=icmp chksum=0x6c79 src=192.168.115.188 dst=192.168.115.198 options=[] |<ICMP  type=echo-reply code=0 chksum=0x1826 id=0x0 seq=0x0 |<Raw  load='test' |<Padding  load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>>>
>>> p.show()
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 32
  id= 26000
  flags= 
  frag= 0L
  ttl= 128
  proto= icmp
  chksum= 0x6c79
  src= 192.168.115.188
  dst= 192.168.115.198
  \options\
###[ ICMP ]###
     type= echo-reply
     code= 0
     chksum= 0x1826
     id= 0x0
     seq= 0x0
###[ Raw ]###
        load= 'test'
###[ Padding ]###
           load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Data packet sniff
A=sniff (count=1,filter= "TCP and host 192.168.1.1 and Port 80")


The use of sniff is mainly used for packet reception, according to the conditions set by the filter, will meet the conditions of the packet received back. 3. Scene Construction



The disadvantage of scapy is that he is only responsible for the construction of the package, is one-way. Unlike Packetdrill, Packetdrill can not only construct packages, but also implement system calls to construct different scenarios and help you check whether packets sent by the protocol stack meet expectations. The process of the TCP protocol stack is only two ends, one end uses the system call to simulate the stack behavior, the other end is the package we construct. Common scenarios are mainly: Server scenarios, client scenarios. Server scenario:



The server scenario uses system calls (that is, the user state program), while the client is a scapy-constructed package.



Here constructs a simple three times handshake to send the data to the server side. To prevent Linux client rst.


Iptables-a output-p TCP--tcp-flags RST rst-s 192.168.56.1-j DROP
#!/usr/local/bin/python from
scapy.all import *

VARIABLES
src = sys.argv[1]
DST = sys.argv[2]
Sport = Random.randint (1024,65535)
dport = Int (sys.argv[3))

# SYN
ip=ip (SRC=SRC,DST=DST)
syn=tcp ( Sport=sport,dport=dport,flags= ' S, seq=1000)
synack=sr1 (Ip/syn)

# ACK
ack=tcp (Sport=sport, dport= Dport, flags= ' A ', Seq=synack.ack, Ack=synack.seq + 1)
Send (Ip/ack)


Here you can install a nginx to verify. Client Scenario:



The client scenario uses system calls (that is, the user state program), and the server side is the Scapy construction package.



Here, use Scapy to construct a simple HTTP server. In order to prevent the protocol stack from sending RST, the iptables needs to be set.


iptables -A OUTPUT -p tcp --tcp-flags RST RST --sport 80 -j DROP
#!/usr/bin/python
from scapy.all import *

# Interacts with a client by going through the three-way handshake.
# Shuts down the connection immediately after the connection has been established.
# Akaljed Dec 2010, http://www.akaljed.wordpress.com

# Wait for client to connect.
a=sniff(count=1,filter="tcp and host 192.168.1.1 and port 80")

# some variables for later use.
ValueOfPort=a[0].sport
SeqNr=a[0].seq
AckNr=a[0].seq+1

# Generating the IP layer:
ip=IP(src="192.168.1.1", dst="192.168.1.2")
# Generating TCP layer:
TCP_SYNACK=TCP(sport=80, dport=ValueOfPort, flags="SA", seq=SeqNr, ack=AckNr, options=[('MSS', 1460)])

#send SYNACK to remote host AND receive ACK.
ANSWER=sr1(ip/TCP_SYNACK)

# Capture next TCP packets with dport 80. (contains http GET request)
GEThttp = sniff(filter="tcp and port 80",count=1,prn=lambda x:x.sprintf("{IP:%IP.src%: %TCP.dport%}"))
AckNr=AckNr+len(GEThttp[0].load)
SeqNr=a[0].seq+1

# Print the GET request
# (Sanity check: size of data should be greater than 1.)
if len(GEThttp[0].load)>1: print GEThttp[0].load

# Generate custom http file content.
html1="HTTP/1.1 200 OK\x0d\x0aDate: Wed, 29 Sep 2010 20:19:05 GMT\x0d\x0aServer: Testserver\x0d\x0aConnection: Keep-Alive\x0d\x0aContent-Type: text/html; charset=UTF-8\x0d\x0aContent-Length: 291\x0d\x0a\x0d\x0a<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\"><html><head><title>Testserver</title></head><body bgcolor=\"black\" text=\"white\" link=\"blue\" vlink=\"purple\" alink=\"red\"><p><font face=\"Courier\" color=\"blue\">-Welcome to test server-------------------------------</font></p></body></html>"

# Generate TCP data
data1=TCP(sport=80, dport=ValueOfPort, flags="PA", seq=SeqNr, ack=AckNr, options=[('MSS', 1460)])

# Construct whole network packet, send it and fetch the returning ack.
ackdata1=sr1(ip/data1/html1)
# Store new sequence number.
SeqNr=ackdata1.ack

# Generate RST-ACK packet
Bye=TCP(sport=80, dport=ValueOfPort, flags="FA", seq=SeqNr, ack=AckNr, options=[('MSS', 1460)])

send(ip/Bye)

# The End


This server only needs to use wget or curl to achieve authentication. 4. References

http://www.secdev.org/projects/scapy/doc/usage.html#starting-scapy

https://akaljed.wordpress.com/2010/12/12/scapy-as-webserver/

http://lost-and-found-narihiro.blogspot.com/2012/12/scapy-simple-web-server-with-scapy.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.