발단
시스템보안실습 수업의 3번째 과제가 올라왔다.
코드는 대충 이렇다.
#include <stdio.h>
#include <string.h>
void ShowWelcomeMessage (void)
{
puts ("Welcome!");
}
int CheckPassword (void)
{
char aBuffer [32];
printf ("Password: ");
scanf ("%s", aBuffer);
return strcmp (aBuffer, "tltmxpaqhdkstlftmq");
}
int main (int argc, char * argv [])
{
CheckPassword () ? puts ("Access Denied.") : ShowWelcomeMessage ();
return 0;
}
대략 CheckPassword() 함수에서 버퍼의 크기가 32바이트지만, scanf로 입력을 받고 있기 때문에 그 부분을 공략하면 될 듯 하다.
문제에서는 올바른 패스워드인 "tl..mq"를 입력하지 않고 ShowWelcomeMessage() 함수의 출력문을 실행하는 것을 요구한다.
공격 시작
문제의 바이너리는 아래와 같이 컴파일되었다.
gcc -g -o hw hw.c
모든 보호기법이 다 적용되었을 것이다.
세부 정보를 확인하면 아래와 같다.
아뿔싸! 내 서버에서 사용하는 glibc 버전보다 상위 버전을 요구한다.
매번 실행마다 환경변수를 설정해주기도 번거로우니 그냥 가상머신으로 옮겨서 확인하기로 하였다.
일단 GDB를 통해 CheckPassword()의 어셈블리 코드를 보자.
함수에 버퍼가 존재하지만 스택 가드가 없다! 아마도 교수님이 -fno-stack-protector 옵션을 넣으셨거나 다른 이유가 있는 듯 하다.
<CheckPassword+4>에서 스택 프레임의 크기를 32바이트로 잡는 것을 확인 가능하다. aBuffer 배열의 크기와 동일하다.
이어서 ShowWelcomeMessage() 함수의 어셈블리 코드는 아래와 같다.
바이너리에 PIE가 적용되어 있기 때문에 GDB 상에선 aBuffer 입력부분에 아래와 같은 형태로 입력하면 될 듯 하다.
aBuffer (32바이트) | rbp (8바이트) | return address (2바이트) |
왜 반환 주소는 2바이트만 입력하는가?
- file 명령어로 확인된 LSB -> 바이너리는 리틀엔디언을 따름 -> 메모리에 적재된 숫자 값은 레지스터로 이동 시에 거꾸로 이동됨 -> 주소값 입력도 거꾸로
- PIE와 x64 리눅스 ABI로 인해 상위 2바이트는 0, 하위 12비트는 기존 주소를 따라감 -> scanf로 입력받기 때문에 12비트 입력은 불가능 -> 하위 2바이트 중 상위 4비트의 값은 때려맞추기에 가까움
따라서 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBiQ를 입력하면 실행 흐름이 CheckPassword() -> ShowWelcomeMessage()가 될 것이다.
하지만 간과해야 할 것은 입력을 scanf("%s", aBuffer); 받고 있다는 것이다. scanf() 함수는 버퍼에 문자열 입력 시에 널바이트를 문자열 끝에 삽입한다. 따라서 아래와 같이 입력해야 할 것이다.
aBuffer (32바이트) | rbp (8바이트) | return address (6바이트) |
텍스트 영역의 주소값이 상위 2바이트가 0이기 때문에 scanf()가 삽입하는 널바이트 문제는 해결되었다.
PIE base 값이 문제가 되겠지만 디버깅 상태로 프로그램을 실행시키는 것이기 때문에 PIE base 값은 바로 확인이 가능하다.
현재 상황에서 PIE base 값은 0x555555554000이다. 이를 고려하면 ShowWelcomeMessage() 함수의 주소는 아래처럼 0x555555555169가 된다.
공격 결과
따라서 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBiQUUUU를 입력하면 아래와 같이 Welcome! 메세지를 볼 수 있다.
결론
버퍼오버플로우는 이번 실습처럼 스택 상에서 일어나는 것외에도 힙이라던지 다양하게 존재한다.
아직까지도 대부분의 취약점의 트리거가 버퍼오버플로우와 관련된 만큼 공부해서 나쁘지 않다고 생각된다.
실습 때 왜 교수님께서 값을 그렇게 입력하시는지 모르겠다는 인원이 있었는데, 이 글을 보고 조금이나마 해소가 되었으면 좋겠다.
'대학생활' 카테고리의 다른 글
시스템보안실습 | 4. 주통기 점검 스크립트 (0) | 2024.12.15 |
---|---|
시스템보안실습 | 5. 윈도우 RDP 침투 (0) | 2024.12.13 |
시스템보안실습 | 2. Privilege Escalation & Lateral Movement (2) | 2024.10.17 |
시스템보안실습 | 1. shadow 파일 password cracking 해보기 (0) | 2024.09.24 |