
Paracosme — это эксплойт удалённого повреждения памяти с нулевым кликом, который взламывает ICONICS Genesis64 и был успешно продемонстрирован на сцене во время конкурса Pwn2Own Miami 2022.
Paracosme — это эксплойт повреждения памяти, который я написал для атаки на пакет Genesis64 версии 10.97.1, созданный компанией ICONICS, для достижения удаленного выполнения кода.
Эксплойт был продемонстрирован в рамках конкурса Pwn2Own 2022 Miami, который проходил на конференции S4x22 Conference. Подробнее об этом можно прочитать в статье Участие в Pwn2Own ICS 2022 Miami: эксплуатация удаленного повреждения памяти в ICONICS Genesis64 без единого клика.
Проблема получила оценку 9.8 по CVSS, и ей был присвоен CVE-2022-33318 / ZDI-22-1041. Она была исправлена и была исправлена в Genesis64 10.97.2. Вы также можете прочитать рекомендации ICSA-22-202-04, а также технический документ ICONICS об уязвимостях безопасности ICONICS Suite.
Вы можете найти код эксплойта в src/paracosme.py, PoC для запуска аварийного завершения / проверки, затронуты ли вы, в src/paracosme-poc.py, и исполняемую на машине нагрузку в src/payload.
Лучший способ узнать, затронуты ли вы, — включить Page Heap для GenBroker64.exe, перезапустить службу, подключить отладчик к GenBroker64.exe, запустить paracosme-poc.py против вашего сервера — и вы должны увидеть аварийные завершения, как показано ниже:
Чтобы наблюдать аварийное завершение, необходимо подключить отладчик к целевому процессу, в противном случае приложение игнорирует его.
Эксплойт тестировался только в Windows, но также должен работать на платформах Linux:
impacket командой: pip3 install impacketsc config lanmanserver start=disabled и перезагрузите системуsmbserver.py (из примеров impacket) командой: python src\smbserver.py -smb2support x binpython src\paracosme.py --target <ip>
Для получения более подробной информации обратитесь к статье Участие в Pwn2Own ICS 2022 Miami: эксплуатация удаленного повреждения памяти в ICONICS Genesis64 без единого клика.
Paracosme эксплуатирует уязвимость использования после освобождения (use-after-free), найденную в процессе GenBroker64, для достижения удаленного выполнения кода в системе Windows 21H2 x64.
В общих чертах, процесс GenBroker64 прослушивает TCP-порт 38080 и может десериализовать различные пакеты после выполнения рукопожатия с клиентом. Ошибка, которую я нашел, находится в коде, который обрабатывает чтение VARIANT из сетевого сокета. По сути, вариант — это тип и значение. Функция на первый взгляд выглядит хорошо написанной и старается распаковывать только определенные типы. Вот как она выглядит:
bool CheckVariantType(VARTYPE VarType) {
if((VarType & 0x2FFF) != VarType) {
return false;
}
switch(VarType & 0xFFF) {
case VT_EMPTY:
case VT_NULL:
case VT_I2:
case VT_I4:
case VT_R4:
case VT_R8:
case VT_CY:
case VT_DATE:
case VT_BSTR:
case VT_ERROR:
case VT_BOOL:
case VT_VARIANT:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_I8:
case VT_UI8:
case VT_INT:
case VT_UINT:
case VT_HRESULT:
case VT_FILETIME:
return true;
break;
default:
return false;
}
}
size_t VariantTypeToSize(VARTYPE VarType) {
switch(VarType) {
case VT_I1: return 1;
case VT_UI2: return 2;
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_HRESULT:
return 4;
case VT_I8:
case VT_UI8:
case VT_FILETIME:
return 8;
default:
return 0;
}
}
void Utils::ReadVariant(tagVARIANT *Variant, Archive_t *Archive, int Level) {
TRY {
return ReadVariant_((CArchive *)Archive, (COleVariant *)Variant);
} CATCH_ALL(e) {
VariantClear(Variant);
}
}
HRESULT Utils::ReadVariant_(tagVARIANT *Variant, Archive_t *Archive, int Level) {
VARTYPE VarType = Archive.ReadUint16();
if((VarType & VT_ARRAY) != 0) {
// Special logic to unpack arrays..
return ..;
}
Size = VariantTypeToSize(VarType);
if (Size) {
Variant->vt = VarType;
return Archive.ReadInto(&Variant->decVal.8, Size);
}
if(!CheckVariantType(VarType)) {
// ...
throw Something();
}
return Archive >> Variant;
}
Функция сама реализует распаковку массивов, а также чтение простых типов вариантов, но если она получает что-то, что не относится ни к одной из этих двух категорий, она переходит к operator>> экземпляра архива. Этот экземпляр архива — объект, предоставляемый библиотекой Microsoft Foundation Class, которая обрабатывает сериализацию и десериализацию различных объектов. Этот код на самом деле с открытым исходным кодом, и вы можете найти его по пути C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\atlmfc\src\mfc\olevar.cpp, но вот он: