Stack Overflow

Reading time: 5 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Що таке переповнення стеку

Переповнення стеку - це вразливість, яка виникає, коли програма записує більше даних у стек, ніж йому виділено. Ці надмірні дані перезаписують сусідній простір пам'яті, що призводить до пошкодження дійсних даних, порушення контролю потоку виконання та потенційного виконання шкідливого коду. Ця проблема часто виникає через використання небезпечних функцій, які не виконують перевірку меж на вхідних даних.

Основна проблема цього перезапису полягає в тому, що збережений вказівник інструкцій (EIP/RIP) та збережений базовий вказівник (EBP/RBP) для повернення до попередньої функції зберігаються в стеці. Тому зловмисник зможе перезаписати їх і контролювати потік виконання програми.

Вразливість зазвичай виникає, оскільки функція копіює в стек більше байтів, ніж виділено для неї, тим самим здатна перезаписати інші частини стеку.

Деякі загальні функції, вразливі до цього, це: strcpy, strcat, sprintf, gets... Також функції, такі як fgets, read та memcpy, які приймають аргумент довжини, можуть бути використані в уразливий спосіб, якщо вказана довжина перевищує виділену.

Наприклад, наступні функції можуть бути вразливими:

c
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}

Знаходження зсувів Stack Overflow

Найпоширеніший спосіб знайти зсуви стеку - це ввести дуже великий вхід з As (наприклад, python3 -c 'print("A"*1000)') і очікувати Segmentation Fault, що вказує на те, що адресу 0x41414141 намагалися отримати доступ.

Більше того, як тільки ви виявите, що існує вразливість Stack Overflow, вам потрібно буде знайти зсув, поки не стане можливим перезаписати адресу повернення, для цього зазвичай використовується послідовність Де Брюйна. Яка для даного алфавіту розміру k і підпослідовностей довжини n є циклічною послідовністю, в якій кожна можлива підпослідовність довжини _n_** з'являється точно один раз** як безперервна підпослідовність.

Таким чином, замість того, щоб вручну з'ясовувати, який зсув потрібен для контролю EIP, можна використовувати в якості заповнювача одну з цих послідовностей, а потім знайти зсув байтів, які закінчилися перезаписом.

Можна використовувати pwntools для цього:

python
from pwn import *

# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)

# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value)  # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")

або GEF:

bash
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp

Використання переповнень стеку

Під час переповнення (якщо розмір переповнення достатньо великий) ви зможете перезаписати значення локальних змінних всередині стеку, поки не досягнете збереженого EBP/RBP та EIP/RIP (або навіть більше).
Найпоширеніший спосіб зловживання цим типом вразливості - це модифікація адреси повернення, щоб, коли функція закінчується, управлінський потік перенаправлявся туди, куди вказав користувач в цьому вказівнику.

Однак в інших сценаріях просто перезапис деяких значень змінних у стеку може бути достатньо для експлуатації (як у простих CTF викликах).

Ret2win

У цьому типі CTF викликів є функція, всередині бінарного файлу, яка ніколи не викликається і яку вам потрібно викликати, щоб виграти. Для цих викликів вам просто потрібно знайти зсув для перезапису адреси повернення та знайти адресу функції, яку потрібно викликати (зазвичай ASLR буде вимкнено), щоб, коли вразлива функція повертається, прихована функція буде викликана:

Ret2win

Stack Shellcode

У цьому сценарії зловмисник може помістити shellcode у стек і зловживати контрольованим EIP/RIP, щоб стрибнути до shellcode і виконати довільний код:

Stack Shellcode

ROP & Ret2... техніки

Ця техніка є основною основою для обходу основного захисту попередньої техніки: Не виконавчий стек (NX). І вона дозволяє виконувати кілька інших технік (ret2lib, ret2syscall...), які закінчуються виконанням довільних команд, зловживаючи існуючими інструкціями в бінарному файлі:

ROP - Return Oriented Programing

Переповнення купи

Переповнення не завжди буде в стеку, воно також може бути в купі, наприклад:

Heap Overflow

Типи захисту

Існує кілька захистів, які намагаються запобігти експлуатації вразливостей, перевірте їх у:

Common Binary Exploitation Protections & Bypasses

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks