Lord of the BufferOverflow Fedora Core3


[ Level3_Dark_eyes -> Hell_fire ]


다음은 Level3의 hell_fire.c입니다.



힌트부터 확인 해 보면 "another fake ebp or got overwriting"이라고 되어 있는데, 이전 문제와 같이 beist's execl 기법을 사용하여 풀이 할 수 있을 것 같습니다.

하지만 소스를 확인 해 보니, remote bof이기 때문에 이 기법을 이용한 풀이는 어려워보입니다. 해당 문제는 standalone으로 바이너리 자체에 hell_fire 권한이 있어 setuid bit가 걸려 있는 것이 아니라, xinetd.d 슈퍼데몬을 이용해 hell_fire 권한으로 해당 소스를 실행하는 형태입니다. 따라서 이전 문제와 같이 symbolic link를 통해 스크립트를 실행시키는 형태가 불가능 할 것입니다.

두 번째인 got overwriting의 경우 ppr gadget을 필요로 하는 것으로 알고 있는데, 코드 영역을 뒤져 보니 pop;pop;leave;ret 와 같은 leave 명령어를 포함한 가젯밖에 없어 got overwriting 기법으로 풀이하지도 못했습니다. fake ebp보다 got overwriting이 풀이하는 데 조금 더 용이 할 것 같아, 관련 문서를 찾아보았지만 결국 찾지 못해 이번 문제는 다른 분들의 write up을 참고하여 풀이하였습니다.

풀이 방법을 요약하자면 fedora core3에서 system함수를 이용하는 것인데, system 함수에서는 내부적으로 do_system 함수를 호출하도록 되어 있습니다. 이 do_system 함수를 따라 들어가보면 내부적으로 execve 함수를 호출하는 부분이 있습니다. 이 때 execve를 실행하는 과정에서 쉘을 띄워주는 부분이 있는데, 이 부분을 이용한 풀이법입니다.

이제, 설명했던 system 함수를 따라 들어가보겠습니다.



system 함수를 disassemble 한 상태입니다. 코드의 끝 부분을 보면 내부적으로 do_system 함수를 call하는 곳이 보입니다. do_system 함수의 주소를 따라 들어가보면 아래와 같은 코드가 있습니다.



위에서 설명했던 execve 함수를 call 하고 있습니다. 그렇다면 여기서 execve를 호출 할 때 어떤 인자들을 받아 실행하기에 쉘을 띄워준다는 것일까요?

이 과정은 http://sanguine.leaveret.kr/7 를 참고하였습니다.

결론부터 말하자면 do_system+1124 부분으로 ret address를 바꿔주면 쉘을 획득 할 수 있습니다. 이 부분은 sigprocmask 함수의 다음 부분인데, sigprocmask 함수를 이용하여 시그널 마스크를 블록 한 후에 내부적으로 쉘을 실행시키는 것 같습니다.

execve 직전에 받는 인자들을 살펴보면 다음과 같습니다.


execve("/bin/sh",{"/home/dark_eyes/hell_fire",NULL},envp)


hell_fire라는 이름으로 /bin/sh를 실행시키는 과정이기 때문에 do_system+1124 부분으로 루틴을 이동시키면 쉘이 띄워지는 원리인 듯 합니다. 정확한 인자값과 구성에 대해서는 후에 공부를 더 해서 연구 해 봐야 할 것 같습니다.


자, 이제 답은 나왔습니다. 이제 payload만 작성하면 끝날 것 같습니다. 하지만 마지막 관문이 남아있습니다. 바로 fgets 함수에 대한 것인데, 이 함수는 인자를 받아들일 때 마지막에 0x0a를 자동으로 받아들입니다. 0x0a는 개행의 아스키코드인데, 이로 인해 0x750784를 payload로 넘겨 줄 경우 0x0a750784로 넘어가게 됩니다. 이에 대해 고민하고 있었는데, 선임 중 한명이 remote 환경에서 파라미터를 전송 할 경우 null byte를 입력 할 수 있다고 하여 그냥 0x00750784로 넘겨 주니 쉘을 획득 할 수 있었습니다.

위 과정을 core dump 하여 확인 해 보도록 하겠습니다.



payload로는 0x713f40(write 함수의 주소)를 사용하였습니다.



위에서 언급 한 대로, 0x0a가 마지막에 추가 된 것을 확인 할 수 있습니다.

이제 마지막에 0x00을 추가 한 buffer의 상태를 보겠습니다.



정상적으로 0x00713f62가 overwrite 된 것을 확인 할 수 있습니다.

그럼 이제 remote 환경에서 do_system+1124 부분을 return address로 하여 exploit 하면 쉘을 획득 할 수 있습니다.



+ Recent posts