R0pbaby 문제 풀이.
이 문제는 데프콘 2015에서 출제되었던 ROP 문제이다.
64-bit ELF 파일을 제공하고, system 함수를 사용하는 문제.
주요 사항 ===========
1. 64-bit ELF 파일. ====
- system 함수의 인자를 담는 레지스터는 rdi.
- 데이터를 저장하는 기본 단위는 8byte.
2. 실행 환경에 있는 libc.so.6를 가져다 쓴다.
3. Binary 실행 중 system 함수가 있는 곳의 주소를 알려준다.
- Libc 파일 안에서의, system 함수와 다른 gadget간의 offset를 먼저 구한다.
- Binary 실행 중의 system 함수 주소를 기준으로, 구한 offset을 이용하여 다른 gadget
들이 있는 곳의 주소를 알아낸다.
- Binary에 PIE가 걸려있으므로, 실행할 때마다 메모리 주소가 바뀌기 때문이다.
- 특정 함수를 기준으로 offset을 계산해야 한다.
4. Return 주소를 덮을 수 있게 해놓았다.
3번에서 말한 SFP(==RET 주소의 바로 앞에 놓인 Stack Frame Pointer) 위치에 memcpy.’
즉 PIE와 NX 보호기법이 걸려있는 64-BIT ELF 파일.
프로그램을 실행시켜 보았다. 1번에서 libc의 주소 값을 얻을 수 있고, 2번에서 입력한
심볼의 주소값을 얻을 수 있다. 그리고 3번에서는
설정한 크기만큼 값을 입력받게 된다.
코드를 보면 3번을 선택했을 경우 memcpy()를 통해 설정한 크기만큼 데이터를 입력받아 &savedregs에 복사한다.
Savedregs의 주소를 보면, SFP랑 RET가 존재.
값을 8byte이상 입력하면, SFP부터 채우게 되어 overflow가 발생.
한 번 확인해보자.
만약에 크기를 16으로 지정한 후 값을 입력해보면 Segmentation Fault가 뜨는 것을 확인.
즉 결론은 ROP를 이용해서 풀어야 한다. 64bit에서는 첫 번째 인자 값을 버퍼가 아닌 레지스터 RDI에서 가져오게 된다. Cf)레지스터는 RDI, RSI,
RDX,RCX, R8, R9 순으로 파라미터 전달. 즉 RDI에다가 “/bin/sh”를
입력하고, system()함수로 실행시키게 된다. 그러면
쉘이 실행된다. Payload를 입력해보자. 위에서 찾아본 정보를 정리해보자. “A”*8 | & “pop rdi; ret”| &
“/bin/sh” | system() 일단 libc.so 파일을 이용해 system
함수의 offset을 구한다.
그 다음 /bin/sh 주소와 “pop rdi” gadget을 구한다.
RP ++ 를 사용해 gadget를 구한다.
마지막으로 exploit 코드를 작성해 쉘 코드를 구한다.
최종 exploit code는 아래와 같다.
끝.
CF) 일단 낮은 배점이라고 하던데... 좀 생각해 볼 것이 많았던 거 같다.
exploit code 랑 RP++에 대해서는 곧 날잡아서 설명해놓겠다.
'#CTF writeup > defcon' 카테고리의 다른 글
Install Local Problems With NC. (0) | 2018.06.04 |
---|