• XSS.stack #1 – первый литературный журнал от юзеров форума

[CVE-2023-29360] - обсуждение уязвимости в драйвере mskssrv.sys

varwar

El Diff
Забанен
Регистрация
12.11.2020
Сообщения
1 383
Решения
5
Реакции
1 537
Пожалуйста, обратите внимание, что пользователь заблокирован
Бага в технологии "Kernel Streaming", о которой мало что полезного можно найти, чтобы увязать с драйверами.

В mskssrv.sys есть интерфейс SrvDispatchIoControl для обработки ioctl-запросов. Есть прослойка в виде драйвера ksthunk, но это пока не важно.

Код:
3: kd> !devstack @rcx
  !DevObj           !DrvObj            !DevExt           ObjectName
  ffffaa8120ddda60  \Driver\ksthunk    ffffaa8120dddbb0  00000087
> ffffaa8120e54b70  \Driver\MSKSSRV    ffffaa8120e54cc0 
  ffffaa811f84bdd0  \Driver\swenum     ffffaa811f84bf20  KSENUM#00000001

Какие аргументы передаются в NtDeviceIoControlFile - загадка (у кого есть exReven - это не будет загадкой).

Код:
  3: kd> k
 # Child-SP          RetAddr               Call Site
00 ffffa48d`f426f5f8 fffff800`60da782c     MSKSSRV!SrvDispatchIoControl
01 ffffa48d`f426f600 fffff800`5accb875     ks!DispatchDeviceIoControl+0x3c
02 ffffa48d`f426f630 fffff800`63f31415     nt!IofCallDriver+0x55
03 ffffa48d`f426f670 fffff800`63f31133     ksthunk!CKernelFilterDevice::DispatchIrp+0xf5
04 ffffa48d`f426f6d0 fffff800`5accb875     ksthunk!CKernelFilterDevice::DispatchIrpBridge+0x13
05 ffffa48d`f426f700 fffff800`5b0c2c70     nt!IofCallDriver+0x55
06 ffffa48d`f426f740 fffff800`5b0c123c     nt!IopSynchronousServiceTail+0x1d0
07 ffffa48d`f426f7f0 fffff800`5b0bf516     nt!IopXxxControlFile+0x72c
08 ffffa48d`f426fa00 fffff800`5ae3d1e5     nt!NtDeviceIoControlFile+0x56
09 ffffa48d`f426fa70 00007fff`ad4aeee4     nt!KiSystemServiceCopyEnd+0x25
0a 00000019`e16ff758 00007fff`aad0bc5b     ntdll!NtDeviceIoControlFile+0x14
0b 00000019`e16ff760 00007fff`ac4727f1     KERNELBASE!DeviceIoControl+0x6b
0c 00000019`e16ff7d0 00007fff`9a3500f0     KERNEL32!DeviceIoControlImplementation+0x81
0d 00000019`e16ff820 00007fff`9a353542     frameservermonitor!FSMDeviceWatcher::InternalUpdateLoginTriggerToKs+0xe0
0e 00000019`e16ff880 00007fff`9a34a3f7     frameservermonitor!FSMDeviceWatcher::RegisterWatcher+0x402
0f 00000019`e16ffab0 00007fff`9a3496ad     frameservermonitor!FSMonitorService::ProcessWatcherObject+0x137
10 00000019`e16ffb00 00007fff`9d5b9b01     frameservermonitor!FSMonitorService::ProcessWatcherObjectAsyncCallback::Invoke+0xd
11 00000019`e16ffb30 00007fff`ad47299a     RTWorkQ!ThreadPoolWorkCallback+0xd1
12 00000019`e16ffbb0 00007fff`ad446056     ntdll!TppWorkpExecuteCallback+0x13a
13 00000019`e16ffc00 00007fff`ac48244d     ntdll!TppWorkerThread+0x8f6
14 00000019`e16ffee0 00007fff`ad46dfb8     KERNEL32!BaseThreadInitThunk+0x1d
15 00000019`e16fff10 00000000`00000000     ntdll!RtlUserThreadStart+0x28

В свою очередь, путь до уязвимой функции от SrvDispatchIoControl.

Код:
PAGE:00000001C0008520    SrvDispatchIoControl
PAGE:00000001C0009700    ?PublishTx@FSRendezvousServer@@QEAAJPEAU_IRP@@@Z
PAGE:00000001C000BB88    ?PublishTx@FSStreamReg@@QEAAJPEAUFSFrameInfo@@@Z
PAGE:00000001C000A314    ?AllocateMdl@FSFrameMdl@@QEAAJAEBUFSMemoryStream@@@Z
.text:00000001C0001650    FsAllocAndLockMdl

Устройства для этого драйвера нет, следовательно и символьной ссылки, по которой можно отправлять запросы, тоже. Очевидно, используются другие интерфейсы для взаимодействия. Вопрос, какие?
Ресерч по теме должен выйти в августе, но может кто-нибудь уже что-то подраскурил?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Бага в технологии "Kernel Streaming", о которой мало что полезного можно найти, чтобы увязать с драйверами.

если не ошибаюсь, оно для сканеров и камер...
Устройства для этого драйвера нет

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}

Есть прослойка в виде драйвера ksthunk



 
Пожалуйста, обратите внимание, что пользователь заблокирован
если не ошибаюсь, оно для сканеров и камер...
Оно много для чего, даже аудио/видео дату из браузеров эта технология обрабатывает, если верить обрывкам документации.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}

Что с этим делать?

Презу видел, никакой полезной информации для этой задачи не обнаружил. Примеры драйверов также не позволяют понять какими интефрейсами взаимодействовать из юзермода для вызова нужных ioctl-обработчиков в mskssrv.sys (с валидным входящим буфером, который, судя по всему, нетривиален).
 
кого есть exReven - это не будет загадкой).
А кто в живую щупал есть такие? В чем, кроме ценника х20, отличия reven от esReven?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А кто в живую щупал есть такие? В чем, кроме ценника х20, отличия reven от esReven?
Это один и тот же продукт. Его продали eShard'у.

 
Последнее редактирование:
Это один и тот же продукт. Его продали eShard'у.

Та я ж говорю, в чем отличия принципиальные новой версит от старой кто-то знает? Старую я юзаю, а новая стоит как квартира.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
а новая стоит как квартира.
Где ты увидел прайс на esReven? В упор не вижу.
 
Где ты увидел прайс на esReven? В упор не вижу.
Коммерческое предложение запросил.
Сетка цен: 40к, 70к, 120к. эуро.
Персонал, про, коммерс эдишнс.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
В SrvDispatchIoControl немного мудрено идет подсчет ioctl.

C:
Ioctl = Irp->Tail.Overlay.CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode;
    if ( Ioctl > 0x2F0418 )
    {
    // Skip...
    }
    //
    // Handling of the ioctl lower then 0x2F0418
    //
     if ( Ioctl == 0x2F0418 )
    {
        P = 0i64;
        status = FSGetRendezvousServer(&P);
        if ( status >= 0 )
        {
            retVal = FSRendezvousServer::NotifyContext(P, Irp);
            goto Cleanup;
        }
        goto CompleteRequest;
    }                                     
    v4 = Ioctl - IOCTL_KS_PROPERTY;         
    if ( !v4 )
    {
        v12 = KsPropertyHandler(Irp, 1u, &PropertySet);
        goto LABEL_22;
    }
    v5 = v4 - 0x3FD;

    if ( !v5 )
    {
        v12 = FSInitializeContextRendezvous(Irp);
        goto LABEL_22;
    }
    v6 = v5 - 4;
    if ( !v6 )
    {
        P = 0i64;
        status = FSGetRendezvousServer(&P);
        if ( status >= 0 )
        {
            retVal = FSRendezvousServer::InitializeStream(P, Irp);
            goto Cleanup;
        }
        goto CompleteRequest;
    }
    v7 = v6 - 4;
    if ( !v7 )                           
    {
        P = 0i64;
        status = FSGetRendezvousServer(&P);
        if ( status >= 0 )
        {
            retVal = FSRendezvousServer::PublishTx(P, Irp);// Vulnerable path starts here
            goto Cleanup;
        }
        goto CompleteRequest;
    }


Чтобы вычислить ioctl для FSRendezvousServer::PublishTx заюзал z3.

Python:
import z3

IOCTL_KS_PROPERTY = 0x2f0003
ioctl = z3.Real('ioctl')
v4 = z3.Real('v4')
v5 = z3.Real('v5')
v6 = z3.Real('v6')
v7 = z3.Real('v7')

z3.solve(ioctl < 0x2f0418,\
         ioctl > 0, \
         v4 == ioctl - IOCTL_KS_PROPERTY, \
         v5 == v4 - 0x3FD, \
         v6 == v5 - 4, \
         v7 == v6 - 4, \
         v7 == 0)

"""Output:
[ioctl = 3081224, v4 = 1029, v5 = 8, v6 = 4, v7 = 0]
"""

В общем ioctl теперь известен - 0x2f0408.

До того как теперь вызвать NtDeviceIoControlFile кто-нибудь додумался?



DispatchDeviceIoControl из ks.sys вызывает SrvDispatchIoControl, указатель на которую лежит в FsContext объекта файла.
Пока не знаю как это использовать.

C:
NTSTATUS __fastcall DispatchDeviceIoControl(struct _DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
    _FILE_OBJECT *FileObject; // rdx
    __int64 (__fastcall ****FsContext)(struct _DEVICE_OBJECT *, IRP *); // r9

    FileObject = Irp->Tail.Overlay.CurrentStackLocation->FileObject;// kd> !object @rdx
                                                // Object: ffffae0103d8c5a0  Type: (ffffae0ffa2fc400) File
                                                //     ObjectHeader: ffffae0103d8c570 (new version)
                                                //     HandleCount: 1  PointerCount: 32770
                                                //     Directory Object: 00000000  Name: \{3C0D501A-140B-11D1-B40F-00A0C9223196} {KSENUM#00000002}
    FsContext = (__int64 (__fastcall ****)(struct _DEVICE_OBJECT *, IRP *))FileObject->FsContext;
    if ( FsContext )
    {
        if ( (FileObject->Flags & 0x800) != 0 )
            return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
        else
            return (***FsContext)(DeviceObject, Irp);// MSKSSRV!SrvDispatchIoControl
    }
    else
    {
        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        IofCompleteRequest(Irp, 0);
        return STATUS_INVALID_PARAMETER;
    }
}
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Не стал долго думать и достал имя файла из буфера FileObject, попробовал отправить запрос при помощи FileTest и попал в нужный кусок кода, но все еще не хватает некоторых данных.

\\?\ROOT#SYSTEM#0000#{3c0d501a-140b-11d1-b40f-00a0c9223196}\{96E080C7-143C-11D1-B40F-00A0C9223196}&{3C0D501A-140B-11D1-B40F-00A0C9223196}

ioctl2.png


ioctl3.png


Возможно структура FsRendezvousServer (кроме названия никакой информации не нашел) передается как-то в дополнительных аргументах NtDeviceIoControlFile. Уже хотя бы что-то.

deviceiocontrol.png
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Немного инфы как эта логическая бага сплойтится. Любопытная техника.

1692715531816.png


Ресерч по теме должен выйти в августе


P.S.
ИМХО описываемая логическая уязвимость не самое интересное в презентации.
Та же уязвимость с той лишь разницей, что флаг для страниц только на чтение (т.е. мы можем только читать по произвольному адресу), а так то же самое из 2017 года https://www.unknowncheats.me/forum/...fairplaykd-driver-reversed-exploited-rpm.html
Возможно есть еще более ранние упоминания, но не искал.

Ждал, что будет хотя бы какой-то разбор "kernel streaming" и самой "полезной нагрузки", но х#й там плавал. Значит придется поебаться.
 
The researcher didn't actually provide any valuable info but from my analysis, it seems that you need to send a few other IOCTLs with valid data structures that match the checks that are being done on the data from those structures and then after you can call the vulnerable set of functions in order to do what you need to be able to have a working exploit. There is an easier bug (CVE-2023-36802) which is a type confusion that leads to write-what-where which is not that hard to exploit.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
There is an easier bug (CVE-2023-36802) which is a type confusion that leads to write-what-where which is not that hard to exploit.
It's not about easy or not, just found that bug interesting, so discussion is about it in the context of KS technology.

I will read Valentina's research about CVE-2023-36802 when it's come up, hope it will be soon.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
До того как теперь вызвать NtDeviceIoControlFile кто-нибудь додумался?
shit too hot ; - )
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован
C++:
//query disk device information example
BOOLEAN DiskDriveQueryDeviceInformation(
    _In_ HANDLE DeviceHandle,
    _Out_opt_ PPH_STRING* DiskVendor,
    _Out_opt_ PPH_STRING* DiskModel,
    _Out_opt_ PPH_STRING* DiskRevision,
    _Out_opt_ PPH_STRING* DiskSerial
)
{
    ULONG bufferLength;
    IO_STATUS_BLOCK isb;
    STORAGE_PROPERTY_QUERY query;
    PSTORAGE_DESCRIPTOR_HEADER buffer;
    query.QueryType = PropertyStandardQuery;
    query.PropertyId = StorageDeviceProperty;
    bufferLength = sizeof(STORAGE_DESCRIPTOR_HEADER);
    buffer = PhAllocate(bufferLength);
    memset(buffer, 0, bufferLength);
    if (!NT_SUCCESS(NtDeviceIoControlFile(
        DeviceHandle,
        NULL,
        NULL,
        NULL,
        &isb,
        IOCTL_STORAGE_QUERY_PROPERTY,
        &query,
        sizeof(query),
        buffer,
        bufferLength
    )))
    {
        PhFree(buffer);
        return FALSE;
    }
    bufferLength = buffer->Size;
    buffer = PhReAllocate(buffer, bufferLength);
    memset(buffer, 0, bufferLength);
    if (!NT_SUCCESS(NtDeviceIoControlFile(
        DeviceHandle,
        NULL,
        NULL,
        NULL,
        &isb,
        IOCTL_STORAGE_QUERY_PROPERTY,
        &query,
        sizeof(query),
        buffer,
        bufferLength
    )))
    {
        PhFree(buffer);
        return FALSE;
    }
    PSTORAGE_DEVICE_DESCRIPTOR deviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)buffer;
    // STORAGE_BUS_TYPE BusType;
    // DWORD RawPropertiesLength;
    // BYTE RawDeviceProperties[1];
    if (DiskVendor && deviceDescriptor->VendorIdOffset != 0)
    {
        PPH_STRING diskVendor;
        diskVendor = PH_AUTO
 
Пожалуйста, обратите внимание, что пользователь заблокирован
ice80 you probably misunderstood, I know how to call this function, the question was what NtDeviceIoControlFile input buffer will trigger the bug. This code from "Process Hacker" will not trigger the bug.
 
Тут вроде PoC выложили. Чёрт его знает рабочий или нет. Проверю - отпишусь:
Выглядит так как-будто оно. Накатил 10.17763, собрал, запустил:
1.png


Проверил триггерит ли FsAllocAndLockMdl:
3.png


Правда под отладчиком первый раз BSOD словил, жалуется на page fault:
2.png


А в целом отрабатывает.

Тут кстати и автор объявился: https://xss.pro/threads/98819/
Vexer2k если это правда ты, то респект.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх