先容
CVE-2018-8120破绽是Windows 7 及 Windows Server 2008系列中的一个经典的提权破绽,这篇文章中我们将一步步剖析破绽成因,并组织行使POC。
复现环境
Win7 x86虚拟机(Vmware)
破绽点
该破绽存在于SetImeInfoEx函数中;在一处接见内核工具的数据时,没有判断是否正当即举行接见。
回溯剖析
交织引用查找发现,只有在系统挪用函数NtUserSetImeInfoEx中挪用该函数
查看这部门代码,可以知道SetImeInfoE函数的第一个参数泉源是GetProcessWindowsStation
想要搞清楚pWinStation的结构,需要找到GetProcessWindowStation函数原型,在MSDN上对该函数的界说如下:
HWINSTA GetProcessWindowStation(); If the function succeeds, the return value is a handle to the window station.
这样,我们就知道了pWinStation是Window Station的Handle。在Windows中Handle现实也就是内核的工具引用,这里是WindowsStation工具。在Windbg中查看获得该工具的信息
对比破绽触发时引用的位置v3[5]现实是WindowStation结构偏移0x14的数据工具即spklList;而spklList默以为NULL!
另外在查询该API时,同是也能查到关于Window Station其余的API信息,其中关系最慎密的就是
//CreateWindowStation建立一个Window Staion HWINSTA CreateWindowStationA( LPCSTR lpwinsta, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa ); //SetProcessWindowStation 为当前历程设置Window Station BOOL SetProcessWindowStation( HWINSTA hWinSta );
验证POC
凭据上面的破绽点、溯源成因剖析。我们可以用相关的API接口组织一个简朴的POC。
其中NtUserSetImeInfoEX函数属于系统挪用,没有直接的导出函数可以挪用,以是需要凭据挪用号自界说实现。
该函数的界说在Win7上没有找到(在Win10后win32k.sys的系统挪用可以在win32u.dll中找到)然则有公然的文档
在这里可以找到Windows系统挪用在各个版本号上的系统挪用号。
还可以在ntdll.dll中找到系统挪用若何自界说实现
(其中mov eax, 0x….是系统挪用号)
据此我们可以实现自界说的NtUserSetImeInfoEx函数
接下来我们需要编译并在目的Windows7上运行。
运行之后windbg收到异常,断下状态如下
继续运行,目的系统蓝屏
深入剖析可行使性
凭据上述内容,我们知道SetImeInfoEx函数的第一个参数是pWinStation,第二个参数现实就是NtUserSetImeInfoEx的参数(char*)的前0x15c的内容。也即都是可控的。
而我们发现在SetImeInfoEx中,最终将执行qmemcpy操作,而且目的地址、源地址在某种程度都是可控的。只要在接见NULL时不会触发异常即可!
这一部门代码还可以从Windows泄露的部门源码中查到,可以辅助剖析。win2000源码
探索Windows 7 内核分配NULL空间地址
在用户层应用程序中,NULL引用可能是无法导致代码执行的。然则在内核态,NULL引用却有意向不到的效果(Win7上)
这里不得不提Windows的一个未公然API(在ntdll.dll中)
NTSTATUS NtAllocateVirtualMemory( _In_ HANDLE ProcessHandle, _Inout_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _Inout_ PSIZE_T RegionSize, _In_ ULONG AllocationType, _In_ ULONG Protect );
该函数可以在指定历程内分配一块指定巨细的空间;同时第二个参数BaseAddress可以指定为优先选择的分配的空间(当该处有足够的巨细空闲时,就直接分配该地址【页对齐】)。这就意味着,我们有机遇分配一块包罗NULL的地址,并向其中写入组织的数据。
如下行使NtAllocateVirtualMemory分配包罗NULL的地址空间
在windbg调试器中查看效果
随便地址写
通过上述 剖析历程,我们发现可以在NULL分配空间,填充合适的结构,最终行使qmemcpy实现随便地址写。
组织如下的数据,用于最终执行到qmemcpy
最终调试到qmemcpy处状态,可以造成随便地址写
这里发现虽然可以随便地址写,然则注意到目的地址(edi)偏移0x18的位置需要为0。
从有限制的随便地址写到提权的思绪
到现在我们拥有了随便地址写的能力(内核或用户态),我们需要把写的能力转为权限的提升。在Windows上,所有的权限控制都有一个存在Kernel中的Token工具来控制。每个登入系统的用户会天生一个User Token,所有启动的历程会继续用户的Token,子历程继续父历程Token。更多详细的先容建议查阅MSDN文档。
下面我们在Windbg里查看下差别历程的Token
Lsass.exe历程(SYSTEM权限)
在看一下cmd.exe的Token(普通用户)
可以看到Token在_EPROCESS结构偏移0xf8的位置,且最终向下8byte对齐。
我们用lsass.exe的Token复写cmd.exe 的Token,看下情形会若何
不出意外的cmd.exe将拥有SYSTEM的权限!
凭据这种思绪,我们可以行使随便地址写破绽修改当前历程Token。然则需要直到SYSTEM的Token,然则普通用户没有SYSTEM历程的接见权限。
另一种关于随便地址写破绽(www)的行使方式中,在Windows上用的最为经典的就是Bitmap的滥用,也称“PvScan0 Technique” ,该方式可以将随便地址写扩展到随便地址读以泄露信息。
什么是Bitmap
这里建议查阅Window MSDN官方文档(与Windows 绘图相关),与之相关的API重点有
// 建立Bitmap HBITMAP CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, const VOID *lpBits ); // 将bitmap bits拷贝到指定缓冲区 LONG GetBitmapBits( HBITMAP hbit, LONG cb, LPVOID lpvBits ); // 设置bitmap的bits LONG SetBitmapBits( HBITMAP hbm, DWORD cb, const VOID *pvBits );
CreateBitMap建立的结构SURFACE OBJECT
头部是一个BASEOBJECT结构(Windows 未公然,然则Reactos有文档BASEOBJECT
接下来是_SRFOBJ MSDN的界说如下:
这其中的pvScan0指向bitmap的Pixel Data数据区,也即是GetBitmapBits和SetBitsMaps直接操作的数据区。
我们在windbg中考察下这里有什么特别之处:
在历程PEB中有一个结构GdiSharedHandleTable保存着GDICELL结构数组(该结构并没有公然)
,欢迎进入欧博亚洲客户端下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。
其中的pKernelAddress指向SURFACEOBJECT结构(BASEOBJECT首字节)
这几个结构体之间的关联,下面这幅图可以论述:
在windbg中查看(标出了pKernelAddress和wType)
通过上面的结构我们可以获知
PEB.GdiSharedHandleObejct = 0x00300000
Gdiaddr = 0x003000a0
BASEOBJECT中的hMgr = 0x0104000a(CreateBitMap返回值)
这三者之间的关系:
gdiCell_Addr = PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)
其中PEB.GdiSharedHandleObject的地址用户层可以获得,hMgr是CreateBitMap返回的Handle,也就是我们可以盘算获得GdiCell的位置,进而可以获得pKernelAddress。
只管我们在用户态无法接见SURFOBJ的成员,然则由关系图2- 知道pvScan0和pKernelAddress之间的Offset是牢固的:
pvScan0_Offset = pKernelAddress + 0x10 + 0x1c
这样,我们就可以凭据CreateBitMap返回值获得pvScan0的地址。
pvScan0 = *( PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)) + 0x2C;
下面的代码可以用来测试该推理:
Windbg调试历程如下
到这里我们已经有了一个内核态的地址pvScan0,pvScan0处的Value就是用户可以直接读写的Pixel Data;通过GetBitmapBits和SetBitMaps,我们可以对该地址读写操作。
连系随便地址写破绽,我们修改pvScan0,就可以真正到达准确的随便地址写!
BitMap行使流程
在上一环节,我们可以在用户层获取内核地址的读写(通过pvScan0),这里详细先容若何连系BitMap行使随便地址写破绽
(1) 建立2个bitmaps(Manager/Worker)
(2) 使用CreateBitMap返回的handle获取pvScan0的地址
(3) 使用随便地址写破绽将Worker的pvScan0地址写入Manager的PvScan0(作为Value)
(4) 对Manager使用SetBitmapBits ,也就是改写Woker的pvScan0的Value为读/写的随便地址。
(5) 对Worker使用GetBitmapBits/SetBitmapBits,以对第四步设置的地址随便读写!
下面的图示可以很好的示意上述攻击主要流程3、4:
代码实现Attack 3(只需要修改之前 2.5.4 随便地址写的POC)
Windbg调试,修改前Manager pvScan0
顺遂执行到随便地址写破绽(v4+0x18为0 的限制,pvScan0是知足的)
修改之后的mgr_pvScan0
Attack4 就是执行SetBitMapBits修改manager的PvScan值指向的内容(也就是Worker的PvScan0的值),写入目的地址。
例如下面的代码使得Worker的PvScan0指向0xdeadbeef
Windbg调试,修改前Worker PvScan0
修改后
此时Worker的pvScan0值已经指向了我们的目的地址,通过SetBitMapBits即可写入随便内容。
代码执行
当有随便地址写的能力的时刻,最好的代码执行思绪就是重写一个函数指针指向Shellcode,在shellcode中实现Token的重写!而Windows也确实有类似的指针(一个函数分揭晓),在hal模块下(该模块是Windows系统启动时加载的第一个模块)有许多这样的函数指针,我们取其中一个测试下
上图中显示了函数分揭晓中的函数,在偏移0x4的位置hal!HaliQuerySystemInformation是Windows API NtQueryIntervalProfile运行时挪用的函数,若是重写这个地址,就可以挪用触发执行Shellcode。
这里的HalDispatchTable的地址我们可以直接由ntoskrnl.exe模块中查询获得,然则由于ALSR的存在,获得的地址并不是真实的地址,我们只用这个盘算获得偏移,之后再使用。某些系统需要加上一个Detect Offset,调试时自行修改。
获取HalDispatchTable地址
之后可以在2.5.6的基础上修改HalDispatchTable中的函数指针
修改之后的HalDispatchTable
可以发现HalDispatchTable偏移+0x4的函数指针已经被修改为Shellcode地址。
提权Shellcode
对于Windows内核的破绽,一样平常思绪就是到达提权的目的。提权,就和权限相关,建议阅读Windows有关权限控制的官方文档。
提权Shellcode 本质也是一段Shellcode,不外和一样平常的Shellcode实现的功效差别,一样平常的Shellcode在于返回一个执行命令的Shell。而提权Shellcode致力于修改当前历程的Token,使其权限更高,甚至于SYSTEM权限!
这里给人人展示下Windbg遍历系统历程Token的历程
首先,在Windows内核中,fs寄存器指向nt!_KPCR结构
上图中,通过fs指向的KPCR结构找到偏移0x120处的KPRCB结构,在KPRCB偏移0x4的位置是CurrentThread的KTHREAD结构。
上述图展示了由KTHREAD获取PID、Token、FLINK的方式,在Win7 32上获得的偏移如下
网上有公然的Windows提权Shellcode,我这里只是对Shellcode的一个剖析,可以实验自己着手实现。
将提权Shellcode在修改HalDispatchTable的基础上,即可以提权!为了显示提权乐成,可以在触发提权后,启动测试程序的cmd拥有了SYSTEM权限。
提权的触发路径
提权乐成
参考链接
- MSDN-Bitmap
- Bitmap详解
- Steal-Token-Shellcode
环球UG官网声明:该文看法仅代表作者自己,与本平台无关。转载请注明:usdt钱包支付(caibao.it):CVE-2018-8120剖析与行使
有一位女演员,在书本上分享了一件影响她一生的经历。 内容不错,继续加油。
「租金贷本质上是长租公寓行使租户的信用借贷搭建了一个资金池,用租客信用获得贷款,却给了长租公寓用于扩张。」蔡真以为,租金贷的引入,更是把金融风险转嫁给了社会,房东和租客成了首当其冲的受害者,银行也难免受到牵连。」 看得很开心呢