보안전문가로 향하는 길

스택 카라리 알아보기, 생성방법 및 우회 본문

드림핵/시스템 해킹

스택 카라리 알아보기, 생성방법 및 우회

뒷문은 필수 2024. 1. 3. 16:41
728x90

이번에는 스택 카라리에 대해서 알아보자

 

스택 카나리는 스택 버퍼와 return addr 사이에 있는 값으로

스택 카나리가 바뀐다면 스택 버퍼 오버 플로우가 발생한 것으로 확인하고

프로그램을 강제 종료시킨다.

 

 

 

// Name: canary.c
#include <unistd.h>
int main() {
  char buf[8];
  read(0, buf, 32);
  return 0;
}

 

gcc -o no_canary canary.c -fno-stack-protector

-fno-stack-protector 옵션을 줌으로 스택 까나리를 무효화 한다

 

 

gcc -o canary canary.c

까나리 영역을 침범하여 강제적으로 종료 되었다.

 

 

스택 까나리는 어디서 가져오는 것인가?

 

gdb -q canary를 통해서 gdb로 프로그램을 실행시킨 후 main의 어셈블러를 살펴보자

main + 12의 부분을 보면 rax에 fs:0x28값을 저장하는 특이한 부분을 찾을 수 있다.

fs:0x28 부분이 스택 까나리의 값을 가지고 있다.

fs는 세그먼트 레지스터의 일종으로 리눅스에서는 Thread Local Storage(TLS)를 가리키는 포인터로 사용

 

 

 

스택 까나리 값을 어디서 찾을 수 있을까?

info register fs나 print $fs를 사용한다면 값을 알 수 있을까?0으로 나와서 알 수가 없다. 설마 0이 fs의 값이겠는가? 당연히 아니다

 

따라서 fs의 값을 설정할 때 호출되는 arch_prctl(int code, unsigned long addr) 시스템 콜에 중단점을 설정

해당 시스템 콜을 arch_prctl(ARCH_SET_FS, addr)의 형태로 호출되면 fs는 addr로 설정된다.

 

catch syscall arch_prctl

catch명령어는 특정 이벤트가 발생했을 때 프로레서를 중단시키는 명령어다

 

init_tls()  함수에 도달 할때까지 continue 명령어를 실행

 

rdi에 있는 1002는 ARCH_SET_FS 의 상숫값이고rsi에 있는 0x7ffff7d89740는 TLS에 저장 할 값으로 fs는 이 값을 가르킬것이다.

 

 

x/gx 0x7ffff7d89740+0x28 를 해보니 아직 스택 까나리가 설정되어 있지않다.

 

 

watch *(rsi값 + 0x28)명령어를 실행

watch는 특정 주소에 저장되어있는 값이 변경회면 중단하는 명령어다continu 명령어를 이용해서 다음 중단지점까지 실행

 

x/gx 명령어로 해당 값을 조회해보니 특정값이 들어가 있다.해당 값이 스택 까나리이다.

 

위처럼 스택 까나리 값을 알게 된다면 스택까나리를 우회할 수 있다.