Stack Pivoting - EBP2Ret - EBP chaining
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ця техніка використовує можливість маніпулювати Base Pointer (EBP) для з'єднання виконання кількох функцій через обережне використання регістра EBP та інструкційної послідовності leave; ret
.
Нагадаємо, що leave
в основному означає:
And as the EBP is in the stack before the EIP it's possible to control it controlling the stack.
Ця техніка особливо корисна, коли ви можете змінити регістр EBP, але не маєте прямого способу змінити регістр EIP. Вона використовує поведінку функцій, коли вони закінчують виконання.
Якщо під час виконання fvuln
вам вдасться впровадити підроблений EBP у стек, який вказує на область пам'яті, де знаходиться адреса вашого shellcode (плюс 4 байти для врахування операції pop
), ви можете непрямо контролювати EIP. Коли fvuln
повертається, ESP встановлюється на це створене місце, а наступна операція pop
зменшує ESP на 4, ефективно вказуючи на адресу, збережену атакуючим там.
Зверніть увагу, що вам потрібно знати 2 адреси: ту, куди ESP буде йти, де вам потрібно буде записати адресу, на яку вказує ESP.
Спочатку вам потрібно знати адресу, куди ви можете записати довільні дані / адреси. ESP буде вказувати сюди і виконає перший ret
.
Потім вам потрібно знати адресу, яку використовує ret
, яка виконає довільний код. Ви можете використовувати:
Дійсну ONE_GADGET адресу.
Адресу system()
, за якою йдуть 4 байти сміття та адреса "/bin/sh"
(x86 bits).
Адресу гаджета jump esp;
(ret2esp), за якою йде shellcode для виконання.
Деяку ROP ланцюг
Пам'ятайте, що перед будь-якою з цих адрес у контрольованій частині пам'яті повинно бути 4
байти через pop
частину інструкції leave
. Було б можливим зловживати цими 4B, щоб встановити другий підроблений EBP і продовжити контролювати виконання.
Існує специфічний варіант цієї техніки, відомий як "Off-By-One Exploit". Він використовується, коли ви можете змінити лише найменш значущий байт EBP. У такому випадку, місце в пам'яті, що зберігає адресу для переходу з ret
, повинно ділити перші три байти з EBP, що дозволяє подібну маніпуляцію з більш обмеженими умовами.
Зазвичай змінюється байт 0x00, щоб стрибнути якомога далі.
Також поширено використовувати RET sled у стеці та поміщати реальний ROP ланцюг в кінець, щоб підвищити ймовірність того, що новий ESP вказує всередину RET SLED, і фінальний ROP ланцюг виконується.
Отже, поміщаючи контрольовану адресу в запис EBP
стека та адресу leave; ret
в EIP
, можна перемістити ESP
на контрольовану адресу EBP
зі стека.
Тепер ESP
контролюється, вказуючи на бажану адресу, а наступна інструкція для виконання - RET
. Щоб зловживати цим, можна помістити в контрольоване місце ESP наступне:
&(next fake EBP)
-> Завантажити новий EBP через pop ebp
з інструкції leave
system()
-> Викликаний через ret
&(leave;ret)
-> Викликаний після завершення системи, він перемістить ESP на підроблений EBP і почне знову
&("/bin/sh")
-> Параметр для system
В основному, таким чином можна з'єднати кілька підроблених EBP для контролю потоку програми.
Це схоже на ret2lib, але складніше без очевидної вигоди, але може бути цікавим у деяких крайніх випадках.
Більше того, тут у вас є приклад завдання, яке використовує цю техніку з витоком стека для виклику виграшної функції. Це фінальний payload зі сторінки:
Як пояснено в цьому пості, якщо бінарний файл скомпільовано з деякими оптимізаціями, EBP ніколи не контролює ESP, отже, будь-який експлойт, що працює шляхом контролю EBP, в основному зазнає невдачі, оскільки не має жодного реального ефекту. Це пов'язано з тим, що пролог і епілог змінюються, якщо бінарний файл оптимізовано.
Не оптимізовано:
Оптимізовано:
pop rsp
гаджетНа цій сторінці ви можете знайти приклад використання цієї техніки. Для цього завдання потрібно було викликати функцію з 2 специфічними аргументами, і був pop rsp
гаджет та є leak з стеку:
Перевірте техніку ret2esp тут:
64 біти, експлуатація off by one з ланцюгом rop, що починається з ret sled
64 біти, без relro, canary, nx та pie. Програма надає leak для стеку або pie та WWW для qword. Спочатку отримайте leak стеку та використайте WWW, щоб повернутися і отримати leak pie. Потім використайте WWW, щоб створити вічний цикл, зловживаючи записами .fini_array
+ викликом __libc_csu_fini
(більше інформації тут). Зловживаючи цим "вічним" записом, записується ланцюг ROP у .bss і в кінці викликається, підіймаючись з RBP.
В ARM64, пролог та епілоги функцій не зберігають і не відновлюють реєстр SP у стеку. Більше того, інструкція RET
не повертає за адресою, на яку вказує SP, а за адресою всередині x30
.
Отже, за замовчуванням, просто зловживаючи епілогом, ви не зможете контролювати реєстр SP, переписуючи деякі дані всередині стеку. І навіть якщо вам вдасться контролювати SP, вам все ще знадобиться спосіб контролювати реєстр x30
.
пролог
епілог
Спосіб виконати щось подібне до stack pivoting в ARM64 полягатиме в тому, щоб мати можливість контролювати SP
(контролюючи якийсь реєстр, значення якого передається до SP
, або через те, що з якоїсь причини SP
бере свою адресу зі стеку, і у нас є переповнення) і потім зловживати епілогом, щоб завантажити реєстр x30
з контрольованого SP
і RET
до нього.
Також на наступній сторінці ви можете побачити еквівалент Ret2esp в ARM64:
Вчіться та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)