1. 들어가며

Windows Bufferoverfow

많은 사람들이 리눅스에서의 BOF는 접해 보았을 것이다, 하지만 윈도우에서의 BOF는 접해보지 못했을 걸로 안다.

사실 리눅스와 윈도우의 다른점은 그리 많지 않다, 쉘코드. 머신이 다른데 쉘코드가 다른 것은 당연한 이야기다. 쉘코드에 대한 자세한 대용은 4번째 섹션에서 다루기로 한다.

그리고 또한 자세한 메모리 구조도 다를 것 같으나, 깊숙히는 알아보지 못했다. 허나 윈도우의 메모리 구조에도 RET과 SFP있어 해당 자료를 찾아서 이를 이해해 봅니다.

인터넷으로 자료를 찾다가 정리가 잘된 자료가 있어 그대로 옮겨보았으니 양해 바랍니다.

http://hdp.null2root.org/ 해당 사이트의 BOF란의 문서입니다.

2. 기본적인 Window BOF

공격 대상 : Simble Bof v.0.0.1

Use Tool : ollydbg v.1.10, Visual Studio 7.0

Simble Bof v.0.0.1은 아래와 같다.

이곳에서 보면 gets(buff) 부분에서 Bof가 발생하게 된다.

10byte로 선언된 배열에 조건없이 gets로 모든 문자열을 받아 버리면 10byte이후의 문자열부터는 overflow가 발생 된다. 하지만 11byte, 12byte에서는 overflow가 발생하지 않는다.

이유는 stack에 자리를 잡을때 선언된 만큼만 잡히는것이 아니라여유공간인 2byte정도가 더 잡히게 된다.

이 여유공간은 OS 마다 틀리므로 꼭 2byte라고 생각하지 않길 바란다.

(또한, shellcode를 만들 필요없이 [system("cmd");] 함수를 만들어 놓아서그쪽으로 Jump하면 바로 쉘이 떨어진다.)

그럼 입력값을 넘어보도록 하자.

[a]의 갯수는 12개를 입력하였다. 아까 말한대로 buff[10]으로 잡혀 있어도 12byte까지는 입력을 받는다.

두번째를 입력하면 overflow가 발생한다.

이렇게 overflow가 발생하였다. 자 그럼 어디에서 overflow가 발생하는냐?

이곳에서 발생한다.

Offset은 RVA다.

(RVA ; Relative Virutal Address로서 Base Address를 뺀 Offset 주소를 의미한다.)

따라서, 정확한 주소를 알기 위해서는 RVA에 0x00400000을 더해주어야한다.

그럼 Overflow가 발생하는 지점은0x0000146C + 0x00400000 = 0x0040146C이 된다.

그럼 ollydbg로 따라가 보도록 하자.

overflow는 call 한 다음에 스택을 정리하고 나오는 부분에서 발생한다.

040146C 지점에서의 EBP는 [00120062]로 마지막 1byte가 [b]에 해당하는

16진수 [62]가 들어가 있는것을 볼 수있다.

그럼 조금더 넣으면 어떻게 변할지 [b]를 3개더 넣어 보도록 하겠다.

이렇게 EBP가 [62]로 변경 되었다. 하지만, 여기에서 변경해야하는 부분은 EIP 부분이다.

EIP 레지스터의 하는 역할은 다음에 실행될 주소를 가지고 있다.

즉, [EIP만 수정하면 원하는 모든 프로그램을 실행 시킬 수 있다.]는  이야기가 된다.

그럼 일단 EBP는 변경되는것을 확인 하였으니, 조금더 넣어보도록 하자

단위는 4byte 단위로 문자를 변경하여 넣기로 하겠다.(Address의 단위는 4byte 단위므로)

이제 windows가 어떤 구조로 자료를 입력받고 주소 배치가 어떻게 정의 되어 있는지 알 수 있을꺼 같다.

구조는 다음과 같다.[10byte][2byte dummy][EBP][EIP]

공격 코드는 [10byte][2byte dummy][EBP][Shell 주소]

그냥 주소를 입력하면 1byte씩 자리를 잡아서 원하는 주소를 입력하지 못한다.

(※ 0040112F 일때 그냥 주소로 입력값을 넣으면 8byte를 차지한다. 따라서, 그냥 넣으면 안되고 exploit을 만들어서 입력해야 한다.)

exploit을 만들기 전에 [system("cmd");]의 주소를 먼저 알아보도록 하자.

그럼 EIP는 0x00401005로 지정해주면 cmd shell이 뜰 것이다. exploit을 작성해보자.

exploit 코드는 file.txt 파일 안에 들어가 있다. 실행 시켜보도록 하자.

exploit 코드는 아래와 같다.

이상한 특수문자가 보일것이다. 그 문자는 0x00401005 를 표현한 문자이다.

그럼 공격을 해보도록 하자.

쉘이 떨어졌다. exit를 입력하면 남어지 처리를 하므로 Error가 뜰 것이다.

이제 exploit 코드가 정확히 맞다는걸 알았다.

매번 이렇게 입력해서 공격 할 필요없이 실행 파일로 만들어 보도록 하자.

linux에서의 공격 코드를 삽입할 때는 cat명령을 이용하였다.

하지만 windows에서는 cat 명령이 없으므로 echo문을 사용하도록 하겠다.

exploit code는 다음과 같다.

똑같은 exploit code를 넣었지만 prompt이 떨어지지 않어지지 않았다.

이유는 echo에서는 "00(Null 문자)"가 출력이 되지 않기 때문이다.

네모칸을 보면 [02401005] 라는 주소가 보일 것이다.

원래 "02" 대신에 "00"이 들어가야 하는데 출력이 안된 것이다.따라서, 이부분을 처리해야 한다. 방법은 execl 함수를 사용하면 된다. execl 함수는 argument도 입력할 수 있는 아주 유용한 함수이다. 그럼 execl 함수를 이용해서 다시 exploit을 만들어 보도록 하자.

여기에서 보면 bof01을 실행 시키고 exploit을 출력하고 실행이 종료되게 되어 있다.

그럼 실행 시켜보도록 하자.

아무런 변화가 없다. 이상하다.

하지만 exit를 눌러보면 쉘이 하나더 떠 있는것을 확인 할 수 있다.

exploit은 성공이다. 하지만 무조건 exit로 확인 할 수는 없을 것이다.

하지만 확인 할 수 있는 방법은 있다. 바로 [Windows 작업 관리자]이다.

exploit이 성공하면 bof01.exe 파일은 실행된 상태에서 쉘이 유지 된다.

하지만 종료 시켜버리면

bof01.exe 프로세스가 죽어 있는것을 확인 되었다.

이상 간단한 Windows Buffer Overflow를 마치도록 하겟습니다.