diff --git a/Network_and_802.11/socket/reading_socket.py b/Network_and_802.11/other_scripts/netcat_shell.py
similarity index 98%
rename from Network_and_802.11/socket/reading_socket.py
rename to Network_and_802.11/other_scripts/netcat_shell.py
index 68635b4..1076bdb 100755
--- a/Network_and_802.11/socket/reading_socket.py
+++ b/Network_and_802.11/other_scripts/netcat_shell.py
@@ -4,7 +4,6 @@ __author__ = "bt3"
import os
-import socket
from subprocess import Popen, STDOUT, PIPE
# Defining constants
diff --git a/Network_and_802.11/socket/README.md b/Network_and_802.11/socket/README.md
new file mode 100644
index 0000000..a49bbe9
--- /dev/null
+++ b/Network_and_802.11/socket/README.md
@@ -0,0 +1,684 @@
+# The Socket Module
+
+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:
+
+```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 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:
+
+
+```python
+import socket
+
+HOST = 'www.google.com'
+PORT = 80
+DATA = 'GET / HTTP/1.1\r\nHost: google.com\r\n\r\n'
+
+def tcp_client():
+ client = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
+ client.connect(( HOST, PORT ))
+ client.send(DATA)
+ response = client.recv(4096)
+ print response
+
+if __name__ == '__main__':
+ tcp_client()
+```
+
+The simplicity of this script relies in making the following assumptions about the sockets:
+
+* our *connection will always succeed*,
+* 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):
+
+```bash
+$ python tcp_client.py
+HTTP/1.1 301 Moved Permanently
+Location: http://www.google.com/
+Content-Type: text/html; charset=UTF-8
+Date: Mon, 15 Dec 2014 16:52:46 GMT
+Expires: Wed, 14 Jan 2015 16:52:46 GMT
+Cache-Control: public, max-age=2592000
+Server: gws
+Content-Length: 219
+X-XSS-Protection: 1; mode=block
+X-Frame-Options: SAMEORIGIN
+Alternate-Protocol: 80:quic,p=0.02
+
+
+301 Moved
+301 Moved
+The document has moved
+here.
+
+```
+
+Simple like that.
+
+----------
+## A TCP Server
+
+Let's move on and write a *multi-threaded* TCP server. For this we will use Python's [threading](https://docs.python.org/2/library/threading.html) module.
+
+First we define the IP address and port that we want the server to listen on. We then define a **handle_client** function that starts a thread to handle client connections. The function takes the client socket and gets data from the client, sending a **ACK** message.
+
+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:
+
+```python
+import socket
+import threading
+
+BIND_IP = '0.0.0.0'
+BIND_PORT = 9090
+
+def handle_client(client_socket):
+ request = client_socket.recv(1024)
+ print "[*] Received: " + request
+ client_socket.send('ACK')
+ client_socket.close()
+
+def tcp_server():
+ server = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
+ server.bind(( BIND_IP, BIND_PORT))
+ server.listen(5)
+ print"[*] Listening on %s:%d" % (BIND_IP, BIND_PORT)
+
+ while 1:
+ client, addr = server.accept()
+ print "[*] Accepted connection from: %s:%d" %(addr[0], addr[1])
+ client_handler = threading.Thread(target=handle_client, args=(client,))
+ client_handler.start()
+
+if __name__ == '__main__':
+ tcp_server()
+```
+
+We can run this script in one terminal and the client script (like the one we saw before) in a second terminal. Running the server:
+```bash
+$ python tcp_server.py
+[*] Listening on 0.0.0.0:9090
+```
+
+Running the client script (we changed it to connect at 127.0.0.1:9090):
+```bash
+$ python tcp_client.py
+ACK
+```
+
+Now, back to the server server terminal we successfully see the established connection:
+
+```bash
+$ python tcp_server.py
+[*] Listening on 0.0.0.0:9090
+[*] Accepted connection from: 127.0.0.1:44864
+[*] Received: GET / HTTP/1.1
+```
+
+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.
+
+We can make a few changes in the previous script to create a UDP client connection:
+
+* we use **SOCK_DGRAM** instead of **SOCK_STREAM**,
+* because UDP is a connectionless protocol, we don't need to establish a connection beforehand, and
+* we use **sendto** and **recvfrom** instead of **send** and **recv**.
+
+```python
+import socket
+
+HOST = '127.0.0.1'
+PORT = 9000
+DATA = 'AAAAAAAAAA'
+
+def udp_client():
+ client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM)
+ client.sendto(DATA, ( HOST, PORT ))
+ data, addr = client.recvfrom(4096)
+ print data, adr
+
+if __name__ == '__main__':
+ udp_client()
+```
+
+-----
+
+## An UDP Server
+
+Below is an example of a very simple UDP server. Notice that there is no **listen** or **accept**:
+
+
+```python
+import socket
+
+BIND_IP = '0.0.0.0'
+BIND_PORT = 9000
+
+def udp_server():
+ server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ server.bind(( BIND_IP, BIND_PORT))
+ print "Waiting on port: " + str(BIND_PORT)
+
+ while 1:
+ data, addr = server.recvfrom(1024)
+ print data
+
+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!
+
+---------
+## A Very Simple Netcat Client
+
+Sometimes when you are penetrating a system, you wish you have [netcat](http://netcat.sourceforge.net/), which might be not installed. However, if you have Python, you can create a netcat network client and server.
+
+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).
+
+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:
+
+
+```python
+import socket
+
+PORT = 12345
+HOSTNAME = '54.209.5.48'
+
+def netcat(text_to_send):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect(( HOSTNAME, PORT ))
+ s.sendall(text_to_send)
+ s.shutdown(socket.SHUT_WR)
+
+ rec_data = []
+ while 1:
+ data = s.recv(1024)
+ if not data:
+ break
+ rec_data.append(data)
+
+ s.close()
+ return rec_data
+
+if __name__ == '__main__':
+ text_to_send = ''
+ text_recved = netcat( text_to_send)
+ print text_recved[1]
+```
+
+
+
+
+---------
+## A Complete Netcat Client and Server
+
+
+Let's extend our previous example to write a script 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.
+
+
+### The Usage Menu
+The first function we write is **usage**, with the options we want for our tool:
+
+```python
+def usage():
+ print "Usage: netcat_awesome.py -t -p "
+ print " -l --listen listen on HOST:PORT"
+ print " -e --execute=file execute the given file"
+ print " -c --command initialize a command shell"
+ print " -u --upload=destination upload file and write to destination"
+ print
+ print "Examples:"
+ print "netcat_awesome.py -t localhost -p 5000 -l -c"
+ print "netcat_awesome.py -t localhost -p 5000 -l -u=example.exe"
+ print "netcat_awesome.py -t localhost -p 5000 -l -e='ls'"
+ print "echo 'AAAAAA' | ./netcat_awesome.py -t localhost -p 5000"
+ sys.exit(0)
+```
+
+## 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**:
+
+```python
+import socket
+import sys
+import getopt
+import threading
+import subprocess
+
+LISTEN = False
+COMMAND = False
+UPLOAD = False
+EXECUTE = ''
+TARGET = ''
+UP_DEST = ''
+PORT = 0
+
+def main():
+ global LISTEN
+ global PORT
+ global EXECUTE
+ global COMMAND
+ global UP_DEST
+ global TARGET
+
+ if not len(sys.argv[1:]):
+ usage()
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu", \
+ ["help", "LISTEN", "EXECUTE", "TARGET", "PORT", "COMMAND", "UPLOAD"])
+ except getopt.GetoptError as err:
+ print str(err)
+ usage()
+
+ for o, a in opts:
+ if o in ('-h', '--help'):
+ usage()
+ elif o in ('-l', '--listen'):
+ LISTEN = True
+ elif o in ('-e', '--execute'):
+ EXECUTE = a
+ elif o in ('-c', '--commandshell'):
+ COMMAND = True
+ elif o in ('-u', '--upload'):
+ UP_DEST = a
+ elif o in ('-t', '--target'):
+ TARGET = a
+ elif o in ('-p', '--port'):
+ PORT = int(a)
+ else:
+ assert False, "Unhandled option"
+
+ # NETCAT client
+ if not LISTEN and len(TARGET) and PORT > 0:
+ buffer = sys.stdin.read()
+ client_sender(buffer)
+
+ # NETCAT server
+ if LISTEN:
+ if not len(TARGET):
+ TARGET = '0.0.0.0'
+ server_loop()
+
+if __name__ == '__main__':
+ main()
+```
+
+
+### The Client Function
+The **client_sender** function is very similar to the netcat client snippet we have seen above. It creates a socket object and then it goes to a loop to send/receive data:
+
+```python
+def client_sender(buffer):
+ client = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+
+ try:
+ client.connect(( TARGET, PORT ))
+
+ # test to see if received any data
+ if len(buffer):
+ client.send(buffer)
+
+ while True:
+ # wait for data
+ recv_len = 1
+ response = ''
+
+ while recv_len:
+ data = client.recv(4096)
+ recv_len = len(data)
+ response += data
+ if recv_len < 4096:
+ break
+ print response
+
+ # wait for more input until there is no more data
+ buffer = raw_input('')
+ buffer += '\n'
+
+ client.send(buffer)
+
+ except:
+ print '[*] Exception. Exiting.'
+ client.close()
+```
+
+### 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:
+
+```python
+def server_loop():
+ server = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ server.bind(( TARGET, PORT ))
+ server.listen(5)
+
+ while True:
+ client_socket, addr = server.accept()
+ client_thread = threading.Thread( target =client_handler, \
+ args=(client_socket,))
+ client_thread.start()
+```
+
+The **threading** function calls **client_handler** which will either upload a file, or execute a command:
+```python
+
+def client_handler(client_socket):
+ global UPLOAD
+ global EXECUTE
+ global COMMAND
+
+ # check for upload
+ if len(UP_DEST):
+ file_buf = ''
+
+ # keep reading data until no more data is available
+ while 1:
+ data = client_socket.recv(1024)
+ if data:
+ file_buffer += data
+ else:
+ break
+
+ # try to write the bytes (wb for binary mode)
+ try:
+ with open(UP_DEST, 'wb') as f:
+ f.write(file_buffer)
+ client_socket.send('File saved to %s\r\n' % UP_DEST)
+ except:
+ client_socket.send('Failed to save file to %s\r\n' % UP_DEST)
+
+ # Check for command execution:
+ if len(EXECUTE):
+ output = run_command(EXECUTE)
+ client_socket.send(output)
+
+ # Go into a loop if a command shell was requested
+ if COMMAND:
+ while True:
+ # show a prompt:
+ client_socket.send('NETCAT: ')
+ cmd_buffer = ''
+
+ # scans for a newline character to determine when to process a command
+ while '\n' not in cmd_buffer:
+ cmd_buffer += client_socket.recv(1024)
+
+ # send back the command output
+ response = run_command(cmd_buffer)
+ client_socket.send(response)
+```
+
+Observe the two last lines above. The program calls the function **run_command** which use the **subprocess** library to allow a process-creation interface. This gives a number of ways to start and interact with client programs:
+
+```python
+def run_command(command):
+ command = command.rstrip()
+ print command
+ try:
+ output = subprocess.check_output(command, stderr=subprocess.STDOUT, \
+ shell=True)
+ except:
+ output = "Failed to execute command.\r\n"
+ return output
+```
+
+### Firing Up a Server and a Client
+Now we can put everything together and run the script as a server in a terminal and as a client in another. Running as a server:
+
+```bash
+$ netcat_awesome.py -l -p 9000 -c
+```
+
+And as a client (to get the shell, press CTRL+D for EOF):
+
+```bash
+$ python socket/netcat_awesome.py -t localhost -p 9000
+NETCAT:
+ls
+crack_linksys.py
+netcat_awesome.py
+netcat_simple.py
+reading_socket.py
+tcp_client.py
+tcp_server.py
+udp_client.py
+NETCAT:
+```
+
+### The Good 'n' Old Request
+
+Additionally, we can use our client to send out requests:
+
+```bash
+$ echo -ne "GET / HTTP/1.1\nHost: www.google.com\r\n\r\n" | python socket/netcat_awesome.py -t www.google.com -p 80
+HTTP/1.1 200 OK
+Date: Tue, 16 Dec 2014 21:04:27 GMT
+Expires: -1
+Cache-Control: private, max-age=0
+Content-Type: text/html; charset=ISO-8859-1
+Set-Cookie: PREF=ID=56f21d7bf67d66e0:FF=0:TM=1418763867:LM=1418763867:S=cI2xRwXGjb6bGx1u; expires=Thu, 15-Dec-2016 21:04:27 GMT; path=/; domain=.google.com
+Set-Cookie: NID=67=ZGlY0-8CjkGDtTz4WwR7fEHOXGw-VvdI9f92oJKdelRgCxllAXoWfCC5vuQ5lJRFZIwghNRSxYbxKC0Z7ve132WTeBHOCHFB47Ic14ke1wdYGzevz8qFDR80fpiqHwMf; expires=Wed, 17-Jun-2015 21:04:27 GMT; path=/; domain=.google.com; HttpOnly
+P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
+Server: gws
+X-XSS-Protection: 1; mode=block
+X-Frame-Options: SAMEORIGIN
+Alternate-Protocol: 80:quic,p=0.02
+Transfer-Encoding: chunked
+(...)
+```
+
+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).
+
+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.
+
+
+### 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:
+
+```python
+import socket
+import threading
+import sys
+
+def main():
+ if len(sys.argv[1:]) != 5:
+ print "Usage: ./proxy.py "
+ print "Example: ./proxy.py 127.0.0.1 9000 10.12.122.1 9999 True"
+ sys.exit()
+
+ local_host = sys.argv[1]
+ local_port = int(sys.argv[2])
+ remote_host = sys.argv[3]
+ remote_port = int(sys.argv[4])
+
+ if sys.argv[5] == 'True':
+ receive_first = True
+ else:
+ receive_first = False
+
+ server_loop(local_host, local_port, remote_host, remote_port, receive_first)
+```
+
+
+### The Server Loop Function
+
+Like before we start creating a socket and binding this to a port and a host. Then we start a loop that accepts incoming connections and spawns a thread to the new connection:
+
+```python
+def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
+ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+ try:
+ server.bind(( local_host, local_port))
+ except:
+ print "[!!] Failed to listen on %s:%d" % (local_host, local_port)
+ sys.exit()
+
+ print "[*] Listening on %s:%d" % (local_host, local_port)
+ server.listen(5)
+
+ while 1:
+ client_socket, addr = server.accept()
+ print "[==>] Received incoming connection from %s:%d" %(addr[0], addr[1])
+
+ # start a thread to talk to the remote host
+ proxy = threading.Thread(target=proxy_handler, \
+ args=(client_socket, remote_host, remote_port, receive_first))
+ proxy.start()
+```
+
+### The Proxy Handler Functions
+
+In the last two lines of the above snippet, the program spawns a thread for the function **proxy_handler** which we show below. This function creates a TCP socket and connects to the remote host and port. It then checks for the **receive_first** parameter. Finally, it goes to a loop where it:
+
+1. reads from local host (with the function **receive_from**),
+2. processes (with the function **hexdump**),
+3. sends to remote host (with the function **response_handler** and **send**),
+4. reads from remote host (with the function **receive_from**),
+5. processes (with the function **hexdump**), and
+6. sends to local host (with the function **response_handler** and **send**).
+
+This keeps going until the loop is stopped, which happens when both local and remote buffers are empty. Let's take a look:
+
+```python
+def proxy_handler(client_socket, remote_host, remote_port, receive_first):
+ remote_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
+ remote_socket.connect(( remote_host, remote_port ))
+
+ if receive_first:
+ remote_buffer = receive_from(remote_socket)
+ hexdump(remote_buffer)
+ remote_buffer = response_handler(remote_buffer)
+
+ # if we have data to send to client, send it:
+ if len(remote_buffer):
+ print "[<==] Sending %d bytes to localhost." %len(remote_buffer)
+ client_socket.send(remote_buffer)
+
+ while 1:
+ local_buffer = receive_from(client_socket)
+ if len(local_buffer):
+ print "[==>] Received %d bytes from localhost." % len(local_buffer)
+ hexdump(local_buffer)
+ local_buffer = request_handler(local_buffer)
+ remote_socket.send(local_buffer)
+ print "[==>] Sent to remote."
+
+ remote_buffer = receive_from(remote_socket)
+ if len(remote_buffer):
+ print "[==>] Received %d bytes from remote." % len(remote_buffer)
+ hexdump(remote_buffer)
+ remote_buffer = response_handler(remote_buffer)
+ client_socket.send(remote_buffer)
+ print "[==>] Sent to localhost."
+
+ if not len(local_buffer) or not len(remote_buffer):
+ client_socket.close()
+ remote_socket.close()
+ print "[*] No more data. Closing connections"
+ break
+```
+
+
+The **receive_from** function takes a socket object and performs the receive, dumping the contents of the packet:
+
+```python
+def receive_from(connection):
+ buffer = ''
+ connection.settimeout(2)
+ try:
+ while True:
+ data = connection.recv(4096)
+ if not data:
+ break
+ buffer += data
+ except:
+ pass
+ return buffer
+```
+
+The **response_handler** function is used to modify the packet contents from the inbound traffic (for example, to perform fuzzing, test for authentication, etc). The function **request_handler** does the same for outbound traffic:
+
+```python
+def request_handler(buffer):
+ # perform packet modifications
+ buffer += ' Yaeah!'
+ return buffer
+
+def response_handler(buffer):
+ # perform packet modifications
+ return buffer
+```
+
+
+Finallty, the function **hexdump** outputs the packet details with hexadecimal and ASCII characters:
+
+```python
+def hexdump(src, length=16):
+ result = []
+ digists = 4 if isinstance(src, unicode) else 2
+ for i in range(len(src), lenght):
+ s = src[i:i+length]
+ hexa = b' '.join(['%0*X' % (digits, ord(x)) for x in s])
+ text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
+ result.append(b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text))
+```
+
+
+
+### Firing Up our Proxy
+
+Now we just need to run our script with some server. For example, for a FTP server at the standard port 21:
+```sh
+$ sudo ./tcp_proxy.py localhost 21 ftp.target 21 True
+[*] Listening on localhost:21
+(...)
+```
+
+
+
+-----
+
+## References:
+
+- [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).
+- [An asynchronous HTTP Proxy](https://github.com/OffensivePython/PyProxy/blob/master/PyProxy.py).
+- [A network sniffer at the Network Layer](https://github.com/OffensivePython/Sniffy/blob/master/Sniffy.py).
+- [A Guide to Network Programming in C++](http://beej.us/guide/bgnet/output/html/multipage/index.html).
+
+----
+
diff --git a/Network_and_802.11/socket/udp_client.py b/Network_and_802.11/socket/udp_client.py
index 5dee390..73b55d0 100755
--- a/Network_and_802.11/socket/udp_client.py
+++ b/Network_and_802.11/socket/udp_client.py
@@ -7,7 +7,7 @@ import socket
# Defining constants
HOST = '127.0.0.1'
-PORT = 80
+PORT = 9000
DATA = 'AAABBBCCC'
diff --git a/Network_and_802.11/socket/udp_server.py b/Network_and_802.11/socket/udp_server.py
new file mode 100755
index 0000000..7543ad8
--- /dev/null
+++ b/Network_and_802.11/socket/udp_server.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+__author__ = "bt3"
+
+import socket
+
+BIND_IP = '0.0.0.0'
+BIND_PORT = 9000
+
+def udp_server():
+
+
+ server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ server.bind(( BIND_IP, BIND_PORT))
+ print "Waiting on port: " + str(BIND_PORT)
+
+ while 1:
+ data, addr = server.recvfrom(1024)
+ print data
+
+if __name__ == '__main__':
+ udp_server()
\ No newline at end of file