passcode : one step closer
(NO DRAG, NO PASSCODE)
bash2. 소스코드를 분석하여 보자.
이 문제에서는 argv[1][47] == '\x40' 인 것으로 보아 0x40xxxxxx 영역을 사용하는 외부 라이브러리 함수의 주소를 RET에 덮는 방식은 사용할 수 없을 것 같다. 또한 argv[1][47] == '\xbf’ 로 보아 shellcode 를 export 하여 그의 주소를 ret에 덮을 수도 없을 것 같다. 그렇다면 RET은 환경변수의 주소도 아니고 라이브러리 함수의 주소도 아니다. 이때 사용하는 것이 RET Sled이다.
또한 함수의 epilogue 는 leave + ret 명령어로 이루어져 있다. 여기서 ret 명령어는 pop eip, jmp eip로 이루어져 있는데, 이 ret 명령어를 두 번 연속으로 실행되게 하고 RET + 4 위치에 &(system) + dummy + &(“/bin/sh”) 가 있다면 두 번의 ret 후에는 eip가 &(system)이 존재하는 주소를 가리키게 되어 jmp eip를 통하여 system 함수가 실행되게 한다. 아래 그림을 통하여 다시 이해하여 보자.
일단 main 함수에서 strcpy 함수가 실행되어 RET 값이 ret 명령어의 주소로 이미 변조되어있는 상황이다.
먼저 leave(pop ebp) 명령어를 통하여 ebp가 날라가게 된다.
이제 첫번째 ret이 실행된다. ret(pop eip) 명령어를 통하여 eip는 esp가 가리키고 있던 RET을 가리키게 되고 esp 는 RET + 4에 위치하게 된다.
leave (jmp eip) 명령어를 통하여 ret 명령어가 다시금 실행되게 한다.
이제 두번째 ret 명령어가 실행된다. ret (pop eip) 명령어를 통하여 eip는 &(system)이 존재하는 위치에, esp 는 &(system) + 4에 위치하게 된다.
마지막으로 ret (jmp eip) 명령어를 통하여 eip가 가리키는 system 함수의 주소로 이동하여 “/bin/sh”를 인자로 system 함수가 실행되게 된다.
따라서 payload는 다음과 같다.
“\x90”*44 + &(ret) + &(system) + dummy(4) + &(“/bin/sh”)
필요한 주소들을 구하자.
system 주소 -> 0x40058ae0
“/bin/sh” 주소 -> 0x400fbff9
ret 주소 -> 0x804851e
이제 payload를 구성하고 exploit 하여 보자.
[assassin] : pushing me away
'Pwnable > LOB' 카테고리의 다른 글
[LOB] 16. ZOMBIE_ASSASSIN (0) | 2020.08.28 |
---|---|
[LOB] 15. ASSASSIN (0) | 2020.08.28 |
[LOB] 13. BUGBEAR (0) | 2020.08.28 |
[LOB] 12. DARKKNIGHT (0) | 2020.08.28 |
[LOB] 11. GOLEM (0) | 2020.08.28 |