메모리 보호 기법 (Canaries)

메모리 보호 기법 종류

  1. NX Bit ( MS : DEP )
  2. ASLR
  3. Canaries
  4. RELRO
  5. PIE

Canaries

  • Canaries 또는 Canary word는 버퍼 오버 플로우를 모니터하기 위해 버퍼와 제어 데이터 사이에 설정 된 값
  • 버퍼 오버플로가 발생하면 Canary 값이 손상되며, Canaries 데이터의 검증에 실패하여, 오버플로에 대한 경고가 출력되고, 손상된 데이터를 무효화 처리

Canaries 종류

Terminator Canaries

  • Terminator Canaries는 Canary의 값을 문자열의 끝을 나타내는 문자들을 이용해 생성
  • Terminator Canaries의 값은 NULL (0x00), CR (0x0d), LF (0x0a) 및 EOF (0xff)로 구성
    • 공격자는 Canaries를 우회하기 위해 Return Address를 쓰기 전에 Null문자를 써야 한다.
    • Null문자로 인해 Overflow를 방지하게 됨
      • strcpy()는 null문자의 위치까지 복사
    • 이 보호에도 불구하고 공격자는 잠재적으로 Canary를 알려진 값으로 겹쳐 쓰고 정보를 트린 값들로 제어해서 Canary 검사 코드를 통과할 수 있음

Random Canaries

  • Random Canaries는 Canary의 값을 랜덤하게 값이 생성합니다.

    • 일반적으로 익스플로잇을 이용해 Canary를 읽는 것은 논리적으로 불가능하다.
  • Random Canaries는 프로그램 초기 설정 시에 전역 변수에 Canary 값이 저장된다.

    • 이 값은 보통 매핑되지 않은 페이지에 저장
      • 해당 메모리를 읽으려는 시도를 할 경우 segmentation fault가 발생하고 프로그램이 종료
    • 공격자가 Canary 값이 저장된 Stack Address를 알거나 스택의 값을 읽어올수 있는 프로그램이 있다면 Canary의 값을 확인 할 수 있다.

Random XOR Canaries

  • Random XOR Canaries는 Canary의 값을 모든 제어 데이터 또는 일부를 사용해 XOR-scramble 하여 생성
    • 이 방식은 Canary의 값, 제어 데이터가 오염되면 Canary의 값이 틀려짐
  • Random XOR Canaries는 Random Canaries와 동일한 취약점을 가지고 있음
    • 단지 Canary 값을 Stack에서 읽어오는 방법이 조금 더 복잡
    • 공격자는 Canary를 다시 인코딩 하기위해 Original Canary 값, 알고리즘, 제어 데이터가 필요

실습

image

Canary의 메인 부분이다. [rbp-0x8]에서 값을 가져와 검증을 한뒤 같으면 리턴으로 보내고 다르면 stack_chk_fail함수를 호출하여 진행한 뒤 에러메시지를 출력한다. 그렇다면 여기서 Canary의 값은 [rbp-0x8] 일 것이다.

image

bp를 main+64와 73에 각각 걸어주고 Canary 값을 확인해보자.

image

[rbp-0x8]을 rax로 옮겨오는 과정을 거쳐 간단하게 Canary 값을 확인할 수 있었다. 그럼 다음은 Canary 동작과정을 살펴보자.

image

실행 입력은 위와 같이 A로 채운뒤 Canary값을 'B' = '\x42'로 변조하였다.

image

Canary의 값이 '\x42'로 뒤덮인 것을 확인하고 c를 눌러 다음 과정을 살펴보자.

image

xor연산으로 인해 rax가 0이 되지 않고 다른 값이 나왔기 때문에 다음 함수인 stack_chk_fail함수를 호출하여 에러 메시지를 출력하고 종료한다.


Reference

http://lazenca.net/display/TEC/03.Canaries