VirtualBox 7.2.20 - 高 - ローカル - ファイル書き込み - Guest Control copy-from DOTDOT
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-guestctrl-copyfrom-dotdot
クラス: ファイル書き込み 到達範囲: ローカル(ゲスト)confused-deputy
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
ホストの IGuestSession::directoryCopyFromGuest / VBoxManage guestcontrol copyfrom は、ゲストの DIR_NOTIFY 名を宛先に連結する。FsList::AddDirFromGuest は完全一致の . と .. のみをスキップする。GuestPath::Translate はスラッシュ形式に加えて二重スラッシュの圧縮を行う。BuildDestinationPath は、ホストが指定した宛先ルートに対して RTPATH_PROP_DOTDOT_REFS を拒否するが、エントリごとの名前に対しては拒否しない。
ホストが開始したディレクトリの copy-from に対して .. を含む名前で応答するゲストは、VBox UID として宛先の外にファイルを書き込む。
| ID | CVE 未割当 |
| クラス | ファイル書き込み(ホスト宛先の脱出) |
| 到達範囲 | ローカル(ゲスト) confused-deputy。ホストがコピーを開始し、ゲストがファイル名を指定する。 |
| CWE | CWE-22 |
| CVSS | High: 8.2 CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N |
| 製品 | Oracle VM VirtualBox OSS |
| 影響を受けるバージョン | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| 認証 | Guest Additions(または代替の HGCM クライアント)に加え、ホストが開始するディレクトリの copy-from |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ。ソースハーネス。VirtualBox は起動しない。 |
Guest Control は設計上、ホストからゲストへの方向である。本件の残存問題はその逆方向にある。ホストユーザーがゲストのディレクトリをコピーすると、ゲストは HOST_MSG_DIR_READ に対して GUEST_MSG_DIR_NOTIFY / GUEST_DIR_NOTIFYTYPE_READ の名前で応答する。Main はそれらの名前を宛先に連結して開く。
| 手法 | シンク | 権限 |
|---|---|---|
ホストの IGuestSession::directoryCopyFromGuest / VBoxManage guestcontrol copyfrom によるゲストディレクトリのコピー。ゲストの一覧名 ../oracle/VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS。 | CopyFrom::Run が strDstAbs = dest + native_sep + pEntry->strPath を実行し、続いて GuestPath::Translate、そして fileCopyFromGuest -> RTFileOpen(RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE)。 | VBox UID として宛先の外にホストファイルを作成/上書きする。ラボの宛先は /work/vbox-copy。ラボは /work/oracle/VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS に書き込んだ。内容はゲストが選択する(file-read notify)。 |
完全一致の . と .. というディレクトリ名はスキップされ、書き込みは行われない。名前に .. を含むファイルは保存され、連結される。
| 手法 | シンク | 権限 |
|---|---|---|
同じ copy-from。ホストの宛先が /tmp/vbox-copy / C:\Temp\vbox-copy のときに、ゲストが ../../../.ssh/authorized_keys(または DOS 形式の ..\..\...)を一覧に含める。 | 同じ連結 + RTFileOpen。 | その UID が書き込める任意のホストパスを作成または上書きする。ネストした --recursive の名前はさらに深く辿る。 |
ホストがすでに選択した宛先以外には何もない。ゲストはこの残存問題から追加のホストパスを学習しない。
VBox UID が書き込めるファイルの上書き。クラッシュを引き起こす残存問題ではない。CVSS A:N。
fileCopyFromGuest: 宛先は完全にホスト側で指定され、ゲストはそのパスにバイトを供給するだけ。AddDirFromHost はホスト側の一覧で . / .. をスキップする。/etc、他のユーザーのホーム)。HOST_MSG_* の注入。svcCall は GUEST_MSG_* のみをディスパッチする。guestCtrlValidateDirEntryEx 内のパスサニタイザ。このチェックは UTF-8/サイズの確認であり、.. の確認ではない。Guest Additions(またはセッションを所有する代替の HGCM クライアント)および ホスト起点のディレクトリコピー元が必要。3D は不要。VRDP も不要。PUEL でもない。混乱した代理(confused-deputy): ホストユーザーが敵対的ゲストからコピーする。
VirtualBox/virtualbox v7.2.20(f2792cf44)に固定した。Guest Control の調査 H04。ゲストからホストへの方向のみ。共有フォルダの TOCTOU(P0 1037)は別サービス上の同種のクラスであり、この固定バージョンではクローズ済み(字句的な絶対化の後に RTPathStartsWith)。Guest Control のコピー元は SHFL 名ではなく DIR_NOTIFY 名を連結する。
AddDirFromGuest はゲストの Name から strEntry を構築し、完全一致の . / .. のみをスキップする:
Utf8Str strEntry = strPathSub + Utf8Str(bstrName);
switch (enmObjType)
{
case FsObjType_Directory:
{
if ( bstrName.equals(".")
|| bstrName.equals(".."))
{
break;
}
vrc = AddDirFromGuest(strPath, strEntry);
break;
}
case FsObjType_File:
vrc = AddEntryFromGuest(strEntry, fsObjInfo->i_getData());
break;
}
CopyFrom::Run はその後、保存されたパスを dest に連結し、Translate のみを実行します:
strDstAbs += PATH_STYLE_SEP_STR(PATH_STYLE_NATIVE);
strDstAbs += pEntry->strPath;
vrc = GuestPath::Translate(strDstAbs, mSession->i_getGuestPathStyle(), PATH_STYLE_NATIVE);
/* directoryCreateOnHost / fileCopyFromGuest -> RTFileOpen WRITE|OPEN_CREATE */
GuestPath::BuildDestinationPath は「セキュリティ上の理由からドットドットディレクトリは禁止されている」と文書化し、RTPATH_PROP_DOTDOT_REFS を拒否します。この呼び出しは宛先ルートに対してのみ行われます(GuestSessionImplTasks.cpp:1685-1686)。エントリごとの名前がこれを通ることはありません。Translate(GuestCtrlPrivate.cpp:2129-2208)はスラッシュのスタイルを変更し、// を折りたたみます。.. を拒否することはありません。
すでに記録されている誤った道筋:正確な . / .. のスキップをパスサニタイザーとして扱うこと;Translate が正規化を行うと仮定すること;宛先ルートのチェックを各エントリに適用すること;ソースハーネスの代わりに VM を起動すること;これがホストカーネルエスケープであると主張すること;単一ファイルの copy-from 宛先または copy-to-guest を残存物として扱うこと。見せかけ:リバースシェル。オラクルは宛先外の証人ファイルです。
cd lab
./run.sh
Compose プロジェクト vbox-guestctrl-copyfrom-dotdot。ループバック 127.0.0.1:19220。ピン v7.2.20 のピール f2792cf44 のソースハーネス: 完全一致の . / .. のスキップ、GuestPath::Translate(スラッシュスタイルのみ)、CopyFrom::Run の dest+sep+entry 結合後の write/create、dest-root BuildDestinationPath の DOTDOT 拒否。VirtualBox や Guest Additions は起動しない。これをループバックにバインドする。
SUCCESS vbox-guestctrl-copyfrom-dotdot skip-dot=yes translate-keeps-dotdot=yes escaped-write=yes dest-root-check-unused-per-entry=yes VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS
結合された各 dest を GuestPath::BuildDestinationPath(または RTPathParse の RTPATH_PROP_DOTDOT_REFS、あるいは dest に対して RTPATHABS_F_STOP_AT_BASE を指定した RTPathAbsEx)に通してください。コンポーネントに .. を含むリスト名を拒否し、完全一致の . と .. だけに限定しないでください。dest ルートのチェックは維持してください。それだけでは不十分です。
f2792cf44f663989818507e36d3db5f978523c5e)GuestSessionImplTasks.cpp AddDirFromGuest (1195-1235)、dest ルート BuildDestinationPath (1685-1686)、CopyFrom::Run の結合 (1806-1849)、fileCopyFromGuest の RTFileOpen (684-693)GuestCtrlPrivate.cpp BuildDestinationPath (2067-2104) · Translate (2129-2208)GuestDirectoryImpl.cpp GUEST_DIR_NOTIFYTYPE_READ (523-561)GuestCtrlImplPrivate.h guestCtrlValidateDirEntryEx (1546-1559)