ASLR(Address Space Layout Randomization) 은 바이너리가 실행 될 때마다 스택, 힙, 공유 라이브러리 등을 임의의 주소에 할당하는 보호 기법이다.
ASLR 은 컴파일러에서 설정하는 것이 아닌 커널에서 지원하는 보호 기법 이며, 다음 명령어로 확인할 수 있다.
cat /proc/sys/kernel/randomization_va_space
ASLR 은 0, 1, 2 값으로 설정되며 각 값은 아래의 의미를 가진다.
brk
로 할당 된 영역코드 영역의 main
함수를 제외한 다른 영역의 주소들은 실행할 때마다 변경됨(주소 예측 불가)
바이너리를 반복해서 실행해도 libc_base
주소 하위 12비트 값과 printf
주소 하위 12비트 값은 변경되지 않음
리눅스는 ALSR 이 적용됐을 때, 파일을 페이지(page) 단위로 임의 주소에 매핑하는데 페이지는 4kb 크기로 나누어지기 때문에 페이지 크기인 12비트 이하로는 주소가 변경되지 않는다.
libc_base
와 printf
의 주소 차이는 항상 같다NX(No-eXecute) 는 실행에 사용되는 메모리 영역과 쓰기에 사용되는 메모리 영역을 분리하는 보호 기법이다.
CPU 가 NX 를 지원하면 컴파일러 옵션을 통해 바이너리에 NX 를 적용할 수 있으며, NX 가 적용된 바이너리는 실행될 때 각 메모리 영역에 필요한 권한만을 부여받는다.
NX가 적용되면 코드 영역 외의 다른 영역은 실행 권한이 해제된다.
NX 는 아키텍처와 운영체제에 따라 명칭이 조금씩 달라진다.
만약 스택에 쉘 코드 삽입 후, 해당 주소를 return address 에 대입하여 실행하게 된다면, 스택 영역에는 실행 권한이 없으므로 쉘 코드가 실행되지 못하고 Segmentation fault 에러가 발생하고 종료 된다.