このバグはどれほどユニークですか?
より洗練され、よく研究された試みが背後にありますか?偶然ですか?以下の記事は「UDPへの継続的なストリーム」と述べています。どのストリーム?ゼロのたった1時間の流れ?ゼロの1601バイトパケットの1.000.000PS?
このバグに関して提供された情報のうち、「誤って発見された」ように見えます。この問題は、サービスのないポートに関連していると説明されています(本当にリスクになる可能性がありますか?)。また、このバグはTCP/IPバグとして表示されますが、Windows 8/Server 2008/Windows VistaFWにのみ影響します。
それは本当にTCP/IPのバグですか?
または、「これはTCP/IPのバグです」という、より複雑なアプローチでカバーされているFWのバグですか。 TCP/IPがMicrosoftにバンドルされていないため、技術者をより満足させるには?
バグ修正に関する記事 (MS自身の情報ではなく)。
Microsoft自身の情報 はこの問題をかなり説明しています。これは、参照カウンターのオーバーフローの脆弱性です。非常に簡単に言えば、次のようなコードがあると想像してください。
size_t num_of_connections = 0;
これが接続数を追跡する方法ですが、size_t
のサイズには制限があるという事実にも対処する必要があります。 size_t
に1を追加し続けると、最終的に整数値が「オーバーフロー」します。その時点で何が起こるかは、データの符号によって異なります。
すべてのレジスタが4ビットであると少しの間言います。これはお使いのPCには当てはまりませんが、数字は機能し続けます。したがって、単一のレジスタに保持できる符号なしの最大値は1111 = 15
になります。 15+1
を実行するとします。答えは10000 = 16
ですが、それは4ビットレジスタに収まりません。起こり得ることが2つあります。標準のx86add
命令を使用する場合、その余分な1
はただ深淵に落ち、二度と見られることはありません。したがって、プログラムによる結果は15+1 = 0
になります。 adc
を使用している場合、結果は同じですが、キャリーフラグが設定され、次のadc
も結果に1
を追加します。利益のために、Cはadc
を使用したりキャリーフラグを使用したりしません。
さて、もう1つの方法は、符号付きの値を使用することです。この場合、正の最大値は0111 = 7
であり、負の最大値は1111 = 8
です(2の補数を使用)。 1から7を追加しても、オーバーフローが発生するため、0111+1 = 1000
は、7+1 =-8
を意味します。
問題は、これが発生することではありません-表示される可能性のある値のセットに基づいてコードで仮定を行い、オーバーフローの場合を処理しないことです(もちろん、オーバーフローによって例外やエラーが発生することはありません)まったく-それはただ起こります)。減算も問題になる可能性があります。この場合、逆に「オーバーフロー」したために、小さな値から大きな値に移動します。このトピックに関する phrack article は、非常に興味深い読み物であることがわかるかもしれません。
それで、あなたの質問に答えるために、私は詳細を知りませんが、 バグは古いパケットが送信された結果だと思います 下のコメントで爆発が発生する前に...バグはおそらく古いパケットが送信されたことが原因である可能性がありますが、クラッシュを引き起こす可能性があります。実際にそれを悪用するには、ペイロードを取得する方法が必要です。つまり、クラッシュで何が起こるかを制御します。そこで、パケットを慎重に選択することが重要になります(Hendrik、+ 1に感謝)。ここで使用されているrefカウンターがオーバーフローするのに十分な数です。これは独特の脆弱性ですか?実際にはそうではありません-これは既知の問題です。 UDPとTCPは異なるものであるため、TCPのバグではありません。MicrosoftのTCP/UDPスタックでのUDPパケットの処理のバグです。サービスがリッスンしていないポートの処理はまだです。セキュリティリスクの潜在的な領域-OSはこれらのパケットを正しく拒否し、そのようなパケットの潜在的なフラッドを処理する必要があるためです。
独自のコードでこのような問題を軽減するには、 整数に関するCERT-Cガイドラインからのアドバイス 、特に INT03-C が役立ちます。
この脆弱性により、攻撃者が特別に細工したUDPパケットの継続的なフローをターゲットシステムの閉じたポートに送信した場合に、リモートでコードが実行される可能性があります。 https://technet.Microsoft.com/en-us/security/bulletin/ms11-08
したがって、すべてのビットがゼロに設定された大量のUDPパケットがクラッシュする可能性はありますが、コードが実行される可能性はほとんどありません。問題を悪用するために特別に作成されたコンテンツを含める必要があります。
同じMicrosoftの情報源によると、これは参照カウンターのオーバーフローです。
プログラムがメモリのブロックを割り当てるとき、参照カウンタを使用してそれを管理できます。プログラムコードの一部がそれにアクセスしたいときはいつでも、カウンタはインクリメントされます。コードのこの部分がメモリブロックの処理を完了するたびに、カウンタがデクリメントされます。カウンタが0に達すると、誰もメモリブロックに関心がなくなり、解放されます。
整数は、カウントに使用される数値です。コンピュータのメモリ内のサイズは固定されています。たとえば、32ビットまたは64ビット。したがって、整数とは異なり、数学からわかるように、可能な最大数があります。その数に1を加えると、非常に負の数になるか、0になります。
つまり、1を何度も追加すると、0になります。
参照カウンターの脆弱性は通常、参照カウンターのデクリメントに失敗したプログラムパスによって引き起こされます。したがって、攻撃者はカウンタを何度もインクリメントすることができます。
その結果、彼はカウンターを0以上にすることができます(前のセクションを参照)。カウンターがオーバーフローして再び1になった後、カウンターをデクリメントする通常のプログラムパスをトリガーします。
カウンタが0に達した。0は、メモリブロックに誰も興味がなくなったことを意味するため、解放されます。
UDPポートでリッスンしているサービスがない場合、カウンタのデクリメントに失敗したプログラムパスが使用されます。
この問題を悪用するための最終的なデクリメントには、開いているUDPポートが必要であると簡単に結論付けることができます。ただし、Microsoftはこれについて言及していません。さらに、彼らは、Windowsファイアウォールはこのバグに対する保護を提供しないと述べました。したがって、結論はおそらく間違っています。
メモリを解放するとは、「使用可能」としてマークされることを意味します。したがって、メモリのブロックを要求する他の誰かがそれを取得する可能性があります。しかし、元のプログラムはまだ考えており、ブロックを所有しており、必要に応じて使用できます。
したがって、2つのプログラムが、お互いを認識せずに同じメモリブロックを使用することになります。これは明らかにデータの不整合につながります。
少しの不運と特別な細工で、このプログラムの1つが他に悪いことをするかもしれません。他のプログラムがプログラムコード、プログラムコードへのポインタ、または信頼できるデータを格納していると想像してください。これにより、このメモリブロックにプログラムコードへのポインタが格納されます。
はい。悪用するのは簡単ではなく、低速のインターネット接続を介してこのような大量のUDPパケットを送信することに注意する必要があります。しかし、パッチを適用する必要があるのは実際の問題です。