Python

A comprehensive article on the Python programming language which is increasingly being used to develop and assist various cybersecurity functions.

Python is an easy to understand, interpreted programming language that is commonly used across the cybersecurity community.

Data Types

Integers and Strings

Integers are set without quotation and can also include mathematical operators (+-/*). Strings are required to be wrapped in quotation marks (singular (') or double (“)) however cannot contain special characters unless they are explicitly escaped using a backslash (). Multi line strings can be used instead of escaping characters (''') and can also carry the single string to multiple lines.

a = 10
aa = a * 2
b = "string"
bb = "Escaping \"special characters using backslash\""
c = '''Multi-line strings
or strings that contain special characters "can be used like this"'''

Strings and Integers can look similar to humans, for example the string ‘10’ and integer 10, however are completely different when being interpreted by a computer. Python interrupts user input as strings, therefore if the input is required to be parsed as an integer or other value they will need to be converted.

a = '10'
converted_a = int(a)
b = '10.5'
converted_b = float(b)

Empty Values

In Python, an empty value is referred to as ‘None’. It's important to understand that the value None is different than a value of 0. These are used to create a variable without assigning a value.

a = None

Lists

A list is a data type that can contain more than one value and are created using the square bracket ([). Entries inside of a list are referred to an index and begin with the first entry at index 0. Lists are modifiable, with indexes being able to change. Lists can contain any values, including other lists.

d = ['darkcybe', 'security']
mylist = ['one', 2, 'three' 4]
converged = [[1, 2, 3, 4], ['one', 'two', 'three', 'four']]

Calling a specific index is done by its index number, as in the example below where we want to return ‘security’ from the d list above. In the case of nested lists, such as the ‘converged’ list, two indexes are required: the first being the list index, and the second the value index. An example is show below of calling the value 'three; from the nested list.

d[1]
converged[1][2]

Lists can be modified using methods. Methods are similar to function in which they allow certain actions to be taken on an object. Some of the commonly used methods relating to lists can be found here Data Structures.

MethodDescriptionExample

.append

Add an item to the end of a list

converged.append('five')

.inset

Insert an item to a specific index, the argument consists of (index, value)

mylist.insert(2, 'five')

.remove

Removes the first object equal to the argument value

d.remove('security')

.pop

Removes an item from a specific index

d.remove([1])

.clear

Remove all items from a list

d.clear()

Tuples

Tuples are similar to lists in construction, replacing the square bracket with a round bracket ((). However, unlike the indexes of a list which are able to be modified, indexes inside of a tuple are static and cannot be changed.

3 = ('darkcybesec', 'security blog')

Ranges

Ranges represent an immutable sequence of numbers and is commonly used for looping a specific number of times in for loops. Ranges can accept two arguments as depicted in the below example. The first example depicts a ‘stop’ argument, creating a list with 10 indexes. The second involves three arguments; start, stop and step. Start is the beginning of the count, stop the finish, and step being the increment in which the values are counted.

list(range(10)) # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
list2(range(0, 50, 5)) # 0, 5, 10, 15, 20...

Dictionaries

Dictionaries are similar to lists, however include pairs of data, a key and a value. Dictionaries can hold anything, numbers, strings, a mix and even lists or nested dictionaries. Unlike lists and tuples where values are called via index, dictionaries do not contain index values and storage of key-value pairs is random. To call a value or pair within a dictionary, they are accessed via the key.

protocols = {'HTTP': 80,
             'HTTPS': 443,
             'FTP': 21,
             'SSH': 22}

traffic = {'Allowed': ['HTTP', 'HTTPS'],
           'Blocked': ['FTP', 'SSH']}

contacts = {"number":2,
            "students": [{"name":"Harry Potter", "email":"hpotter@gmail.com"},
                         {"name":"Ronald Weasley", "email":"rweasley@gmail.com"}]}

Dictionaries can be modified using methods, some of the commonly used methods relating to dictionaries can be found at the Python Dictionary Methods by W3Schools.

MethodDescriptionExample

clear()

Removes all the elements from the dictionary

protocols.clear()

fromkeys()

Returns a dictionary with the specified keys and value (value is optional)

x = ('HTTP', 'HTTPS') protocols = dict.fromkeys(x)

get()

Returns the value of the specified key

protocols.get('SSH')

keys()

Returns a list containing the dictionary's keys

protocols.keys()

pop()

Removes the element with the specified key

protocols.pop('SSH')

popitem()

Removes the last inserted key-value pair

protocols.popitem()

setdefault()

Returns the value of the specified key. If the key does not exist: insert the key, with the specified value

protocols.setdefault('SMB') protocols.setdefault('ELASTICSEARCH', 9200)

update()

Updates the dictionary with the specified key-value pairs

protocols.update({'SYSLOG': 514})

values()

Returns a list of all the values in the dictionary

protocols.values()

Functions

Functions are pre-compiled instructions that can be executed to perform certain actions. Python contains a set of built-in functions, however they can be extended by importing modules. In Python, defining a function is done using the ‘def’ keyword. Functions are called by entering the function name followed by a set of parenthesis, any arguments that are to be passed to the function reside within the parenthesis.

Standard Functions

Some of the built-in and commonly used functions that exist in Python are listed below, a more through list of examples can be found atwithin the Python Documentation for Built-in Functions.

MethodDescriptionExample

print()

Prints an argument to STDOUT

print("darkcybe")

int()

Returns an integer number. If a float is passed as an argument, the decimal will be removed.

int(10.9)

float()

Returns a floating point number

float(99.9)

str()

Returns a string object

str(variable)

input()

Reads user input drops the terminal input to the next line

input("What is your name?"\n)

Defining Functions

Functions can be created to perform and repeat code blocks. To do this, the keyword ‘def’ for define, is used to create a function. The below example shows the process of creating and calling a defined function that prints a customized greeting to the terminal.

Note that the flow of execution through the program does not execute the function until it is called. The variable ‘name’ within the defined function only resides within the function itself and cannot be called, this is referred to as local scope. Typical variables such as ‘input_name’ can be referenced throughout the code and is known as a global variable.

def greeting(name):
    print('Hello', name)

input_name = input('Enter your name: \n')

greeting(input_name)

Defining functions structures code and allows for better code reuse. The below example shows a simple dice rolling game that contains two functions; roll_dice which uses the random module to generate two random numbers (simulating two dice being rolled), and the play_game function which is the main function to initiate the game. At the very bottom, the play_game function is called which executes the code.

import random

def roll_dice():
    dice_total = random.randint(1,6) + random.randint(1,6)
    return dice_total

def play_game():
    player1 = input("Enter Player 1's name: ")
    player2 = input("Enter Player 2's name: ")

    roll1 = roll_dice()
    roll2 = roll_dice()

    print(player1, 'rolled', roll1)
    print(player2, 'rolled', roll2)

    if roll1 > roll2:
        print(player1, 'Wins!')
    elif roll1 < roll2:
        print(player2, 'Wins!')
    else:
        print('Tie')

play_game()

Modules/Libraries/Packages

A module in Python is a way of providing useful code to be used by another program, containing functions and other resources. Python contains an already extensive library which can be accessed natively, more information can be found at The Python Standard Library Documentation. More advanced or third-party modules can be found at the PyPI · The Python Package Index, which maintains a repository of software for the Python Language:

Importing a Standard Module

The below example imports the ‘random’ module into Python for use, the Random module implements pseudo-random number generators.

import random

Module Functions

Modules will typically contain functions that allow for actions to be performed. To call a function within a module, first explicitly call the module and then select a function, Visual Studio and other IDEs will populate a list of available functions.

The below example uses a function within the random module to generate a random integer between the numbers 1 and 6 which are set as arguments to the instruction. The value is then stores and is callable via the ‘roll’ variable.

roll = random.randint(1,6)

Using the random module as an example again, we can see that there a numerous function available via the random — Generate pseudo-random numbers document by Python.

choices = ["rock", "paper", "scissors"]
computer_choice = random.choice(choices)

Installing Third-Party Packages

Apart from the extensive libraries available by default with Python, there exist a vat number of specialized packages that have been created by the Python community to extend the capabilities of modules. As previously mentioned, a repository of these packages can be found at PyPI · The Python Package Index, and also via custom repositories on GitHub.

To install third-party packages, the Python Install Package (PIP) is required, PIP manages the installation of packages from the Python Package Index and can be interacted with via the Python Terminal. In the below example, the package ‘requests’ is downloaded and installed via PIP. The Requests package allows HTTP requests to be made to webservers in order to interact with APIs and retrieve/post data.

pip --version # Returns the version of PIP installed

pip install requests

pip --upgrade requests # If already installed, packages can be upgraded

Once installed, a package can then be imported and used in the same manner as built-in modules or libraries. In the example below, the requests package is used to make an outbound connection to a webserver https://randomuser.me/api/, returning and parsing the data in .json format.

import requests

retrieve = requests.get('https://randomuser.me/api/')
output = retrieve.json()

print(output)

An example is shown below of a practical use of the requests package. User information is retrieved from the webserver and parsed to print the username and password. Due to the JSON data being quite overwhelming, online tools such as JSON Parser can be used to break the dictionaries and lists into a more readable format.

import requests

retrieve = requests.get('https://randomuser.me/api/')
output = retrieve.json()

login = output.get('results')[0].get('login')
print("Username is: ", login.get('username'))
print("Password is: ", login.get('password'))

In some circumstances, an API key may be required when interacting with a webserver. In such circumstances, the following can be included in the code. Some webservers will provide instructions on how to structure API calls, including the specific implementation of the API key.

import requests

api_key = "asdfklj43po587sadkfjn3487"
city = "Narnia"
url = "https://api.locationweather.org/data/weather?q="+city+"&appid="+api_key

retrieve = weather.get(url)
json = weather.get()
print(json)

Virtual Environments and Packages

In some circumstances, packages and modules may require specific versions of libraries in order to function. This means that one Python installation may not meet the requirements of every application. The solution is to create a self-contained directory contain specific versions of Python and the required packages. This self-contained Python structure is called a virtual environment (VENV).

To create a virtual environment, the following command is run to create a standalone environment called ‘example’

python -m venv example # A file path such as "C:\Python\Venv\example" can also be used

Once the virtual environment has been created, the next step is to set the environment to be used instead of the local Python instance. To activate and deactivate a virtual environment, the following commands can be run on Windows. Once the PowerShell script is run, the venv name, in this case ‘example’ will be highlighted at the beginning of the terminal. Deactivating is done by executing the deactivate batch script and by running exit on the Python terminal.

C:\Python\Venv\example\Scripts\activate.ps1
C:\Python\Venv\example\Scripts\deactivate.bat

When operating inside of the virtual environment, instructions and commands are as they would be if using the Python instance installed on the host. Once a virtual environment is no longer required, they can be deleted from disk, an empty environment takes up around 15-20MB of space.

Logical Statements (IF and ELSE)

Programs utilize logical statements to determine execution of code based on conditions. For example, if an condition is true do this, or is false do that.

IF Statements

IF statements are made up of two parts, the IF keyword followed by a condition and colon (:). The example below is a basic statement that only has one condition, if the condition is met a string will be returned to the console using the ‘print’ function.

age = 33
if age > 29:
    print('''You're in your thirties!''')

Additional conditions can be added to logical statements in what is referred to as a ‘block' of code. A block is simply a set of statements. In the below example, additional print functions will be executed upon the condition being met. Note that there are 4 spaces between the starting line and the beginning of the function. Python uses whitespace (singles spaces or tab) to create blocks, code that is in the same position will be grouped, every positional change will create a new group.

age = 33
if age > 29:
    print('''You're in your thirties!''')
    print('''Still a spring chicken''')

If statements can be used to check data types such as the below example which checks a list for a specific value.

acronyms = ['HTTPS', 'SSL', 'TLS']
user_input = 'HTTPS'
if user_input in acronyms:
    print(user_input + "Is an encypted channel")

IF-then-ELSE Statements

The above IF statements only perform an action when the condition is true. IF-then-ELSE statements can be introduced to creation actionable conditions for statements that are true or false.

age = 33
if age > 29:
    print('''You're in your thirties!''')
    print('''Still a spring chicken''')
else:
    print('''You're still a bebe, cherish it''')

IF and ELIF Statements

Logical conditions can be extended even further using ELIF (else-if). Unlike the IF-then-ELSE statement which relies of a condition being met once and everything else being treated as false, ELIF can provide more verbose conditioning.

age = 33
if age > 29:
    print('''You're in your thirties!''')
    print('''Thats not great''')
elif age < 29:
    print('''You're still young, cherish it''')
elif age > 39:
    print("What was it like riding dinosaurs to school?")
else:
    print('''Weow! You're actually ancient''')

Combining Conditions

Conditions can be combined by using keywords ‘and’ and ‘or’ to provide shorter and simpler code, both statements must be true for an and statement to be true in the below example. Or only requires one of the conditions to be true.

age = 24
if age => 20 and age < 30
    print('''You're in your twenties''')

colour = "red"
if colour == "red" or colour == "yellow"
    print('''Stop''')

Loops

Loops are used to carry out an instruction or set of instructions over a data set. The below example depicts a simple for loop that will print each value within the protocols list. the variable ‘p’ acts as a temporary variable to store the protocols in for each run of the loop.

protocols = ['HTTP', 'HTTPS', 'FTP', 'SSH']
for p in protocols:
    print(p)

Loops often make use of Ranges to create lists that can be populated based upon user input, such as the example below.

study_hours = []
x = int(input("How many days of study did you perform this week?\n"))

for i in range(x):
    study_hours.append(float(input("Enter the amount of hours for each day:\n")))
    total = sum(study_hours)

print("Your total amount of study hours this week is: ", total)

Loops can be used with the Dictionary data type also, including dictionaries that contained lists. By default however, when a dictionary is printed using a loop it will only return the key and not the attached value. To return both the key and value pair, the below loop can be used. Note that the method .items is used to return the key and value pair.

traffic = {'Allowed': ['HTTP', 'HTTPS'],
           'Blocked': ['FTP', 'SSH']}

for v, k in traffic.items():
    print(v, ':', k)

More granular calls can be made to return specific data from nested dictionaries also, such is the example below which contains a dictionary ‘contacts’ containing a key ‘students’ with a nested dictionary containing key and value pairs for ‘name’ and ‘email’. The example depicts how to use a loop to return the ‘email’ from the nested dictionary.

contacts = {
    "number":2,
    "students":
    [
        {"name":"Harry Potter", "email":"hpotter@gmail.com"},
        {"name":"Ronald Weasley", "email":"rweasley@gmail.com"}
    ]
}

for s in contacts["students"]:
    print(s["email"])

The above example discuss the ‘for’ loop which is great when a loop is running over a specific length, such as the range inclusions. There is another type of loop however than will run until a specific condition is met, called a ‘while’ loop.

brute_force = 0

while brute_force < 10000
    print(brute_force)
    if authentication == True:
        break
    elif locked_out == True:
        break
    else:
        brute_force = brute_force + 1

Last updated