12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
三国霸业 战车-珍宝-觉醒-攻城掠地SF-全新玩法 免费玩新区 攻城掠地私服 进入游戏
手游私服盒子 各类免费游戏 0.1折送海量资源 各类手游私服 进入游戏
皇家MU2 《奇迹 2:传奇》韩国网禅公司《奇迹》正统续作。 3D锁视角Mmrpg 暗黑3+传奇+流放之路+奇迹 进入游戏
查看: 473|回复: 0

CVE-2015-1701本地特权提升漏洞成因分析

[复制链接]

52

主题

52

帖子

114

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
114
发表于 2019-8-20 11:24:46 | 显示全部楼层 |阅读模式
一个老漏洞了,主要是最近老师让查找这个漏洞的相关资料,我一搜还没有介绍漏洞具体成因的。索性自己分析了一下,比较入门,大牛就不要看啦。
从主函数入手分析


从TEB结构的偏移0x30处获得PEB的位置。


获取当前进程PID

得到PsLookuoProcessByProcessID函数的入口地址,并赋给函数指针g_PsLookupProcessByProcessIdPtr。下面进入GetPsLookupProcessByProcessId()函数内部。


得到内核中已加载的第一个模块在磁盘中的全路径。经过动态调试可知这个模块是ntoskrnl.exe


得到进程中加载的ntoskrnl.exe模块的优先加载地址,又因为此时的这个ntoskrnl.exe是在系统启动中在内核模式下记载到内存中的,所以此时的加载地址应该在内核内存空间中。经过调试观察KernelBase变量的值可以验证。


函数PsLookuoProcessByProcessID就在这个ntoskrnl.exe中。但此时ntoskrnl.exe在内核地址空间中,程序此时在用户态无法访问这一空间,就无法得到PsLookuoProcessByProcessID在ntoskrnl.exe中的RAV和在内存中的地址,就无法进行调用。我们可以在用户态加载ntoskrnl.exe,这样就可以访问ntoskrnl.exe内部函数了。


用户态加载ntoskrnl.exe,返回模块句柄到MappedKernel中,也就是ntoskrnl.exe模块加载到用户态内存地址空间的地址。


GetProcAddress函数在MappedKernel指向的模块句柄中通过关键词PsLookupProcessByProcessId搜索此函数,并返回该函数在用户态内存中的地址。通过调试可看出


FuncAddress=0x00000001403440e4;MappedKernel=0x0000000140000000。则MappedKernel-FuncAddress=0x3440e4就是PsLookupProcessByProcessId函数在ntoskrnl.exe中的RAV。再加上KernelBase就是该函数在内核态地址空间的位置。既内核态FuncAddress = KernelBase +(用户)FuncAddress - (ULONG_PTR)MappedKernel;如下图


GetPsLookupProcessByProcessId()函数最终返回这个FuncAddress值。并回到主函数中。


创建并注册一个窗口类,其中lpfnWnProc是这个窗口的过程处理函数,是MainWindowProc


PEB->KernelCallbackTable是PEB的回调函数表,在这里的索引是0x36,即指向了User32.dll中的ClientCopyImage函数。g_originalCCI= InterlockedExchangePointer(g_ppCCI, &hookCCI);这行代码是关键,Hook了ClientCopyImage函数,替换为hookCCI函数。g_ppCCI原来的值(就是原本的ClientCopyImage函数)返回给了g_originalCCI,g_ppCCI的新值是攻击的函数地址。


这行代码根据刚才注册的窗口类class_atom创建了Window对象,xxxCreateWindows在分析一系列参数后,会使用HMAllocateObject分配一个窗口类型的win32对象, 并为其填充一些参数,如窗口的Class(类)对象等,里面有这样的一个逻辑过程[C] 纯文本查看 复制代码if( pcls->spicn &&!pcls->spicnSm ) {          CreateClassSmIcon(pcls);}pwnd->hModule = hMoudle;pwnd->lpfnWndProc =MapClientNeuterToClientPfn(pcls, 0, bansi);这里CreateClassSmIcon的目的是为该窗口类的图标创建小图标缓存,接下来,系统会通过MapClientNeuterToClientPfn根据窗口类为窗口设置WindowProc。这个CreateClassSmIcon函数是通过KeUserModeCallback来实现的,这个调用最终是配合用户模式回调来实现的。KeUserModeCallback实际最后会调用放置在PEB->KernelCallbackTable中的对应函数来实现功能的,而这些函数都是最终实现在用户模式的,例如这里就将最终调用user32.dll中的ClientCopyImage函数来实现。而这个函数在之前就被Hook了,实际执行函数是hookCCI所指向的函数,如下图所示:


hookCCI函数先把正常的ClientCopyImage地址重新存入g_ppCCI中,然后调用SetWindowLongPtr函数,然后再调用g_originalCCI也就是ClientCopyImage函数,完成功能,这样就在正常执行ClientCopyImage函数之前先执行了SetWindowLongPtr函数。通过查找相关资料可知,SetWindowLongPtr是设置窗口相关数据、属性的函数,这里GWLP_WNDPROC这个功能索引(index)的作用是对窗口进行子类化(subclass)/去子类化(unsubclass),可以通过子类化,替换窗口的调用过程为自己的函数,来接管窗口的一些处理,也可以通过设置为DefWindowProc来去子类化,取消接管过程。这里面GetFirestThreadHWND是一个获得当前正在被创建的窗口句柄的一个技巧,因为现在CreateWindowEx正在被中断在内核过程中,仅仅通过用户模式的代码和CreateClassSmIcon的信息,是无法得知当前正在被创建的窗口对象/句柄的。但是在Win32k内核中,所有的内核窗口信息是全部被映射到用户模式的一块内存地址上的,通过user32!gSharedInfo可以得到它的地址(是内核模式窗口信息列表的一个只读映射),而刚才说过内核窗口对象在中断时已经经由HMAllocateObject被创建了,那么它实际就已经可以在gSharedInfo中检索到。这里代码使用SetWindowLongPtr将当前线程正在创建的窗口的WindowProc替换为了DefWindowProc。SetWindowLongPtr,当index(GWLP_WNDPROC(-4) ) lpfnWndProc=ptr;}这里的逻辑,是检查此处GWLP_WNDPROC是不是一个去子类化操作(unsubclass),如果是的话,就认为这里需要设置为内核来接管窗口过程,给窗口设置Server Side Proc的标志,这个标志的含义是窗口的窗口过程函数将在内核模式下调用。同时将窗口过程函数修改为DefWindowProc对应的内核处理函数。从CreateClassSmIcon返回,继续调用MapClientNeuterToClientPfn转化当前窗口类函数的默认WindowProc(也就是用户模式可控的函数),再将窗口对象的WindowProc设置为用户自己的窗口对象因为这个中断过程恰好在CreateWindowProc为窗口设置WindowProc前面,所以SetWindowData修改窗口的WindowProc为DefWindowProc是无效的,窗口的WindowProc还是被修改为用户模式应用程序设置的WindowProc,窗口过程处理函数也变成了MainWindowProc。而此时,这个窗口的标志已经被设置为是需要在内核模式执行WindowProc,那么接下来再遇到SendMessage等函数对这个窗口发送消息时,就会在内核模式下直接跳转、调用实际在用户模式的函数来进行处理,从而直接导致内核模式代码执行。MainWindowProc函数如下图所示


此时就可以在内核态执行StealProcessToken();获得内核态最高权限System的安全令牌就可以获得具有System权限的Cmd了。

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-11-24 16:09 , Processed in 0.078125 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表