当前位置: 首页 > news >正文

VulnScan:微软内存损坏漏洞自动化分析与根因检测技术

VulnScan – 内存损坏问题的自动化分类与根因分析

微软安全响应中心(MSRC)负责接收产品潜在漏洞报告,工程团队需评估问题的严重性、影响和根本原因。实践中,大部分报告涉及内存损坏问题。MSRC安全工程师通常需要分析崩溃并理解错误原因,这一流程同样适用于通过模糊测试和变种调查发现的内部漏洞。

为此,MSRC多年投入开发自动化根因分析工具。VulnScan是MSRC设计的工具,帮助安全工程师和开发者确定内存损坏漏洞的类型和根本原因。它基于两个内部工具构建:Windows调试工具(WinDbg)和时间旅行调试(TTD)。

WinDbg是微软的Windows调试器,近期界面更新使其更易用。TTD是内部开发的记录和重放Windows应用程序执行的框架,该技术于2017年CPPCon大会发布。

通过结合WinDbg和TTD,VulnScan能自动推断最常见内存损坏问题的根本原因。应用验证器的PageHeap机制用于在接近问题根因时触发访问违规。分析从崩溃位置开始,向根因推进。VulnScan支持的内存损坏问题类型包括:

越界读/写

无效指针值被追溯至其起源。如果起源指向有效分配且指针随后无效,VulnScan尝试确定更改指令及原因。这意味着工具能检测整数溢出和下溢,以及由错误循环计数器引起的越界访问。

释放后使用

访问违规时的无效指针值用于反向查找,确定执行时间线中指针变为有效的点。从此点开始,VulnScan正向跟踪应用代码,追踪所有内存释放操作以确定指针释放位置。

在选择上述方法前,我们实验了多种技术。最初记录所有内存分配和释放,但这非常消耗资源和时间,也拖慢其他错误的分类速度,因为即使非释放后使用错误也会准备堆对象映射。此方法允许我们在未启用PageHeap时分类释放后使用错误。它仍可使用,但默认禁用。

类型混淆

对于此漏洞类型,工具使用启发式方法检查指针大小和对齐是否一致。如果在反向执行流中,污染指针值被相同大小的值部分覆盖(未对齐的结构成员内存写入)或被不同大小的值修改,可能表明类型混淆漏洞(不同结构成员类型)。

类型混淆错误的示例分析见下文博客案例研究。

未初始化内存使用

通过在内读取地址插入内存断点,验证每次内存读取操作是否初始化。然后代码反向运行至写入点。如果缺少写入操作,我们向用户报告未初始化内存使用并继续分析。

未初始化内存指针的示例分析:

[*]     当前指令:cmp         qword ptr [r8+00000558h],rax
[*]     当前位置:0x2B3DC0000001
[*]     源内存值:0x2390E31B940
[*]     污染回溯寄存器:r8
[*]     寄存器值:0x0
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         r8,qword ptr <b style="color: orange">[rcx+00000410h]</b> <- 未初始化内存
[*]     当前位置:0x2b3d80000144
[*]     源有效地址:0x2417f9a2690
[*]     源内存值:0x0
[*]     ----------------------------------------------------------------------
[*]     检测到未初始化堆对象漏洞!!!

空/常量指针解引用

VulnScan中的多分支污染引擎追踪所有值至其初始化。如果所有分支回溯至未修改的空或常量值,我们向用户报告空或常量指针解引用。

空指针解引用错误的示例分析:

[*]     当前指令:test        byte ptr [rcx+4Ch],1
[*]     当前位置:0x6328B80000001
[*]     源内存值:0x1
[*]     污染回溯寄存器:rcx
[*]     寄存器值:0x0
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         rcx,qword ptr [rcx+20h]
[*]     当前位置:0x6328B4000014E
[*]     源有效地址:0x1E3A54FDC20
[*]     源内存值:0x0
[*]     内存已初始化 @TTTPos: 1744423515849038。
[*]     内存已初始化!
[*]     污染回溯内存:0x1E3A54FDC20
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         qword ptr [rbx+20h],rax
[*]     当前位置:0x6327FC00002AE
[*]     源内存值:0x0
[*]     污染回溯寄存器:rax
[*]     寄存器值:0x0
[*]     ----------------------------------------------------------------------
[*]     当前指令:xor         eax,eax
[*]     当前位置:0x6327FC00002AD
[*]     污染寄存器被清零!
[*]     ----------------------------------------------------------------------

MSRC将VulnScan用作自动化框架Sonar的一部分。Sonar自动处理所有支持平台和软件版本的外部报告概念验证文件,用于复现和执行根因分析。为此,我们采用多种不同环境,并尝试不同配置多次复现问题。

VulnScan计划纳入Microsoft安全风险检测服务(Project Springfield),用于重复崩溃去重和提供通过模糊测试发现的漏洞的扩展分析。

在10个月期间,VulnScan用于分类Microsoft Edge、Internet Explorer和Microsoft Office产品的所有内存损坏问题,成功率约85%,为MSRC工程师节省约500小时工程时间。

案例研究 – 分类类型混淆错误(CVE-2017-0134)

借助时间旅行调试(TTD),我们可以在代码执行时间线的两个方向探索代码。我们使用污染技术跟踪寄存器更改,使用内存断点跟踪内存写入。污染过程中的每条指令都在先前执行指令的上下文中分析,以找到问题的可能根本原因并确定错误类别。

VulnScan污染分析是多分支的,意味着它可以顺序跟踪从单个指令获得的所有值。VulnScan有一个与执行时间线中特定位置关联的寄存器和内存地址队列。污染分析对每个分支单独执行。使用此技术,可以完整重建应用数据流。随时间推移,我们进行了一些简化和优化以加速分析过程。以下分析是一个简单示例,仅突出工具的基本概念和能力。

示例来自Jordan Rabet(微软进攻性安全研究团队)提交给MSRC的Chakra漏洞。

跟踪中的重要位置:

  • 位置0x2D0780000001:访问违规位置。地址(0xA0000000A)通过mov指令解引用,未指向有效内存位置。我们通过从此指针计算中使用的寄存器(rcx)反向污染开始分析。
  • 位置0x2CFA8000014D:启发式首次触发。这可能是此分析的最重要点。无效指针值作为64位值回溯至此点,但它在内存写入操作中作为32位值使用。启发式在分析中多次触发,但这些不重要,因为它们不影响我们在访问违规位置看到的无效指针值。
  • 位置0x1D420000037E至0x1D40400000A7:污染值在这些位置之间更改。由于这是由NtReadFile系统调用外部设置的,意味着攻击者可能控制该值。进一步回溯显示内存设置为PageHeap特定常量值,这也表明我们正在处理堆分配。

调用栈:

00 ch!memcpy          <- 位置0x1D420000037E
01 ch!memcpy_s
02 ch!_fread_nolock_s <- 系统调用
03 ch!fread_s
04 ch!fread
05 ch!Helpers::LoadScriptFromFile
...
0n <- 位置0x1D40400000A7
  • 位置0x2A8C80001709:主分支污染分析在此结束。解引用地址(0x7FFC239B2358)是ChakraCore二进制文件中的只读全局变量。从此点执行其他分支(称为连接点)的分析。分析将在下一个分支继续,因为指令是目标操作数中寄存器的算术操作。

此操作在源代码中由dbl *= g_rgdblTens[lwExp]表示,其中g_rgdblTens是全局变量。

其他分支(位置0x2A8C800016F9和位置0x1D404000001A)导致常量和空值,但仍值得调查以确保不错过任何重要细节。

db    db db    db db      d8b   db .d8888.  .o88b.  .d8b.  d8b   db
88    88 88    88 88      888o  88 88'  YP d8P  Y8 d8' `8b 888o  88
Y8    8P 88    88 88      88V8o 88 `8bo.   8P      88ooo88 88V8o 88
`8b  d8' 88    88 88      88 V8o88   `Y8b. 8b      88~~~88 88 V8o88`8bd8'  88b  d88 88booo. 88  V888 db   8D Y8b  d8 88   88 88  V888YP    ~Y8888P' Y88888P VP   V8P `8888Y'  `Y88P' YP   YP VP   V8P[*]     加载跟踪。
[*]     在跟踪文件中找到异常!
[*]     当前指令:mov         rax,qword ptr [rcx+8]
[*]     当前位置:<b style="color: red">0x2D0780000001</b>
[*]     源有效地址:0xA0000000A
[*]     污染回溯寄存器:rcx
[*]     寄存器值:0xA00000002
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         rcx,qword ptr [rsp+00000088h]
[*]     当前位置:0x2D0740000FE7
[*]     源有效地址:0x99C17FDCF8
[*]     源内存值:0xA00000002
[*]     内存已初始化 @TTTPos: 49509161766887。
[*]     内存已初始化!
[*]     污染回溯内存:0x99C17FDCF8
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         qword ptr [r15],rax
[*]     当前位置:0x2D0740000FD0
[*]     源内存值:0xA00000002
[*]     污染回溯寄存器:rax
[*]     寄存器值:0xA00000002
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         rax,qword ptr [rcx+18h]
[*]     当前位置:0x2D0740000FCC
[*]     源有效地址:0x2967D8CC0C0
[*]     源内存值:0xA00000002
[*]     内存已初始化 @TTTPos: 49509161766860。
[*]     内存已初始化!
[*]     污染回溯内存:0x2967D8CC0C0
[*]     ----------------------------------------------------------------------
[*]     当前指令:mov         dword ptr [r10+rax*4+18h],r11d
[*]     当前位置:<b style="color: orange">0x2CFA8000014D</b>
[*]     源内存值:0xA
<b style="color: orange">[*]     检测到指针大小不匹配!</b>
[*]     污染回溯寄存器:r11d
[*]     寄存器值:0xA
[*]     ----------------------------------------------------------------------
...(详细分析日志继续)...
<b style="color: orange">[*]     检测到类型混淆漏洞!!!</b>
[*]     加载符号。
[*]     构建输出。
[*]     将发现写入文件:n:\CVE-2017-0134\ch.run.html
[*]     分析在00:01:08内完成

此初始输出提供错误的汇编语言分析。VulnScan然后生成更详细的报告,包含寄存器值、源代码、局部变量和调用栈。这帮助产品开发者提供准确全面的修复。

使用两个报告获得的数据,我们可以开始调查崩溃位置和触发启发式之间的源代码。我们可以观察到,用作指针的值在Js::JavascriptArray::DirectSetItemInLastUsedSegmentAt中设置为数组元素,并来自Js::JavascriptArray::EntryConcat函数。Jordan找到一种方法,通过在IntArray对象的属性上使用自定义getter,将数组类型更改为VarArray。函数JavascriptArray::ConcatIntArgs(如报告中调用栈所示)和JavascriptArray::ConcatFloatArgs使用数组对象的Symbol.isConcatSpreadable属性,并且是该符号上的自定义getter,可用于更改数组类型。这导致在类型更改后,连接的IntArray项被写入VarArray而不是IntArray,从而引起数组对象损坏。此问题的修复在此ChakraCore提交中引入。

今天的内容到此为止。如果您想了解更多关于此工具及其使用的启发式和污染技术,请留下反馈。我们的下一步高度依赖社区响应。该工具经常更新,添加Microsoft内部工具用户请求的新启发式和功能。

感谢MSRC英国团队的反馈和想法,Jordan Rabet发现的错误,Steven Hunter、Matt Miller和Gavin Thomas帮助撰写此博客文章。还应赞扬WinDbg、TTD、Sonar和Microsoft安全风险检测团队开发的惊人工具。

Mateusz Krzywicki来自微软安全响应中心(英国)。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码

http://www.sczhlp.com/news/66056/

相关文章:

  • 郑州做网站优化地址东莞常平有哪些好玩的地方
  • 常州网站制作企业株洲第三方网站建设哪家好
  • 网站开发与设计结课论文wordpress 获取总页数
  • 网站开发能赚钱吗找工程项目信息哪个app好用
  • php+ajax网站开发典型实例pdfnet程序员网站开发工程师
  • unittest用例执行的流程
  • 数据结构专题
  • 关于如何从零推出中国剩余算法
  • Js 中 async-await 和 事件循环
  • 专门做流程图的网站深圳互联网推广公司
  • php图片展示网站wordpress文章接口
  • 诸城市做网站wordpress SEO化
  • 陕西建设厅网站人才库西安o2o网站设计公司
  • 网站地图提交地址城建网站论坛 建设
  • 网站备案后下一步做什么企业网站设计图
  • 佛山网站建设咨询wordpress漂浮侧边栏
  • ui设计师做网站网站制作中搜索栏怎么做
  • 什么网站程序适合做seo百姓网找工作
  • 网站开发公司广告文案网站开发公司售后服务
  • 上海 高端 网站建设温州外贸网站建设公司
  • 网站出现弹窗网站 经营性
  • 重庆做网站熊掌号网页ui素材中心下载
  • 免费营销型企业网站模板小程序源码网站论坛
  • 做平面资源比较好的网站wordpress最大文件上传大小修改
  • 建设银行手机官方网站下载新浪短网址链接生成器
  • 手机网站前端开发布局技巧网站seo专员
  • 做网站开发有前途吗做外汇的人一般看什么网站
  • 利用别人域名做自己的网站信息流广告投放工作内容
  • dw网站设计与制作海外服务器租用平台
  • 做网站 做好把我踢开wordpress无法修改密码