DDexec / EverythingExec
Контекст
У Linux для запуску програми вона повинна існувати як файл, вона повинна бути доступна якимось чином через ієрархію файлової системи (це просто як працює execve()
). Цей файл може знаходитися на диску або в оперативній пам'яті (tmpfs, memfd), але вам потрібен шлях до нього. Це дуже спрощує контроль за тим, що запускається в системі Linux, дозволяє виявляти загрози та інструменти зловмисників або запобігати їм спробувати виконати що-небудь своє (наприклад, не дозволяючи непривілейованим користувачам розміщувати виконувані файли де завгодно).
Але ця техніка призначена змінити все це. Якщо ви не можете запустити процес, який вам потрібен... тоді ви захоплюєте один вже існуючий.
Ця техніка дозволяє вам обійти загальні техніки захисту, такі як тільки для читання, noexec, білістинг імен файлів, білістинг хешів...
Залежності
Остаточний скрипт залежить від наступних інструментів для роботи, вони повинні бути доступні в системі, яку ви атакуєте (зазвичай ви знайдете їх скрізь):
Техніка
Якщо ви можете довільно змінювати пам'ять процесу, то можете захопити його. Це можна використовувати для захоплення вже існуючого процесу та заміни його іншою програмою. Це можна досягти, використовуючи виклик системного виклику ptrace()
(що вимагає можливості виконання системних викликів або наявності gdb в системі) або, що цікавіше, записуючи в /proc/$pid/mem
.
Файл /proc/$pid/mem
є однозначним відображенням всього адресного простору процесу (наприклад, від 0x0000000000000000
до 0x7ffffffffffff000
в x86-64). Це означає, що читання або запис у цей файл за зсувом x
те саме, що читання або зміна вмісту за віртуальною адресою x
.
Тепер ми маємо чотири основні проблеми:
Загалом, тільки root та власник програми файлу можуть змінювати його.
ASLR.
Якщо ми спробуємо прочитати або записати адресу, яка не відображена в адресному просторі програми, ми отримаємо помилку вводу-виводу.
Ці проблеми мають рішення, які, хоча вони не є ідеальними, є досить ефективними:
Більшість оболонкових інтерпретаторів дозволяють створювати файлові дескриптори, які потім будуть успадковані дочірніми процесами. Ми можемо створити fd, що вказує на файл
mem
оболонки з правами запису... тому дочірні процеси, які використовують цей fd, зможуть змінювати пам'ять оболонки.ASLR навіть не проблема, ми можемо перевірити файл
maps
оболонки або будь-який інший з procfs, щоб отримати інформацію про адресний простір процесу.Тому нам потрібно використовувати
lseek()
у файлі. З оболонки це не можна зробити, якщо не використовувати погано відомийdd
.
Детальніше
Кроки досить прості і не потребують жодних спеціальних знань для їх розуміння:
Розібрати бінарний файл, який ми хочемо запустити, та завантажувач, щоб дізнатися, які відображення їм потрібні. Потім створити "shell"код, який буде виконувати, загалом кажучи, ті самі кроки, які робить ядро при кожному виклику
execve()
:Створити вказані відображення.
Прочитати бінарні файли в них.
Налаштувати дозволи.
Нарешті ініціалізувати стек з аргументами для програми та розмістити допоміжний вектор (необхідний завантажувачем).
Перейти до завантажувача та дозволити йому зробити все інше (завантажити бібліотеки, необхідні для програми).
Отримати з файлу
syscall
адресу, на яку процес повернеться після виклику системного виклику, який він виконує.Перезаписати це місце, яке буде виконуваним, нашим "shell"кодом (через
mem
ми можемо змінювати незаписувані сторінки).Передати програму, яку ми хочемо запустити, в stdin процесу (її буде
read()
цим "shell"кодом).На цьому етапі все залежить від завантажувача, який завантажить необхідні бібліотеки для нашої програми та перейде до неї.
Перевірте інструмент на https://github.com/arget13/DDexec
EverythingExec
Є кілька альтернатив для dd
, одна з яких, tail
, наразі є програмою за замовчуванням для lseek()
через файл mem
(що було єдиним метою використання dd
). Зазначені альтернативи:
Встановивши змінну SEEKER
, ви можете змінити використаний пошуковик, наприклад:
Якщо ви знайдете інший дійсний пошуковик, який не реалізований у скрипті, ви все ще можете використовувати його, встановивши змінну SEEKER_ARGS
:
Заблокуйте це, EDRs.
Посилання
Last updated