
writeup of CVE-2020-1362
WalletService исправил ошибки повышения привилегий в последний Patch Tuesday, одна из ошибок назначена CVE-2020-1362. Ошибка использует выход за границы (out-of-bound) в сервисе. Здесь мы делимся нашими методами эксплуатации.
Мы провели бинарный анализ следующих функций в walletservice.dll:
Функция SetGroup записывает управляемые пользователем данные в память по управляемому пользователем смещению.
signed __int64 __fastcall Wallet::WalletCustomProperty::SetGroup(__int64 this, int a2, int a3, int a4)
{
signed __int64 result; // rax
result = 0i64;
if ( a2 == 1 )
{
if ( a3 & 0xFFFFFFDF )
return 0x80070057i64;
}
else if ( a3 == 0x20 )
{
return 0x80070057i64;
}
if ( a4 == -1 )
{
*(_DWORD *)(this + 8i64 * a2 + 0x74) = 0;
*(_DWORD *)(this + 8i64 * a2 + 0x78) = 0x7FFFFFFF;
}
else
{
*(_DWORD *)(this + 8i64 * a2 + 0x74) = a3;
*(_DWORD *)(this + 8i64 * a2 + 0x78) = a4;
}
return result;
}
Можно заметить, что функция не проверяет диапазон смещения, которым может управлять пользователь. В этом и заключается уязвимость.
Теперь мы можем записывать данные за границы буфера. Наблюдая, можно заметить, что в том же классе есть функции для установки и получения BSTR:
Таким образом, мы можем легко изменить указатель на BSTR через oobw, чтобы получить возможность чтения и записи по произвольному адресу.
Получив WWW (write-what-where), мы можем записать vtable объектов Wallet::WalletCustomProperty в куче, чтобы управлять RIP. Сначала мы пытались изменить его напрямую с помощью oobw, но обнаружили, что oobw не выровнен по 8 байтам. Поэтому нам пришлось выполнить две записи для перехвата vtable, используя состояние гонки. Это могло сделать эксплойт нестабильным. Есть и другие способы обойти это. Однако в нашем POC мы просто используем другую уязвимость утечки информации (CVE-2020-1361), чтобы получить адрес кучи, и используем WWW для прямой записи vtable. Кстати, хотя CVE-2020-1361 помечена как уязвимость утечки информации, на самом деле она может быть использована для достижения EOP. Мы подготовим writeup для неё в будущем.
Мы нашли функцию ATL::CComObject<CDXGIAdapter>::vector deleting destructor`` в dxgi.dll, которая помогла нам перейти от выполнения произвольных функций к произвольному исполнению кода. Эта функция вызывает LoadLibraryExW и использует глобальный указатель в качестве первого параметра LoadLibraryExW. Затем мы можем добиться произвольного исполнения кода, загружая собственную DLL.
Пример POC приведен в директории POC.
С помощью этой уязвимости можно повысить привилегии с обычного пользователя до NT AUTHORITY\system.
Тестирование проводилось на Windows 10.0.18363.815, x64

Haoran Qin
Zhiniang Peng (@edwardzpeng) из Qihoo 360
10 апреля 2020: Уязвимость сообщена
21 апреля 2020: MSRC исследовала и подтвердила ошибку
14 июля 2020: Выпущено обновление
17 июля 2020: Опубликован writeup