Simple pwntools QoL scripts
Project description
pwnscripts
Very simple script(s) to hasten binary exploit creation. To use, pip install pwnscripts
OR run
git clone https://github.com/152334H/pwnscripts
cd pwnscripts
pip install -e .
and replace from pwn import *
with from pwnscripts import *
, e.g.
from pwnscripts import *
context.binary = './my_challenge'
...
Additionally, the libc_database()
extension of pwnscripts requires the libc-database.
You might want to look at some of the examples in user_tests_and_examples.py
.
Features
Pwnscripts has a number of different features.
Libc
Things like LibcSearcher have always felt incomplete.
Pwnscripts provides two libc classes: libc()
and libc_database()
. The easiest way to start with both is with context
:
context.libc_database = '/path/to/libc-database' # https://github.com/niklasb/libc-database
context.libc = '/path/to/pwnscripts/examples/libc.so.6'
Anything you can run with ./libc-database/[executable]
is available as a libc_database()
method:
>>> context.libc_database.dump('libc6_2.27-3ubuntu1_amd64')
b'offset___libc_start_main_ret = 0x21b97\noffset_system = 0x000000000004f440\noffset_dup2 = 0x00000000001109a0\noffset_read = 0x0000000000110070\noffset_write = 0x0000000000110140\noffset_str_bin_sh = 0x1b3e9a\n'
>>> output = context.libc_database.add()
>>> print(output.decode())
Adding local libc /path/to/pwnscripts/examples/libc.so.6 (id local-18292bd12d37bfaf58e8dded9db7f1f5da1192cb /path/to/pwnscripts/examples/libc.so.6)
-> Writing libc /path/to/pwnscripts/examples/libc.so.6 to db/local-18292bd12d37bfaf58e8dded9db7f1f5da1192cb.so
-> Writing symbols to db/local-18292bd12d37bfaf58e8dded9db7f1f5da1192cb.symbols
-> Writing version info
libc_database()
also has a few additional methods; you can look at the tests and examples and documentation to see.
The libc()
object is a subclass of pwntools' pwnlib.elf.elf.ELF()
. It starts off with a base address of 0
, but you can change that to match a remote executable by providing it with leaked addresses:
>>> context.libc.calc_base('scanf', 0x7fffa3b8b040) # Provide a leaked address to libc
>>> context.libc.address
0x7fffa3b10000
>>> context.libc.symbols['str_bin_sh'] # Symbols from libc-database are stored in context.libc
0x7fffa3cc3e9a
libc()
provides one_gadget
integration in the form of an interactive selection:
>>> context.libc.select_gadget()
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
[?] choose the gadget to use:
1) 0x4f2c5
2) 0x4f322
3) 0x10a38c
Choice
You're free to shut up the interactive menu by giving .select_gadget()
an argument:
>>> context.libc.select_gadget(1)
0x4f322
More features exist, but this is already too long.
Format string exploitation
pwnscripts provides the fsb
module, which can be split further into:
-
.find_offset
: helper functions to bruteforce wanted printf offsets.If you've ever found yourself spamming
%n$llx
into a terminal: this module will automate away all that. Take a look at the example code to see how.This already partially exists as a feature in pwntools (see
pwnlib.fmtstr.FmtStr
), but pwnscripts expands functionality by having bruteforcers for other important printf offsets, includingcanary
s, for defeating stack protectors,stack
addresses, to make leaking a stack pointer much easier,- other things like
code
addresses with more niche purposes
-
.leak
: a simple two-function module to make leaking values with%s
a lot easier.The simple idea is that you get a payload to leak printf values:
offset = fsb.find_offset.buffer(...) # == 6 payload = fsb.leak.deref_payload(offset, [0x400123, 0x600123]) print(payload) # b'^^%10$s||%11$s$$#\x01@\x00#\x01`\x00'
And after sending the payload, extract the values with a helper function:
r = remote(...) r.sendline(payload) print(fsb.leak.deref_extractor(r.recvline())) # [b'\x80N\x03p\x94\x7f', b' \xeb\x04p\x94\x7f']
Minor features
Pwnscripts also comes with a few minor extensions and functions:
ROP
: an extension ofpwnlib.rop.rop.ROP
. Core feature is to simplify ROP building outside of SIGROP:>>> context.arch = 'amd64' >>> r = ROP('./binary') >>> r.system_call(0x3b, ['/bin/sh', 0, 0]) >>> print(r.dump()) 0x0000: 0x41e4af pop rax; ret 0x0008: 0x3b 0x0010: 0x44a309 pop rdx; pop rsi; ret 0x0018: 0x0 [arg2] rdx = 0 0x0020: 0x0 [arg1] rsi = 0 0x0028: 0x401696 pop rdi; ret 0x0030: 0x40 [arg0] rdi = AppendedArgument(['/bin/sh'], 0x0) 0x0038: 0x4022b4 syscall 0x0040: b'/bin/sh\x00'
- other unlisted features in development
Proper examples for pwnscripts
are available in examples/
and user_tests_and_examples.py
.
I tried using it; it doesn't work!
File in an issue, if you can. With a single-digit userbase , it's hard to guess what might go wrong, but potentially:
-
pwnscripts is broken
-
Python is outdated (try python3.8+)
-
libc-database is not properly installed/initalised (did you run ./get?)
-
The binary provided is neither i386 or amd64; other architectures aren't implemented (yet).
-
The challenge is amd64, but
context.arch
wasn't set toamd64
- Set
context.binary
appropriately, or setcontext.arch
manually if no binary is given
- Set
-
Other unknown reasons. Try making a pull-request if you're interested.
Updates
v0.2.1 - Hotfix: libc.select_gadget()
will return with the correct libc.address
adjusted value
v0.2.0 - libc-database update
New features
-
pwnlib.context.context
is now extended for pwnscripts:context.libc
andcontext.libc_database
have been added as extensions. -
pwnscripts.libcdb_query
has undergone a revamp:- Two new classes have been created:
libc_database()
andlibc()
. libc()
is the replacement forlibc_db()
, and inherits frompwnlib.elf.elf.ELF
to simplify libc offset calculation.libc_database()
is a class to represent an existing installation of thelibc-database
The older
libc_db()
class (and the associatedlibc_find()
) will remain as deprecated features for the time being. - Two new classes have been created:
Bugfixes and internal changes
- Internal code: removal of
attrib_set_to()
& replacement withcontext.local
internally - Tests & examples have been pruned to ensure that neither file has copied examples from the other.
- More error catching for libcdb_query.py
- Lots and lots of documentation + tests
v0.1.0 - Initial release
pwnscripts is out of pre-alpha, and will follow Semantic Versioning where possible.
20-09
Begin following PEP 440
NEW: fsb.find_offset
extended with offset-matching searches.
NEW: pwntools
' ROP
class has been extended with new features.
libc_db() can (must) now be initialised with either a filepath to a libc.so.6 binary
, or with an identifier id
.
This breaks the original behaviour of allowing e.g. libc_db('/path/to/libc-database', '<identifier>')
20-08.1
NEW: printf() functions are now kept under the pwnscripts.fsb
module. Older prototypes for find_printf_* functions remain available for now.
Addition of a lot of docstrings, plus example binaries.
20-08
Added a lot of whitespace.
Added a wrapper object for libc-database: the libc_db
object. This is mostly a reinvention of tools like LibcSearcher
, although I have yet to see another project tack on one_gadget
searching, which is a (hacky) feature added for libc_db
.
Minor adjustments to printf. Logging is suppressed for offset bruteforcing; new feature to make a leak payload.
Extended readme.
20-06
Added module packaging stuff, so that pip install -e .
works
You can now see a test example of this library in test.py
.
Gradual updates expected as I continue to do pwn.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pwnscripts-0.2.1.tar.gz
.
File metadata
- Download URL: pwnscripts-0.2.1.tar.gz
- Upload date:
- Size: 19.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
77d3c8ebedbb7f3157e59d59862610dbdae2665b78d08a3dfffc668f97d4dcbe
|
|
MD5 |
9c500673705f5919093b22be4f1cef9b
|
|
BLAKE2b-256 |
e6d4b2c820f7b8ad35e161941ec64e3a9030ec9ae6973de3f38864674a393c96
|
File details
Details for the file pwnscripts-0.2.1-py3-none-any.whl
.
File metadata
- Download URL: pwnscripts-0.2.1-py3-none-any.whl
- Upload date:
- Size: 30.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
a9b2badc2f5638852c9158207c5dc957580e109a0810638d196c013de8b032b8
|
|
MD5 |
40ab51b7646b70e1841ef8d3b5d9daa9
|
|
BLAKE2b-256 |
4dac2366eeece0ddf16a7f342b0301b3160393589844b6fd7240917e88ff907f
|