반응형

쉘코드를 만드는 것에 대한 내용은 BOF 챕터의 포스팅에서는 일절 언급하지 않습니다. 쉘코드에 대한 지식이 필요하다 싶은 경우, 쉘코드 챕터로 넘어가셔서 쉘코드에 대한 내용을 숙지하고 오시기 바랍니다.

다른 포스팅에서도 말햇듯, 이하 존칭은 생략합니다.

버퍼 오버플로우(=버퍼 오버런)

버퍼 오버플로우 취약점은 컴퓨터 초기부터 지금까지 쭉 발생되고 있으며, 대부분의 인터넷 웜은 전파를 위해 버퍼 오버플로우 취약점을 이용한다.

C는  하이레벨 프로그래밍 언어지만 자체적으로 데이터 무결성을 검사하는 기능이 없고, 프로그래머 직접 데이터 무결성을 검사해야 한다. C 컴파일러에서 직접 데이터를 무결성을 검사했다면 어떻게 됫을까? 당연히 속도가 엄청나게 느려졌을 것이다. 또한 프로그래머가 프로그램을 세세하게 제어하게 할 수 없게 됬을것이고 언어도 복잡해졌을 것이다.

정리해보면, C는 단순한 언어여서 프로그래머가 프로그램을 원하는 대로 제어하고 효율적으로 만들 수 있다는 장점이 있다. 그러나 한편으로는 프로그래머가 신경 쓰지 않을 경우 버퍼 오버플로우와 메모리 누수 현상이 일어날 수 있다는 단점이 있다. 즉, 어떤 변수가 메모리에 할당되어 있을 경우 그변수의 내용이 메모리 경계를 벗어나지 않는지 검사하는 내부 안전장치가 존재하지 않는다. 예를 들면 프로그래머가 8바이트 크기의 버퍼에 10바이트를 넣을 수도 있다. 그렇게하면 프로그램이 잘못된 연산으로 종료되는데 우리는 이것을 '버퍼 오버플로우(=버퍼 오버런)'이라 부른다.

위와같은 예로 첫번쨰 포스팅에서는 여러분들이 오버플로우를 공부하는데 의지를 꺾지 않기 위해 기초적인 예시를 가지고 살펴보려 한다



이 프로그램은 패스워드를 인자로 받아서 check authentication() 함수를 호출한다.

check_authentication()함수는 다음과 같이 두개의 패스워드를 허용하고, 둘중 하나가 사용된다면 접근 허용을 의미하는 1을 리턴한다.(소스코드를 한번 쭉 훑어보면 어떤 코드인지 이해가 갈것이다.)

소스를 보고 이해한대로 소스는 아주 잘 작동하고 있다.

하지만 우리가 원하는건 이렇게 잘 작동하는 프로그램을 보고 기분좋아 하는것이 아니다.

우리가 해볼 것은 이 프로그램을 오버플로우 시켜 예상치 못한,올바르지 않은 패스워드를 허용하게 하는 것이다.

우선 결과를 한번 보자 A를 엄청나게 집어넣었더니 다음과 같이 access complete 이 떳다.

와 신기하다! 라는 말보다는 왜 이렇게 access complete가 나올까라는 의문을 가져야한다.

gdb로 분석을 해보도록 하자.

여기서 우리는 9번과 16번에 break를 걸것이다. 왜  이 부분에 break를 걸까? 

여러분들에게 주는 2번째 과제다.. 마찬가지로 생각해보고 이해가 되지 않는다면 방명록이나 댓글을 남겨주면 답을 주도록 하겟다.

이제 gdb로  break를 건 부분을 하나하나 진행해 가면서 메모리를 조사해보도록 하겟다.

<1번 break>

첫 번째 break는 strcpy()바로 전에 있다. password_b 포인터를 조사해보니 0xbffff9e0에 존재하고, 초기화 되지 않은 임의의 값들이 들어있다. 또한 flag변수의 주소를 조사해보니 0xbffff9fc에 존재하고 값은 0이다. print 명령으로 계산해보면 flag는 password_b의 28 byte 뒤에있음을 알수있다.  따라서 password_b의 메모리 블럭안에서 flag를 찾을수 있다 (0x00000000)


<2번 break>

strcpy()이후 디버깅을 계속해 다음 break에 도착했다. 여기서도 메모리를 주소하면 password_b가 오버플로우 되어 flag의 첫 두바이트를 0x41로 바꿔 버렸다. 궁극적으로 프로그램은 이 값을 16705라는 정수로 처리하게 된다.

오버플로우 후에는 check_authentication함수가 0대신 16705를 리턴한다. if 구문에서 0이 아닌 값은 모두 인증되는 것으로 처리했으므로 프로그램은 접근 허용 쪽 구문을 실행한다.

위의 예제에서는 덮어씌어진 flag변수가 바로 실행 제어 포인트여서 위와 같이 아주 쉽게 오버플로우 되어있지만 실제로 오버플로우 기법은 이렇게 쉬운 기법만은 아니다. 다음 포스팅에서는 password_b와 flag변수를 앞뒤만 한번 바꾸어 볼것인데 어떤 일이 일어날지에 대해 포스팅을 할 것이다. 어떻게 변할지 한번 생각해보자!


반응형
,