<문제 소스코드>


FPO를 이용하는 문제이다.

FPO란 무엇일까?

오랜만에 그림 설명을 사용하겠다!




SFP는 이전 스택 프레임의 EBP이 저장되어 있다.그리고 SFP의 바로 다음은 RET 어드레스가 저장되어 있는 것을 우리는 알고 있다.

Stack Frame Pointer인지 Saved Frame Pointer인지, 후자가 더 실제 용도에 가깝다고 생각되지만 때에 따라 두 용어 모두 사용된다.

즉, EBP가 변하면 RET 영역은 EBP+4이므로 함께 변하게 된다.


SFP가 1 byte overwrite가 가능하다.

->EBP를 조작할 수 있다.

->RET 영역을 조작할 수 있다.

->shellcode를 실행할 수 있다.

여기서 RET 영역을 조작할 수 있다는 의미는, 정확히 말하면

이전 문제들에서 RET 영역에 직접 shellcode를 적었던 것과는 반대로

shellcode의 주소를 적어놓고 SFP를 변조해 그 곳으로 RET 영역을 옮기는 것이다.


이전에는 RET 변조 -> SHELL 실행이었다면

이번에는 FPO -> RET 변조 -> SHELL 실행인 것이다.


shellcode의 주소를 적어놓을 곳은 buffer가 될 것이다. 오직 1 바이트만 오버플로우가 발생하기 때문에 다른 곳은 불가능하다.

shellcode는 다양한 영역에 삽입할 수 있다. 버퍼든, 매개인자든, 환경변수든 등등.




problem_child 함수 종료 전, 스택 프레임을 정리하기 전에 bp를 걸자.



프로그램 실행 후

현재 ebp가 0xbffffabc이므로

0xbffffa00부터 메모리를 출력해봤다.

1 바이트만 변조가 가능한 상황에서 우리가 EBP를 움직일 수 있는 공간은 0xbffffa00~0xbfffffff이기 때문이다.

사진을 보면 인자로 전달한 0x41이 메모리에 strncpy를 통해 카피되어 있고, SFP(현재 EBP)도 1 바이트 0x41로 변조된 것이 확인된다.


FPO 설명은 여기서 마치겠다.

개념은 다른 글에서 더 자세히 친절하게 다룰 것이다.


개념 이해 후 쉘코드의 주소를 찾아보자.


<shellcode address>



./darkknight `python -c 'print "\xff\xff\xff\xff"*10+"\xcc"+"\x90"*10000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`


gdb -q -c core


필자는 argv[1]에 쉘코드를 삽입했다. nop을 많이 넣는 걸 좋아하기 때문에..

다른 블로그들의 풀이에서는 아마 쉘코드를 버퍼에 삽입할 것이다.


core 파일의 메모리 덤프는 main 함수에서 seg fault가 발생한 후의 상황이므로, problem_child의 스택 프레임이었던 영역보다 조금 높은 주소에 있을 것이다.

buffer는 problem_child의 스택 프레임 영역에 있으므로

x/64x $esp-256

ESP를 기준으로 problem_child의 스택 프레임을 찾음을 통해 금방 buffer를 찾을 수 있다.


위와 같이 0xff가 버퍼에 잘 들어가있다. 이 buffer 부분은 shellcode의 주소가 삽입될 공간이다.



esp보다 높은 주소로 가보면, argv를 발견할 수 있다.

메모리를 확인할 때 buffer와 argv[1]을 헷갈려서 

SFP에 0x90이 덮어씌워진 것으로 착각할 수도.. 필자가 그랬다.


어쨌든 nop+shellcode의 주소까지 확인했으니 exploit을 시도해보자.


<exploit>



payload는

shellcode의 주소*10(총 40바이트)

FPO 1바이트

NOP
SHELLCODE

가 될 것이다.


Overflow로 인해 FPO Overwrite가 발생하고, problem_child 함수 종료 후 main 함수까지 종료가 된다.

그 과정에서 RET Address로 EIP가 JMP하게 되는데

RET 영역이 Shellcode의 주소가 있는 영역(0xbfffd358)으로 움직이도록 Frame Pointer(0xbfffd354)를 움직였으므로

이 때 shellcode가 실행되게 된다.


심볼릭 링크로 원본 바이너리에 exploit을 시도하여

shell을 따냈다.

darkknight의 패스워드는 new attacker

'Wargame Writeup > LOB(Redhat)' 카테고리의 다른 글

LOB bugbear -> giant  (0) 2015.11.18
LOB darkknight -> bugbear  (0) 2015.11.15
LOB skeletom -> golem  (1) 2015.11.14
LOB vampire -> skeleton  (0) 2015.11.14
LOB troll -> vampire  (0) 2015.11.13

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/