Python

Pining for the fjords

The Python language

Python is a high-level, general-purpose programming language that is popular among developers for its simplicity, readability, and ease of use. It was first released in 1991 by Guido van Rossum and has since become one of the most widely used programming languages in the world. Python is open-source and free to use, which has contributed to its widespread adoption.

One of the primary strengths of Python is its ease of use. The language is designed to be readable and intuitive, with syntax that closely resembles natural language. This makes it accessible to developers of all skill levels, from beginners to experts. Additionally, Python's extensive standard library provides a wide range of pre-built modules that make it easy to perform many common programming tasks without having to write code from scratch.

Python is also known for its versatility. It can be used for a variety of purposes, from developing web applications to data analysis to scientific computing. The language's flexibility is due in part to its support for multiple programming paradigms, including procedural, functional, and object-oriented programming. This makes Python a powerful tool for a wide range of applications.

Python on the Packet Squirrel

Python is included on the Packet Squirrel, but is not the default language for payloads. As a much more complex language, Python is often slower to start and requires more resources to run. Payloads using Python may require extra time to start, but can perform more complex tasks.

There are two ways to use Python:

  1. As the native language of a payload, by setting the interpreter of the payload to Python

  2. As a helper, implementing commands used by a normal payload as external scripts

Writing payloads in Python

Recall that the first line of the payload starts with #! and defines the interpreter which is used to run the payload.

A payload can use Python as the primary language by setting the first line accordingly:

#!/usr/bin/python

# Title: A python payload
#
# Description: A payload written in native python

import subprocess

subprocess.run(["NETMODE", "NAT"])
subprocess.run(["LED", "G", "SOLID"])

In this case, the entire payload is run inside Python. Accordingly, we must use the Python utilities for running external commands, such as subprocess.run. The standard DuckyScript for Packet Squirrel commands are all available, but must be launched as external processes.

In general, writing a full payload in Python is more complex, but may in some specific use cases offer more powerful options. Additional effort must be taken to read the results of commands like SWITCH, USB_FREE, and similar.

Using Python tools in normal payloads

Python scripts can be called directly from a Bash-based payload. The script can be embedded in the payload, or can be included as a secondary file in the payload directory.

Including a Python script as a separate file

Including the Python code separately requires the user to upload both the payload file and the Python file: In this example we'll call it python_led.py.

The python_led.py file contains the Python code:

#!/usr/bin/python

# This is a simple example of a Python script

import subprocess

subprocess.run(["LED", "W", "SOLID"])

And the payload file could then execute it:

#!/bin/bash

# Title: Python-assisted payload
#
# Description: Use a python script in the same directory

NETMODE NAT
LED G SINGLE

# Execute the python_led.py script from the same payload
# directory
python /root/payloads/$(SWITCH)/python_led.py

Notice how we specifically called python to run the file, ensuring that no matter what the file permissions are, it will be executed as expected, and the SWITCH command to determine where to find the payload (using the $(..) expansion which executes a command and returns the result).

Embedding Python in a Bash payload

Since a Python script is simply text, we can include it in the payload and write it to a file before running it. To accomplish this, we use a Bash trick to embed a chunk of text:

#!/bin/bash

# Title: Embedded python payload
#
# Description: Use embedded python in a payload

NETMODE NAT
LED G SINGLE

# The following will write everything between the
# 'cat' command and 'EOF' to the specified file
cat <<EOF > /tmp/python_led.py
#!/usr/bin/python

import subprocess
subprocess.run(["LED", "W", "SOLID"])
EOF

# Now we can run the python script we just created
python /tmp/python_led.py

Embedding the Python script directly in the payload can simplify transferring the payload to the Packet Squirrel, but may be more difficult to debug and maintain.

Often it makes sense to develop the Python script as an independent file, and embed it in the payload only at the end of development and testing.

Python basics

Python is a complete programming language, with an enormous ecosystem of libraries, and is far beyond the scope of a single chapter, however we attempt to include an introduction to the basics of the language to aid in reading example payloads.

Indentation

Python is relatively rare among programming languages, where the indentation is part of the syntax of the language itself.

In Python, indentation is used to group statements together into blocks of code. The amount of indentation used in a block is significant and determines the scope of the statements in the block.

For example, consider the following if-else statement:

if x > 5:
    print("x is greater than 5")
else:
    print("x is less than or equal to 5")

Notice that the two statements inside the if block and the two statements inside the else block are indented by four spaces. This indentation tells Python that these statements belong to their respective blocks. The statements inside the if block will be executed only if the condition x > 5 is true, and the statements inside the else block will be executed otherwise.

Indentation in Python is typically done using spaces, but tabs can also be used. However, it is important to be consistent in your choice of indentation method. Mixing tabs and spaces can cause errors in your code.

Python does not use curly braces ({}) to delimit blocks of code, as many other programming languages do. Instead, indentation is used to indicate where a block begins and ends.

Here is another example that shows how indentation affects the structure of a Python program:

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

In this example, the function factorial is defined with an if-else statement inside it. The if block and the else block are indented, and this indentation is what tells Python that these statements belong to the function definition. The return statements are indented even further, indicating that they belong to the if or else blocks.

Indentation is a fundamental aspect of Python syntax that is used to group statements together into blocks of code. Proper indentation is essential to ensure that your code is properly structured and executes correctly.

It is important to remember that indentation can cause unexpected behavior and errors when mixing Python based code with normal Bash payloads!

Parentheses

Python does not typically use parentheses () around conditions on if, while, and similar statements. For example:

x = 5
if x > 5:
    print("gt")

Variables

Variables are used to store data values in Python. You can assign a value to a variable using the "=" operator, and the value can be of any data type (e.g., string, integer, float, etc.).

# Assigning values to variables
x = 5
y = "Hello, World!"

# Printing the values of variables
print(x)
print(y)

Output:

5
Hello, World!

Datatypes

Python supports several data types, including strings, integers, floats, and booleans. You can convert between data types using typecasting. Typecasting tells Python to explicitly change the type of a variable; for instance to convert 5 from an integer (no decimal precision) to a floating point number like 5.00.

# Strings
string1 = "Hello"
string2 = 'World'
print(string1 + " " + string2)

# Integers
x = 10
y = 5
print(x + y)

# Floats
a = 3.14
b = 2.0
print(a * b)

# Booleans
flag1 = True
flag2 = False
print(flag1 or flag2)

# Typecasting
x = 5
y = float(x)
print(y)

Output:

Hello World
15
6.28
True
5.0

Control Structures

Control structures are used to control the flow of your program. Python supports if-else statements, for and while loops, and try-except blocks for error handling.

# If-else statement
x = 10
if x > 5:
    print("x is greater than 5")
else:
    print("x is less than or equal to 5")

# For loop
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# While loop
i = 0
while i < 5:
    print(i)
    i += 1

# Try-except block
try:
    x = 5 / 0
except ZeroDivisionError:
    print("Cannot divide by zero")

Output:

x is greater than 5
apple
banana
cherry
0
1
2
3
4
Cannot divide by zero

Functions

Functions are reusable blocks of code that perform a specific task. You can define your own functions in Python, or use built-in functions from Python's standard library.

# Defining a function
def add_numbers(x, y):
    return x + y

# Calling a function
result = add_numbers(3, 5)
print(result)

# Built-in functions
string = "hello, world!"
print(len(string))
print(string.upper())

Output:

8
13
HELLO, WORLD!

Conclusion

These are just a few examples of basic Python syntax. There are many more features and concepts to learn in Python, but understanding these basics is a great first step in becoming proficient in the language. Python supports class-based programming models, complex networking, and has a large ecosystem of add-in libraries.

Last updated