Home

Python for Cyber - Part 1

martin reato - June 21, 2021

Introduction 

This post is the first in a series that will serve as an introduction to Python scripting for Cyber. This series does assume the reader has a basic understanding of Python and networking. 

A recommended pre-requisite pathway before beginning this series is getting familiar with the basics of programming and knowing the Python fundamentals; which can be achieved by doing WYWM’s awesome Software Development Pathway. Go check it out!

This will teach you the basics of programming and Python fundamentals. Furthermore, an understanding of networking terminology is also recommended. You guessed it… WYWM has got you covered with their Networking Fundamentals Course. Go check that one too !

For those who will continue on ahead, each part of the series will build upon the previous part. These are presented in a step-by-step fashion and can easily be recreated by anyone; however, as the series progresses it might become more difficult for an individual who has no knowledge of programming. 

Who is this series useful for ?

This series will benefit python enthusiasts, cyber security analysts, penetration testers and anyone who wants to familiarize themselves with exploit writing. During the series we will explore how to program client-server networks, program our own exploits, create our own attack tools and much more. I believe those interested in pentesting will greatly benefit from writing their own code. 

This first entry into the series will focus on demonstrating how we can create a simple TCP client. It is very simple to do and is the first step towards writing some awesome tools and exploits in Python. For those aspiring or junior pentesters, the TCP client is what you will be using to interact and exploit basic buffer overflows.

TCP Client

Our TCP client can have many usages, but for simplicity we will do a simple client that connects to www.google.com on port 80. 

Step 1

First we are going to create a file called “tcp_client.py” using a text editor. Feel free to use nano, VIM or any text editor. For our first TCP client our script starts with the importing of the socket module. This module provides us with the necessary functions to create a client. 

import socket

The socket module provides many useful functions and methods when it comes to networking. For our TCP client we will use the below: :

  • socket()
  • connect()
  • send()
  • recv()
  • close()

For those who are interested in investigating the module more in-depth  they can find the full documentation of the socket module here: https://docs.python.org/3/library/socket.html

Step 2

The next step will be to add two variables to our script which will be named “host” and “port”. The “host” variable will hold the name of the host/server we want to connect to. The “port” variable will hold the port number for our client to connect to. In this example we are using a domain name; however, an IP address can also be used.  

Step 3

This next step creates a socket object called “client” and specifies a socket type of protocols we want to use. Our next line will be the following:

 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

  • Client - is the name we give our object. It can be anything besides reserved names. Ideally you would want to write something that describes the function of the object you are creating.
  • socket.socket() - is the object we are creating from our imported module
  • socket.AF_INET is a constant. This parameter is typically what you will most often use when creating a client. When passed to socket() indicates we are going to use ipv4.
  • socket.SOCK_STREAM is a constant. This parameter is passed to socket() and indicates we will be using TCP.

Step 4

Our next line of code will use the connect() method from the socket module. This method is what initiates the connection to a host/server. Since we are building a TCP client, this initiates the 3-way handshake from the client to a host/server.

  • client - refers to the object we created in the previous step where we basically identified that our client will be using ipv4 and TCP.
  • connect() - initiates the connection using the host and port specified by the variables we created in step 2.

Great ! Now we can connect to a host and a port. Now what we need to do is either send or receive data. For our use, we will use our TCP client to connect to www.google.com; therefore,  we will use the HTTP GET request. In order to receive information we need to request it, so we will send data first.

Step 5

Now that we know we will send data in the form of a HTTP GET request we need to use the send() function. Our next line will be the following:

client.send(b”GET / HTTP/1.1\r\n\r\n”)

  • client - refers to the object we created in step 3 where we basically identified that our client will be using ipv4 and TCP. 
  • send() - is the function that permits us to send data through the connection we made in the previous step.
Python

Step 6

Sending data is great. Now we need to tell our client to receive data from our target host. For this we will use the recv() function to receive the information from the server. We will also save that data to a variable. Our next line of code will be this:

response = client.recv(1024)

  • Response is the name given to our variable. This will hold the information received in memory.
  • client - refers to the object we created in step 3 where we basically identified that our client will be using ipv4 and TCP. 
  • recv(1024) - this permits the client to receive the data it requested with the send() function. The 1024 number is the buffer size indicating the maximum amount of data to be received at once. This basically will be enough to get the Response header from the server. If one were to increase that number the data saved in the variable would also include the body of the HTTP response.

Step 7

Now that we have our response from the server saved in a variable. Lets print that variable and since this TCP client was only a one time use let's close our connection to the server.

print(response.decode())

client.close()

  • print - instructs our program to output our response variable to the screen.
  • response - is the variable where we saved the data from our target response.
  • close() - this closes our connection with the server.

In a few lines of code we have built a TCP client! Let's test our client and make sure everything works. For myself, I choose to run this in the CLI of my Linux OS.  

There we have it. Our TCP client sent a HTTP request to www.google.com and the response received was outputted to the screen through our print() function. In the above picture we can observe the HTTP header from google.com.

Arguments

The target host and port have been hardcoded into the script. Oftentimes this can suffice; however, for those who want a little more versatility we can make minor changes to our code so it accepts command line arguments. For example, the following python command runs our script and then has two arguments that are passed to it.

Python3 tcp_client.py www.google.com 80

In order to do this we start by importing the sys module:

Then we replace the data we hardcoded in the “host” and “port” variables with the following :

sys.argv[1]

sys.argv[2]

Now when the arguments are passed the data will be stored in both our variables. The numbers in the square brackets refer to the arguments passed at the command line in the order they are passed. If we passed a third argument we could add a third variable and have it store “ sys.argv[3]”. 

Our script now accepts command line arguments passed to it.

User Experience

The TCP Client is working and we can have it connect to a server and port successfully; however, what happens if we share our script with others. They might not understand at first glance how to use our script. Let's improve the user experience by telling a user how exactly to run our TCP client.

There is a python module that will help us do exactly that. That module is the argparse module. Importing the argparse module is done the same way as the previous modules we imported.

The argparse module is really useful as it automatically generates help and usage messages, and issues errors when users give the program invalid arguments.

Adding the 4 lines of code below is all that is necessary for our TCP client. Of note, are the two lines where we specify arguments. These two lines instruct the module  and the parser function to expect two arguments - host and port - and if a user does not pass two arguments an error message is generated instructing the user on how to use the client.

With No Arguments:

With the --help Argument:

Although adding argparse is not necessary for scripts meant to be written quickly when pentesting inside a network or writing an exploit meant for a one time use. It is very handy when wanting to share a tool or exploit and provide guidance to the user.

For more information on this module please refer to: https://docs.python.org/3/howto/argparse.html#id1

Python 2 vs Python 3

I used Python 3 to write the script; However, for those who are wondering what this would look like in python 2... 

Here is what the code would be in python 2:

The differences between the two are very little. Line 10 does not have the ‘b’ prefix and line 14 has a pair of parentheses removed. Running the code would result in the following error.

Running it with python 2 we get no errors :

This happens because in Python 2 default strings were bytes whereas in Python 3 default strings are Unicode. With the ‘b’ prefix we are changing the string from unicode to bytes.

In addition sometimes python 2 scripts are written with no parentheses for the print() function. This will cause an error in python 3.

Code:

In python 2:

In python 3:

Knowing these two differences can go a long way in changing python2 scripts/exploits to python3. There are still many python2 scripts/exploits outhere that have not been updated to python3. Knowing some of these differences will benefit anyone wanting to stick to python3 and not having to juggle between both versions.

Conclusion

This marks the end of part 1 of the Python for Cyber series. Our very simple TCP client can be applied in a variety of ways. For those aspiring pentesters, the TCP client will certainly be how you will send payloads when exploiting buffer overflow vulnerabilities.  As this series progresses, we will use this first part as a building block for many interesting scripts we will build.

In part 2, we will build a server and have our client and server communicate with each other. 

Feel free to reach out for any questions/comments/suggestions.

Cheers ! 

martin.reato@withyouwithme.com

If you want to break into the tech industry then sign up to our platform and begin your training today.

Leave a Reply

Your email address will not be published. Required fields are marked *

Join our community

We have a Discord server where you’ll be able to chat with your instructors and cohort. Stay active in your learning!
Join discord