Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
Provides the basic functionalities provided by the ARP Protocol. It implements Layer. It keeps an ARP cache which is updated when an ARP reply is received. It also provides methods to do ARP request.
Return the MAC address associated with the given IP if present. Otherwise it returns None.
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.udp_application.UDPApplication
Provide basic DNS implementation. It can send DNS request to resolve an hostname, and process replies sent by the server. The server used is a server of OpenDNS
Just forge the DNS packet with arguments sent in **field
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
This class provides all the functionalities to accomplish the layer 2 routing. When a packet is received from an upper layer this class basically look up in the host routing table to get the ip to send the packet to and if the mac address is not found trigger an ARP request. It also maintain a pool of packet for which the destination MAC address is unknown until an ARP reply is received.
Forge the Ethernet packet using the given kwargs and the given packet
Decapsulate the packet as the Layer would have done except that if the packet is an IP packet this method update the ARP cache with ip and mac
Method called by arp layer when receive an arp reply (is_at) Loop through all packets if the newly resolved MAC match dst of on of them complete the packet and send it.
When a packet is received from an upper layer try to route it. If the method return something call forge and transfert it (to scapyio)
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
IPProtocol assure the routing at the layer 3 IP.
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Default implements Layer. It just override packet_received to do nothing. Class called when there is not handler for the packet
Bases: object
Mother class for all the layers(protocols) of the stack. It provides many methods to register an upper or lower layer. Moreover it provides methods that should be overriden by children layers according to theirs behavior. By the way Layer is an “abstract” class it should not be instanciated
By default does nothing but should be overriden by child class
Define the default behavior when a packet is received. By default decapsulate the packet and send the payload to the upperlayer referenced by the payload name (TCP, IP ..)
Shortcut method to register the given layer as upperlayer and register self as the default lowerlayer for layer. This can not be used in all cases
Register the given layer in the lowerlayers dict using the given name as key
Add the given layer into the upperlayers dict using the given name as key
By default when calling send_packet it forge the packet calling forge_packet and forward it to the lower layer calling transfer_packet
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: twisted.internet.base.BasePort
SacpyIO play the role of interface with Input/Output functions of Scapy. So all the packets that are received and sent pass through here. To receive packet ScapyIO use a L2ListenSocket object. Then to read packets two methods are implemented, either twisted reactor add a reader on the socket or a thread that will loop reading packet in the socket. To send packet the sendp method is called
Method called when the reader read a packet in the socket. So basically forward it to the handler(s)
Register an handler for the packet received. We can put multiples ones but in the classical case there will be one which is the Ethernet layer.
Start listening on the socket using the appropriate method. If reactor is choosen it adds a reader on the socket and create a callback that will be able to check with the user want to stop. Note that signalHandlers are disabled for the reactor. If not reactor is choosen then a thread is used and will be started enclosed in the _do_read_thread method.
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
TCPProtocol assure routing functions of the TCP protocol. It basically route packets to the right tcp session.
Forge the TCP packet with the given argument and the payload if present
Loop through all the connections to check that the given port is free. Note this method does not take in account real connection made by the kernel
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
TCPApplication provides the functionnalities for layer 7 protocols. So there is just connection management and buffer reading/writing. Moreover for connection management it basically just call the ones from tcpsession which really do the stuff.
Call the bind method of TCPSession with attributes. Be careful it is really important to understand what are attributes:
connect the server will be attached to this tcpapplication If no app is provided the tcpapplication used is self ! - newinstance: Define if all the clients should be linked on the same tcpapplication (attribute app) or if should be forked for each.
By default does nothing, but could be important in some layer 7 implementation like SSH ..
Fetch_data acquire the mutex in order to pop data of the wanted size. If no size is specified return all the datas
Method called by tcpsession when a packet is received. Can be overriden to apply operation on incoming packets
Method called by tcpsession just before a tcp packet is crafted and sent
At this level a packet is Raw data so bytes. This method acquire the mutex add received datas and release the mutex.
Override the transfertPacket method of Layer. Because for a server that use the same tcpapplication for every client the tcpsession to target is not the default me the right client. So check if a client was sent in kwargs if it is the case send the packet to the tcpsession of the client default otherwise
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
FINACK = 17 SYNACK = 18 PSHACK = 24 RSTACK = 20
State class is the mother class that describe a state at a given moment. A state is just characterised by a name and should implement a method called packet_received that will provide the adapted state behavior for every packets
Bases: pystack.layers.tcp_session.State
Any packets received on a Closed connection is being replied with a reset packet
Bases: pystack.layers.tcp_session.State
This state is not implemented in the stack. The stack always send both FIN and ACK in the same packet
Bases: pystack.layers.tcp_session.State
When the session is in the established state it should handle a lot’s of different cases and react in consequences
Bases: pystack.layers.tcp_session.State
When in FIN_WAIT expect a FIN and ACK packet. If it received a FIN_ACK packet it sends a ACK switch to closed and unregister itself from both the upper and the lower layer
Bases: pystack.layers.tcp_session.State
In FIN_WAIT2 if the host send a FIN to session can be ended up sucessfully.
Bases: pystack.layers.tcp_session.State
When in Last_ACK just wait for the final ack to close the connection
Bases: pystack.layers.tcp_session.State
A tcp session in Listen state only process SYN packet. When a SYN packet is received it checks that the number of connection to accept is not exceeded. If this is ok it creates another TCP session specific for this connection. Then it attachs it a TCPApplication either by forking it or not depending of the config. Then it switched the newly created connection to SYN_SENT state.
Bases: pystack.layers.tcp_session.State
When in SYN_RCVD only process ACK packets. Then switch the state to ESTABLISHED and call ConnectionMade
Bases: pystack.layers.tcp_session.State
When in SYN_SENT only process SYN_ACK packets by replying a ACK packet. It also switch the state to ESTABLISHED and call the session _call_connection_made method
Bases: pystack.layers.tcp_session.State
Not implemented state directly deleted (normally put to closed for few sec)
Bases: pystack.layers.layer.Layer
TCPSession contains the core methods to deal with a lot of cases that can be met with TCP. This class mainly implement methods to connect, bind and close a TCP session with a remote host. At every moment a TCP session have a standardised state from CLOSED, ESTABLISHED, .. This class also keeps at every moment all the variables needed in order to process TCP packets like sequence number, acknowledgement number, port ..
From a server point of view every client connections are hold in the connections attribute. When accept is called the method start by flushing all CLOSED connections from the connections list. Then it waiting for a connection to be appended to the list to return it. (when the currentconnection value is changed)
The bind method is quite ligthweight. It justs register itself to the TCP protocol as a handler and an entry is added to iptables to prevent the Hosting host to reply with RST. Note app and newinstance define on which TCPApplication client connections should be redirected and if the TCPApplication should be forked for every client or not.
For a client will send a FIN packet and switch to FIN_WAIT1. For a server will send a FIN packet for every clients in order to unregister itself from the TCP layer
This method try to connect to the given ip and port. If the TCP session is not CLOSED the operations are aborted. Else a local port is generated, an entry is added in iptables to preven the kernel to disturbe our connection and then a SYN packet is sent. Then the connection state is switched to SYN_SENT. The method will then loop for 20 seconds checking if the state has changed to ESTABLISHED. If not it means that a problem occured and everything is rolled back.
This method basically just switch the current state from CLOSED to LISTEN so that SYN request will be handled.
The more important thing with this method is that for each packet this method can be called twice. The first time by the lower layer and the packet is TCP. Then the packet is processed and packet_received is possibly called once again with the packet decapsulated (in Raw). When a TCP packet is received seq and ack value are updated when the packet_received method of the current state of the connection is called to know what to do with the current packet.
Just call send_packet with datas. The nextAck indicator is also updated to the excpected value.
This method is one of the most critical. Every TCP packet are sent through this method. This method basically deal with all the flags and is in charge to incremente sequence number. In addition it sets all the TCP fields in order to generate the packet. It increment the ack value of the data size of the previously received packet.
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
UDP Protocol provides basic functions of UDP. It allow to send and receive UDP packet
Author: Robin David License: GNU GPLv3 Repo: https://github.com/RobinDavid
Copyright (c) 2012 Robin David
PyStack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version http://www.gnu.org/licenses/.
Bases: pystack.layers.layer.Layer
UDP Application provides input output functionalities above the UDP layer. An UDP application is directly linked to the UDP layer (not like in TCP) because UDP is stateless
Bind like connect will register a handler in the UDP layer. But it will also prevent the host to send ICMP host port unreachable
In UDP connect is not really meaningfull. In this case it just means register an handler for the connection in the UDP layer
fetch_data_from use the socket syntax and arguments. It returns the datas associated to the given host. Because data in UDP is not a string this a list of string identified by the remote IP.