gentilkiwi / mimikatz

A little tool to play with Windows security
http://blog.gentilkiwi.com/mimikatz
18.99k stars 3.62k forks source link

Potential memory leak in busy light error path #359

Closed JohnLaTwC closed 2 years ago

JohnLaTwC commented 2 years ago

Busy light code does not free memory on DevicePath in error path

While building up the list of busy light devices and filling the BUSYLIGHT_DEVICE structure, there are a couple of error paths where it will abandon the current device and not add it to the devices linked list. This means the error handling code must free all resources since they will not be freed later in kull_m_busylight_devices_free. There are a couple of paths where the duplicated DevicePath string is not freed.

if(*next = (PBUSYLIGHT_DEVICE) LocalAlloc(LPTR, sizeof(BUSYLIGHT_DEVICE)))
{
    if(HidD_GetPreparsedData(deviceHandle, &PreparsedData))
    {
        status = HidP_GetCaps(PreparsedData, &(*next)->hidCaps);
        if(!NT_SUCCESS(status))
            PRINT_ERROR(L"HidP_GetCaps (%08x)\n", status);
        HidD_FreePreparsedData(PreparsedData);
    }
    (*next)->DevicePath = _wcsdup(DeviceInterfaceDetailData->DevicePath);
    (*next)->hidAttributes = attributes;
    (*next)->deviceId = deviceId;
    (*next)->dpi.box_sensivity = 4;
    (*next)->dpi.box_timeout = 4;
    (*next)->dpi.box_triggertime = 85;
    (*next)->id = id;
    (*next)->hBusy = CreateFile(DeviceInterfaceDetailData->DevicePath, FILE_READ_DATA | FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

    if((*next)->hBusy && ((*next)->hBusy != INVALID_HANDLE_VALUE))
    {
        if(bAutoThread)
        {
            (*next)->dKeepAliveThread = 5000;
            if((*next)->hKeepAliveThread = CreateThread(NULL, 0, kull_m_busylight_keepAliveThread, *next, 0, NULL))
            {
                next = &(*next)->next;
                id++;
            }
            else
            {
                PRINT_ERROR_AUTO(L"CreateThread (hKeepAliveThread)");
                CloseHandle((*next)->hBusy);
+               if ((*next)->DevicePath)) free((*next)->DevicePath)
                LocalFree(*next);
            }
        }
        else
        {
            next = &(*next)->next;
            id++;
        }
    }
    else
    {
        PRINT_ERROR_AUTO(L"CreateFile (hBusy)");
+       if ((*next)->DevicePath)) free((*next)->DevicePath)
        *next = (PBUSYLIGHT_DEVICE) LocalFree(*next);
    }
}

See: https://github.com/gentilkiwi/mimikatz/blob/baaa26116a4240d31b182a509a8dbc84ff23e99d/modules/kull_m_busylight.c#L119 and: https://github.com/gentilkiwi/mimikatz/blob/baaa26116a4240d31b182a509a8dbc84ff23e99d/modules/kull_m_busylight.c#L131