본문 바로가기

wargame

[메모리 보호기법]Canaries

출처

http://lazenca.net/display/TEC/02.TechNote https://bpsecblog.wordpress.com/2016/05/16/memory_protect_linux_1/



Canaries

Canaries
SFP와 return address를 저장할 때, 이 정보들이 공격자에 의해 덮어씌워지는 것으로부터 보호하기 위해 스택상의 변수들의 공간과 SFP 사이에 넣는 특정한 값
버퍼 오버 플로우가 발생하면 Canary 값이 손상되어 Canaries 데이터의 검증에 실패하여, 오버 플로에 대한 경고가 출력되고, 손상된 데이터를 무효화 처리된다.

Terminator canaries
Canary의 값을 문자열의 끝을 나타내는 문자(NULL 0x00, CR 0x0d, LF 0x0a, EOF 0xff)들을 이용해 생성한다.
Canaries를 우회하기 위해 return address를 쓰기 전에 null 문자를 써야 하는데 strcpy 함수가 null 문자의 위치까지 복사하므로 overflow를 방지할 수 있다.
그러나 공격자는 잠재적으로 Canary를 알려진 값으로 겹쳐쓰고 정보를 틀린 값으로 제어해서 canary 검사 코드를 통과할 수 있다.
Random canaries
Random Canaries는 Canary의 값을 랜덤하게 생성하여 프로그램 초기 설정 시에 전역 변수에 저장한다.
해당 메모리를 읽으려고 할 경우 segmentation fault가 발생한다.
공격자가 canary 값이 저장된 stack address를 알거나 스택의 값을 읽어올 수 있는 프로그램이 있다면 canary의 값을 확인할 수 있다.
Random XOR canaries
Canary의 값을 모든 제어 데이터 또는 일부를 사용해 XOR-scramble하여 생성한다.
Canary 값, 제어 데이터가 오염되면 Canary 값이 틀려진다.
Canary 값을 stack에서 읽어오는 방법이 좀 더 복잡해질뿐, Random canaries와 동일한 취약점을 가지고 있다.

예시

vi canary.c


gcc -fstack-protector -o canary canary.c (do not set canary)


Do not overwrite the value in the canary area.의 경우

disass main

정지점 걸기
call
mov rax, QWORD PTR [rbp-0x8]


첫 번째 정지점에서 rdi값은 0x7fffffffde40


stdin으로 A를 32개 저장한다.


들어간 값을 확인해보자.


continuing. 두 번째 정지점으로 이동하자.


두 번째 정지점에서 rbp -0x8의 값은 0x1474167a337e7700


0x400614에서 rax 레지스터의 값과 fs:0x28 레지스터에 저장된 값을 xor 연산
rax 레지스터 값이 0이면 0x400624으로 이동


0x400624로 이동했음을 알 수 있다.


This value is overwritten in the canary area의 경우

다시 실행


rdi 레지스터의 값은 그대로 0x7fffffffde40


stdin으로 A 40개, B 8개를 저장하자.(buffer 40byte + canary 8byte)


잘 저장되어 있다.


continuing. 두 번째 정지점으로 이동하자.


rbp -0x8의 값을 확인해보자.

BBBBBBBB로 차있다.
이후 ni 명령어를 통해 rax값과 fs:0x28 레지스터에 저장된 값을 xor 연산을 한다.

ni

rax 값이 0이면 0x400624로 이동

segmentation fault를 호출한다.


'wargame' 카테고리의 다른 글

[메모리 보호기법]PIE  (0) 2019.12.01
[메모리 보호기법]RELRO  (0) 2019.12.01
[메모리 보호기법]ASLR  (0) 2019.12.01
[메모리 보호기법]NX  (0) 2019.12.01
[BOF]simpleBOF  (0) 2019.11.27