카나리 정적 분석
스택 버퍼 오버플로우 취약점이 존재하는 코드
#include <unistd.h>
int main() {
char buf[8];
read(0, buf, 32);
return 0;
}
gcc는 기본적으로 스택 카나리를 적용하여 컴파일한다
-fno-stack-protector 옵션으로 카나리 없이 컴파일 가능
바이너리를 실행하고 긴 문자열을 입력하면 반환 주소가 덮여서 Segmentation fault가 발생
카나리를 활성화하여 컴파일하고 실행하면
stack samshing detected, Aborted 에러가 발생
→ 스택 버퍼 오버플로우가 탐지되어 프로세스가 강제 종료됐다는 뜻
카나리 동적 분석
이제 카나리가 적용된 바이너리를 분석해보자
중단점을 설정하고 바이너리를 실행시킨다
<main+12>는 fs:0x28의 데이터를 읽어서 rax에 저장한다
fs는 세크먼트 레지스터의 일종으로, 리눅스는 프로세스가 시작될 때, fs:0x28에 랜덤 값을 저장한다
따라서 rax에 리눅스가 생성한 랜덤 값이 저장된다
fs cs, ds, es는 CPU가 사용 목적을 명시한 레지스터인 반면, fs와 gs는 목적이 정해지지 않아 운영체제가 임의로 사용할 수 있는 레지스터이다. 리눅스는 fs를 Thread Local Storage(TLS)를 가리키는 포인터로 사용한다. TLS에는 카나리를 비롯하여 프로세스 실행에 필요한 여러 데이터가 저장된다. |
코드를 두 줄 실행하면 rax에 첫 바이트가 널 바이트인 8바이트 데이터가 저장된다
코드를 한 줄 더 실행한다
그러면 rax에 저장된 랜덤값은 rbp-0x8에 저장된다
<main+54>에 중단점을 설정하고 H*16를 입력한다
rbp-0x8에 저장된 카나리 값이 버퍼 오버플로우로 인해 0x4848484848484848('HHHHHHHH')이 됨
<main+58>의 연산 결과가 0이 아니므로 <main+69>의 __stack_chk_fail 을 실행하게 됨
→ 프로세스가 강제로 종료됨
'시스템 해킹 > 학습' 카테고리의 다른 글
[시스템] 스택 카나리 우회(Canary) (0) | 2025.01.03 |
---|---|
[시스템] 스택 카나리 생성 과정(Canary) (0) | 2025.01.02 |
[시스템] (스택) 버퍼 오버플로우 (0) | 2024.08.26 |
[시스템] 함수 호출 규약 (SYSV) (0) | 2024.08.22 |
[시스템] 바이트 코드 쉘 코드 만들기 (objdump) (0) | 2024.08.20 |