脆弱性が XNUMX つあります...

脆弱性が XNUMX つあります...

21年前の2019年XNUMX月XNUMX日 バグ報奨金プログラム Mail.Ru 非常に優れたものが HackerOne にやって来ました バグレポート から マクサール。 HTTP リダイレクトを返す Web メール API リクエストの 0 つの POST パラメータにゼロ バイト (ASCII XNUMX) を導入すると、初期化されていないメモリの部分がリダイレクト データに表示されます。この中には、GET パラメータと他のリクエストのヘッダーからのフラグメントが含まれています。同じサーバー。

これは重大な脆弱性です。なぜなら...リクエストにはセッション Cookie も含まれます。数時間後、ゼロバイトをフィルタリングする一時的な修正が行われました (後で判明しましたが、これでは十分ではありませんでした。CRLF / ASCII 13、10 を挿入する可能性がまだあったため、ヘッダーやヘッダーを操作できるようになります) HTTP 応答のデータ、これはそれほど重要ではありませんが、それでも不快です)。同時に、問題はセキュリティ アナリストと開発者に転送され、バグの原因を見つけて排除しました。

Mail.ru メールは非常に複雑なアプリケーションです。応答の生成には、オープン ソース (フリー ソフトウェア開発者の皆様に感謝します) と社内開発の両方の、多数の異なるフロントエンド/バックエンド コンポーネントが関与する可能性があります。 nginx と openresty を除くすべてのコンポーネントを除外し、呼び出す前に問題を特定することができました。 ngx.req.set_uri() 期待どおりに動作しなかった OpenResty スクリプト内 (ドキュメントによると、ngx_http_rewrite_module でリライトを使用して GET パラメーターを介して null バイトまたは改行を挿入すると、これが使用され、まったく同じように動作するはずと思われます)うまくいかない)。考えられる結果を排除し、可能な限り厳密にフィルタリングを追加し、考えられるすべてのベクトルを排除するためにフィルタリングが検証されました。しかし、メモリ内容の漏洩につながるメカニズムは謎のままでした。 XNUMX か月後、バグ レポートは解決されたとして閉じられ、バグの原因の分析は状況が改善されるまで延期されました。

OpenResty は、nginx 内で Lua スクリプトを記述できるようにする非常に人気のあるプラグインであり、いくつかの Mail.ru プロジェクトで使用されているため、問題は解決されたとはみなされていませんでした。そしてしばらくして、彼らは本当の理由と考えられる結果を理解し、開発者に推奨事項を作成するために、最終的にこの問題に戻りました。ソースコードの発掘に参加しました デニス・デニソフ и ニコライ・エルミシュキン。それは明らかになった:

  • nginx では、ユーザー データの書き換えを使用する場合、一部の構成でディレクトリ トラバーサル (およびおそらく SSRF) が発生する可能性がありますが、これは既知の事実であり、静的構成アナライザーによって検出される必要があります。 Nginx 増幅 и ジクシー Yandex から (はい、私たちもそれを使用しています、ありがとう)。 OpenResty を使用している場合、この機能は見落とされがちですが、これは構成には影響しませんでした。

    構成例:

    location ~ /rewrite {
        rewrite ^.*$ $arg_x;
    }
    
    location / {
        root html;
        index index.html index.htm;
    }

    結果

    curl localhost:8337/rewrite?x=/../../../../../../../etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...

  • Nginx には、書き換え行に null バイトが含まれている場合にメモリ リークを引き起こすバグがあります。リダイレクトが発行されると、nginx は行の全長に対応する新しいメモリ バッファを割り当てますが、ゼロ バイトが行終端文字である line 関数を通じて行をそこにコピーします。そのため、行はゼロまでしかコピーされません。バイト; バッファの残りの部分には初期化されていないデータが含まれます。詳細な分析が見られます ここで.

    設定例(^@ゼロバイト)

    
    location ~ /memleak {
        rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf";
    }
    
    location / {
        root html;
        index index.html index.htm;
    }

    結果
    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Location: http://localhost:8337/secret
    ...

  • Nginx は、サービス文字の挿入から GET パラメーターを保護し、書き換えで GET パラメーターのみを使用できるようにします。したがって、nginx のユーザー制御パラメータを介してインジェクションを悪用することはできません。 POSTパラメータは保護されていません。 OpenResty では GET パラメーターと POST パラメーターの両方を操作できるため、OpenResty 経由で POST パラメーターを使用するときに特殊文字を挿入することが可能になります。

    構成例:

    location ~ /memleak {
        rewrite_by_lua_block {
            ngx.req.read_body();
            local args, err = ngx.req.get_post_args();
            ngx.req.set_uri( args["url"], true );
        }
    }
    
    location / {
        root html;
        index index.html index.htm;
    }
    

    結果:

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{...может содержать secret...}
    ...

さらなる反応

この問題は nginx と OpenResty の開発者に報告されましたが、開発者はこの問題を nginx のセキュリティ バグとは考えていません。 nginx 自体では、特殊文字を挿入してエラーを悪用する方法はありません。修正してください 記憶の開示 16月4日に出版されました。レポートから 18 か月間、OpenResty には変更が加えられていませんでしたが、ngx.req.set_uri() 関数の安全なバージョンが必要であるという理解はありました。 2020年21月XNUMX日 情報公開、XNUMX月XNUMX日 OpenRestyリリース バージョン1.15.8.3これにより、URI 検証が追加されます。

ポートウィガー написал これは良い記事であり、OpenResty と Nginx からのコメントを取り入れています (ただし、メモリの小さな断片だけが公開されているというコメントは不正確で誤解を招きますが、これは null バイトに続く行の長さによって決まります。また、明示的な制限がない場合は、長さは攻撃者によって制御可能です)。

では、何が間違いだったのでしょうか?また、それを防ぐために何ができるでしょうか?

nginxにバグがあったのでしょうか? はい、そうでした。メモリ内容のリークはいずれにしてもエラーだからです。

OpenRestyにバグがあったのでしょうか? はい、少なくとも OpenResty が提供する機能のセキュリティの問題は調査も文書化もされていません。

OpenRestyの設定や使用に誤りはありませんか? はい、明示的な記述がないため、使用されている機能のセキュリティについて未検証の仮定がなされたためです。

次のバグのうち、10000 ドルの報奨金が課せられるセキュリティ脆弱性はどれですか? 私たちにとって、これは通常は重要ではありません。どのようなソフトウェアでも、特に複数のコンポーネントが交差する部分、特に異なるプロジェクトや開発者によって提供されるコンポーネントでは、その作業のすべての機能が既知で文書化されており、エラーがないことを保証できる人は誰もいません。したがって、セキュリティ上の脆弱性は、まさにセキュリティに影響を与える場所で発生します。

いずれの場合も、明示的な指示があり、その必要がないことが明確に理解されている場合を除き、外部モジュール/API に入力される入力データを可能な限り正規化または制限/フィルター処理することをお勧めします。

正誤表

経験から 前の記事、言語の純粋性を保つために:

バグ報奨金 — 虫探しコンテスト
バグレポート - エラー通知
リダイレクト - リダイレクト
オープンソース - オープンソース
正誤表 - 間違いに取り組む

出所: habr.com

コメントを追加します