Skip to content

A collection of Python network programming tools and pentesting scripts inspired by "Black Hat Python", featuring a custom Netcat alternative, TCP/UDP clients, and a unified CLI runner.

Notifications You must be signed in to change notification settings

joaoluke/python_networks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Contributors Forks Stargazers Issues Python GitHub Licence


🇧🇷 Leia em Português

Logo

Python Networks

Python Network Programming for devs, hackers, and pentesters.

· Report Bug · Request Feature

Table of Contents
  1. About the Project
  2. Initial Questions
  3. TCP Client
  4. UDP Client
  5. TCP Server
  6. Replacing Netcat
  7. Creating a TCP Proxy
  8. SSH with Paramiko
  9. Contribution
  10. Contact
  11. Acknowledgments

About the Project

Python is the "darling" language for cybersecurity lovers. As we explore the content of one of the biggest best-sellers on the subject (Black Hat Python), we will learn deeply about the technologies and even build our own pentesting tools with Python!

We will learn about chapters 2, 3, and 4 of Black Hat, covering networking themes. We will learn to make our own TCP client, UDP client, TCP server, create a Netcat substitute, a Proxy, SSH tunneling, IP layer decoding, email credential theft, Sniffing, and much more (let's stop being just "script kiddies"). So sit back comfortably and let's get hacking!

If you love programming, love Python, and love cybersecurity, this content is for you! I made it with lots of love 💜.

Initial Questions

Let's start preparing the environment for programming. To begin, have a computer with internet access, a text editor or IDE (my advice is to use PyCharm free version). The book asks you to install Kali Linux in a VM, but it can be any Linux machine or even MacOS. If we need any specific package installation, I will mention it in each chapter, don't worry!

My tips are: practice each theme a lot, look closely at the examples and external references I will place in each subject, search for information on the discussed theme on the internet. If you have any specific doubt, you can send it to me via contact or post on StackOverflow. I hope you have the curiosity and commitment to absorb each topic deeply. If an example seems very difficult at first, calm down and look carefully and without haste, as I will comment on each topic step by step.

Prerequisites

  • Linux Machine (either VM or installed on HDD)
  • Prior knowledge in Python (I won't go into syntax details but rather functionalities, so it's good to have intermediate knowledge of programming logic and Python)
  • Kali-Linux (optional)
  • Knowledge of Linux commands
  • Python3 installed on your machine (preferably system-wide default)
  • WingIDE (optional, book suggestion)
  • Basic knowledge of computer networks (knowing how protocols work can help you a lot in this demo)

Note: I placed some cool links in the Acknowledgments at the end of the file with some cool content on Networks, Linux commands, PyCharm installation...

Installations

To install pip so we can install some tools we will use, run the following command:

sudo apt-get install python-setuptools python-pip

To install Python 3, first check if there is any Python version installed on your machine with the command:

$ which python

or

$ which python3

which should return something like /usr/bin/python. This means Python is installed at that address.

To install it with apt-get:

$ sudo apt-get install python3
$ sudo apt-get install python3-pip

To install WingIDE use the command:

$ sudo dpkg -i wingide5_5.0.9-1_i386.deb

and

$ sudo apt-get -f install

TCP Client

To send some garbage data for testing, fuzzing, or any other task, we must have a TCP Client in a simple way.

  • I import the socket library to use blocking sockets.
  • I define my host and port to connect to.
  • I create a socket object with the AF_INET parameter which tells me we want a standard IPv4 address or a host name, and SOCK_STREAM which indicates this will be a TCP client.
  • I send some data to it.
  • I receive some data.

Note: Making some serious assumptions about sockets that you should be aware of. The first assumption is that our connection will always succeed, the second is that the server will always be expecting us to send data first (as opposed to servers that expect to send data to you first and wait for your response), the third assumption is that the server will always send data back immediately.

UDP Client

Not being very different from the TCP client, we make only four small changes so that packets are sent in UDP format:

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  • Where SOCK_DGRAM indicates a UDP client.
  • We do a bind() to connect the socket to the destination address.
  • And with sendto() we pass the data and the server to which you want to send the data.
  • The last step consists of calling recvfrom() to receive the UDP data back.

Note: Since the UDP protocol is not connection-oriented, there is no call prior to connect(). You will observe that both data and details about the remote host and port are received, along with the UDP message which in our case was Hello, server UDP.

For more information about UDP connection with Python see the link UDP example

TCP Server

Creating a TCP server is as simple as creating a client, but attention is needed to configure your server to your client; maybe connection errors can occur because you might be trying to make this connection on reserved ports. Pay attention!

Here is a standard multithreaded TCP server:

  • At the beginning, we do what we are already used to doing with bind(), passing the IP address and the port we want the server to listen on.
  • Then with server.listen(1) we tell the server to start listening with a maximum of connections defined at 1 (my choice, you can put as many as you want).
  • Then with the function handle_client() the server enters its main loop, where it waits for an incoming connection.
  • When the client connects, we receive the client socket in the client variable and the remote connection details in an addr variable in client, addr = server.accept().
  • Next, we create a new thread object pointing to our handle_client() function and pass the socket object referring to the client as the client argument.
  • We start the thread to handle the connection with the client, and our server's main loop will be ready to handle another incoming connection in client_handler.start().
  • The function client_handler() executes recv() and then sends a simple message to the client "ARK!".

For more information about the connection between TCP server and TCP client with Python see the link TCP connection example

Note: That's it, these codes will be extended (in new files, so as not to mess up versioning) in the next sections, where we will develop a substitute for Netcat and a TCP Proxy! So let's go!

Netcat

The time has come to create our own Swiss Army knife of networking: NETCAT. Often "smart" network administrators remove it from the system, but python is present on the servers.

So for these cases, it is very useful to create a simple network client and server that can be used to send files or have a listener (process that checks for connection requests) that enables access.

If you hacked a web system, you certainly should leave a Python callback for secondary access before resorting to using one of your Trojans or backdoors.

1 - So let's start with our Netcat: Calm down! The file is large, I know! But let's go by parts, I'll start explaining from the beginning:

  • First I do some imports.
  • Then I define some global variables.
  • Then create the main function def usage():, it will be responsible for handling command line arguments by calling the rest of the functions.

Starting by reading all command line options:

try:
    opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",
    ["help", "listen", "execute=", "target=", "port=", "command", "upload="])
except getopt.GetoptError as err:
    logging.error("%s", err)
    usage()

and defining the necessary variables according to the detected options. And if any command information does not meet our criteria, we will display information on how to use the script according to our usage() function. And here we try to imitate netcat and send data from stdin over the network:

if not listen and len(target) and port > 0:
    buffer = sys.stdin.read()

    client_sender(buffer)

And finally, we detect that it is necessary to set up a socket to listen to the network and process additional commands: server_loop() where we load a file, execute a command, start a command shell.

2 - From now on let's talk about the second part of our script def client_sender():, I already think you are getting familiar with all this.

  • We start creating our TCP socket object and then we test it.
  • Then we test it to know if we receive any input data from stdin.
if len(buffer):
    client.send(buffer)
while True:
    ...
  • If everything is ok, we will send the data remotely and receive data back (while recv_len:)
  • Then we prepare more input data (buffer = input('')) from the user and will continue to send and receive data until the user terminates our script.

3 - Now let's create the main loop of our server, along with a stub function that will handle both the execution of our command and our full command shell.

Well at this stage of the championship you should already be very familiar with creating a complete TCP server with threading, so let's not go into details of our function server_loop():

  • Something in the function run_command(): that we haven't talked about yet is subprocess, which is a library that provides an effective interface to create processes, providing several ways to start and interact with client programs.
  • Here output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) we simply execute whatever command is passed, executing on the operating system and returning the command output to the client that connected to us.

4 - Finally, let's implement the logic to upload files, execute commands, and implement our shell: client_handler():

  • This first portion of code (if len(upload_destination):) is responsible for determining if our network tool is configured to receive a file when a connection is established.
  • Initially, we receive the file data in a loop (while True: data = client_socket.recv(1024)) to ensure we receive everything.
  • Then, we process our execution functionality, where we call our function run_command() and simply send the result back over the network.
  • Finally, we have the code that handles our command shell, it continues to execute commands as we send them and the output is kept back.

Testing

In a terminal or cmd.exe shell, run our script as follows:

kali-linux$ ./szynet.py -l -p 9999 -c

You can go to another terminal or cmd.exe and run our script as a client (just like we did with the TCP server and client). Remember that our script is reading from stdin and will do so until it receives the EOF (end-of-file) marker. To do this, press CTRL + D on your keyboard:

kali-linux$ ./szynet.py -l -p 9999 -c
<CTRL-D>
<BHP:#> ls -la
drwxr-xr-x 4 kali-linux staff 136 18 Dec 19:45 .
drwxr-xr-x 4 kali-linux staff 136 9 Dec 17:34 ..
-rwxrwxrwx 1 kali-linux staff 8498 19 Dec 06:14 szynet.py
-rw-r--r-- 1 kali-linux staff 844 10 Dec 10:45 listing-1-3.py
<BHP:#> pwd
/home/kali-linux/scripts/netcat

Note: You will notice that the code and functions are not in the order of the comments, that's because I made the commentary according to importance and the script execution process.

Congratulations, you reached the end of a very difficult stage, I hope you understood what we did and are still willing to learn more, because this was just the beginning, we are just warming up for now. Now let's create a TCP PROXY that we will use in various attack scenarios.

TCP Proxy

The reasons for having a proxy in your toolbox are numerous; we can use it to forward traffic to be sent from a host, or to evaluate network-based software. When performing penetration tests in corporate environments, you will commonly encounter the fact that you cannot execute Wireshark, cannot load drivers to do sniffing on Windows loopback... So let's create our own TCP proxy!

Our script contains seven functions, I'll explain one by one, some you should already be used to.

1 - server_loop()

  • You should already be very familiar with this function, we start by receiving some command line arguments.
  • Then we fire a loop on the server that listens waiting for connections.
  • When a new connection request arises, it will be passed to the next function proxy_handler()

2 - main()

  • The main function of our script capable of defining the data to be used and calling our function server_loop() with the correct parameters to listen to our network.

3 - proxy_handler()

  • Here is the function that will do all the work of sending and receiving data to either side of the data stream.
  • We start by doing a check to ensure we won't need to start a new connection.
  • Then we use our function receive_from() which will be used on both sides of the communication.
  • Then we dump the packet content to inspect them and see if there is anything interesting.
  • Next we pass the output to our function response_handler().
  • The rest is simple: we read continuously from the local host, process, send to the remote host, read the host, process, and send to the local host.

4 - hexdump()

  • In the last part of the code.
  • Initially we create our hex dumping function that will simply display the packet details showing both hexadecimal values and ASCII characters that can be displayed.

5 - receive_from()

  • This function is used to receive both local and remote data and simply passes the socket object to be used.

6 - request_handler() & response_handler()

  • The last two functions allow modifying any traffic destined for either side of the proxy.

Testing

Well, to test you can simply run a command with the parameters that we already predefined for our function to receive in the prompt, preceded by sudo because it may be that the port you chose might be privileged and requires root user authorizations (in my case I will put on port 21 to connect with my or our TCP client) like this:

kali-linux$ sudo python3 ./main.py 127.0.0.1 ftp.target.ca 21 True

Or as I think you want to be a little more bold and comprehensive you can connect to an FTP server of your choice and that will really answer you, like google.com, facebook.com,... Just configure your browser's proxy on port 80 (HTTP access port) and run your code with the modifications as in the following example:

In the browser (in my case I will use Firefox):

Go to Preferences > Network Settings

Leave the configuration as follows and run the command:

kali-linux$ sudo python3.9 ./main.py 127.0.0.1 80 www.google.com  80 True 

And something like this will appear on your screen:

[*] Listening on 127.0.0.1:80
[==>] Received incoming connection from 127.0.0.1:41452

[<==] Received 201 bytes from localhost.
0000   43 4F 4E 4E 45 43 54 20 77 77 77 2E 67 6F 6F 67    C O N N E C T   w w w . g o o g
0010   6C 65 2E 63 6F 6D 3A 34 34 33 20 48 54 54 50 2F    l e . c o m : 4 4 3   H T T P /
0020   31 2E 31 0D 0A 55 73 65 72 2D 41 67 65 6E 74 3A    1 . 1 . . U s e r - A g e n t :
0030   20 4D 6F 7A 69 6C 6C 61 2F 35 2E 30 20 28 58 31      M o z i l l a / 5 . 0   ( X 1
0040   31 3B 20 4C 69 6E 75 78 20 78 38 36 5F 36 34 3B    1 ;   L i n u x   x 8 6 _ 6 4 ;
0050   20 72 76 3A 37 38 2E 30 29 20 47 65 63 6B 6F 2F      r v : 7 8 . 0 )   G e c k o /
0060   32 30 31 30 30 31 30 31 20 46 69 72 65 66 6F 78    2 0 1 0 0 1 0 1   F i r e f o x
0070   2F 37 38 2E 30 0D 0A 50 72 6F 78 79 2D 43 6F 6E    / 7 8 . 0 . . P r o x y - C o n
0080   6E 65 63 74 69 6F 6E 3A 20 6B 65 65 70 2D 61 6C    n e c t i o n :   k e e p - a l
331: [==>] Sent to remote.
332: [<==] Received 1775 bytes from remote.
333:  65 64 69 61 20 6F 6E 6C 79 20 73    0 } } @ m e d i a   o n l y   s
334: 0500   63 72 65 65 6E 20 61 6E 64 20 28 2D 77 65 62 6B    c r e e n   a n d   ( - w e b k
335: 0510   69 74 2D 6D 69 6E 2D 64 65 76 69 63 65 2D 70 69    i t - m i n - d e v i c e - p i
336: 05A0   74 2D 62 61 63 6B 67 72 6F 75 6E 64 2D 73 69 7A    t - b a c k g r o u n d - s i z
337: 05B0   65 3A 31 30 30 25 20 31 30 30 25 7D 7D 23 6C 6F    e : 1 0 0 %   1 0 0 % } } # l o
338: 05C0   67 6F 7B 64 69 73 70 6C 61 79 3A 69 6E 6C 69 6E    g o { d i s p l a y : i n l i n
339: 05D0   65 2D 62 6C 6F 63 6B 3B 68 65 69 67 68 74 3A 35    e - b l o c k ; h e i g h t : 5
340: 05E0   34 70 78 3B 77 69 64 74 68 3A 31 35 30 70 78 7D    4 p x ; w i d t h : 1 5 0 p x }
341: 05F0   0A 20 20 3C 2F 73 74 79 6C 65 3E 0A 20 20 3C 61    .     < / s t y l e > .     < a
342: 0600   20 68 72 65 66 3D 2F 2F 77 77 77 2E 67 6F 6F 67      h r e f = / / w w w . g o o g
343: 0610   6C 65 2E 63 6F 6D 2F 3E 3C 73 70 61 6E 20 69 64    l e . c o m / > < s p a n   i d
344: 0620   3D 6C 6F 67 6F 20 61 72 69 61 2D 6C 61 62 65 6C    = l o g o   a r i a - l a b e l
345: 0630   3D 47 6F 6F 67 6C 65 3E 3C 2F 73 70 61 6E 3E 3C    = G o o g l e > < / s p a n > <
346: 0640   2F 61 3E 0A 20 20 3C 70 3E 3C 62 3E 34 30 35 2E    / a > .   
347: [==>] Sent to localhost.
348: [*] No more data. Closing connections.

Well that's all folks. Let's go to the next one!

SSH with Paramiko

Contribution

The comments and codes were taken from the book: Black Hat Python by Justin Seitz published by Novatec. With some changes regarding the comments and the code adapted to Python version 3.9

Contact

Send me a message if you have any questions


João Lucas (Instagram)
🚀

Linkedin Badge Gmail Badge

Acknowledgments

About

A collection of Python network programming tools and pentesting scripts inspired by "Black Hat Python", featuring a custom Netcat alternative, TCP/UDP clients, and a unified CLI runner.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages