
VirtualBox 7.2.20 - 높음 - 로컬 - 파일 쓰기 - OVF href 대상 이스케이프
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-ovf-href-dest-escape
분류: 파일 쓰기 도달 범위: 로컬(호스트) UI:R
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
악성 OVF/OVA를 가져오는 호스트 사용자는 새 VM 폴더 외부에 디스크 이미지 바이트를 기록하게 된다. ovf:href가 대상 파일명이다. RTPathAbsExCxx는 RTPATHABS_F_STOP_AT_BASE를 사용하지 않는다. 고유 경로 헬퍼는 접미사 앞에 _%i를 삽입하며 basename을 제거하지 않는다.
| ID | 아직 CVE 없음 |
| 분류 | 파일 쓰기 (OVF/OVA 대상 경로) |
| 도달 범위 | 로컬(호스트) UI:R (피해자가 악성 어플라이언스를 가져옴) |
| CWE | CWE-22 |
| CVSS | 높음: 7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| 제품 | Oracle VM VirtualBox OSS |
| 영향 받음 | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| 인증 | VirtualBox에 대한 인증 없음. 호스트 사용자가 File/Import 또는 VBoxManage import를 연다. |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용. 소스 하네스. VirtualBox는 부팅되지 않음. |
OVF 디렉터리 또는 OVA를 전달한다. ovf:href에 ../somewhere/disk.vmdk 또는 절대 경로 /path/disk.iso를 넣는다. 이를 가져오는 운영자는 가져오는 UID로 해당 디스크 이미지 바이트를 CREATE_REPLACE 방식으로 기록하며, 존재하지 않았던 상위 디렉터리까지 생성한다. 접미사가 필요하다(vmdk / iso / 기타 MediumFormat 확장자). 이는 접미사 없이 authorized_keys를 떨어뜨리는 것이 아니다.
| 권한 | 방법 + 싱크 | 부여하는 것 | 출처 |
|---|---|---|---|
| 무결성 | IAppliance::read가 basename 제거 없이 File/href를 복사한다(ovfreader.cpp). Appliance::interpret()가 dest = di.strHref로 설정한다(ApplianceImplImport.cpp 802-851). | 대상 파일명은 공격자가 선택하며, ../ 및 절대 경로를 포함한다. | 랩 입증(상대 및 절대 href) |
| 무결성 | i_ensureUniqueImageFilePath(ApplianceImpl.cpp 1126-1160)가 RTPATHABS_F_STOP_AT_BASE 없이 RTPathAbsExCxx(strAbsName, aMachineFolder, aName)를 호출한다. 충돌 시 basename이 아닌 aName의 접미사 앞에 _%i를 삽입한다. | 고유 대상도 여전히 머신 폴더를 벗어난다. ../oracle/WITNESS.vmdk는 ../oracle/WITNESS_1.vmdk가 된다. | 랩 입증(unique-keeps-dotdot=yes) |
| 무결성 | 가져오기 시 i_importOneDiskImage가 다시 AbsEx를 호출한다(ApplianceImplImport.cpp 4169-4171). i_importCreateAndWriteDestinationFile(1043-1053)이 상위 디렉터리를 mkdir한 후 RTFILE_O_CREATE_REPLACE를 수행한다. | 디스크 이미지 바이트가 VM 폴더 외부에 기록된다. 절대 href는 머신 폴더를 무시한다. 대조군 disk.vmdk는 폴더 내에 유지된다. | 랩 입증(relative-escape=yes absolute-href=yes control-in-folder=yes) |
| 정찰 | 가져오기 마법사 / VBoxManage import --dry-run이 대상을 표시한다. | 경로가 보인다. 그 자체로는 비밀 유출이 아니다. | 추론 |
| 가용성 | 다른 VM의 디스크에 위치하는 상대 대상. | 가져오는 UID로 해당 파일을 덮어쓴다. | 추론(동일한 CREATE_REPLACE 쓰기) |
| 차단됨 | MediumFormat 접미사가 없는 대상 | 가져오기 시 has no extension이 발생한다. 접미사 없는 authorized_keys / crontab 쓰기가 아니다. | 차단됨 |
| 차단됨 | NVRAM 대상 | 머신 폴더 아래 {vmname}.nvram으로 강제된다. | 차단됨 |
| 차단됨 | VM 이름 .. | sanitiseMachineFilename이 이를 변형한다. | 차단됨 |
| 차단됨 | 공유 폴더 / ExtraData / 직렬 RawFile | vbox:Machine 경로에서 정리된다. | 차단됨 |
| 차단됨 | 호스트 커널, 게스트-호스트 | 이 잔여 문제가 아니다. VM 시작이 필요 없다. 가져오는 사람과 동일한 UID. | 차단됨 |
OVA는 깔끔한 경로입니다. tar 멤버가 바이트를 제공하고, href가 이스케이프된 dest를 제공합니다. 3D도, Guest Additions도, VRDP도, PUEL도 없습니다.
2026년 9월 CPU 이후 태그 v7.2.20(f2792cf44)에 머물며 OVF 가져오기를 읽었습니다. ExtraData, 공유 폴더, NVRAM dest, 시리얼 RawFile은 이미 제거되어 있습니다. 디스크 dest는 그렇지 않습니다. interpret()는 di.strHref를 HardDiskImage VBox 값에 그대로 복사합니다:
Utf8Str strFilename = di.strHref;
/* ... */
i_ensureUniqueImageFilePath(strMachineFolder, devType, strFilename);
pNewDesc->i_addEntry(VirtualSystemDescriptionType_HardDiskImage,
hd.strDiskId,
di.strHref,
strFilename,
di.ulSuggestedSizeMB,
strExtraConfig);
ApplianceImpl.cpp 1126-1160은 RTPATHABS_F_STOP_AT_BASE 없이 해당 이름을 머신 폴더 기준으로 완성한 다음, aName을 제자리에서 변경합니다:
int vrc = RTPathAbsExCxx(strAbsName, aMachineFolder, aName);
/* ... */
const char *pszSuffix = RTPathSuffix(aName.c_str());
offDashNum = pszSuffix ? (size_t)(pszSuffix - aName.c_str()) : aName.length();
aName.replace(offDashNum, cchDashNum, szTmp, cchTmp);
Import는 여전히 상대 경로인 dest에 AbsEx를 반복 적용하고(ApplianceImplImport.cpp 4169-4171) CREATE_REPLACE 방식으로 기록합니다. IPRT 테스트는 동일한 결합 방식을 문서화합니다. 절대 경로인 두 번째 인자가 우선하며, /VirtualBox/Machines에 ../VirtualBox.xml을 결합하면 /VirtualBox/VirtualBox.xml이 됩니다.
이미 기록된 잘못된 접근: 접미사 없는 authorized_keys 쓰기를 잔여물로 간주(import가 예외 발생); NVRAM dest(폴더 내부로 강제됨); VM 이름 ..(정규화기); 공유 폴더 / ExtraData / 직렬 RawFile(이미 정규화됨). 허구적 검증: 호스트 커널, 게스트에서 호스트로. 판별 기준은 머신 폴더 외부의 증인 라인과 제자리에 남아 있는 대조용 disk.vmdk입니다.
python3 vbox-ovf-href-dest-escape-Abraxas-Labs.py
또는
cd lab
./run.sh
interpret dest-join, unique-path 및 import CREATE_REPLACE 쓰기의 소스 하네스. Docker compose, loopback, VirtualBox 바이너리 없음. 머신 폴더 /work/Machines/ImportedVM. Oracle /work/oracle.
SUCCESS vbox-ovf-href-dest-escape relative-escape=yes unique-keeps-dotdot=yes absolute-href=yes control-in-folder=yes VBOX-OVF-HREF-DEST-ESCAPE-WITNESS
ovf:href가 dest가 되기 전에 basename을 제거하거나, RTPATHABS_F_STOP_AT_BASE를 전달하고(절대 경로 이름은 거부) RTPATH_PROP_DOTDOT_REFS를 거부한다. 고유 경로는 상대 문자열이 아니라 basename을 변경해야 한다.
f2792cf44f663989818507e36d3db5f978523c5e)ApplianceImplImport.cpp 802-851, 1043-1053, 4169-4171ApplianceImpl.cpp 1126-1160GNU Affero GPL v3.0. LICENSE를 참조한다. 루프백 실습 환경 전용. 보증 없음.