일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- BOF
- Kaggle
- Dreamhack
- Widget
- MDP
- 백준
- Computer Architecture
- BFS
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- FastAPI
- Image Processing
- fastapi를 사용한 파이썬 웹 개발
- Algorithm
- MATLAB
- Stream
- PCA
- ARM
- 영상처리
- rao
- bloc
- Flutter
- DART
- study book
- ML
- Got
- pytorch
- llm을 활용 단어장 앱 개발일지
- BAEKJOON
- C++
- system hacking
- Today
- Total
Bull
[System Hacking] Stack Canary 본문
Stack Cnanary란?
Stack Canary는 스택 버퍼 오버플로우 공격을 탐지하고 방지하기 위해 사용된다.
이 기술은 '카나리아'라는 새에 비유되는데, 과거에 광부들이 가스 누출을 감지하기 위해 새를 채굴장에 가져갔던 것에서 유래한다.
마찬가지로, 스택 카나리는 메모리의 특정 부분에 의도적으로 배치된, 변경되면 안 되는 값(카나리 값)으로, 스택 버퍼의 오버플로우를 감지하는 데 사용된다.
프로그램이 실행될 때, 스택 카나리 값은 스택에 있는 로컬 변수와 반환 주소 사이에 배치된다.
이 값은 실행 동안 불변이어야 하며, 보통 실행 때마다 또는 프로그램이 시작될 때마다 무작위로 생성된다.
공격자가 버퍼 오버플로우를 이용하여 스택의 메모리를 덮어쓰려고 시도할 때, 카나리 값도 변경될 가능성이 높다.
Ubuntu 22.04의 gcc는 기본적으로 스택 카나리를 적용하여 바이너리를 컴파일한다.
gcc -o no_canary canary.c -fno-stack-protector
카나리 실습을 하려면 컴파일 할 때 위와 같이 -fno-stack-protector를 사용하여 컴파일한다.
카나리 난수 저장 및 인증 방식
카나리는 기본적으로 fs:0x28에 난수값이 저장된다.
특히 이 fs를 비롯하여 fs, gs 레지스터는 목적없이 운영체제에서 사용되는 레지스터이다.
이를 Thread Local Storage(TLS) 포인터를 사용하여 접근할 수 있다.
main()의 시작 후 생성된 카나리 난수는 버퍼오버플로우가 발생할 만한 스택 영역에 카나리 값을 배치시켜
xor연산을 통해 카나리 값을 검증한다.
je의 조건이 만족하게 되면 main함수는 반환되고
그렇지 않으면 두 값이 동일하지 않으면 __stack_chk_fail이 호출되면서 함수를 종료한다.
카나리 생성 과정
1. 프로세스가 시작될 때, 카나리 값은 TLS에 전역 변수로 저장된다.
2. 리눅스 시스템에서는 fs 레지스터가 TLS를 가리키고 있으므로, fs의 값을 통해 TLS의 주소를 알 수 있다.
fs의 값은 arch_prctl 시스템 콜을 통해 설정할 수 있다.
따라서 arch_prctl(ARCH_SET_FS, addr)를 호출하여 fs를 설정하고, 이를 통해 TLS의 주소를 파악한다.
3. TLS의 주소를 알았다면, gdb의 watch 명령어를 사용하여 TLS 오프셋에 위치한 카나리 값의 변경을 감시한다.
pwndbg> catch syscall arch_prctl
이제 init_tls() 안에서 c(continue)를 통해 arch_prctl에 도달할 때 까지 실행한다.
이때 [rdi = 0x1002 = ARCH_SET_FS]이 될 때, rsi의 값이 fs가 된다.
이때 TLS는 0x7ffff7d7f740이고, fs가 이것을 가리키게 된다. (즉 fs는 TLS 포인터)
pwndbg> x/gx 0x7ffff7d7f740 + 0x28
0x7ffff7d7f768: 0x0000000000000000
다시 fs+0x28주소에 catch를 하면
pwndbg> watch *(0x7ffff7d7f740+0x28)
security_init()에서 멈춘다.
그리고 이 때 카나리 값이 생성된다.
pwndbg> x/gx 0x7ffff7d7f740+0x28
0x7ffff7d7f768: 0x8ab7f53277873d00
카나리가 추가된 스택 구조
이제 기존 Return Adrress Overwrite기법에서 Canary를 추가하여 조작해주어야한다.
참고자료
[DreamHack 강의]
'Computer Science > System Hacking' 카테고리의 다른 글
[System Hacking] PLT & GOT (0) | 2024.04.10 |
---|---|
[System Hacking] NX & ASLR (0) | 2024.04.09 |
[System Hacking] Return Address Overwrite (0) | 2024.04.05 |
[System Hacking] Shell Code 및 syscall (2) | 2024.03.31 |
[pwntools] 함수 및 모듈 정리 (0) | 2023.09.27 |