「Game of RARs」 - WinRAR の新しいリモート コード実行の脆弱性の概念実証調査
- 500 億人を超えるユーザーを抱える WinRAR は、新たな脆弱性 (CVE-2023-40477、CVE-2023-38831) に直面しています。
- 本日は、CVE-2023-40477 の PoC を初めて紹介します。
- RCE は悪用可能であると考えられていますが、多くの理由からその実装は有望ではありません。
- ここでは、このテクノロジーの影響、悪用可能なシナリオ、緩和策などの包括的な調査を紹介します。
- この脆弱性は最近の WinRAR v6.23 で修正されており、ここでは代替の緩和策も提供しています。
CVE-2023-40477: 技術概要と概念実証
8 月 2 日、Winrar 6.23 が更新され、深刻な脆弱性に関するいくつかの漠然とした警告が追加されました。
私たちが知っていることは、次の図に示すように、脆弱性 (CVE-2023-40477) が修正されたということです。
BinDiff、IDA、メモ帳を備えているので、詳しく見てみましょう。
バイナリファイルを比較する
v6.23 で脆弱性が修正されていることがわかっているので、修正前と修正後のバージョンを見つけて観察してみましょう。winrar-v6.22 および winrar-v6.23:
winrar.exe は単なる GUI であることがわかりますが、解凍時のバグであれば、「unrar.exe」にも存在する可能性があります。6.23 と 6.22 を比較すると、次のような違いがあります。
6.23 では、フローチャートを見ると、興味深い追加がいくつかありました (大きな関数図では、主要な部分の抜粋のように見えます)。
よく見ると、これらは追加の小切手であるように見えます。
これは期待できそうです!ここでは、var < 255 に関する追加のチェックがいくつか見られます。興味深いことに、ここにはオーバーフローチェック権限があるようです。
そこで、トリガーを実行します (つまり、バイトを最大値に変更します)。
RAR 形式について調べたところ、説明からこれが RAR4 (vol3?) リカバリ ボリュームに関連していることがわかったので、
これらのプロパティを使用して RAR4 を生成すると、次のようなファイルのリストが得られました。
- RAR ファイル.RAR
- RAR_ファイル.r00
- RAR_FILE00.rev バージョン
- RAR_ファイル.r01
- RAR_FILE01.rev版
「.rev」および「rXX」ボリューム内の「バイトのような」値の内容を強制的に削除しようとしましたが、成功しませんでした。それは何も引き起こしたり変化させたりしません。
次に、「unrar」ソース コードをグーグルで調べてみました。おそらく、他のプロジェクトの一部として存在しているのではないでしょうか? !
そこで私はこの古いリポジトリを見つけることに成功しました: https://github.com/aawc/unrar
ソース コードを見ると、特に"recvol3.cpp"に複数の "255" 定数が選択されていることがわかります。これはオリジナルにも表示されています。 6.22 ソース コードなので、オーバーフローのために余分なソース コードが追加された可能性がありますか?
もう少し詳しく調べてみましょう。セキュリティ チェックが実際には 0xff/255 に関連していることがわかりました。
抜け穴
ここで、P[i] は「.rev」ファイル自体から抽出されます。これらはファイルの最後にあります。
これらのP[i]は、それらがどの回復ボリュームを表すか、およびどのFileNumber に適合するかを決定するために使用されます。
FileNumberもP[2]で取得されます。
その直後に、File* が割り当てられ、サイズ 256 の制御する配列のインデックスに配置されます。(241行目)。
255 のチェックについて説明します。
インデックスは実際にはP[2]+P[0]-1に等しいためです。「rev」ボリュームの内容を介してほぼ任意に制御できます。
したがって、結局のところ、そのバッファをポインター (ファイル構造を指す) で上書きすることができ、現在のオブジェクト内の次のプロパティが上書きされます。
実証実験
この脆弱性を引き起こすには、recvol3.cpp で「Restore()」を呼び出す必要があることがわかりました。
また、再構築手順が必要であることもわかりました。そのため、その一部はポインタを上書きすることによって実行されます。
これを行うには、欠落している rar ボリューム (.r00 が欠落) と .rev ボリュームが利用可能である必要があります。
さらに、crc32 チェックサムが正しいことを確認する必要があります。
便宜上、GUI を使用してオリジナルの rar4 リカバリ ボリュームを生成しました。このボリュームは確実に小さく効率的であり、最大で 2 ~ 3 個のファイルが含まれる可能性があります。
# 1. re-generate malformed recovery vols.
data = open('%s01.rev' % ARCHIVE_NAME, 'rb').read() # just use the first and malform it up.
names = ['%s%s.rev' % (ARCHIVE_NAME, str(i).zfill(2)) for i in range(256)]
# "destroy" the P[i]'s
datas = [data[:-7] + bytes([0xf0, 0x00, i]) + calc_crc(data[:-7] + bytes([0xf0, 0x00, i])) for i in range(256)]
# 2. overwrite malformed recovery vols.
for i in range(256):
fname = names[i]
data = datas[i]
open(fname, 'wb').write(data)
ただし、 rar-labs Web サイトではCVE-2023-40477 脆弱性も確認されており、これはおそらく私たちの調査結果を裏付けるものです。
次の状況で winrar/unrar をクラッシュさせることに成功しました。
1. Memset は無効なメモリをゼロで上書きします (おそらくバッファの後)。
「extract to」を使用すると、winrar.exe でヒープ オーバーフローが発生する可能性があります。
可用性
悪用可能性を判断するために、256 配列の後に取り上げた構造を見てみましょう。
攻撃者がこのプリミティブを使用して RCE を取得する方法と、どのような軽減策が存在するかを判断してみましょう。
// RecVolume3 struct - that gets overflowed
class RecVolumes3
{
private:
File *SrcFile[256]; // overflow in here with File* pointers.
Array Buf;
#ifdef RAR_SMP
ThreadPool *RSThreadPool;
#endif
public:
RecVolumes3(CommandData *Cmd,bool TestOnly);
~RecVolumes3();
void Make(CommandData *Cmd,wchar *ArcName);
bool Restore(CommandData *Cmd,const wchar *Name,bool Silent);
void Test(CommandData *Cmd,const wchar *Name);
};
...
...
// Array template class:
template class Array
{
private:
T *Buffer;
size_t BufSize;
size_t AllocSize;
size_t MaxSize;
public:
Array();
Array(size_t Size);
Array(const Array &Src); // Copy constructor.
~Array();
ここでは、「File*」ポインタを使用して、「Buffer」オブジェクトをオーバーフローさせます。
幸いなことに、ASLR、CFG、Stack-Cookie、DEP など、多くの保護機能が導入されています。
また、winrar バージョン間のバイナリの違いについても触れられていません。これらはすべて悪用を可能にしますが、一般的な脅威アクターによる悪用は考えられません。
影響
CVE 評価が高いにもかかわらず、悪用を成功させるために必要な複雑さは、広く悪用されている Log4j RCE 脆弱性とは異なり、広範囲に悪用される可能性が低いことを示唆しています。
興味深いことに、Chromium は unrar ライブラリも利用しているようです: https://chromium.googlesource.com/chromium/src//6ff23b0604e2edbe7ef282564ea340f5c72ab91a^/
unrar ライブラリがサードパーティの依存関係として Chrome OS に組み込まれたと考えられますが、その使用方法を示すコード参照はありません。
緩和
緩和戦略に関しては、考慮すべき実行可能なオプションがいくつかあります。
- 完全な修正: Winrar を 6.23 以降に更新すると、問題は完全に修正されます。
- 修正: アップデートが利用できない、または展開が難しい場合は、*.rev ファイルをブロックします (*.rXX ファイルと *.partXX.rar もブロックすることが望ましい)。これは簡単な修正である可能性がありますが、完全に確認されておらず、公式でもありません。
プロジェクトのダウンロードを完了する
[CSDNダウンロード] https://download.csdn.net/download/qq_39190622/88291093
テスト方法は?
独自の PoC を生成することも、付属のデモ RAR ファイル (解凍後に winrar-6.22 がクラッシュすることが確認されている) をテストすることもできます。
- PoC 生成 -
cve_2023_40477_poc.py
- デモ RAR ファイル - ディレクトリ
Rar.rar
からのみ抽出します示例 poc_after_gen
。