socket readme - fixed some typos

This commit is contained in:
Mari Wahl 2014-12-17 16:43:58 -05:00
parent 48cbb073f1
commit 2802913b9c

View File

@ -3,20 +3,19 @@
Python's [socket](https://docs.python.org/2/library/socket.html) module contains all the tools to write [TCP](http://en.wikipedia.org/wiki/Transmission_Control_Protocol)/[UDP](http://en.wikipedia.org/wiki/User_Datagram_Protocol) clients and servers, including [raw sockets](http://en.wikipedia.org/wiki/Raw_socket). It's really nice!
---
## A TCP Client
Let's start from the beginning. Any time when you want to create a TCP connection with the **socket** module, you do two things: create a socket object and then connect to a host in some port:
Let's start from the beginning. Whenever you want to create a TCP connection with the **socket** module, you do two things: create a socket object and then connect to a host in some port:
```python
client = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
client.connect(( HOST, PORT ))
```
The **AF_INET** parameter is used to define the standard IPv4 address and the **SOCK_STREAM** parameters indicate it is a **TCP** connection.
The **AF_INET** parameter is used to define the standard IPv4 address (other options are *AF_UNIX* and *AF_INET6*). The **SOCK_STREAM** parameters indicate it is a **TCP** connection (other options are *SOCK_DGRAM*, *SOCK_RAW*, *SOCK_RDM*, *SOCK_SEQPACKET*).
The next things you want to do is to send and receive data, using socket's **send** and **recv** functions.
Let's put everything together to create our client script:
All right, so the next thing you want to do is to send and receive data using socket's **send** and **recv** methods. And this should be good enough for a first script! Let's put everything together to create our TCP client:
```python
@ -43,7 +42,7 @@ The simplicity of this script relies in making the following assumptions about t
* the *server is always waiting for us to send data first* (as oppose to servers that expect to send data and then wait for response), and
* the server will always send us data back in a *short time*.
Let's run this script (notice that we get *Moved Permanently* because Google only issues HTTPS connections):
Let's run this script (notice that we get *Moved Permanently* because Google issues HTTPS connections):
```bash
$ python tcp_client.py
@ -78,7 +77,7 @@ First we define the IP address and port that we want the server to listen on. W
The main function for our server, **tcp_server**, creates a server socket and starts listening on the port and IP (we set the maximum backlog of connections to 5). Then it starts a loop waiting from when a client connects. When this happens, it receives the client socket (the client variables go to the **addr** variable).
At this point, the program creates a thread object for the function **handle_client** which we mention above:
At this point, the program creates a thread object for the function **handle_client** which we mentioned above:
```python
import socket
@ -121,7 +120,7 @@ $ python tcp_client.py
ACK
```
Now, back to the server server terminal we successfully see the established connection:
Now, back to the server terminal, we successfully see the established connection:
```bash
$ python tcp_server.py
@ -137,7 +136,7 @@ Awesome!
----------
## An UDP Client
UDP is an alternative protocol to TCP. Like TCP, it is used for packet transfer from one host to another. Unlike TCP, it is a connectionless and non-stream oriented protocol. This means that an UDP server receives incoming packets from any host without establishing a reliable pipe type of connection.
UDP is an alternative protocol to TCP. Like TCP, it is used for packet transfer from one host to another. Unlike TCP, it is a *connectionless* and *non-stream oriented protocol*. This means that an UDP server receives incoming packets from any host without establishing a reliable pipe type of connection.
We can make a few changes in the previous script to create a UDP client connection:
@ -188,7 +187,7 @@ if __name__ == '__main__':
udp_server()
```
You can test running the client in one terminal and the client in another. It works and it's cool!
You can test it by running the server in one terminal and the client in another. It works and it's fun!
---------
## A Very Simple Netcat Client
@ -197,7 +196,7 @@ Sometimes when you are penetrating a system, you wish you have [netcat](http://n
The following script is the simplest netcat client setup one can have, extended from our TCP client script to support a loop.
In addition, now we use the **sendall** method which, unlike **send**, continues to send data until either all data has been sent or an error occurs (None is returned on success).
In addition, now we use the **sendall** method. Unlike **send**, it will continue to send data until either all data has been sent or an error occurs (None is returned on success).
We also use **close** to release the resource. This does not necessarily close the connection immediately so we use **shutdown** to close the connection in a timely fashion:
@ -237,7 +236,7 @@ if __name__ == '__main__':
## A Complete Netcat Client and Server
Let's extend our previous example to write a script for a netcat server and client.
Let's extend our previous example to write a full program for a netcat server and client.
For this task we are going to use two special Python modules: [getopt](https://docs.python.org/2/library/getopt.html), which is a parser for command line options (familiar to users of the C getopt()), and [subprocess](https://docs.python.org/2/library/subprocess.html), which allows you to spawn new processes.
@ -262,7 +261,7 @@ def usage():
```
## Parsing Arguments in the Main Function
Now, before we dive in each specific functions, lets see what the **main** function does. First it reads the arguments and parses them using **getopt**, following up by the handling of these arguments. Then the program decides if it is a client or a server, with the constant **LISTEN**:
Now, before we dive in each specific functions, let's see what the **main** function does. First it reads the arguments and parses them using **getopt**. Then, it processes them. Finally, the program decides if it is a client or a server, with the constant **LISTEN**:
```python
import socket
@ -370,7 +369,7 @@ def client_sender(buffer):
```
### The Server Functions
Now, let's take a look into the **server_loop** function, which is very similar to the TCP server script we saw above:
Now, let's take a look into the **server_loop** function, which is very similar to the TCP server script we saw before:
```python
def server_loop():
@ -385,7 +384,7 @@ def server_loop():
client_thread.start()
```
The **threading** function calls **client_handler** which will either upload a file, or execute a command:
The **threading** function calls **client_handler** which will either upload a file, or execute a command (in a special shell named *NETCAT*):
```python
def client_handler(client_socket):
@ -499,13 +498,13 @@ Cool, huh?
## A TCP Proxy
A TCP proxy can be very useful for forwarding traffic and when assessing network-based softwares (for example, when you cannot run [Wireshark](http://bt3gl.github.io/wiresharking-for-fun-or-profit.html) or you cannot load drivers or tools).
A TCP proxy can be very useful for forwarding traffic and when assessing network-based softwares (for example, when you cannot run [Wireshark](http://bt3gl.github.io/wiresharking-for-fun-or-profit.html) or you cannot load drivers or tools in the machine you are exploiting).
To create a proxy we need to first verify if we need to *first initiate a connection* to the remote side and *request data before going into our main loop*. Some server daemons will expect you to do this first (FTP servers, for example, send a banner first). We will send this information as one of the running arguments.
To create a proxy we need to verify if we need to *first initiate a connection* to the remote side. This will request data before going into our main loop and some server daemons expect you to do this first (for instance, FTP servers send a banner first). We call this information **receive_first**.
### The Main Function
So let us start with our **main** function. First we define the usage, which should have four more arguments together with the above **receive_first** information. Then we check these arguments to variables and start a listening socket:
So let us start with our **main** function. First we define the usage, which should have four more arguments together with **receive_first**. Then we check these arguments to variables and start a listening socket:
```python
import socket
@ -643,7 +642,7 @@ def response_handler(buffer):
```
Finallty, the function **hexdump** outputs the packet details with hexadecimal and ASCII characters:
Finally, the function **hexdump** outputs the packet details with hexadecimal and ASCII characters:
```python
def hexdump(src, length=16):
@ -669,10 +668,67 @@ $ sudo ./tcp_proxy.py localhost 21 ftp.target 21 True
-----
## References:
---
## Extra Stuff: The socket Object Methods
Additionally, let's take a quick look to all the methods available with the **socket** object from the **socket** module. I think it's useful to have an idea of this list:
* **socket.accept()**: Accept a connection.
* **socket.bind(address)**: Bind the socket to address.
* **socket.close()**: Close the socket.
* **socket.fileno()**: Return the socket's file descriptor.
* **socket.getpeername()**: Return the remote address to which the socket is connected.
* **socket.getsockname()**: Return the socket's own address.
* **socket.getsockopt(level, optname[, buflen])**: Return the value of the given socket option.
* **socket.listen(backlog)**: Listen for connections made to the socket. The backlog argument specifies the maximum number of queued connections
* **socket.makefile([mode[, bufsize]])**: Return a file object associated with the socket.
* **socket.recv(bufsize[, flags])**: Receive data from the socket.
* **socket.recvfrom(bufsize[, flags])**: Receive data from the socket.
* **socket.recv_into(buffer[, nbytes[, flags]])**: Receive up to nbytes bytes from the socket, storing the data into a buffer rather than creating a new string.
* **socket.send(string[, flags])**: Send data to the socket.
* **socket.sendall(string[, flags])**: Send data to the socket.
* **socket.sendto(string, address)**: Send data to the socket.
* **socket.setblocking(flag)**: Set blocking or non-blocking mode of the socket.
* **socket.settimeout(value)**: Set a timeout on blocking socket operations.
* **socket.gettimeout()**: Return the timeout in seconds associated with socket operations, or None if no timeout is set.
* **socket.setsockopt(level, optname, value)**: Set the value of the given socket option.
* **socket.shutdown(how)**: Shut down one or both halves of the connection.
* **socket.family**: The socket family.
* **socket.type**: The socket type.
* **socket.proto**: The socket protocol.
## Further References:
- [Python's Socket Documentation](https://docs.python.org/2/library/socket.html)
- [Black Hat Python](http://www.nostarch.com/blackhatpython).
- [My Gray hat repo](https://github.com/bt3gl/My-Gray-Hacker-Resources).
- [A TCP Packet Injection tool](https://github.com/OffensivePython/Pinject/blob/master/pinject.py).