이전 학습 ↓

 

[시스템] 스택 카나리 분석(Canary)

카나리 정적 분석 스택 버퍼 오버플로우 취약점이 존재하는 코드#include int main() { char buf[8]; read(0, buf, 32); return 0;}   gcc는 기본적으로 스택 카나리를 적용하여 컴파일한다-fno-stack-protector 옵션

fight-hacker.tistory.com

 

 

[시스템] 스택 카나리 생성 과정(Canary)

이전 학습 ↓ [시스템] 스택 카나리 분석(Canary)카나리 정적 분석 스택 버퍼 오버플로우 취약점이 존재하는 코드#include int main() { char buf[8]; read(0, buf, 32); return 0;}   gcc는 기본적으로 스택 카나

fight-hacker.tistory.com

 

 

 

스택 카나리 우회

 

무차별 대입 

거의 불가능

 

TLS 접근

TLS 주소는 매 실행마다 바뀌지만, 만약 실행 중에 TLS의 주소를 알 수 있

임의 주소에 대한 읽기 또는 쓰기가 가능하다면 카나리 값을 읽거나 임의로 조작할 수 있다

그러면, 스택 버퍼 오버플로우를 수행할 때, 카나리 값으로 스택 카나리를 덮으면 

카나리 검사를 우회할 수 있다

 

 

스택 카나리 릭

가장 현실적인 우회 기법

다음과 같은 코드는 카나리 값을 읽을 수 있는 취약점이 존재한다

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

int main() {
  char memo[8];
  char name[8];
  
  printf("name : ");
  read(0, name, 64);
  printf("hello %s\n", name);
  
  printf("memo : ");
  read(0, memo, 64);
  printf("memo %s\n", memo);
  return 0;
}

 

| memo[8]          |  <= 먼저 위치
|---------------------|
| name[8]          |  <= 뒤에 위치
|---------------------|
| Canary (8 bytes) |  <= 스택 카나리
|---------------------|
| Return Address  |  <= 반환 주소

 

 

read() 호출 시, 버퍼 크기를 초과한 데이터를 입력받을 수 있다

name은 8바이트 크기인데, read()는 64바이트를 읽어오므로, 초과된 데이터는 스택의 name 바로 뒤에 위치한

카나리와 다른 데이터를 침범하게 된다

 

memo가 name보다 먼저 위치한다(낮은 주소에 저장 된다)

 

이 구조를 통해 name 버퍼를 오버플로우하면 카나리를 포함한 memo 영역을 읽을 수 있다

 

 

 

 

 

 


실습

 

 

바이너리 실행

9바이트 이상 입력 시 카나리 변조가 탐지되어 프로그램 강제 종료

오버 플로우로 카나리 값도 노출

 

 

 

카나리 값을 hex dump로 출력하는 방법

 

 

 

스택 구조 확인

memo[8]에 입력할 때,

문자열(8 byte) + 문자열 (8 byte) + 알아낸 카나리 값 + 원하는 실행 주소

를 넣으면 카나리 탐지를 우회하고 오버플로우 공격을 수행할 수 있다

+ Recent posts