mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
기본 바이너리 익스플로잇 방법론
{{#include ../../banners/hacktricks-training.md}}
ELF 기본 정보
무언가를 익스플로잇하기 전에 ELF 바이너리의 구조 일부를 이해하는 것이 흥미롭습니다:
{{#ref}} elf-tricks.md {{#endref}}
익스플로잇 도구
{{#ref}} tools/ {{#endref}}
스택 오버플로우 방법론
많은 기술이 있기 때문에 각 기술이 유용할 때의 스킴을 갖는 것이 좋습니다. 동일한 보호가 서로 다른 기술에 영향을 미친다는 점에 유의하십시오. 각 보호 섹션에서 보호를 우회하는 방법을 찾을 수 있지만 이 방법론에서는 찾을 수 없습니다.
흐름 제어
프로그램의 흐름을 제어하는 방법은 여러 가지가 있습니다:
- 스택 오버플로우: 스택에서 반환 포인터 또는 EBP -> ESP -> EIP를 덮어쓰기.
- 오버플로우를 유발하기 위해 정수 오버플로우를 악용해야 할 수도 있습니다.
- 또는 임의 쓰기 + 실행을 위한 쓰기 위치 지정을 통해.
- 포맷 문자열:
printf를 악용하여 임의의 내용을 임의의 주소에 쓰기. - 배열 인덱싱: 잘못 설계된 인덱싱을 악용하여 일부 배열을 제어하고 임의의 쓰기를 얻기.
- 오버플로우를 유발하기 위해 정수 오버플로우를 악용해야 할 수도 있습니다.
- bof to WWW via ROP: 버퍼 오버플로우를 악용하여 ROP를 구성하고 WWW를 얻을 수 있습니다.
Write What Where to Execution 기술은 다음에서 찾을 수 있습니다:
{{#ref}} ../arbitrary-write-2-exec/ {{#endref}}
영원한 루프
고려해야 할 점은 일반적으로 취약점을 한 번 익스플로잇하는 것만으로는 충분하지 않을 수 있습니다. 특히 일부 보호를 우회해야 할 수 있습니다. 따라서 단일 취약점을 동일한 바이너리 실행에서 여러 번 익스플로잇할 수 있는 옵션에 대해 논의하는 것이 흥미롭습니다:
main함수의 주소 또는 취약점이 발생하는 주소를 ROP 체인에 작성.- 적절한 ROP 체인을 제어하면 해당 체인에서 모든 작업을 수행할 수 있습니다.
exitGOT의 주소에 (종료 전에 바이너리가 사용하는 다른 함수의 주소) 취약점으로 돌아가는 주소를 작성.- .fini_array에서 설명한 대로, 여기에서 두 개의 함수를 저장하여 하나는 취약점을 다시 호출하고 다른 하나는 **
__libc_csu_fini**를 호출하여 **.fini_array**의 함수를 다시 호출합니다.
익스플로잇 목표
목표: 기존 함수 호출
- ret2win: 플래그를 얻기 위해 호출해야 하는 코드에 함수가 있습니다(특정 매개변수와 함께 호출할 수 있습니다).
- PIE가 없는 정상적인 bof에서는 스택에 저장된 반환 주소에 주소를 작성하기만 하면 됩니다.
- PIE가 있는 bof에서는 이를 우회해야 합니다.
- canary가 있는 bof에서는 이를 우회해야 합니다.
- ret2win 함수를 올바르게 호출하기 위해 여러 매개변수를 설정해야 하는 경우:
- 모든 매개변수를 준비할 수 있는 충분한 가젯이 있는 경우 ROP 체인을 사용할 수 있습니다.
- SROP (이 시스템 호출을 호출할 수 있는 경우)로 많은 레지스터를 제어합니다.
- 여러 레지스터를 제어하기 위해 ret2csu 및 ret2vdso에서 가젯을 사용합니다.
- 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 가젯을 사용하기 위해 이를 무력화해야 합니다.
- SROP은 ret2execve를 준비하는 데 유용할 수 있습니다.
- 여러 레지스터를 제어하기 위해 ret2csu 및 ret2vdso에서 가젯을 사용합니다.
libc를 통해
- Ret2lib: **
libc**의 함수(예:system)를 호출하는 데 유용하며, 준비된 인수(예:'/bin/sh')가 필요합니다. 호출하려는 함수가 있는 라이브러리를 바이너리가 로드해야 합니다(일반적으로 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'의 주소를 계산합니다. - ASLR와 PIE가 모두 활성화되고 libc를 모르는 경우:
- PIE를 우회해야 합니다.
- 사용된
libc버전을 찾아야 합니다(몇 개의 함수 주소를 유출). - 계속하기 위해 ASLR가 있는 이전 시나리오를 확인합니다.
EBP/RBP를 통해
- 스택 피벗팅 / EBP2Ret / EBP 체이닝: 스택에 저장된 EBP를 통해 RET를 제어하기 위해 ESP를 제어합니다.
- 오프 바이 원 스택 오버플로우에 유용합니다.
- EIP를 제어하는 대체 방법으로 유용하며, EIP를 악용하여 메모리에 페이로드를 구성한 다음 EBP를 통해 점프합니다.
기타
- 포인터 리디렉팅: 스택에 호출될 함수에 대한 포인터나 흥미로운 함수(system 또는 printf)에서 사용될 문자열에 대한 포인터가 포함된 경우 해당 주소를 덮어쓸 수 있습니다.
- ASLR 또는 PIE가 주소에 영향을 미칠 수 있습니다.
- 초기화되지 않은 변수: 당신은 결코 알 수 없습니다.
{{#include ../../banners/hacktricks-training.md}}