기본 바이너리 익스플로잇 방법론

Reading time: 6 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기

ELF 기본 정보

무언가를 익스플로잇하기 전에 ELF 바이너리의 구조 일부를 이해하는 것이 흥미롭습니다:

ELF Basic Information

익스플로잇 도구

Exploiting Tools

스택 오버플로우 방법론

많은 기술이 있기 때문에 각 기술이 유용할 때를 이해하는 것이 좋습니다. 동일한 보호가 서로 다른 기술에 영향을 미친다는 점에 유의하십시오. 각 보호 섹션에서 보호를 우회하는 방법을 찾을 수 있지만 이 방법론에서는 찾을 수 없습니다.

흐름 제어

프로그램의 흐름을 제어하는 방법은 여러 가지가 있습니다:

  • 스택 오버플로우: 스택에서 반환 포인터 또는 EBP -> ESP -> EIP를 덮어쓰기.
  • 오버플로우를 유발하기 위해 정수 오버플로우를 악용해야 할 수도 있습니다.
  • 또는 임의 쓰기 + 실행을 위한 쓰기 위치 지정을 통해.
  • 포맷 문자열: printf를 악용하여 임의의 내용을 임의의 주소에 씁니다.
  • 배열 인덱싱: 잘못 설계된 인덱싱을 악용하여 일부 배열을 제어하고 임의의 쓰기를 얻습니다.
  • 오버플로우를 유발하기 위해 정수 오버플로우를 악용해야 할 수도 있습니다.
  • bof to WWW via ROP: 버퍼 오버플로우를 악용하여 ROP를 구성하고 WWW를 얻을 수 있습니다.

Write What Where to Execution 기술은 다음에서 찾을 수 있습니다:

Write What Where 2 Exec

영원한 루프

고려해야 할 점은 일반적으로 취약점을 한 번 익스플로잇하는 것만으로는 충분하지 않을 수 있습니다. 특히 일부 보호를 우회해야 합니다. 따라서 단일 취약점을 동일한 바이너리 실행에서 여러 번 익스플로잇할 수 있는 옵션에 대해 논의하는 것이 흥미롭습니다:

  • main 함수의 주소 또는 취약점이 발생하는 주소를 ROP 체인에 작성합니다.
  • 적절한 ROP 체인을 제어하면 해당 체인에서 모든 작업을 수행할 수 있습니다.
  • exit GOT의 주소에 (종료 전에 바이너리가 사용하는 다른 함수의 주소) 취약점으로 돌아가는 주소를 작성합니다.
  • .fini_array에서 설명한 대로, 여기에서 두 개의 함수를 저장합니다. 하나는 취약점을 다시 호출하고 다른 하나는 **__libc_csu_fini**를 호출하여 .fini_array의 함수를 다시 호출합니다.

익스플로잇 목표

목표: 기존 함수 호출

  • ret2win: 플래그를 얻기 위해 호출해야 하는 코드에 함수가 있습니다(특정 매개변수와 함께 호출할 수 있습니다).
  • PIE가 없는 정상적인 bof에서는 스택에 저장된 반환 주소에 주소를 작성하기만 하면 됩니다.
  • PIE가 있는 bof에서는 이를 우회해야 합니다.
  • canary가 있는 bof에서는 이를 우회해야 합니다.
  • ret2win 함수를 올바르게 호출하기 위해 여러 매개변수를 설정해야 하는 경우:
  • 모든 매개변수를 준비할 수 있는 충분한 가젯이 있는 ROP 체인 사용
  • SROP (이 시스템 호출을 호출할 수 있는 경우) 많은 레지스터를 제어하기 위해
  • 여러 레지스터를 제어하기 위해 ret2csuret2vdso에서 가젯 사용
  • Write What Where를 통해 다른 취약점(버퍼 오버플로우가 아님)을 악용하여 win 함수를 호출할 수 있습니다.
  • 포인터 리디렉션: 스택에 호출될 함수에 대한 포인터 또는 흥미로운 함수(system 또는 printf)에서 사용될 문자열에 대한 포인터가 포함된 경우 해당 주소를 덮어쓸 수 있습니다.
  • ASLR 또는 PIE가 주소에 영향을 미칠 수 있습니다.
  • 초기화되지 않은 변수: 당신은 결코 알 수 없습니다.

목표: RCE

쉘코드를 통해, nx가 비활성화된 경우 또는 쉘코드와 ROP 혼합:

  • (스택) 쉘코드: 반환 포인터를 덮어쓰기 전후에 스택에 쉘코드를 저장한 다음 점프하여 실행하는 데 유용합니다:
  • 어떤 경우든 canary가 있는 경우, 정상적인 bof에서는 이를 우회(유출)해야 합니다.
  • ASLR가 없고 nx가 없으면 스택의 주소로 점프할 수 있습니다. 주소는 절대 변경되지 않기 때문입니다.
  • ASLR가 있는 경우 ret2esp/ret2reg와 같은 기술을 사용하여 점프해야 합니다.
  • nx가 있는 경우, ROP를 사용하여 memprotect를 호출하고 일부 페이지를 rwx로 만들어야 하며, 그런 다음 거기에 쉘코드를 저장(예: read 호출)하고 점프해야 합니다.
  • 이는 쉘코드를 ROP 체인과 혼합합니다.

시스템 호출을 통해

  • Ret2syscall: 임의의 명령을 실행하기 위해 execve를 호출하는 데 유용합니다. 특정 시스템 호출을 매개변수와 함께 호출할 수 있는 가젯을 찾아야 합니다.
  • ASLR 또는 PIE가 활성화된 경우, 바이너리 또는 라이브러리에서 ROP 가젯을 사용하기 위해 이를 무력화해야 합니다.
  • SROPret2execve를 준비하는 데 유용할 수 있습니다.
  • 여러 레지스터를 제어하기 위해 ret2csuret2vdso에서 가젯 사용

libc를 통해

  • Ret2lib: **libc**의 함수(예: '/bin/sh'와 같은 준비된 인수로 system)를 호출하는 데 유용합니다. 호출하려는 함수가 있는 라이브러리를 바이너리가 로드해야 합니다(일반적으로 libc).
  • 정적으로 컴파일되고 PIE가 없는 경우, system/bin/sh주소는 변경되지 않으므로 정적으로 사용할 수 있습니다.
  • ASLR가 없고 로드된 libc 버전을 알고 있는 경우, system/bin/sh주소는 변경되지 않으므로 정적으로 사용할 수 있습니다.
  • ASLR가 있지만 PIE가 없는 경우, libc를 알고 있고 바이너리가 system 함수를 사용하는 경우 **GOT에서 system의 주소로 ret**하고 /bin/sh의 주소를 매개변수로 사용하여 호출할 수 있습니다(이를 알아내야 합니다).
  • ASLR가 있지만 PIE가 없는 경우, libc를 알고 있고 바이너리가 system을 사용하지 않는 경우:
  • ret2dlresolve를 사용하여 system의 주소를 해결하고 호출합니다.
  • ASLR를 우회하고 메모리에서 system'/bin/sh'의 주소를 계산합니다.
  • ASLRPIE가 모두 활성화되고 libc를 모르는 경우:
  • PIE를 우회해야 합니다.
  • 사용된 libc 버전을 찾아야 합니다(몇 개의 함수 주소를 유출).
  • 계속하기 위해 ASLR가 있는 이전 시나리오를 확인합니다.

EBP/RBP를 통해

  • 스택 피벗 / EBP2Ret / EBP 체이닝: 스택에 저장된 EBP를 통해 RET를 제어하기 위해 ESP를 제어합니다.
  • 오프 바이 원 스택 오버플로우에 유용합니다.
  • EIP를 제어하는 대체 방법으로 유용하며, EIP를 악용하여 메모리에 페이로드를 구성한 다음 EBP를 통해 점프합니다.

기타

  • 포인터 리디렉션: 스택에 호출될 함수에 대한 포인터 또는 흥미로운 함수(system 또는 printf)에서 사용될 문자열에 대한 포인터가 포함된 경우 해당 주소를 덮어쓸 수 있습니다.
  • ASLR 또는 PIE가 주소에 영향을 미칠 수 있습니다.
  • 초기화되지 않은 변수: 당신은 결코 알 수 없습니다.

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기