
ProFTPD 1.3.9d - 高 - リモート - クラッシュ - RewriteMap int:utf8trans BSS オーバーフロー
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
解説記事: https://abraxaslabs.tech/research/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 が発生します。セッション子プロセスはアボートします。デーモンは稼働し続けます。クラスはクラッシュです。RCE ではありません。
| ID | CVE 未割当 |
| クラス | クラッシュ |
| 到達性 | リモート(FTP 引数が int:utf8trans に渡される) |
| 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 ではない。 |
.ftpaccess による RewriteMap の設置 | CONF_DYNDIR | クローズ。 RewriteMap は .ftpaccess では許可されない。 |
prg: シェル | そのようなマップ型は存在しない | クローズ。 FIFO は行単位の I/O である。 |
ラボで実証済み vs 推測: ASan のサイズ 8 の WRITE、セッション子プロセスのアボート、短い引数の対照が正常に処理されること、トリガー後のログインはラボで実証済みです。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 バイトごとに unsigned long を 1 つ書き込み、上限はありません。PR_TUNABLE_CMD_BUFFER_SIZE は 512 KiB です。Issue 2173 ではすでに unescape が修正されています。このマップはその修正には含まれていませんでした。
誤った方向性:2173 をこのバグと同一視すること。ASan がサイズ 8 の WRITE と報告したため RIP だと主張すること。.ftpaccess で RewriteMap を仕込めると期待すること。1 つ目は別の関数です。2 つ目は依然として Crash です。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 はサイズ 8 の ASan global-buffer-overflow WRITE となり、セッション子プロセスが異常終了する。トリガー後の新規ログインは引き続き機能する。
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 を参照してください。ループバックラボ専用です。保証はありません。