
ProFTPD 1.3.9d - 高 - リモート - クラッシュ - RewriteMap int:utf8trans BSS オーバーフロー
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
クラス: クラッシュ 到達性: リモート
ProFTPD 1.3.9d (f59f248) - ProFTPD (proftpd.org)
contrib の mod_rewrite には RewriteMap int:utf8trans が同梱されています。このビルトインは、クライアントの FTP 引数(最大 CommandBufferSize、512 KiB)を、宛先の上限なしで 2 つの 1024 スロット BSS バッファにコピーします。長い ASCII の STOR 名は、サイズ 8 の ASan global-buffer-overflow WRITE となります。セッション子プロセスは abort します。デーモンは稼働し続けます。クラスはクラッシュ。RCE ではありません。
| ID | CVE はまだなし |
| クラス | クラッシュ |
| 到達性 | リモート(int:utf8trans に渡される FTP 引数) |
| CWE | CWE-120 |
| CVSS | High: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H(RewriteRule が認証前の場合)。ラボではログイン後の STOR を使用したため、その実行では PR:L が正直です(AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H)。 |
| 製品 | ProFTPD |
| 影響を受けるバージョン | 1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_rewrite |
| 認証 | ラボは認証済み STOR。USER などに対する認証前の RewriteRule であれば PR:N となります。 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
RewriteEngine は設定するまでオフです。文書化されているパターンは RewriteRule (.*) ${map:$1} です。RewriteRule がクライアント引数を int:utf8trans に通すと、1024 バイトを超えるキーがセッション子プロセス内の 2 つの静的バッファをオーバーフローさせます。
| 手法 | シンク | 権限 |
|---|---|---|
| 引数が utf8trans マップキーである FTP コマンド、長さ > 1024 | rewrite_utf8_to_ucs4 の後に utf8_val[i] = ucs4_longs[i] | 可用性(ラボで実証): セッション子プロセスをクラッシュさせる。ASan: global-buffer-overflow WRITE of size 8、その後 ABORTING。prefork: 新規ログインはまだ機能し、デーモンは稼働し続けた。200 ASCII バイトの短い STOR は生き残った。近傍の rewrite BSS の完全性は推測であり、コンパイラのレイアウトに依存する。 |
| RIP / コード実行 | 主張なし | クローズ。 ペイロードなし。クラスはクラッシュ。RCE ではない。 |
RewriteMap の .ftpaccess 設置 | CONF_DYNDIR | クローズ。 RewriteMap は .ftpaccess では許可されていない。 |
prg: シェル | そのようなマップタイプはない | クローズ。 FIFO は行 I/O である。 |
ラボで実証済み vs 推測: サイズ 8 の ASan WRITE、セッション子プロセスの abort、短い引数の対照が生き残ること、トリガー後のログインはラボで実証済み。RIP/RCE は主張していない。
Issue 2173 はこのピンで int:unescape の 1 バイト OOB にパッチを当てた。この残存は int:utf8trans である。別のビルトイン。別のバグ。
proftpd/proftpd のタグ v1.3.9d をピン留めした。2026 年の CVE の山と、その tarball にまだ残っている公開 GitHub issue(2170、2173、2175、2180、2095、2256、2286、2319、2330、2301)はスキップリストとした。サンプルの basic.conf を使ったデフォルトのコア FTP では、未公開の Crit/High は得られなかった。contrib の rewrite がそれを与えた。
rewrite_map_int_utf8trans(contrib/mod_rewrite.c)には次がある:
static unsigned char utf8_val[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
static unsigned long ucs4_longs[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
ucs4strlen = rewrite_utf8_to_ucs4(ucs4_longs, strlen(key), (unsigned char *) key);
rewrite_utf8_to_ucs4 は ASCII バイトごとに 1 つの unsigned long を上限なしで書き込む。PR_TUNABLE_CMD_BUFFER_SIZE は 512 KiB である。Issue 2173 はすでに unescape を修正している。このマップはその修正には含まれていなかった。
誤った道: 2173 をこのバグとみなすこと。ASan が WRITE of size 8 と言ったからといって RIP を主張すること。.ftpaccess が RewriteMap を設置できると期待すること。1 つ目は別の関数である。2 つ目は依然としてクラッシュである。3 つ目は CONF_DYNDIR である。
ASan と標準の libcrypt は、rewrite シンクの前に PASS で SIGSEGV する。ラボでは、ログインが機能するように小さな crypt(3) スタブをプリロードしている。そのスタブはエクスプロイトではない。
python3 proftpd-rewrite-utf8trans-Abraxas-Labs.py
または:
cd lab
./run.sh
ループバック 127.0.0.1:18740 とパッシブ 18741-18750。Compose プロジェクト proftpd-rewrite-utf8trans。ウィットネス PROFTPD-REWRITE-UTF8TRANS-WITNESS。イメージは 1.3.9d mod_rewrite の ASan ビルドである。200 ASCII バイトの対照 STOR は成功する。2048 ASCII バイトの STOR は ASan global-buffer-overflow WRITE of size 8 となり、セッション子プロセスは abort する。トリガー後の新規ログインはまだ機能する。
SUCCESS PROFTPD-REWRITE-UTF8TRANS asan=global-buffer-overflow write=yes child-dead=yes PROFTPD-REWRITE-UTF8TRANS-WITNESS
rewrite_utf8_to_ucs4 の宛先長を PR_TUNABLE_BUFFER_SIZE-1 に制限する。ucs4_longs / utf8_val を超えて書き込むのをやめる。収まらないマップキーを拒否または切り詰める。
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_rewrite.c rewrite_utf8_to_ucs4 / rewrite_map_int_utf8transint:unescapeGNU Affero GPL v3.0。LICENSE を参照。ループバックラボのみ。無保証。