This is the last release supporting Python 2 and Python <3.10. See #2495
This release comes with a bunch of fixes, some new features, and a few deprecations. Thank you to every contributing their features and fixes!
Highlights
- Added
context.gdb_binary
to specify whichgdb
command to use. Useful to specify e.g.pwndbg
. Checkout thepwn.conf
config file to set it globally. (@Ninja3047) - Added
tube.upload_manually
to upload data to a shell using shell commands. Quickly upload your exploit into that kernel pwn challenge without manually typing theecho {chunk} | base64 -d >> exploit
loop. - Improved libcdb handling of a local libc-database without relying on external services. (@the-soloist)
- Cache the output of
asm()
to speed up subsequent exploit runs. (Disable the cache usingcontext.cache_dir = None
) - Improve documentation regarding which
ELF
functions run the binary internally. (Thanks to @Hackrrr who made a CTF challenge for it at Compete With Team Europe CTF 2025)
Deprecations
Removal of some CLI command scripts
Many of the CLI utilities coming with pwntools had ambiguous names and caused problems while packaging in different distributions. Most of the commands are deprecated now and print a warning suggesting to use pwn <thecommand>
instead.
Only checksec
, constgrep
, libcdb
, phd
, pwnstrip
, and shellcraft
stay as standalone CLI scripts. The rest will be removed and only accessible through the pwn
wrapper in the future.
$ debug
/home/user/.local/bin/debug:8: DeprecationWarning: The 'debug' command is deprecated and will be removed in a future version. Please use 'pwn debug' instead.
sys.exit(deprecated_main())
usage: pwn debug [-h] [-x GDBSCRIPT] [--pid PID] [-c context] [--exec EXECUTABLE] [--process PROCESS_NAME] [--sysroot SYSROOT]
Deprecate 'keepends' argument in favor of 'drop' in tube.recvline*
tube.recvline
used the keepends
argument to specify whether to include the trailing newline in the return value while tube.recvuntil
uses drop
to specify inclusion of the delimiter. The semantics are inversed for both functions causing confusion:
io.recvuntil(b'pwn', drop=True) # Don't include `pwn` at the end.
io.recvline(keepends=False) # Don't include `\n` at the end.
Since drop
is a more generic name (and shorter to type), tube.recvline*
accepts a drop
parameter now and usage of keepends
is deprecated.
The detailed changelog is as follows:
- Allow setting debugger path via context.gdb_binary by @Ninja3047 in #2602
- Cache output of
asm()
by @peace-maker in #2358 - docs: warn that .libs/.libc/.maps are dangerous by @Arusekk in #2626
- Add
tube.upload_manually
to upload files in chunks by @peace-maker in #2410 - Deprecate direct commandline scripts invocation and exclude nonsense ones by @tkmikan in #2364
- Extract libraries from Docker image by @lcian in #2479
- libcdb-cli: add
--offline-only
, refactor unstrip and add fetch parser for download libc-database by @the-soloist in #2478 - darwin: Bump syscalls from sdk 15.1 by @patryk4815 in #2448
- Support longer function names in Windows
getexport
shellcode by @peace-maker in #2587 - Fix attaching to a gdbserver with tuple
gdb.attach(('0.0.0.0',12345))
by @ckxckx in #2291 - regsort: respect register aliases by @Arusekk in #2576
- Nicely handle non ELF files in checksec by @tesuji in #2457
- Add ELF.close() to release resources by @peace-maker in #2444
- Properly close spawned kitty window by @k4lizen in #2471
- Redirect kitty kill command stderr to /dev/null by @k4lizen in #2472
- libcdb: improve the search speed of
search_by_symbol_offsets
by @the-soloist in #2413 - Fix waiting for gdb under WSL2 by @peace-maker in #2470
- Stop using cmd.exe to keep current directory by @robbert1978 in #2488
- Only print
checksec
output ofELF.libc
when it was printed for theELF
already by @peace-maker in #2483 - Throw error when using
sni
and settingserver_hostname
manually inremote
by @peace-maker in #2482 - Allow to disable caching by @peace-maker in #2484
- Fix loading ELF files without valid .dynamic section by @peace-maker in #2502
- Deprecate 'keepends' argument in favor of 'drop' by @MrQubo in #2476
- ssh tube: replaced nonexistent key with str(e) in error handling method to get proper error message displayed in stacktrace by @findus in #2512
- Ignore a warning with unused args in
asm
on NIX by @sbancuz in #2508 - SSH: fix download/upload with -1 exit status by @kilimnik in #2545
- Fix invalid parsing of loader error message in elf.libc by @tesuji in #2567
- Add automatic detection of statically linked binaries in
detect_missing_binaries
function. by @chaitanyarahalkar in #2570 - Add Ubuntu and Debian debuginfod servers by @peace-maker in #2595
- Use unicorn on macOS w/ SIP enabled by @Feyorsh in #2593
- Ignore colored_traceback error when TERM is unset by @peace-maker in #2596
- Fix poll error in
process.libs()
by @R42ccoon in #2579 - Fix log level of child remotes of
server
tube by @peace-maker in #2609 - Exclude Unicorn versions segfaulting on MIPS PLT by @Arusekk in #2621
- Fix lookup of binutils for
mipsel
architecture by @peace-maker in #2612 - Fix regression: gdbserver can't handle command-line argument containing whitespace by @peace-maker in #2624
- CI: Install pwntools on Windows and import it once by @peace-maker in #2450
- Fix collecting coverage in CI by @peace-maker in #2477
- Cache HTTP requests to external libcdb services in CI by @peace-maker in #2487
- Update documentation for format strings by @Legoclones in #2501
- Update sphinx for Python 3.13 support by @peace-maker in #2503
New Contributors
- @lcian made their first contribution in #2479
- @robbert1978 made their first contribution in #2488
- @ckxckx made their first contribution in #2291
- @Legoclones made their first contribution in #2501
- @findus made their first contribution in #2512
- @sbancuz made their first contribution in #2508
- @kilimnik made their first contribution in #2545
- @chaitanyarahalkar made their first contribution in #2570
- @R42ccoon made their first contribution in #2579
Full Changelog: 4.14.1...4.15.0