RCEの検出と確認を行うツールキット。URLまたはキャプチャしたHTTPリクエストに対してコマンドインジェクション、SSTI、ブラインドおよびOOBの経路をテストし、証拠付きの段階的な判定を返します。
confirmed はターゲットが入力を実行したことを意味する。negative はプローブが到達したことを意味する。
バージョン 2.40.0 · MIT · Python 3.8+ · サードパーティ依存ゼロ
RCEKit は、許可されたペネトレーションテスト、レッドチーミング、セキュリティリサーチ向けの RCE 検出・確認ツールキットである。テストを許可されているターゲット — URL またはキャプチャした HTTP リクエスト — を指定すると、すべての検出結果はそれが獲得したティアとともに返ってくる。
すべての confirmed は、RCEKit がそのプローブ用にランダムに生成し、そのリフレクションでは生成し得ない値に基づいている。レスポンスに存在し、ペイロードなしのコントロールには存在しない計算結果か、ターゲットだけが保持したトークンを運ぶアウトオブバンドコールバックのいずれかである。より弱いシグナルはそれぞれのティアに留まり、決してそこへ昇格されることはない。そして、何かをテストできなかった実行が、それをクリーンとして報告することは決してない。
RCEKit は単一の CLI の下で 複数の手法 を通じて RCE を確認する。以下では、本番ソフトウェアにおける 実際の、公開文書化された CVE に対して実行している — 各判定はペイロードなしのコントロールと差分比較されている:
| RCE クラス | --methods | 実世界のターゲット | 判定 |
|---|
| OS コマンドインジェクション (結果ベース) | reflected | Webmin 1.910 — CVE-2019-15107 | confirmed |
| 式インジェクション (OGNL) | eval | Apache Struts2 — S2-001 | confirmed |
| 式ルックアップ (Log4Shell/JNDI) | lookup | Apache Solr 8.11.0 (Log4j 2.14.1) — CVE-2021-44228 | lookup-sink |
| ブラインドコマンドインジェクション (出力なし) | time | Webmin 1.910 — CVE-2019-15107 | needs-review |
すべての行は tests/bench/ によって再現される。これは Docker 上でこれらのビルドに対して RCEKit を実行し、判定 および そのネガティブコントロールを検証する。最後の実行は 2.36.0 (2026-09-20) でグリーン: 3/3 ケース。これはある時点での主張であり、継続的なものではない -- ベンチマークはすべての変更ではなく、定期的な間隔で実行される。
各コントロールは、その行の真のテストである。reflected でプローブされた Struts2 は negative を返す。なぜなら S2-001 は OGNL を再評価し、その背後にシェルが存在しないからである。Webmin の time シグナルは、たまたま正しいターゲット上で needs-review に留められている。そして Solr を oob でプローブすると、エクスプロイト可能であるにもかかわらず negative を返す -- oob はシェルコマンドを構築し、${jndi:...} シンクはそれらのいずれも実行しない。これが lookup が埋めるために存在するギャップであり、主張ではなく測定されたものである。
Log4Shell の行は confirmed ではなく lookup-sink と表示する。コールバックが証明するのは、シンクが RCEKit の選んだ URI を解決したということである。RCE に到達するには、ルックアップにロード可能なクラスで応答するサーバーが必要であり、デフォルトのリスクティアでは jndi:dns:// のみが出ていく -- 名前解決であり、その先にそのようなサーバーが応答するための接続はない。
reflected — OS コマンドインジェクション、Webmin CVE-2019-15107 → confirmed
eval — OGNL 式インジェクション、Apache Struts2 S2-001 → confirmed
lookup-sink
time — ブラインドコマンドインジェクション、Webmin CVE-2019-15107 → needs-review
RCEKit には 2 つのサポートされた形態 があり、どちらも他方のフォールバックではない。
インストール — pipx は CLI を独自の環境に保つ。これはライブラリではなくツールに求めるものだ:```bash
pipx install rcekit # or: pip install rcekit
rcekit --doctor # confirms the corpus it will run with
**または1つのファイルだけを取得する。** ペイロードコーパスはモジュールに組み込まれているため、
`rcekit.py` は他に何もなくても単独で動作する — インストール手順も、site-packagesも、後に残すものもない。クライアントのジャンプボックス、エアギャップされたホスト、または `pip install` が選択肢にならないあらゆる場所で:```bash
curl -O https://raw.githubusercontent.com/kabiri-labs/rcekit/main/rcekit.py
python rcekit.py --doctor # same corpus, same check, zero installation
どちらも同じコードを実行し、同じ判定を報告する。チェックアウトから作業するのが第三の方法で、これもインストール不要である:```bash git clone https://github.com/kabiri-labs/rcekit.git cd rcekit # Python 3.8+, standard library only
入力を配置する場所に `FUZZ` マーカーを置き(またはキャプチャしたリクエストを使用する際に `-p` でパラメータを選択し)、RCEKit に RCE を証明するよう依頼します:```bash
rcekit --acknowledge-consent \
--verify-url "https://target.example/lookup?host=FUZZ" \
--methods reflected,eval
git clone https://github.com/yourusername/secret-scanner.git
cd secret-scanner
pip install -r requirements.txt
python secret_scanner.py /path/to/scan
| オプション | 説明 |
|---|---|
-h, --help | ヘルプメッセージを表示して終了します |
-e, --entropy | エントロピー分析を有効にします |
-t, --threshold | エントロピーしきい値(デフォルト: 4.5) |
-r, --rules | カスタムルールを含むJSONファイルへのパス |
-x, --exclude | 除外するファイルまたはディレクトリのカンマ区切りリスト |
-j, --json | 結果をJSON形式で出力します |
# 基本的なスキャン
python secret_scanner.py ./myproject
# エントロピー分析を有効にする
python secret_scanner.py ./myproject --entropy
# カスタムルールを使用する
python secret_scanner.py ./myproject --rules custom_rules.json
# ファイルを除外する
python secret_scanner.py ./myproject --exclude "*.log,node_modules,*.min.js"
# JSON出力
python secret_scanner.py ./myproject --json > results.json
カスタムルールはJSONファイルで定義できます。
{
"patterns": [
{
"name": "Custom API Key",
"regex": "custom_api_key_[a-zA-Z0-9]{32}",
"severity": "high"
},
{
"name": "Internal Token",
"regex": "internal_token_[a-f0-9]{40}",
"severity": "medium"
}
],
"entropy_threshold": 4.5,
"exclude_patterns": [
"*.test.js",
"*.spec.js",
"test/fixtures/*"
]
}
[CRITICAL] AWS Access Key found in config/aws.yml:15
[HIGH] GitHub Token found in src/api.js:42
[MEDIUM] High entropy string found in data/keys.txt:8
{
"scan_path": "/path/to/scan",
"timestamp": "2024-01-15T10:30:00Z",
"findings": [
{
"file": "config/aws.yml",
"line": 15,
"type": "AWS Access Key",
"severity": "critical",
"match": "AKIAIOSFODNN7EXAMPLE"
}
],
"summary": {
"total_files_scanned": 150,
"total_findings": 3,
"critical": 1,
"high": 1,
"medium": 1,
"low": 0
}
}
コントリビューションを歓迎します!お気軽にPull Requestを送信してください。
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)このプロジェクトはMITライセンスの下でライセンスされています - 詳細についてはLICENSEファイルを参照してください。
このツールは、教育および認可されたセキュリティテストの目的のみを意図しています。所有していない、またはスキャンする明示的な許可を得ていないシステムでは使用しないでください。著者は、このソフトウェアの誤用によって引き起こされるいかなる損害についても責任を負いません。``` [detect] methods: reflected, eval [detect] sent 13 probes: confirmed=4, negative=9
[detect] CONFIRMED execution (4): [reflected/unix/raw] ; echo RKYZRIP$((540141+314681))RKFWVFS$(echo RKBWOOC)RKYZRIP (target computed 'RKYZRIP854822RKFWVFSRKBWOOCRKYZRIP' — random operands, absent from control)
### キャプチャしたリクエストから — 実際のターゲットのほとんどが持つ形
`--verify-url` が運ぶのは URL だけで、それ以外は何もありません。テストする価値のあるシンクのほとんどは、セッション Cookie、Content-Type、ボディを伴う POST の背後にあり、RCEKit はそのリクエストを丸ごと受け取ります。プロキシまたはブラウザの devtools から保存し、インジェクトするフィールドに名前を付けてください。```bash
rcekit --acknowledge-consent \
-r search.req -p q \
--methods reflected,eval
# リポジトリをクローン
git clone https://github.com/yourusername/kitploit-tool.git
cd kitploit-tool
# 依存関係をインストール
pip install -r requirements.txt
# ツールをインストール
python setup.py install
# 単一のターゲットをスキャン
python kitploit.py -t example.com
# 複数のターゲットをスキャン
python kitploit.py -f targets.txt
# 詳細出力を有効化
python kitploit.py -t example.com -v
ツールは設定に config.yaml ファイルを使用します:
scan:
timeout: 30
threads: 10
retries: 3
output:
format: json
directory: ./results
api:
key: YOUR_API_KEY
endpoint: https://api.example.com
以下の環境変数を設定できます:
KITPLOIT_API_KEY - APIキーKITPLOIT_TIMEOUT - リクエストのタイムアウト(秒)KITPLOIT_THREADS - 同時スレッド数KITPLOIT_OUTPUT_DIR - 出力ディレクトリpython kitploit.py -t 192.168.1.1
python kitploit.py -t example.com -c custom_config.yaml
python kitploit.py -t example.com -o results.json
ツールは複数の出力形式をサポートしています:
| 形式 | 説明 | フラグ |
|---|---|---|
| JSON | 構造化データ | -o json |
| CSV | 表形式データ | -o csv |
| XML | マークアップ形式 | -o xml |
| HTML | レポート形式 | -o html |
スキャンモジュールは以下を担当します:
レポートモジュールは以下を提供します:
[detect] CONFIRMED execution (3): [reflected/unix/raw] ; echo RKHWNHK$((114157+752773))RKXGFIH$(echo RKHSEIF)RKHWNHK (target computed 'RKHWNHK866930RKXGFIHRKHSEIFRKHWNHK' — random operands, absent from control)
メソッド、パス、ヘッダー、ボディ、クッキーはキャプチャされたまま再利用され、各値はそれが到達するコンテキストに応じてエンコードされる — JSONのリーフ、フォームフィールド、クッキーではエスケープの方法が異なる。代わりに `-p` を外して `FUZZ` または `*` でその箇所をマークしてもよい。
### ツールが持つすべて
キャプチャされたリクエストからのみ到達できるものが2つある: **インジェクションポイントの列挙**(`--auto-params`)と、セッションを必要とするシンクである。したがって、RCEKitが実行できる最も完全な実行はURLからではなく `-r` から始まる — これはターゲットがクリーンであると結論付ける前に知っておく価値がある。```bash
rcekit --acknowledge-consent \
-r search.req --auto-params all --point-order thorough \
--methods reflected,eval,time,lookup,deser \
--oob-host oob.yourdomain.example --listen-dns-port 53 \
--verify-active-risk stateful --probe-depth full \
--detect-json findings.json
# リポジトリをクローン
git clone https://github.com/example/malware-scanner.git
cd malware-scanner
# 仮想環境を作成
python -m venv venv
source venv/bin/activate # Windowsの場合: venv\Scripts\activate
# 依存関係をインストール
pip install -r requirements.txt
# パッケージをインストール
pip install -e .
pip install malware-scanner
# ディレクトリをスキャン
malware-scanner scan /path/to/directory
# 単一のファイルをスキャン
malware-scanner scan /path/to/file
# 詳細出力でスキャン
malware-scanner scan /path/to/directory --verbose
# 特定の出力形式でスキャン
malware-scanner scan /path/to/directory --output report.json --format json
使用方法: malware-scanner [オプション] コマンド [引数]...
オプション:
--version バージョン情報を表示して終了
--help このヘルプメッセージを表示して終了
コマンド:
scan ファイルまたはディレクトリをスキャン
update マルウェアシグネチャデータベースを更新
config 設定を管理
report スキャンレポートを生成
malware-scanner scan [オプション] ターゲット
オプション:
-r, --recursive ディレクトリを再帰的にスキャン
-t, --threads N スレッド数(デフォルト: 4)
-o, --output FILE 出力ファイル
-f, --format FORMAT 出力形式(text、json、html、csv)
-v, --verbose 詳細出力
-q, --quiet 最小限の出力
--no-yara YARAスキャンを無効化
--no-hash ハッシュスキャンを無効化
--no-entropy エントロピー分析を無効化
--no-strings 文字列抽出を無効化
--no-pe PE分析を無効化
--max-size SIZE 最大ファイルサイズ(バイト単位)
--exclude PATTERN 除外するパターン
--include PATTERN 含めるパターン
設定ファイルは ~/.malware-scanner/config.yaml にあります:
# スキャン設定
scan:
threads: 4
max_file_size: 104857600 # 100 MB
recursive: true
follow_symlinks: false
# 検出設定
detection:
yara_enabled: true
hash_enabled: true
entropy_enabled: true
entropy_threshold: 7.0
strings_enabled: true
pe_enabled: true
# 出力設定
output:
format: text
verbose: false
color: true
# データベース設定
database:
update_url: https://example.com/signatures/
auto_update: true
update_interval: 86400 # 24時間(秒単位)
スキャナーは既知のマルウェアシグネチャのデータベースを使用して、既知の脅威を検出します。データベースは定期的に更新されます。
YARAルールは、マルウェアのパターンを検出するための強力なパターンマッチング機能を提供します。カスタムルールを ~/.malware-scanner/rules/ ディレクトリに追加できます。
スキャナーはファイルのMD5、SHA1、SHA256ハッシュを計算し、既知のマルウェアハッシュのデータベースと照合します。
高いエントロピー値は、暗号化または圧縮されたデータを示している可能性があり、マルウェアの兆候である場合があります。
スキャナーはファイルから疑わしい文字列を抽出し、既知のマルウェア関連の文字列と照合します。
ポータブル実行可能ファイル(PE)は、疑わしい特性(異常なセクション、疑わしいインポート、パッカーなど)について分析されます。
スキャン結果
=============
スキャン対象: /path/to/directory
スキャン日時: 2024-01-15 10:30:00
スキャン時間: 5.23秒
スキャンしたファイル数: 1234
検出数: 3
検出された脅威:
1. /path/to/malware1.exe
タイプ: Trojan
名前: Trojan.Generic.12345
重大度: 高
ハッシュ: abc123...
2. /path/to/malware2.dll
タイプ: Worm
名前: Worm.Generic.67890
重大度: 中
ハッシュ: def456...
3. /path/to/suspicious.js
タイプ: Suspicious
名前: Suspicious.Script.11111
重大度: 低
ハッシュ: ghi789...
{
"scan_info": {
"target": "/path/to/directory",
"timestamp": "2024-01-15T10:30:00Z",
"duration": 5.23,
"files_scanned": 1234,
"detections": 3
},
"threats": [
{
"path": "/path/to/malware1.exe",
"type": "Trojan",
"name": "Trojan.Generic.12345",
"severity": "high",
"hash": "abc123..."
}
]
}
HTML形式は、ブラウザで表示できる視覚的に魅力的なレポートを生成します。
CSV形式は、スプレッドシートアプリケーションでの分析に適した表形式の出力を提供します。
~/.malware-scanner/rules/ ディレクトリにYARAルールを追加できます:
rule CustomMalware {
meta:
description = "カスタムマルウェア検出"
author = "Your Name"
date = "2024-01-15"
strings:
$s1 = "malicious_string" nocase
$s2 = { 4D 5A 90 00 }
condition:
$s1 or $s2
}
from malware_scanner import Scanner
# スキャナーを初期化
scanner = Scanner()
# ディレクトリをスキャン
results = scanner.scan_directory("/path/to/directory")
# 結果を処理
for threat in results.threats:
print(f"検出: {threat.path}")
print(f"タイプ: {threat.type}")
print(f"名前: {threat.name}")
print(f"重大度: {threat.severity}")
from malware_scanner.api import scan_file, scan_directory
# 単一のファイルをスキャン
result = scan_file("/path/to/file")
# ディレクトリをスキャン
results = scan_directory("/path/to/directory")
| オプション | 説明 | デフォルト |
|---|---|---|
| threads | スレッド数 | 4 |
| max_file_size | 最大ファイルサイズ(バイト単位) | 104857600 |
| recursive | 再帰的にスキャン | true |
| follow_symlinks | シンボリックリンクを追跡 | false |
| オプション | 説明 | デフォルト |
|---|---|---|
| yara_enabled | YARAスキャンを有効化 | true |
| hash_enabled | ハッシュスキャンを有効化 | true |
| entropy_enabled | エントロピー分析を有効化 | true |
| entropy_threshold | エントロピーしきい値 | 7.0 |
| strings_enabled | 文字列抽出を有効化 | true |
| pe_enabled | PE分析を有効化 | true |
| オプション | 説明 | デフォルト |
|---|---|---|
| format | 出力形式 | text |
| verbose | 詳細出力 | false |
| color | カラー出力 | true |
スキャンが遅い
--threads 8--no-yara --no-entropy誤検出
--exclude "*/node_modules/*"メモリ不足
--max-size 10485760--threads 2ログは ~/.malware-scanner/logs/ に保存されます。ログレベルは設定ファイルで調整できます。
貢献を歓迎します!詳細については CONTRIBUTING.md を参照してください。
このプロジェクトはMITライセンスの下でライセンスされています。詳細については LICENSE ファイルを参照してください。
このツールは、教育および研究目的のみを目的としています。マルウェアの分析と検出に責任を持って使用してください。このツールの使用によって生じたいかなる損害についても、作者は責任を負いません。``` [verify] loaded request from search.req: enumerating 4 injection point(s) [detect] enumerating 4 injection point(s) x 3 method(s) [detect] cost: 4 points x ~1739 probes = at least 6964 requests [detect] body param 'q': confirmed (1544 probes) <-- CONFIRMED [detect] sent 6371 probes: confirmed=446, negative=5925
各フラグが有効にするもの:
| | |
|---|---|
| `--auto-params all` | 名前付きフィールド1つではなく、すべてのクエリ値、JSONリーフ、フォームフィールド、マルチパートパート、Cookie、ヘッダー |
| `--point-order thorough` | 高収率のものだけでなく、hop-by-hop以外のすべてのヘッダー |
| `--methods ...,lookup,deser` | 式ルックアップとデシリアライゼーションのシンク。シェル型のメソッドでは到達できない |
| `--oob-host` | ブラインドメソッド用のコールバックホスト。委任されたドメインが必要。ポート53にはroot権限が必要 |
| `--verify-active-risk stateful` | 最上位 — RCEKitが選択していないアドレスからターゲットにフェッチさせるプローブ形状を追加する |
| `--probe-depth full` | 安価なものだけでなく、シンクごとにすべてのブレイクアウト形状 |
| `--detect-json` | 同じ判定を機械可読なJSONで出力 |
**これは大量のリクエストになります。** コスト行は何かが発火する前に表示され、
`--max-points` / `--max-payloads` がそれを制限します。壊してもよいインスタンスに対して実行してください:
`--verify-active-risk stateful` は使い捨てのターゲット向けの階層であり、本番環境向けではありません。
外部インフラストラクチャ不要、設定ファイル不要。
**GIFを鵜呑みにしないでください** — docker化されたWebminとStruts2のターゲットに対して
[自分で再現してください](https://github.com/kabiri-labs/rcekit/blob/main/docs/verify-it-yourself.md)。約5分でできます。
**次:** [**フィールドガイド**](https://github.com/kabiri-labs/rcekit/blob/main/docs/guide.md)では、実際の状況 — キャプチャされた
リクエスト、WAF、フィルタリングされたセパレーター、クォートされたシンク、ブラインドおよび
egressなしのターゲット — を、それぞれ1つの実例で解説します。
---
## 判定の意味
RCEの*候補*を見つけるのは簡単です。他人の再テストに耐えるものを報告するのが難しい部分であり、
それは2つの方向で失敗します: 反射であることが判明する「脆弱性の可能性あり」と、
実際には何もテストしていない実行からの「脆弱ではない」です。
RCEKitは**互いに決して混同されない8つの判定**で答えます:
| 判定 | 何を主張するか |
|---|---|
| **`confirmed`** | ターゲットが入力を実行した。それ以外では生成できない値を返した — そのプローブに固有のランダムなオペランドから計算された値であり、その値はペイロードなしのコントロールには存在しない。 |
| **`deserialization-sink`** | ターゲットが攻撃者提供のオブジェクトグラフを再構築した。証明済みだが、*別の特性*についてである: そこからRCEに到達するかはクラスパスガジェットに依存するため、RCEとは決して呼ばれない。 |
| **`lookup-sink`** | ターゲットがRCEKitから渡されたURIを解決した — `${jndi:…}`式がルックアップに到達し、そのプローブだけが保持していたトークンを含むコールバックで証明された。これはシンクであり実行ではない: そこからRCEに到達するには、ロード可能なクラスを返すサーバーが必要。 |
| **`needs-review`** | それ自体では証明にならない本物のシグナル — 線形のタイミング回帰、パーサーフィンガープリント。時間をかける価値はあるが、「confirmed」という言葉に値することは決してない。 |
| **`inconclusive`** | 証拠は現れたが、実行に帰属できなかった — ペイロードなしのコントロールにもそれが含まれていた。 |
| **`negative`** | プローブが構築され、ターゲットに到達し、何も見つからなかった。 |
| **`error`** | 何もターゲットに到達しなかった。 |
| **`nothing-tested`** | プローブがまったく構築されなかった。 |
`confirmed`と`maybe`が曖昧になった瞬間、`confirmed`は何の意味も持たなくなる — だから
何かが上方に昇格されることは決してない。タイミング回帰はどれほどきれいな傾きでも`needs-review`のまま。
デシリアライゼーションコールバックは、クラスパスが悪用可能だとどれほど確信していても`deserialization-sink`のまま。
### もう半分: 何もテストしなかった実行は決してクリーンではない
最後の2行は他のツールにはないもので、見た目以上に重要です。ターゲットに到達できなかった、
またはフラグがすべてのプローブを除外したためにプローブを構築しなかったスキャナは、
ターゲットについて**何も**学んでいない — そしてそこで`negative`を出力するのは、
安全であるかのように読める嘘です。
そのため`error`と`nothing-tested`は第一級の判定であり、実行は非ゼロで終了し、
RCEKitはどちらが起きたのか、そしてその理由を告げます:```
[!] No probes were built, so NOTHING WAS TESTED — this is not a negative result.
[!] None of the selected methods (reflected, file) apply to environment(s): sql.
実行が静かに空になり得るあらゆる場所で発火します。選択した環境に適用されないメソッド、選択したシェルに構文がない --sink-shape の段、安全性の上限によって完全に抑え込まれた --bridges の選択、届く前に配信が壊れたリクエストボディなどです。
部分的にしか目隠しされなかった実行は、一段下で同じ扱いを受けます。二次オラクルを要求したのに、観測されたエンドポイントが一度も応答しなかった場合、プローブの判定は依然として有効です — ただし、その実行は、二次のネガティブとして通してしまうのではなく、指定したチャネルを一度も読むことなく判定されたことを伝えます。
1つの CLI、1つの --methods フラグで、RCE への主要な経路をカバーします:
| RCE クラス | --methods | RCEKit がそれを証明する方法 |
|---|---|---|
| OS コマンドインジェクション | reflected | ランダムなオペランドに対してシェルに $((a+b)) を計算させ、$(echo TAG) を畳み込ませる。確認するのは結果であり、リテラル式では決してない。シンク自身の方言 — POSIX、cmd.exe、PowerShell — で記述される。 |
コード / 式インジェクション — SSTI、SpEL、OGNL、Groovy、eval() (CWE-94) | eval | あらゆる一般的なテンプレート構文 (${…} {{…} #{…} %{…} <%=…%> @(…)、ベア) で a*b を注入する。リテラルの a*b が現れない一方で積が現れることを確認する。 |
| ブラインドコマンドインジェクション (出力なし) | time | 制御された 0/N/2N の遅延系列を発火させ、応答時間が遅延に線形に追従することを確認する。needs-review として報告される — ジッターでは偽装できないが、タイミングは計算された値ではない。 |
| 内部 / エグレスなし のターゲット | file | ランダムなトークンを書き込み、あらゆる読み戻し経路 — Web ルート、LFI パラメータ、ダウンロードまたはエクスポートハンドラ、/tmp に裏打ちされたプレビュー — を通じてそれを取得する。外部リスナーなしで、実行および書き込みプリミティブを証明する。 |
| アップロード / 書き込みプリミティブ — PUT-a-JSP、未チェックのアップロード (CWE-434) | write | 自身のアップロードリクエストを通じて積を計算するワンライナーを書き込み、そのファイルを取得する。積が返れば confirmed な RCE、ソースがそのまま返ってくれば needs-review — 任意ファイル書き込みであり、配信されるが解釈はされない。 |
| デシリアライゼーションシンク — fastjson、shiro、weblogic (CWE-502) | deser | 非実行の DNS ガジェットまたはエラー形状の差分を通じて、エンドポイントが攻撃者データをデシリアライズすることを証明する。deserialization-sink として報告され、決して RCE としては報告されない。 |
| ブラインド / アウトオブバンド — 持ち出し、非同期 | oob | 組み込みの HTTP/DNS リスナーがコールバックを受信し、それぞれを正確なペイロードに相関させる。すべてのプローブは自身のトークンを運ぶ。 |
| 式ルックアップシンク — Log4Shell/JNDI | lookup | シンクはコマンドを実行する代わりに ${jndi:…} URI を解決するため、oob のシェルプローブは何にも到達しない。コールバックのみでそれを証明し、 として報告し、 とはしない。送信されるのは のみ — 名前解決であり、それ以外ではない — したがって証明されるのはルックアップであり、ガジェットチェーンではない。 |
これらのメソッドが到達できる範囲を広げる3つの要素がありますが、いずれも confirmed と呼ぶ対象を変えるものではありません:
--observe-url) — ペイロードが一方のリクエストで着地し、別の場所で実行される場合: プロフィールページでレンダリングされる保存型 SSTI、テンプレートエンジンが後でレンダリングするログに書き込まれたペイロード、キューに入れられたジョブ。観測されたエンドポイントは、プローブが送信される前に取得されたスナップショットと差分比較されます。--bridges) — COPY … FROM PROGRAM、xp_cmdshell、expect://。ブリッジはキャリアであり、オラクルではありません: メソッドがすでに構築したコマンドをラップするため、同じ段階がそれを介して適用されます。-p all) — クエリ、JSON リーフ、フォームフィールド、マルチパートパート、Cookie、ヘッダー、パスセグメント。それぞれが着地する場所に合わせてエンコードされ、プローブコストが発火前に表示されます。GraphQL ボディは、実際に確認できるものによって順序付けられます: リゾルバが操作ドキュメント自体より先に読む variables です。メソッドは自由に組み合わせられます: --methods reflected,eval,time は3つすべてを実行し、それぞれの段階を個別に報告します。
正直な範囲。 RCEKit は、リクエストへの注入によって到達可能で、シェルまたは評価器によって解釈される RCE を確認します。メモリ破壊のバグ (バッファオーバーフロー、UAF) や、シェルを介さない
argv配列への引数インジェクションは対象外です — これらは別の問題です。デシリアライゼーションガジェットチェーンも対象外です:--methods deserはエンドポイントが攻撃者データをデシリアライズすることを証明し、それを独自の段階で報告しますが、どのガジェット (もしあれば) がそれを実行に変えるかはターゲットのクラスパスに依存し、RCEKit はそれを知っているとは主張しません。あらゆるものに対して凡庸であるよりも、上記のインジェクション駆動型 RCE クラスにおいて卓越することを目指しています。
この分野の他のツールは、あなたを侵入させるために作られています。RCEKit は、その発見が他者の精査に耐えるように作られています — クライアントの再テスト、トリアージキュー、レポートレビュー。その違いは3つの場面で現れます。
テストする前にクラスを知っていることはほとんどありません。単一クラスのツールで未知のシンクをカバーするには、それぞれを順番に実行し、そのたびにリクエストを再構築する必要があります:
| 確認できるもの | RCEKit | commix | SSTImap | Nuclei |
|---|---|---|---|---|
| OS コマンドインジェクション | ✅ | ✅ (その全範囲) | — | テンプレートごと |
| 式インジェクション / SSTI | ✅ | eval ベースの手法による | ✅ (その全範囲) | テンプレートごと |
| ブラインド — タイミング | ✅ 別個の段階として | ✅ | ✅ | — |
| ブラインド — アウトオブバンド | ✅ 組み込みリスナー | — | — | interactsh 経由 |
| エグレスなし — 書き込み & 読み戻し | ✅ あらゆる読み戻し経路 | ✅ (Web ルート) | — | — |
cmd.exe および PowerShell シンク | ✅ 方言ごとのプローブ | ✅ (cmd) | — | テンプレートごと |
| アップロード → 書き込み後実行 | ✅ 書き込みと実行を別個の段階で | — | — | テンプレートごと |
| 二次 — ここで着地し、あちらで実行 | ✅ | — | — | — |
| OS へのクエリ言語ブリッジ | ✅ | — | — | テンプレートごと |
| デシリアライゼーションシンク | ✅ 独自の段階、RCE とは決して呼ばない | — | — | テンプレートごと |
| 上記すべて、1つの CLI、1回の実行 | ✅ | — | — | — |
カバレッジは各プロジェクト自身が文書化した手法リストに基づきます。SSTImap は tplmap のメンテナンスされた後継であり、その作者は tplmap をメンテナンス終了としています。```bash
python rcekit.py --acknowledge-consent -r request.txt -p host --methods reflected,eval,time
### 2. 自身の結果と矛盾する
ツールは発見した内容を報告する。RCEKit はさらに、**信じることを拒否した内容**も報告する —
`inconclusive` はそれ自体が一つの判定であり、証拠は現れたものの実行に帰属できなかった場合に用いられる:```
[detect] methods: reflected, eval
[detect] sent 13 probes: confirmed=0, inconclusive=2, negative=11
それら二つは、他人の発見であったはずだ。その判定を生み出す五つのメカニズムがあり、それらはすべての確認で実行される:
inconclusive であり、発見ではない。$((a+b)) が返り、実行だけが値を返す。confirmed と呼ぶ範囲は広がらない。同じ本能は逆方向にも働く。タイミングは決して自己確認しない、デシリアライゼーションコールバックは決して RCE と呼ばれない、そしてプローブを一つも構築しなかった実行は決してネガティブとは呼ばれない。
クライアントのエンゲージメント規則が実際に問い合わせる統制は、あなたのノートではなくツールの中にある:
| 同意ゲート | --acknowledge-consent なしでは、悪用目的のものは何も生成または発火しない。 |
| 実行計画 | 最初のリクエストが出る前に、正確なプローブ数、シンク形状、安全ティア、および任意のアウトバウンドコールバック先を出力する。 |
| デフォルトで安全 | リバースシェル、資格情報アクセス、クラウドメタデータ、ラテラルムーブメント、コンテナエスケープは、--verify-active-risk を引き上げるまで保留される。永続化とバックドアにはさらに二つ目のフラグが必要。ターゲット上にオブジェクトを作成するブリッジも同じ上限に従う。 |
| クリーンアップコマンド | file、write、およびステートフルブリッジはターゲットの状態を変更するため、すべての発見 — needs-review を含む — はそれを元に戻すために実行すべき内容を出力する。 |
| 資格情報はそのまま | file の読み戻しフェッチは、実行の Authorization/Cookie ヘッダーを同一オリジンにのみ運び、それらを差し控えるときはその旨を明示する。観測チャネルのフェッチは、--observe-request でリクエストを渡さない限り、一切送信しない。 |
| 秘匿化された監査証跡 | すべての実行は exploit_audit.log に記録され、資格情報ヘッダーが送信された事実を記録するが、その値は決して記録しない。 |
| ウォーターマーキング | --watermark は各ペイロードに追跡可能なトークンを刻印するため、数か月後にクライアントのログで見つかったペイロードはあなたの実行に帰属できる。 |
| サードパーティのコールバックなし | OOB リスナーはあなたのものである。公開インタラクションサーバーを経由するものは何もなく、それを完全に禁じるエンゲージメントもある。 |
| 単一の stdlib ファイル | rcekit.py は単独で動作する — ジャンプボックス、エアギャップされたホスト、pip install が選択肢にならないあらゆる場所で。 |
判定ではなくシェルが欲しい? commix と SSTImap はポストエクスプロイテーションへと続くが、RCEKit は設計上、証明で止まる。既知の CVE のために何千ものホストをスイープする? それは Nuclei の仕事だ — そして RCEKit は Nuclei テンプレートを書き出す(--output-format nuclei)ので、競合するのではなくあなたのスキャナに供給する。インジェクションが SQL であることは既に分かっていて、データベースそのものが欲しい?
sqlmap がその領域を担う — RCEKit のブリッジは、テキストパラメータから OS に到達可能であることを証明するために存在し、データベースを悪用するためではない。
各行はフィールドガイドの実例である — コマンド、それが送信するもの、そして返ってきたものをどう読むか。
| 状況 | 参照先 |
|---|---|
| URL とパラメータがある | URL を指定する |
| Burp から保存したリクエストがある | キャプチャしたリクエストを指定する |
| アプリが JSON / ペイロードが何度も壊される | ペイロードを無傷で着地させる |
| どのクラスか分からない | メソッドの選択 |
シンクが ; を除去する | シンクがセパレータをフィルタするとき |
入力が 'quotes' の内側に着地する | クォート内へのインジェクション |
| シンクが入力をコマンド全体として実行する | コマンド全体のシンク |
| ターゲットが Windows、またはシンクが PowerShell | Windows と PowerShell のシンク |
| WAF がある | WAF を回避する |
| 出力が全く返ってこない | ブラインドターゲット |
| 出力も外向き通信もない | 外向き通信なしのターゲット |
| リクエストが何かを実行する代わりにファイルを保存する | アップロードおよび書き込みプリミティブのターゲット |
| ペイロードが後で、別のリクエストで実行される | 実行が別のリクエストで起こるとき |
| インジェクションポイントが SQL で、シンクがデータベースホスト |
| 自分で検証する | 上記の確認を、docker 化された脆弱なターゲットに対して自分のマシンで再現する。5分。 |
| フィールドガイド | 最初のプローブからマルチステップチェーンまで、あらゆる実際の状況を例でたどるウォークスルー。ここから始める。 |
| ペイロード生成 & エクスポート | ペイロードジェネレータとしての RCEKit:ターゲットプロファイル、および Burp / ffuf / Nuclei エクスポート。 |
| リファレンス | すべてのフラグ、環境、カテゴリ、コンテキスト、エンコーディング、およびコード実行シンク。 |
| CHANGELOG.md | 各リリースでの変更点、およびアップグレード時に再確認すべきこと。 |
| CONTRIBUTING.md | シンク、カテゴリ、エンコーディング、検出メソッドを追加する方法。 |
| SECURITY.md | RCEKit 自体の脆弱性を報告する方法。 |
RCEKit は悪用する、そしてそれが要点だ。 脆弱性は、ターゲットにそのことを実行させることで確認される。なぜならそれが、シグネチャが偽造できず、パッチを当てたビルドが偶然に生成できない唯一の証拠だからである。実行を制限するのは、悪用へのためらいではない。それは二つの構造的事実と一つのスイッチである。
それはあなたから任意のペイロードを受け取らない。 プローブはオラクルに仕えるためにエンジンによって構築される — そのプローブにとってランダムなオペランドに対する算術、この実行だけが選び得た名前。検出を別の何かに変える入力は存在しない。なぜなら、与えるべきそのような入力が存在しないからである。
値を計算することを超えるものはすべて、必要とするティアを宣言するため、一つのフラグが実行がどこまで進むかを決める:--verify-active-risk safe | intrusive | stateful。そのティアを超えるメソッドまたは単一のプローブ形状は、それを送信するであろうフラグと共に、名前で保留される — 静かに縮小するラダーは、何も見つけるものがないターゲットと区別がつかない。使い捨てのインスタンスに対しては、ティアを引き上げてツールの持つすべてを得る。
--acknowledge-consent が必要;--detection-only は無害であり不要。--verify-active-risk を引き上げるまで保留される。破壊的ペイロード(永続化、バックドア)は --verify-allow-destructive なしでは決して発火しない。実行計画は、何かが発火する前に正確に何が送信されるかを出力する。safe / intrusive / stateful。コーパスペイロードは --max-safety でフィルタされる;検出メソッドとそのプローブ形状は同じ段を宣言し、--verify-active-risk でフィルタされるため、ターゲットに外部へ到達させたり何かを残したりするメソッドは、すべてのコーパスペイロードと同じ順序に従う。プリフライトは、保留された各項目が実際に必要とするティアを名指しする。file と write は代わりに独自の設定でゲートされる:どちらも、書き込むディレクトリと読み戻す URL を指定するまで何もしない。exploit_audit.log に記録される;--watermark は追跡可能なトークンを埋め込む;実行ログは rcekit.log に送られる。--template-file が見つからない場合、RCEKit は実行を拒否して非ゼロで終了する。黙って何も生成しないのではなく(--doctor がそれをチェックする)。不在のデフォルトコーパスファイルのみが組み込みコピーにフォールバックし、そうするときはその旨を告げる。このツールキットは、許可されたペネトレーションテスト、セキュリティ研究、教育、および防御的トレーニングのみを目的としている。明示的な許可なくシステムに対して決して使用しないこと — 許可なきテストは違法である。
python -m unittest discover -s tests # dependency-free test suite
コントリビューションを歓迎します — 新しいシンク/カテゴリ、エンコーディング、環境、検出方法、バグ修正、ドキュメントなどです。ペイロードのベースは編集可能な JSON テンプレート(`templates/payloads.json`)にあるため、ほとんどのカバレッジは Python ソースに触れることなく拡張できます。コーパスを変更した後は、`rcekit.py` 内に同梱されている組み込みコピーを更新してください:```bash
python tools/embed_corpus.py # --check verifies it is current
テストスイートは、両者が乖離した場合に失敗します。CONTRIBUTING.md を参照してください。
MIT — LICENSE を参照してください。
lookup-sinkconfirmedjndi:dns://| エンドポイントがシリアライズされたオブジェクトを受け取る | デシリアライゼーションシンク |
| シンクがログインまたはファイルアップロードの背後にある | マルチステップチェーン |
needs-review / inconclusive / error が出た | 結果の読み方 |
| コーパスが使用不能だと言われる | トラブルシューティング |