
Kali365 - EvilTokens Replica
デバイスコードフィッシングサーバー。敵対的エミュレーション用。Microsoft 365 OAuthトークンをDevice Authorization Grantフローでキャプチャします。GraphSpyに触発されました。
警告 — 許可された使用のみ。 このツールは、明示的な書面による許可を得たペネトレーションテスターおよびレッドチームメンバーを対象としています。誤用はコンピュータ不正使用法に違反する可能性があります。
microsoft.com/deviceloginでの認証を促します。Pythonバックエンド(キャンペーンごとに1ポート) + nginxフロントエンド + SQLite永続化。
main_server.py ← 統一エントリポイント(これを実行)
db.py ← SQLite永続化レイヤー
html_enroll.py ← 被害者登録ページビルダー
html_search.py ← 被害者認証後検索ページビルダー
css_shared.py ← オペレーターUI用共有CSS
nginx_helper.py ← nginxリバースプロキシ設定の自動生成とリロード
nginx.conf ← ベースnginx設定(/etc/nginx/conf.d/*.conf を含む)
キャンペーン作成時にドメインが設定されている場合、nginx_helper.py は自動的にNGINX_CONF(デフォルトでは/etc/nginx/conf.d/easytokens.conf)にドメインごとのサーバーブロックを書き込み、nginxをリロードします。そのドメインへのポート80に到着した被害者トラフィックは、正しいPythonサーバーインスタンスにプロキシされます。
nginx.confは、Hostヘッダーが既知のキャンペーンと一致しないリクエストをドロップし(return 444)、Pythonバックエンドの偶発的な露出を防ぎます。NGINX_CONF=''またはNGINX_RELOAD_CMD=''を設定して自動nginx管理を無効にします。docker compose up --build
Dockerが公開するポート:
| ポート | 目的 |
|---|---|
80 | nginx — ドメインベースの被害者トラフィック |
3000 | Python — オペレーターUI + 直接の被害者アクセス |
http://localhost:3000/http://localhost:3000/apphttp://<campaign-domain>/ (nginx経由でポート80にルーティング)キャプチャされたトークンとログはDockerボリュームに永続化されます:
| ボリューム | コンテナ内のパス | 目的 |
|---|---|---|
easytokens-data | /data/easytokens.db | SQLiteデータベース |
./logs | /logs/ | リクエストごとのログファイル |
必要要件: Python 3.12以上、サードパーティパッケージ不要。
python main_server.py
php-relay/ディレクトリには、分散型の被害者向けノードとして動作するスタンドアロンのApache/PHPコンテナが含まれています。メインサーバーと同じデバイスコード登録ページを提供し、Microsoftに直接ポーリングし、キャプチャしたトークンをPOST /webhook経由でメインパネルに転送します。
checkin.phpはメインパネルのPOST /relay/checkinにPOSTし、RELAY_SECRETで認証します。パネルはノードを登録し、node_idを返します。index.php)にアクセスし、新しいデバイスコードフローを開始します。poll.phpをポーリングします。トークンがキャプチャされると、poll.phpはそれをnode_idタグ付きでメインパネルのPOST /webhookに転送します。php-relay/.envで設定:
両方のコンテナを同時に(推奨):
# from EasyTokens/
docker compose -f docker-compose.yml -f php-relay/docker-compose.yml up --build
両方を1つの-fマージで実行すると、同じDockerネットワーク上に配置されるため、MAIN_SERVER_URL=http://easytokens:3000が正しく解決されます。
アクセス:
| URL | 目的 |
|---|---|
http://localhost:8082/ | リレー被害者登録ページ |
http://localhost:3000/app/nodes | 登録されたリレーノードのオペレーター表示 |
リレーのみ(リモートパネル):
cd php-relay
# Set MAIN_SERVER_URL to the public panel URL in .env
docker compose up --build
openssl rand -hex 32EasyTokens/.env に RELAY_SECRET=<secret> を設定(docker-compose.yml 経由でメインパネルに反映されます)php-relay/.env にも同じ値を設定SQLiteデータベース内の2つのテーブル:
tokens — キャプチャされたすべてのアクセス/リフレッシュトークン(UPN、アクセストークン、リフレッシュトークン、IDトークン、スコープ、ソース、キャプチャタイムスタンプ)device_codes — オペレーターが開始したキャンペーン(ユーザーコード、デバイスコード、検証URL、ステータス、リンクされたトークンID、ポート、ドメイン)MITライセンス — Copyright (c) 2026 Casey Smith
| メソッド | パス | 対象 | 説明 |
|---|
GET | / | 被害者 | デバイスコード登録ページ(ダンダー・ミフリンテーマ) |
POST | /poll | 被害者(JS) | MSトークンエンドポイントをポーリング;成功時にトークンを保存 |
GET | /search?s=<id> | 被害者 | 認証後のOneDrive/メール検索ページ |
GET | /app | オペレーター | ダッシュボード — 統計情報 + 最近のキャプチャ |
GET | /app/device-codes | オペレーター | すべてのキャンペーンとライブポールステータス |
POST | /app/device-codes/new | オペレーター | 新しいデバイスコードキャンペーンを作成 |
GET | /app/tokens | オペレーター | キャプチャされたすべてのトークン |
GET | /app/search?id=<id> | オペレーター | 特定のトークンのOneDrive + メール検索 |
POST | /webhook | リレーノード | 認証されたリレーノードからのトークンを取り込む |
POST | /relay/checkin | リレーノード | リレーノードを登録;node_idを返す |
| 変数 | デフォルト | 説明 |
|---|
PORT | 3000 | Pythonサーバーのリスニングポート |
PORT_MAX | 3010 | Dockerが公開するポート範囲の上限 |
DB_PATH | /data/easytokens.db | SQLiteデータベースのパス |
LOG_DIR | /logs | リクエストごとのログディレクトリ |
NGINX_CONF | /etc/nginx/conf.d/easytokens.conf | nginx_helperが生成した設定を書き込むパス;''に設定すると無効 |
NGINX_RELOAD_CMD | nginx -s reload | 設定変更後にnginxをリロードするシェルコマンド;''に設定すると無効 |
RELAY_SECRET | (未設定) | リレーノード認証用の共有シークレット。openssl rand -hex 32で生成。php-relay/.envのRELAY_SECRETと一致させる必要があります。未設定のままにするとリレーサポートを無効にします。 |
| 変数 | デフォルト | 説明 |
|---|
MAIN_SERVER_URL | http://easytokens:3000 | リレーコンテナ内部から到達可能なメインパネルのURL |
RELAY_SECRET | (必須) | メインパネルのRELAY_SECRETと一致する必要があります |
RELAY_PORT | 8082 | リレーを公開するホストポート |
RELAY_LABEL | ホスト名 | パネルに表示されるこのノードの人間可読な名前 |
CHECKIN_RETRIES | 10 | 諦めるまでのチェックイン再試行回数 |
CHECKIN_DELAY | 5 | チェックイン再試行間の秒数 |
NODE_ID_FILE | /tmp/relay_node_id | node_idがチェックイン後にキャッシュされるパス |
| フィールド | 値 |
|---|
| クライアントID | d3590ed6-52b3-4102-aeff-aad2292ab01c (Microsoft Office) |
| リソース | https://graph.microsoft.com |
| スコープ | openid profile email offline_access Mail.Read Files.Read |
| デバイスコードURL | https://login.microsoftonline.com/common/oauth2/devicecode |
| トークンURL | https://login.microsoftonline.com/Common/oauth2/token |