exploit_utils 0.2.0
template code for exp
Requires Python: >=3.12

# Exploit Utils

[中文](README_CN.md)

This project aims to encapsulate boilerplate code for writing exploits, accelerating exploit development.

Functionality is primarily accumulated through practical experience, focusing on commonly used features.

The author primarily focuses on web vulnerability reproduction and batch attack script development. Due to the author's work habits, some potentially useful features may not be encapsulated.

Additionally, libraries introduced by this project may be outdated. Following the principle of "if it works, it's fine," this project may not utilize the latest technologies.

> [!important]
> 
> This project is designed for Python 3.12+ and utilizes features introduced in version 3.12.
>
> Exploits depending on this library must run under Python 3.12+.

# Installation

Install using pip:

```sh
pip install exploit_utils
```

# Feature Overview

This project's functionalities are designed to be "modular," allowing users to replace specific modules with minimal overhead.

| File | Functionality |
|------|---------------|
| args.py | Command-line argument related functionality |
| crypto.py | Common cryptographic operations (MD5/SHA1/AES encryption/decryption) |
| encode.py | Common encoding/decoding operations (Base64/URL/HTML) |
| fs.py | Filesystem operation encapsulation |
| http.py | Network request related functionality |
| log.py | Logging operation encapsulation |
| misc.py | Miscellaneous utilities |
| mt.py | Multithreading related functionality |
| rand.py | Randomness related functionality |
| sh.py | System command execution encapsulation |

The following sections highlight features that significantly improve development efficiency.

## Configuring Command-Line Arguments

Writing scripts often involves repetitive boilerplate code:

```python
import argparse

parser = argparse.ArgumentParser()

# Options present in almost every exploit...
parser.add_argument("--url", "-u", help="Target URL")
parser.add_argument("--file", "-f", help="Batch URLs from file")
parser.add_argument("--threads", "-t", type=int, default=5, help="Number of threads")
parser.add_argument("--output", "-o", help="Output file")
parser.add_argument("--debug", action="store_true", help="Enable debug mode")

args = parser.parse_args()
```

Now you only need:

```python
# Step 1: Import exploit_utils
import exploit_utils as exp

# Step 2: Use the args module to get a Parser
parser = exp.args.Parser()

# Step 3: Use presets to configure common options with one command
parser.load_args(exp.args.BASIC_PRESET + [exp.args.DEBUG])

# Step 4: For custom options beyond presets, add them using the original method
parser.add_argument("--foo", action="store_true", help="foo")

# Step 5: Parse arguments using the original method
args = parser.parse_args()
```

You can modify details of options provided by the args module:

```python
import exploit_utils as exp

# Add required=True attribute to the preset --url option and modify help text
url_option = exp.args.URL({"required": True, "help": "Custom URL option"})

parser = exp.args.Parser()
parser.load_args([url_option])
```

## Creating Multithreaded Tasks

Classic multithreading boilerplate: reading URLs from a file and creating 5 threads for attacks:

```python
import threading
import queue

task_queue: queue.Queue[str] = queue.Queue()

def attack(url: str) -> None:
    ...

def task() -> None:
    while not task_queue.empty():
        url = task_queue.get()
        attack(url)

with open("urls.txt", "r", encoding="utf-8") as file:
    for url in file.readlines():
        task_queue.put(url.strip())

threads: list[threading.Thread] = []
for _ in range(5):
    t = threading.Thread(task)
    t.start()
    threads.append(t)
for t in threads:
    t.join()
```

Python provides thread pools that greatly simplify the code:

```python
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import wait

def attack(url: str) -> None:
    ...

with open("urls.txt", "r", encoding="utf-8") as file:
    urls = [i.strip() for i in file.readlines()]

with ThreadPoolExecutor(max_workers=5) as pool:
    wait([pool.submit(attack, url) for url in urls])
```

Now you only need:

```python
import exploit_utils as exp

def attack(url: str) -> None:
    ...

# This code's functionality is explained in "Quick File Input Processing"
urls: list[str] = exp.fs.parse_lines("urls.txt")

with exp.mt.ThreadPool(max_workers=5) as pool:
    exp.mt.wait([pool.submit(task, url) for url in urls])
    # Alternatively:
    # exp.mt.handle_fs([pool.submit(task, url) for url in urls])
```

## Processing File Input

Writing exploits often involves repetitive `with open()... readlines()` code:

```python
with open("urls.txt", "r", encoding="utf-8") as file:
    for url in file.readlines():
        if url.strip():
            task_queue.put(url.strip())
```

Now you can quickly process file input using:

```python
# Step 1: Import exploit_utils
import exploit_utils as exp

# Step 2: Directly use the encapsulated function
# Automatically handles empty lines and removes trailing newlines
for url in exp.fs.parse_lines("urls.txt"):
    task_queue.put(url)
```

`parse_lines` can use user-provided callbacks to automatically process data, for example:

```python
def handler(data: str) -> str:
    if data[-1] != "/":
        data += "/"
    return data

urls: list[str] = exp.fs.parse_lines("urls.txt", parser=handler)
```

## Nearly Configuration-Free Real-Time Logging System

The logging module is encapsulated to provide near-zero configuration requirements similar to loguru.

Implementing a logger that outputs to both console and file originally required extensive boilerplate:

```python
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

formatter = logging.Formatter("[%(levelname)s] %(message)s")

# Add console output
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

# Add file output
file_handler = logging.FileHandler("output.log")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
```

Now you only need:

```python
# Step 1: Import exploit_utils
import exploit_utils as exp

# Step 2: Get logger through the log module
logger = exp.log.get_logger()

# Step 3: Use the log module's method to add output file with one command
exp.log.add_outputfile("output.log")

# The logger automatically has an ok method for SUCCESS level logging
logger.ok("you did it!")
```

This logging system is compatible with tqdm, requiring no additional code:

```python
import exploit_utils as exp
import tqdm
import time

logger = exp.log.get_logger()

for i in tqdm.tqdm(range(100)):
    if i % 10 == 0:
        logger.info(f"{i=}")
    time.sleep(0.1)
```

## Automatic Common HTTP Configuration Support

Writing exploits often requires random User-Agents, timeout configurations, and SSL certificate verification disabling.

To suppress warnings, we also need to import urllib3.

Thus, a simple request becomes:

```python
import requests
import urllib3
from fake_useragent import UserAgent

# Disable warnings
urllib3.disable_warnings(urllib3.exceptions.HTTPWarning)

ua = UserAgent()
http = requests.Session()

http.get(
    url="http://example.com",
    # Random User-Agent
    headers={"User-Agent": ua.random},
    # Set timeout
    timeout=5,
    # Ignore SSL certificate
    verify=False,
)
```

Now you only need:

```python
# Step 1: Import exploit_utils
import exploit_utils as exp

# Step 2: Get session through the http module
http = exp.http.get_session()

# Step 3: Directly use the http module's method to disable warnings
exp.http.no_warn()

# Step 4: Use the session to make requests
# Requests automatically get random UA, 5s timeout, and SSL certificate verification disabled
http.get("http://example.com")
```

## Generating Random Strings

Writing exploits often requires generating random strings of specified length, such as session IDs:

```python
import random
import string

sessid = random.choices(string.ascii_letters, k=16)
```

Now you only need:

```python
import exploit_utils as exp

# Random word (composed of uppercase and lowercase letters), length 16
a = exp.rand.rand_word(16)

# Random hexadecimal digits, length 10
b = exp.rand.rand_digits(10, base=16)

# If you want randomized length, use a tuple to specify min and max bounds
# Random word, length 1-3
c = exp.rand.rand_word((1, 3))
```

## Log-Integrated File Server

Some vulnerability exploits require malicious files provided by remote servers.

Examples include DTD files for XXE vulnerabilities or shell scripts for curl reverse shells.

The `FileServer` class in the fs module enables rapid file server deployment:

```python
import exploit_utils as exp

def attack(url: str) -> None:
    ...

# Start file server on 0.0.0.0:5000
# Root directory is the 'files' folder in the script's directory
with exp.fs.FileServer("0.0.0.0", 5000, exp.fs.rget("files")):
    attack("http://example.com")
```

This file server uses the log module for logging.

When log level is `INFO`, startup and shutdown messages are output.

When log level is `DEBUG`, all connection information is output.

# Additional Information

## Usage Recommendations

1. Provide the source code in the `exploit_utils` folder to AI assistants to help generate code.  
If necessary, provide the project's `examples` folder to AI assistants to optimize output.

2. While code organization is your choice, we recommend using type annotations when writing exploits.

## Disclaimer

This tool is limited to legally authorized scenarios. Users must strictly comply with local laws and regulations when writing vulnerability exploitation scripts using this tool.