Ret2lib
기본 정보
Ret2Libc의 본질은 취약한 프로그램의 실행 흐름을 공격자가 제공한 셸코드를 스택에 실행하는 대신 공유 라이브러리(예: system, execve, strcpy) 내의 함수로 리다이렉트하는 것입니다. 공격자는 페이로드를 작성하여 스택의 반환 주소를 원하는 라이브러리 함수를 가리키도록 수정하고, 호출 규약에 따라 필요한 인수가 올바르게 설정되도록도 조치합니다.
예시 단계 (간소화)
호출할 함수의 주소(예: system) 및 호출할 명령(예: /bin/sh)을 가져옵니다.
첫 번째 인수를 가리키는 ROP 체인을 생성하여 명령 문자열을 가리키고 함수로 실행 흐름을 전달합니다.
주소 찾기
현재 시스템에서 사용되는
libc
를 가정하면 메모리에 로드될 위치를 다음과 같이 찾을 수 있습니다:
ASLR가 libc 주소를 변경하는지 확인하려면 다음을 수행할 수 있습니다:
사용된 libc를 알면
system
함수의 오프셋을 찾을 수도 있습니다:
사용된 libc를 알면
/bin/sh
문자열 함수의 오프셋을 찾을 수도 있습니다:
gdb-peda / GEF를 사용하는 방법
사용 중인 libc를 알고 있다면 Peda 또는 GEF를 사용하여 system 함수, exit 함수 및 문자열 **/bin/sh
**의 주소를 얻을 수도 있습니다:
/proc/<PID>/maps 사용
프로세스가 매번 대화할 때마다 자식 프로세스를 생성하는 경우 (네트워크 서버), 해당 파일을 읽어보려고 시도해보세요 (아마도 루트 권한이 필요할 것입니다).
여기서 프로세스 내부에 libc가 정확히 로드된 위치와 프로세스의 각 자식이 로드될 위치를 찾을 수 있습니다.
이 경우 0xb75dc000에 로드됩니다 (이것이 libc의 기본 주소가 될 것입니다)
알 수 없는 libc
바이너리가 로드하는 libc를 알 수 없을 수도 있습니다 (접근할 수 없는 서버에 위치할 수 있기 때문에). 이 경우 취약점을 악용하여 일부 주소를 노출시키고 어떤 libc 라이브러리가 사용 중인지 찾을 수 있습니다:
pageLeaking libc address with ROP또한 이에 대한 pwntools 템플릿을 다음에서 찾을 수 있습니다:
pageLeaking libc - template2개의 오프셋을 사용하여 libc 알아내기
페이지 https://libc.blukat.me/를 확인하고 libc 내의 함수 주소 중 두 개의 주소를 사용하여 사용된 버전을 확인하세요.
32비트에서 ASLR 우회
이 무차별 대입 공격은 32비트 시스템에만 유용합니다.
공격이 로컬인 경우, libc의 기본 주소를 무차별 대입할 수 있습니다 (32비트 시스템에 유용):
원격 서버를 공격할 때,
libc
함수usleep
의 주소를 브루트 포스하여 10을 인자로 전달할 수 있습니다. 예를 들어, 서버가 응답하는 데 10초 더 걸린다면, 이 함수의 주소를 찾은 것입니다.
원 가젯
libc
에서 특정 주소로 점프하여 셸을 실행합니다:
x86 Ret2lib 코드 예시
이 예시에서 ASLR 브루트 포스가 코드에 통합되어 있으며 취약한 이진 파일이 원격 서버에 위치해 있습니다:
x64 Ret2lib 코드 예제
다음 예제를 확인하십시오:
pageROP - Return Oriented ProgramingARM64 Ret2lib 예제
ARM64의 경우, ret 명령은 x30 레지스터가 가리키는 곳으로 점프하며 스택 레지스터가 가리키는 곳으로는 점프하지 않습니다. 따라서 조금 더 복잡합니다.
또한 ARM64에서는 명령이 하는 대로 동작하며(명령의 중간으로 점프하여 새로운 명령으로 변환하는 것은 불가능합니다).
다음 예제를 확인하십시오:
pageRet2lib + Printf leak - arm64printf로 Ret하기 (또는 puts)
이를 통해 printf
/puts
를 호출하여 특정 데이터를 인수로 전달함으로써 프로세스에서 정보를 누출할 수 있습니다. 예를 들어 puts
의 주소를 GOT에 넣고 puts
를 실행하면 메모리에서 puts
의 주소를 누출할 수 있습니다.
Ret2printf
이는 기본적으로 printf
형식 문자열 취약점으로 변환하기 위해 Ret2lib를 남용하는 것을 의미하며, ret2lib
를 사용하여 해당 값을 이용하여 printf를 호출하는 것입니다 (의미 없어 보이지만 가능합니다):
기타 예제 및 참고 자료
Ret2lib, libc의 함수 주소 누출을 통해 one gadget 사용
64비트, ASLR 활성화되어 있지만 PIE 비활성화, 첫 번째 단계는 canary의 바이트 0x00까지 오버플로우를 채운 다음 puts를 호출하여 누출합니다. Canary로부터 ROP 가젯을 생성하여 GOT에서 puts의 주소를 누출하고
system('/bin/sh')
를 호출하는 ROP 가젯을 호출합니다.64비트, ASLR 활성화, canary 없음, 메인 함수에서 자식 함수로의 스택 오버플로우. puts를 호출하여 puts의 주소를 GOT에서 누출한 다음 one gadget을 호출합니다.
64비트, PIE 없음, canary 없음, relro 없음, nx. write 함수를 사용하여 write (libc)의 주소를 누출하고 one gadget을 호출합니다.
스택에서 canary를 누출하기 위해 형식 문자열을 사용하고 버퍼 오버플로우를 사용하여 system을 호출하여
/bin/sh
의 주소로 이동합니다(GOT에 있음).32비트, relro 없음, canary 없음, nx, pie. libc 및 힙의 주소를 스택에서 누출하기 위해 잘못된 인덱싱을 남용합니다. 버퍼 오버플로우를 남용하여
system('/bin/sh')
를 호출하는 ret2lib를 수행합니다(힙 주소가 필요하여 체크를 우회합니다).
Last updated