NX & ASLR
NX : No-Execute의 약자로, 메모리 영역의 실행 권한을 제거
ASLR : Address Space Layout Randomization의 약자로, 바이너리가 실행될 때 마다 스택, 힙, 라이브러리등을 "임의의 주소"에 배치시키는 것
1. ASLR
ASLR을 사용하면 앞에서 배웠던 기법중에 buffer의 주소같은것을 알 수가 없게 된다. 그래서 이 buffer의 주소를 출력하는 공격이 선행되어야 한다.
- ASLR은 커널단에서 지원하는 보안 기법!
- cat /proc/sys/kernel/randomize_va_space 를 통해 확인할 수 있으며 0인경우 꺼져있는 것
그러나 ASLR이 완전 랜덤화는 아니라는 점
$ ./addr
buf_stack addr: 0x7ffcd3fcffc0
buf_heap addr: 0xb97260
libc_base addr: 0x7fd7504cd000
printf addr: 0x7fd750531f00
main addr: 0x400667
$ ./addr
buf_stack addr: 0x7ffe4c661f90
buf_heap addr: 0x176d260
libc_base addr: 0x7ffad9e1b000
printf addr: 0x7ffad9e7ff00
main addr: 0x400667
$ ./addr
buf_stack addr: 0x7ffcf2386d80
buf_heap addr: 0x840260
libc_base addr: 0x7fed2664b000
printf addr: 0x7fed266aff00
main addr: 0x400667
1) 우선, main 주소(code segment)는 변화하지 않음
2) printf의 하위 12비트(3byte)가 변화하지 않음
- 이는 ASLR이 파일을 페이지 단위로 맵핑하기 때문
- 그래서 libc_base 주소 - printf 주소 를 계산하면 항상 동일한 주소가 나옴
- 즉, 맵핑된 주소로부터 함수별 심볼까지의 거리(Offset)는 항상 일정하다는 뜻
2. NX
No-eXecute의 약자로, 메모리 영역의 쓰기권한과 실행권한을 분리하는 것!
- 보편적으로 코드영역은 Read, Execute / 나머지는 Read, Write 권한을 준다
즉, 각 메모리 영역에 딱 필요한 권한만으 부여하게 됨.
- NX가 적용되면 code영역 외에는 실행 권한이 없음(stack과 heap 등에 없음)
- NX는 명칭이 다양함 (인텔-XD, 윈도우-DEP, ARM-XN)
NX가 적용된 바이너리에다 R2S 공격을 하고 스택에 코드를 넣으면 Segfault가 발생함
여기서의 결론
- NX와 ASLR은 좋은 보호기법이지만, "코드 영역"에는 여전히 실행권한과 고정된 주소가 부여되어있다!!!!
- 이를 우회하는 공격이 대표적으로 RTL(Return To Libc)과 ROP(Return Oriented Programming)이다