Return Oriented Programming
리턴가젯 찾는법
ROPgadget --binary ./rtl --re "pop rdi"
이건 워게임 문제는 아니고 드림핵 시스템 해킹 로드맵에 나오는 문제이다.
하지만 로드맵만 슬적 보고 풀어지는 문제가 아니다.
로드맵 설명에서는
리턴가젯을 이용해 libc.so.6의 read가 매핑된 주소를 puts를 한 후에
read로 read_got의 내용을 system의 오프셋으로 덮어씌우면
system("/bin/sh")를 할 수 있다는 내용이다. 그리고 예제에서는 read할때의 rdx는 충분한 값이니, 고려하지 않는다고 했다.
하지만 ida로 디버깅 해본 결과 puts를 하면 rdx가 0이 된다. read로 한바이트도 읽어들이지 않아서 문제였다.
rdx를 설정하는 방법은 libc의 코드 가젯이나, __libc_csu_init가젯.
또는 rdx의 값을 변화시키는 함수의 호출이다. ex)strncmp 등
나는 __libc_csu_init가젯을 이용해 rdx를 설정했다.
https://py0zz1.tistory.com/m/107
Return-to-Csu 기법 정리
포너블 문제를 풀 때, 64Bit 바이너리가 까다로운 이유가 바로 'Gadget' 때문이다. 64Bit의 Calling Convention은 Fastcall로 호출된 함수에 인자를 레지스터로 전달한다. 이 때문에 Exploit을 구성할 때도 [POP R.
py0zz1.tistory.com
해당 블로그를 보고 따라해봤다.
그랬더니 로컬에서 exploit에 성공!
하지만 원격에서는 exploit에 실패했다.
이유는 libc의 버전이 다른것.
인터넷에서 libc-2.27.so를 다운받아서 열어봤지만 실패했다.
결국 한 방법은 https://libc.nullbyte.cat/
사이트에서 read의 주소를 검색한것이다.
libc base가 0x*************000 형태라서 하위 3byte는 항상 일정하다고 한다.
__read, 140을 검색하면 오른쪽 matches에 매치되는 libc들이 나온다. 그것들 중 하나를 클릭하면 read write system등 다양한 함수의 offset을 알 수 있다.
이 offset값을 직접 넣어서 실행하니 원격 exploit을 성공했다.
exploit은 성공했지만 궁금한게 하나 생겼다.
__libc_csu_init()가젯을 이용할 때마다 rbp를 1로 설정하면 무한 함수 호출이 가능한데, 뭔가 오류가 있다.
__libc_csu_init()가젯을 3번 이상 이용할 때부터 read_got의 값이 변경되는건지 뭔지 생각한대로 작동이 안된다.
ida디버깅으로 직접 스택에 값을 넣어주면 잘만 되는데말이다...
나중에 더 알아봐야겠다.