You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
; Start of Token Stealing Stubxorrax,rax ; get ZEROmovrax, QWORD PTR gs:[rax+0x188] ; get nt!_KPCR.PcrbData.CurrentThread ; _KTHREAD is located at GS : [0x188]movrax,[rax+0x70] ; get nt!_KTHREAD.ApcState.Processmovrcx,rax ; Copy current process _EPROCESS structuremovrdx,4 ; WIN 7 SP1 SYSTEM process PID = 0x4SearchSystemPID:movrax,[rax+0x188] ; Get nt!_EPROCESS.ActiveProcessLinks.Flinksubrax,0x188cmp[rax+0x180],rdx ; Get nt!_EPROCESS.UniqueProcessIdjne SearchSystemPIDmovrdx,[rax+208h] ; Get SYSTEM process nt!_EPROCESS.Tokenmov[rcx+208h],rdx ; Replace target process nt!_EPROCESS.Token ; with SYSTEM process nt!_EPROCESS.Token
Windows内核漏洞学习之栈溢出(x86/x64)
由于上个月找工作,有几个面试官大佬问到了有关内核漏洞和缓解绕过机制的问题,我基本在这一块属于简单了解,回答的很不好,因而感觉需要在这一块学习一下,而且随着
Windows
漏洞审核变的越来越严,普通的漏洞就直接拒了,每次挖到洞都在寻找能够扩大漏洞攻击面的机会,如果能够影响到内核那被拒的可能性就比较低了,所以趁此机会好好学习一下内核漏洞相关知识和一些缓解机制绕过的方法。这是hevd
学习的一个系列,这是第一篇,关于栈溢出,这种溢出在windows 10
中基本已经完全没法使用了,但对于windows
内核底层机制了解还是有作用的,作为第一篇,所以写的会比较细,具体实验步骤都会写出来。其中用到的
poc
和exp
代码,我放在github上了,后续的代码也会更新在上面,有问题欢迎交流,学习。本文介绍了
hevd
中栈溢出在x86
和x64
环境下exp
编写及其原理。环境准备
因为
vmware 15
升级了很多东西,往常使用的VirtualKD
已经没法用了,所以这里使用其加强版本VirtualKD-Redux
下载VirtualKD-Redux,这个版本
VirutalKD
一直在更新,可用性比单纯的VirtualKD
要好用很多下载
windows 7 sp1
并安装,安装完成环境
x86
利用
VirtualKD
禁用windows 7
的驱动签名限制成功启动之后,开启服务
打开
hevd.sys
大概看一下代码逻辑跟进
IrpDeviceIoCtlHandler
继续跟进
BufferOverflowStackIoctlHandler
最终溢出函数
poc
函数编译执行,崩溃
从网上找到了一段p
ython
利用的提权shellcode
转化为
c++
可用中间忘了栈上存在
DEP
的问题,从而没有开辟空间直接执行,DEP
导致执行失败,可以验证一下试试,在函数return
前设置断点bp HEVD+0x4527e
没有执行权限,发生了异常。
使用
VirtualAlloc
重新分配可执行内存重启继续
可以发现,再次出错了,出错的原因在于执行完我们的
shellcode
之后,我们没有对环境进行复原那么我们来分析一下如何复原现在这个环境,这个得仔细思考,没有想象中的那么想当然,我们最好从原理上搞懂,为什么这么做。首先分析一下,如果栈没有溢出,正常执行完
popad
,我们应该执行的指令shellcode
执行完后,正常应该跳出TriggerBufferOverflowStack
,回到BufferOverflowStackIoctlHandler
函数看一下汇编指令
可以发现
eax
是作为返回值使用的,成功执行eax
应该是0
,所以简化指令讲汇编指令转化为二进制数据
将环境复原指令添加到
shellcode
中在上次那个断点断下,并逐步调试
继续,成功跳出
继续
提权成功
完整提权代码
一个有意思的问题
在做上面的实验时,遇到了一个比较隐蔽的问题,调试了很久,最终才发现原因,在这里也跟大家讨论讨论,避免大家以后遇到这个问题,不知道是为什么
如果
exp
的代码这么写注释掉之后,我们通过
cmd.exe
启动另一个cmd.exe
,新启动的cmd.exe
会是system
权限吗?编译执行,为了不掺杂别的影响,我们把系统重启一下,看看结果
可以发现,无论是原先的
cmd.exe
还是新启动的cmd.exe
,权限都没有提升成功。这个问题困扰了我大概两个晚上的下班时间,期间找了各种资料,以为shellcode
出问题了,我在shellcode
下断点,一步一步执行,怎么想都是成功的改变了cmd.exe
的token
数据,为什么会失败呢?失败的地方就在这里,我以为我该成功了,但事实是没有成功,来通过
windbg
看一下,首先关闭新启动的cmd.exe
,只保留我以为我成功改变token
的cmd
列一下进程
查看一下
system
进程及其token
信息查看一下
cmd
进程及其token
信息可以发现,我并没有成功替换
cmd
的token
,但是汇编代码明明完成了token
替换,为啥没有成功呢,难道真的是shellcode
的问题吗?这次下一个断点,一步一步调试
shellcode
调试到这里,正常我们已经成功替换了
token
,按照上面的步骤再看一下cmd
的token
情况,可以发现依然没有提权成功。没有提权成功的原因是因为我们忽视了一个隐含进程BufferOverflowStack.exe
,来看一下这个进程的信息对比一下
system
的token,可以发现,成功替换了。至此,终于可以解释为什么
cmd.exe
没有提权成功了,因为我们提权的是BufferOverflowStack.exe
进程,老的cmd.exe
不是BufferOverflowStack.exe
启动,所以它不继承BufferOverflowStack.exe
的system
权限,只有BufferOverflowStack.exe
拉起来的进程才具有真正的system
权限。如果你的新cmd.exe
不是BufferOverflowStack.exe
拉起来的,那必然也就会产生我上面的困扰,而且特别不容易发现其中的原因x64
在栈溢出上,
64
位和32
位差别不大,首先通过poc
确定栈溢出的长度,之后利用适用于64
位的exp
即可添加注释版本
shellcode
去除注释版本,方便转化
最终
exp
的源码需要注意的就是
shellcode
中各个结构体在x64
位中的位置变化,如果不对的话,就需要不断一步一步调试shellcode
,看到底那一行汇编出问题了。这个过程只是比较繁琐,并不难。结论
内核调试的难点在于繁琐,可能机器需要不停的重启,重启之后需要重新设置环境,启动服务,重新设置断点。需要比调试
ring3
程序更耐心。如果觉得环境被破坏了,重启即可。这部分
exp
的编写主要的难点在于shellcode
,在实验过程中,建议不要直接使用hevd
提供的利用代码,可以尝试自己写,最多可以用一个shellcode
,这样的话收获要比直接用要多很多。参考链接
Windows Kernel Exploitation Tutorial Part 2: Stack Overflow
HEVD Exploits – Windows 7 x86-64 Stack Overflow
Online x86 / x64 Assembler and Disassembler
The text was updated successfully, but these errors were encountered: