버퍼 오버 플로우, 오버런
지난강의동안 많이 언급된 것 중하나가, 보안결함일 것이다. 이것이 ‘Buffer over flow’(버퍼 오버 플로우)인데, 이것이 오늘 배울 Overrun(오버런)이다.
오버런은 지난시간에 배운 적이 있다. 변수에 값을 넣어줄 때, 변수의 메모리크기보다 더 큰 값을 넣어주면 오버플로우, 정보가 변수를 넘어져서 기록된다. 이때, 부르지도 않은 다른 변수의 값이 정보가 넘친 만큼 변경될 수 있는데, 이것이 오버런이다. 이때 이런 것이 일어나는 함수는 보안결함이 있다고 했는데, 그 이유는 이걸 의도해서 해킹에 쓸 수 있기 때문이라고도 지난시간에 배웠다.
예시
puts로 여러 문자열을 출력하고, 그사이에 함수를 호출해서, 그 함수는 printf로 매개변수로 받은 값을 printf()로 출력하게 했다. 그러면 정상적으로 출력이 되는데, 여기서 컴파일러의 보안결함 문제의 제어하는 기능을 꺼두고, 함수에 *(&nData + 2) += 14;를 해주게 되면(nData는 함수의 지역변수로, int nData = 10;으로 미리 선언했다) 실행된 화면에, 함수호출 뒤에 출력 돼야할 puts가 작동을 안 한 것을 볼 수 있다. 과연 *(&nData + 2) += 14;가 무슨 문제였을까?
이 코드의 메모리를 그려본다면,
nParam의 매개변수와 그 함수의 지역변수 nData사이에 2메모리 공간이 있는 것을 알 수 있다.
이때, 메모리의 주소는 아래로 갈수록 증가한다고 했다. 그래서 *(&nData + 2)는 nData의 주소(&)에 +2가 돼서 Return Address의 값을 += 14하는 것이다. 근데 이게 무슨 문제일까?
SFP와 Return Address는 자동으로 만들어지는 메모리고 그중, Return Address는 함수로 호출된 후에 되돌아가는 (헨젤과 그레텔에서)빵가루 같은 역할이다. 그래서 Return Address에서는 되돌아갈 주소가 담겨있는데, 그 값에 += 14를 하면 당연히 되돌아 갈 때 원래 되돌아가는 주소의 + 14로 가게 되는 것이다. 그래서 puts();의 함수가 건너뛰게 돼서 실행되지 않는다. (이것이 Overrun(오버런)이다.)
그래서 신기한 것이, system("notepad.exe");로 메모장을 여는 함수를 만들고, Return Address의 값인 *(&nData + 2)에 =(int)함수; 를 해주면, 함수가 되돌아가는 것이 메모장으로 간다. (함수호출 뒤에 반환될 때, 메모장을 연다.)
이것을 해킹에서 사용하면, 권한으로 제한된 관리자 시스템을 Overrun(오버런)으로 건너가서, 관리자권한을 상속하게 만드는 것이다. (이런 일은 꼭 없도록 대비하자.)
'c언어 > 워딩(미정리)' 카테고리의 다른 글
구조체의 선언과 활용 (0) | 2019.07.08 |
---|---|
함수 호출 규약 (0) | 2019.07.08 |
정적 라이브러리 개발 (0) | 2019.07.08 |
함수 포인터 (0) | 2019.07.08 |
재귀호출 (0) | 2019.07.08 |