1) ASLR: Address Space Layout Randomization
2) 라이브러리, 힙, 스택 영역 등의 주소를 바이너리가 실행될 때마다 랜덤하게 바꿔 RTL과 같이 정해진 주소를 이용한 공격을 막기 위한 보호 기법
3) NX bit가 바이너리의 컴파일 옵션에 따라 적용 여부가 결정되었던 것과 달리, ASLR은 서버의 설정 파일에 의해 보호 기법의 적용이 결정됨.
4) Ubuntu 16.04에서는 /proc/sys/kernel/randomize_va_space 파일의 값을 확인하면 서버의 ASLR 설정 여부를 알 수 있음. 설정 파일의 값으로는 0, 1, 2가 존재
0: ASLR을 적용하지 않음
1: 스택, 힙 메모리를 랜덤화
2: 스택, 힙, 라이브러리 메모리를 랜덤화
5) 만약 해당 파일의 값이 2가 아니라면, 루트 권한으로 다음 명령어를 실행하여 ASLR 보호 기법을 적용 가능
$ cat /proc/sys/kernel/randomize_va_space
$ echo 2 > /proc/sys/kernel/randomize_va_space
$ cat /proc/sys/kernel/randomize_va_space
1) example3.c: 프로세스 자신의 메모리 맵을 읽어 출력해주는 코드
2) 코드
3) 실행결과
서버에 ASLR이 켜져있을 때, 라이브러리, 힙, 스택 영역의 주소가 랜덤하게 바뀌는 것을 확인할 수 있음. 라이브러리 주소가 계속 바뀌기 때문에 스택 버퍼 오버플로우 취약점을 공격할 때, 정적 주소를 이용한 공격을 사용할 수 없음. 바이너리 코드 영역의 주소는 변하지 않음. 이를 이용해 ASLR 보호 기법을 우회하여 익스플로잇 할 수 있음.
1) example4: scanf 함수로 32바이트 크기의 배열 buf에 데이터를 입력받음. “%s” 포맷 스트링을 사용하기 때문에 입력 길이의 제한이 없어 스택 버퍼 오버플로우 취약점이 발생.
2) 코드
3) NX bit 적용 확인
readelf로 확인한 스택 메모리의 권한은 RW, 바이너리에 NX bit가 적용되어 있음. 서버에 ASLR 보호 기법이 적용되어 있기 때문에 이전의 공격 기법은 사용할 수 없음.
4) 스택의 리턴 주소 덮기
ebp 레지스터가 가리키는 위치에는 스택 프레임 포인터가 존재하고 ebp+4에 main 함수의 리턴 주소가 위치. “A”*36+”BBBB”를 입력했을 때 main 함수가 리턴한 이후 eip 레지스터의 값이 0x42424242로 바뀐 것을 확인할 수 있음.
NX bit가 걸려 있으므로 프로그램이 비정상 종료하지 않기 위해서는 실행 권한이 있는 코드 영역으로 덮어야 함. 앞서 example3을 순차적으로 실행시킨 결과를 볼 때 라이브러리, 힙, 스택 메모리의 주소는 랜덤으로 변하지만 바이너리의 코드나 데이터 영역들의 주소는 변하지 않는 것을 알 수 있음.