
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 이름을 대상(dest)에 이어 붙인다. FsList::AddDirFromGuest는 정확히 .와 ..만 건너뛴다. GuestPath::Translate는 슬래시 스타일과 이중 슬래시 축약을 사용한다. BuildDestinationPath는 호스트가 지정한 대상 루트에서 RTPATH_PROP_DOTDOT_REFS를 거부할 뿐, 개별 항목 이름에서는 거부하지 않는다.
호스트가 시작한 디렉터리 copy-from에 ..가 포함된 이름으로 응답하는 게스트는 VBox UID 권한으로 대상 외부에 파일을 쓴다.
| ID | 아직 CVE 없음 |
| 분류 | 파일 쓰기 (호스트 대상 이탈) |
| 도달 범위 | 로컬(게스트) 혼동된 대리인. 호스트가 복사를 시작하고, 게스트가 파일 이름을 지정한다. |
| CWE | CWE-22 |
| CVSS | 높음: 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를 썼다. 내용은 게스트가 선택한다(파일 읽기 알림). |
정확히 .와 ..인 디렉터리 이름은 건너뛰며 쓰지 않는다. 이름에 ..가 포함된 파일은 저장되고 이어 붙여진다.
| 방법 | 싱크 | 권한 |
|---|---|---|
동일한 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 클라이언트) 그리고 호스트가 시작하는 디렉터리 copy-from이 필요하다. 3D 없음. VRDP 없음. PUEL 아님. 혼동된 대리인(confused-deputy): 호스트 사용자가 적대적인 게스트로부터 복사하는 경우.
VirtualBox/virtualbox v7.2.20(f2792cf44)을 고정했다. Guest Control 헌트 H04. 게스트에서 호스트로만. 공유 폴더 TOCTOU(P0 1037)는 다른 서비스의 형제 클래스이며 이 고정 버전에서는 닫혀 있다(어휘적 절대 경로화 후 RTPathStartsWith). Guest Control copy-from은 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에 이어 붙인 뒤 Translates만 수행합니다:
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. pin v7.2.20 peel 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-root 검사는 유지합니다. 그것만으로는 충분하지 않습니다.
f2792cf44f663989818507e36d3db5f978523c5e)GuestSessionImplTasks.cpp AddDirFromGuest (1195-1235), dest-root 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)