ROP(Return-Oriented Programming)은 시스템 해킹 기법 중 하나로, 실행 흐름을 조작하여 보안 취약점을 이용하는 공격 방법입니다.
일반적으로 실행 스택의 취약점을 이용하여 악의적인 코드를 주입하는 것으로, NX Bit, ASLR 메모리 보호기법과 같은 보안 기술이 적용된 시스템에서 보호기법을 우회하기 위해 사용하는 공격 기법입니다.
ROP 기법을 사용하기 위해서는 PLT, GOT, RTL, Gadget 등의 지식이 필요합니다.
필요한 지식에 대해 간단하게 알아봅시다.
GOT (Global Offset Table)
GOT는 프로그램의 전역 변수와 라이브러리 함수의 주소를 저장하는 테이블입니다. 프로그램이 실행될 때 라이브러리 함수의 주소를 GOT에 저장하고, 이후 해당 함수를 호출할 때 GOT에서 주소를 참조합니다. GOT를 조작하면 원래 의도와는 다른 함수 호출이 가능합니다.
PLT (Procedure Linkage Table)
PLT는 라이브러리 함수 호출을 위한 테이블입니다. 프로그램은 라이브러리 함수를 호출할 때 PLT를 통해 해당 함수의 실제 주소를 GOT에 저장하고, 이후 함수 호출은 GOT에 저장된 주소를 사용합니다. GOT와 마찬가지로 PLT를 조작하여 원래 함수 호출의 흐름을 변경할 수 있습니다.
RTL (Return to Library)
RTL은 리턴 주소를 라이브러리 내에 존재하는 함수의 주소로 바꿔 NX bit를 우회하는 공격기법입니다.
Gadget
Gadget은 프로그램 내에서 이미 존재하는 작은 코드 조각으로, ROP 공격에서 사용됩니다. 주로 'ret' (리턴) 명령이 포함되어 있어 실행 흐름을 변경하는 역할을 합니다. 공격자는 가젯들을 조합하여 악성 코드를 실행할 ROP 체인을 생성하는 데 활용합니다.
바로 관련된 문제를 보겠습니다.
buf의 크기가 0x10인데, read 함수에서 0x100만큼 읽고 있으므로 BOF를 발생시킬 수 있습니다.
이를 이용하여 buf와 sfp를 덮고 write 함수를 leak 한 뒤, 라이브러리의 주소를 알아낼 수 있습니다.
이때, leak 된 주소는 "0x7fXXXXXXXXXX"의 형태입니다. 64비트 바이너리의 libc주소는 보통 0x7f부터 시작되기 때문입니다. 그리고 총 6바이트로 나머지는 0x00(NULL)로 채워집니다.
이렇게 leak 된 라이브러리 주소로 libc_base를 구하여 system 함수의 주소와 "/bin/sh" 문자열의 주소까지도 알아낼 수 있습니다.
그렇다면 system 함수로 /bin/sh 을 실행하여 쉘을 따낼 수 있게 됩니다.
문제 설명은 여기까지 하고 설명한걸 토대로 익스플로잇 코드를 짜보았습니다.