Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
Weblogic-CVE-2020-2551-To-Internet — CVE-2020-2551 POC(インターネット上で使用) | Kitploit
ツール/GitHubGitHub/dido1960/weblogic-cve-2020-2551-to-internet
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ペイロード開発
GitHubdido1960/weblogic-cve-2020-2551-to-internet

Weblogic-CVE-2020-2551-To-Internet

CVE-2020-2551 POC(インターネット上で使用)

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る
2276年前Kitploit レビュー済み

Weblogic-CVE-2020-2551-To-Internet

CVE-2020-2551 POCをインターネットで使用する

  • POCのテスト(外部ネットワークで使用可能)

    python CVE-2020-2551.py [HOST] [IP]

  • codebaseを変更してリモートローディングを試みる(失敗)

    python CVE-2020-TEST.py [HOST] [IP]

Weblogic CVE-2020-2551 脆弱性と外部ネットワークPOCの構築についての考察

(初出は安全客、原文リンク)

0x00 基本概念

この脆弱性を学ぶには、CORBAやRMIなどの前提知識が必要です。

簡単にまとめると:

CORBAはOMGが策定した分散アプリケーション向けの技術標準であり、IDLを使用して言語間サポートを実現し、クライアントとサーバー間はIIOPプロトコルで通信します。

RMIはもう一つの分散アプリケーション技術であり、JavaではJNDIを使用して簡単に利用でき、クライアントとサーバーはJRMPプロトコルで通信します。ただし、weblogicではRMIはT3プロトコルを使用しており、これに関しては以前にも多くの脆弱性が報告されています。

RMI-IIOPはRMIとCORBAのそれぞれの利点を組み合わせ、IIOPプロトコルを介してRMIアプリケーションを展開します。

公式ドキュメントにも次のように記載されています:

RMIサーバーオブジェクトはIIOPプロトコルを使用でき、任意の言語で書かれたCORBAクライアントオブジェクトと通信できます。

0x01 RMI-IIOP

weblogicのことは一旦おいて、まずRMI-IIOPインスタンスの作成方法に注目します:

クライアントコードは、Java における RMI、JNDI、LDAP、JRMP、JMX、JMS のあれこれ(上)のテストプロジェクトを参照できます。HelloClientとHelloServerを自分でコンパイルしても良いですし、テストプロジェクトでコンパイル済みのものを使用しても構いません。

コマンドラインでネーミングサーバー(Java組み込み)を起動します:

root@kitploit:~
start orbd -ORBInitialPort 1050

コマンドラインでサーバーサイドHelloServerを起動し、リモートデバッグを設定します。IDEAでリモートデバッグを行う方法については、こちらの冒頭で紹介されている方法を参照してください。

root@kitploit:~
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 HelloServer

もちろん、リモートデバッグをせずに結果だけを見ても構いません。直接起動します。

root@kitploit:~
java HelloServer

コマンドラインでクライアントを起動します。

root@kitploit:~
Java HelloClient 

この時点で電卓が起動します。リモートデバッグが成功すると、次の呼び出しスタックが表示されます。

EvilMessage.readObejct() でコマンドを実行します。

余談:weblogicのインストールとデバッグに関する記事。

では、weblogic内のRMI-IIOPはどうでしょうか? JavaのRMI-IIOPについてという記事で、weblogic RMI-IIOPの悪用について言及されています。それを基にいくつか調査を行いました。Using WebLogic’s RMI over IIOPでは、weblogicでRMI-IIOPクライアントを使用するいくつかの方法が説明されています。例えば:

  1. 独立したRMIクライアント(JNDIを使用し、weblogicの要素は一切使用しない)
  2. WebLogicクライアント
  3. J2EEクライアント
  4. CORBA/IDLクライアント

最初の2つの方法の違いは、JNDI_FACTORYの設定の違いだけのようです。

以前weblogic T3の逆シリアル化を調査した際、weblogic上にHelloserverアプリケーションをデプロイし、sayhello()メソッドを利用できるようにしました。2種類のJNDI_FACTORYを設定して呼び出してみたところ、2番目のJNDI_FACTORYを使用してsayHello()メソッドの呼び出しに成功しました。

それでは、weblogic T3プロトコルのPOCを修正します。具体的にはRMIをIIOPに変更したところ、jtaTransactionManager利用チェーンが正常に実行され、ローカルのjrmplistenにjrmpリクエストが送信されました。

トラフィックを確認すると、remove()メソッドの呼び出し時にremove__java_lang_Objectリクエストが送信され、トラフィック内に悪意のあるデータが含まれていましたが、acedマジックヘッダーは見つかりませんでした。

サーバー側で特別な解析が行われた後、データが逆シリアル化されると推測されます。呼び出しスタックを見ると、後半部分の実行チェーンは前述のネイティブRMI-IIOPの実行チェーンと非常によく似ています。前半はCDRInputStream.read_value()からトリガーされますが、こちらはweblogicのIIOPInputStream.read_value()からトリガーされます(read_valueという点は、2019年のトピックでも言及されています)。

ここで、リクエストはまずclusterableServerRef.invoke()で処理され、異なるinvokerに応じてthis.invoker.invoke()が呼び出されます。次に、Mejb_dj5nps_HomeImpl_WLSkel.invoke()が呼び出され、"remove"であるため、case 6ブランチに入り、IIOPInputStream.readObject()が呼び出され、read_value()メソッドでIIOPInputStreamデータが解析されて逆シリアル化がトリガーされます。これがremove()メソッドを利用するPOCです。

0x02 CVE-2020-2551

Lucifaer氏の[分析記事](https://lucifaer.com/2020/02/25/WebLogic WLS核心组件RCE分析(CVE-2020-2551)/?from=timeline&isappinstalled=0#2-2-Weblogic解析流程)では、bind()メソッドを使用した悪用方法が言及されています。これがインターネット上の主流な悪用方法でもあります。呼び出しスタックを追ってみましょう。

前回と同様に、リクエストはまずclusterableServerRef.invoke()で処理され、異なるinvokerに応じてthis.invoker.invoke()が呼び出されます。ここではCobraServerRef.invoke()が呼び出され、その後_NamingContextAnyImplBase._invoke()内で、va1が"bind_any"であるため、case 0ブランチに入り、IIOPInputStream.read_any()メソッドが呼び出されます。その後もIIOPInputStream.read_value()が呼び出されて逆シリアル化がトリガーされます。先ほどトラフィック内でacedマジックヘッダーが見られなかったのは、IIOPInputStream内に解析方式が存在するためです。IIOPInputStreamのhex-value形式は以下の通りで、クラス名とフィールド情報が含まれています。

最終的に悪意のあるクラスのreadObejct()メソッドが呼び出されます。

パッチを確認したところ、2015年のT3逆シリアル化悪用のパッチと同じ場所であることがわかりました。

WebLogic CVE-2020-2551脆弱性分析のテストでは、CVE-2020-2551のフィルタリングクラスの場所もweblogic.iiop.Utilsクラス内にあることが確認されています。

しかし、ローカルテストでは、weblogic10.3.6に2015年のパッチを適用しても、isBlacklisted()関数はトリガーされませんでした(ただし、MsgAbbrevInputStreamとInboundMsgAbbrevの両方でisBlacklisted()が呼び出されてブラックリスト検証が行われているため、奇妙です...)。

今回のCVE-2020-2551のパッチでは、weblogic.iiop.Utils.LoadClass()にフィルタリングのverifyclassermitted()メソッドが追加されました。

ブラックリストは悪意のあるクラスをフィルタリングしており、その中にはJtaTransactionManagerの親クラスであるcom.bea.core.repackaged.springframework.transaction.support.AbstractPlatformTransactionManagerが含まれています。このクラスはweblogicに組み込まれており、非常に危険です。パッチを見ていると、606行目の検証がLoadClass()の後に行われるため、もしclassNameのロード時にクラスがロードされて悪意のある静的コードブロックが実行されれば、防御を回避できるのではないか?という考えが浮かびました。これについては後述します。

0x03 IIOPプロトコルをシミュレートしたPOCの構築

JAVAプログラムで書かれたPOCにはネットワーク問題があり、ローカルのweblogicサービスに対しては正常に動作しますが、dockerコンテナや外部ネットワークのマシンに対しては動作しません。この問題を指摘した分析記事:

手把手教你解决Weblogic CVE-2020-2551 POC网络问题

漫谈 WebLogic-CVE-2020-2551

以下、POCのデバッグについて。前述のremoveのものを参考にするか、Y4erのものを参考にしてください。前述の2つの記事では、2つの解決方法が提案されています:

  • weblogic.jarパッケージを変更して再パッケージ化する
  • IIOPプロトコルをシミュレートする

両方を試しました。weblogicを再パッケージ化すると、java.lang.NoSuchMethodError: weblogic.security.subject.SubjectManager.installCESubjectManager というエラーが発生しましたが、解決策は見つかりませんでした。

そこで、IIOPプロトコルのシミュレーションを試みました。まずPOCでブレークポイントを設定してデバッグします。

new InitialContext(env)の際、EndPointImpl.sendReceive()内で2つのパケットが送受信されていることがわかりました。

LocateReplyにはIOR情報が含まれています。IORとは何かを理解する必要があります。その役割は、RMI-IIOPクライアントがIIOPプロトコルを使用してサーバーサイドのオブジェクトと通信する際に、IIOP通信に必要なホストとポート、および赤枠の部分のObject_keyを提供することで、サーバーサイドの異なるオブジェクトを区別することです。

IIOPプロトコルをシミュレートする際に注目すべき重要な点は、Object_keyです。ホストとIPは実際には影響しません。以前テストを開始したときは、すべてのパケットをそのまま再送信していましたが、resolve_anyを送信するとlocation forwardが返ってきました。

GIOPの公式ドキュメントでは、location forwardについて、Object_keyが変化する可能性があることが説明されています。リクエストごとに返されるObject_keyが異なる可能性があります(ここで言うObject_keyはデータパケット内のkey addressです)。このObject_keyは、前述したように、IIOPプロトコルでどのオブジェクトと通信するかを区別するために使用され、LocateReplyから動的に取得する必要があります。

最終的に、remove()をシミュレートするのではなく、bind()メソッドによって発行されるIIOPリクエストをシミュレートすることを選択しました。リクエストが少ないため、ローカルで正常に利用されるデータパケットを確認します。

LocateRequestを送信し、dataを受信して、正規表現でLocateReply内のkey addressを取得します。

悪意のあるjrmpサーバー(rmi://...)のアドレスを手動で設定し、1秒間隔でbind_anyパケットを送信します。ここでの利用チェーンはDGCClientではなくjrmplistenを介してjrmpリクエストを発行するため、JEP290の影響を受けず、jrmplistenを使用して悪用できます。

POCはdocker環境でテスト成功しました。vulhubのこのSSRF環境を使用し、IPをホストマシンに設定すると、dockerはホストマシンのjrmpリクエストを正常に取得します。具体的なコードはGithubにあります。

0x04 推測の検証

前述の通り、codebaseを使用してリモートコードをロードすることで検出を回避するアイデアがあります。JNDI攻撃を研究したことのある方なら、codebaseを使用してリモートクラスの場所を指定できることをご存知でしょう。codebaseが制御可能で、プログラムがリモートからのクラスロードを許可している場合、リモートの悪意のあるクラスをロードし、静的コードブロック内の悪意のあるコードを実行できます。

コードを読むと、weblogic.iiop.Utils.lodaClass()の2番目の引数はcodebaseを表し、この引数はIIOPInputStream.read_value()で読み取られ、var8パラメーターとなります。1659行目でreadIndirectingRepositoryId(var8)が呼び出され、最終的にweblogic.iiop.Utils.lodaClass()が呼び出されます。1644行と1659行のコードを実行するには、(va4r & 1)=1、(va4 & 6)=2である必要があるため、var4の値は3でなければなりません。

readIndirectingRepositoryIdからgetClassFromIdへの呼び出しスタックを見ると、最終的に304行目のloadclass()が実行されます。

bind_anyデータパケットを見ると、GIOP HeaderとGIOP Requestで構成されています。GIOP Requestには、key address(LocateReply内のものと一致)、ServiceContextList、stub_dataが含まれています。var4の値はstub_data内の\x7f\xff\xff\x02であるため、(va4r & 1)=0、(va4 & 6)=2となり、1644行目のcodebase設定コードは実行されません。

そこで、最初の枠の\x7f\xff\xff\x02を\x00\x00\x00\x03に変更し、2番目の枠にcodebaseの長さと値の情報を追加します。具体的なコードはGithubにあります。さらに、アライメント操作も行われていることがわかります。これは落とし穴です。後続のクラス情報を読み取る前に、次のバイトの位置が4の倍数であるかどうかがチェックされ、倍数でない場合は一部のビットが無視されます。例えば、次のバイトの位置が1の場合、3バイトが無視され、位置4のバイトから読み取りが開始されます。この位置はbind_anyパケット全体に対する相対位置です。ここでバイト数が4の倍数でない場合は、0で埋める操作を行います。

もう一つ問題があります。先ほどreadIndirectingRepositoryIdからgetClassFromIdへの呼び出しスタックを見ると、途中でfindClassInfo()関数を通過します。ここで、クラスが既にロードされている場合、クラスID情報は保存され、findClassInfo()はクラス情報を直接返し、weblogic.iiop.Utils.getClassFromID()関数には入りません。

そのため、テスト時には毎回クラス名を変更する必要があります。

ともあれ、最終的にはIIOPプロトコルのシミュレーションに成功し、codebaseの値を変更し、weblogic.iiop.Utils.getClassFromId()関数を実行することができました。

残念ながら、RMIURLClassFinderの取得時にNULLが返され、RMIEnvironment.getEnvironment().isNetworkClassLoadingEnabled()関数はfalseを返しました。

原因は、ServerMBeanImplの_NetworkClassLoadingEnableパラメータの値がFalseであることです。

どのweblogic設定ファイルでこのパラメーターが設定されているか調べようとしましたが見つかりませんでした...

まとめ

この脆弱性を学習する過程で、Javaの逆シリアル化、RMI、JNDIなどの多くの前提知識が必要であることがわかりました。関連する学習については、この記事シリーズを参照してください。最後にcodebaseを変更しての悪用は失敗しましたが、多くの収穫がありました。

ツールをダウンロード