ipwn

[LOB(Lord Of Buffer overflow)] skeleton -> golem 본문

Write up/LOB

[LOB(Lord Of Buffer overflow)] skeleton -> golem

ipwn 2018. 1. 18. 13:33

이번 단계는 skeleton 단계이다.


바로 접속후 파일들을 보겠다.



golem 파일과 golem.c 코드가 있다.


바로 코드를 읽어보도록 하겠다.



코드를 살펴보니, stack 영역의 공간이 ret 부분말고 전부 초기화 되는 것을 확인할 수 있다.


그럼 어떻게 해결해야할까?


사실 나도 이 부분은 처음 풀 때 다른 블로그들을 많이 참조했다.


바로 공유 라이브러리(LD_PRELOAD)를 사용해야 한다.


공유 라이브러리란 우리가 지정한 사용자 함수를 라이브러리에 올려 라이브러리 함수처럼 사용하는 것이다.


우리가 사용하는 라이브러리 libc.so와 같은 라이브러리들은 효율적으로 함수를 사용하기 위해 메모리상에 적재된다.


그런데 이러한 라이브러리들이 할당받는 공간은 



이 사진과 같이 이뤄져있다. (저 사진의 data공간엔 물론 bss가 포함돼있다.)


이 말은 즉 전부 삭제당해버리는 buffer의 상위공간이 아닌 하위의 공간을 사용한다는 말이다.


그렇다면 공유라이브러리를 nopsled + shellcode가 포함된 이름으로 생성시켜놓고 ret을 그 부분의 주소로 덮어준다면


shell을 획득할 수 있을 것이다. 가장 먼저 공유 라이브러리를 등록해보자.



일단 gcc로 compile해주기 위해 touch 명령어로 tmp.c 파일을 생성해준다.


그리고 -fPIC -shared 옵션을 추가해서 nop(\x90)*100 + shellcode의 이름으로 compile 해준다.


여기서 -fPIC 옵션은 동적 라이브러리로 사용하도록 compile하는 옵션이고,  -shared옵션은 공유라이브러리로 만들어주는 


옵션이다. 이렇게 compile해준 뒤 export LD_PRELOAD=file name(절대경로)의 형식으로 


LD_PRELOAD 환경변수에 등록해준다. 이제 공유 라이브러리에 확실히 등록됐다. 



밑줄 친 부분을 보게되면 제대로 등록 된 것을 확인할 수 있다.


이제 한 번 golem의 copy file을 생성해보자.



copy file을 만들었다. 이제 조건에 맞게 값을 넘겨줘보자.


dummy*44 + \xbf*4의 값을 넘겨주겠다.



성공적으로 core dump가 가져와졌다.


이제 gdb로 core dump의 메모리를 읽어보겠다.



이번에는 예전과 다르게 낮은 주소를 확인한다. 


nop으로 이어진 문장이 보이고 shellcode가 보인다.


확실히 이전에는 높은 주소를 찾았지만 그 부분은 전부 0으로 memset됐을테니 볼 필요가 없을 것이다.


아무튼 이제 우리가 넘겨줄 payload가 완성됐다.


우리가 넘겨줄 payload는 dummy*44 + 0xbffff5c0(임의의 nop의 주소)가 될 것이다.


한 번 copy file에 payload를 넘겨주고 제대로 shell이 가져와지는지 확인해보자.



성공적으로 shell을 가져왔다.


이제 원본 file에 payload를 넣어주고 권한이 상승된 shell을 가져오겠다.



성공적으로 shell을 가져왔다.


golem으로 가는 password는 cup of coffee이다.


아마 이 부분에서 막히는 사람이 굉장히 많을거라고 생각이 된다.



Comments