CodeDom 漏洞模式与 SharePoint RCE

一、介绍 CodeDom 机制 .NET Framework 提供一种叫做 代码文档对象模型 (CodeDom) 的机制。 我们可以使用 CodeDom 元素组合成 CodeDom 图来表示一段源代码的逻辑。 CodeDom 有两个主要的功能: 根据 CodeDom 图生成源代码。 将源代码即时编译为程序集。 当然,也可以忽略中间过程,直接将 CodeDom 图编译为程序集。 二、关于 CodeDom 的例子 为了介绍 CodeDom 的一般用法,下面是提供一个关于 CodeDom 例子。该例子展示了如何使用一段 CodeDom 程序描述一段源码的逻辑。 目标源码类似下面这样: namespace MyNamespace { using System; public class MyClass { public static void MyMethod() { Console.WriteLine("Hello, World!"); } } } 对应的 CodeDom 例子: using System; using System.CodeDom; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.Reflection; namespace CodeDomExample { class Program { static void Main(string[] args) { /************************************************************ // 第一部分:创建 CodeCompileUnit,构建 CodeDom 图以表示一段代码逻辑 ************************************************************/ // 创建一个 CodeCompileUnit 对象,表示要编译的代码单元 CodeCompileUnit compileUnit = new CodeCompileUnit(); // 创建一个 CodeNamespace 对象,表示代码的命名空间 CodeNamespace codeNamespace = new CodeNamespace("MyNamespace"); // 添加需要引用的命名空间 codeNamespace....

2023年12月06日 · 3 分钟 · HuanGMz

Datacon 2023 漏洞分析赛道赛题二官方题解

0x00 前言 赛题二附件.zip ​本题目来源于对openwrt项目源码魔改。基于实战中的场景,在题目中设置了三种相对固定且常见的漏洞模式,希望选手们在对固定漏洞模式理解的基础上,可以利用静态分析工具辅助进行分析,探索各种漏洞分析工具与人工分析相结合的漏洞挖掘模式,减少一定量的重复人工审计。 ​静态分析工具都有其自身的缺陷,分析的结果很难做到尽善尽美。因此站在一位漏洞挖掘工程师的角度,我设置本题的目标是探索如何合理的使用静态分析工具,并最大程度的利用这种自动化的方式帮助我们减少人工分析的工作。 这里的题解主要使用我们自研的二进制静态分析工具——破壳平台的交互式查询来辅助我们进行分析,大致来说有以下思路: 根据漏洞模式的某些参数特征进行匹配 定义source点和sink点进行污点追踪 根据漏洞模式上下文特征来匹配漏洞 我们将会介绍这三种思路来进行查询解题,具体漏洞的答案和查询规则在文末可见。 0x01 根据参数特征查询 根据参数特征查询适用于过滤一些常见的危险函数的危险操作。 1.1 针对strcat函数 例如如果strcat的二个参数是一个常量字符串的话是很难有溢出的,即使有溢出也难以造成很大的危害。故此这种情况我们一般不需重点关注。 在本次datacon赛题二中,我们对strcat进行查询并设置其第二个参数是一个变量的情况。这里我们的查询规则如下,查找类型为变量(identifier),callee的筛选是为了筛选出调用这个变量的函数要是strcat函数,最后index指定了这个变量是strcat的第二个参数(下标从0开始),as taintPropagationPath RETURN taintPropagationPath 是为了前端将结果显示的更好看一些。 MATCH (n:identifier) WHERE n.callee="strcat" AND n.index=1 WITH [n] AS taintPropagationPath RETURN taintPropagationPath 查询结果如下,可以看到符合的结果只有两条。因为查询到的结果并不多,所以可以进行一下人工验证。验证后发现恰好是我们题目设置的答案odhcpd:0x000036A9 odhcpd:0x000035F9 依据这种思路我们可以查询到 漏洞3,漏洞4 总结 与之类似的情况还有strcpy函数,我们依然可以依照上面的原则进行编写规则进行查询。 在现实情况中,如果我们上传了整个固件可以如此查询一下他system和popen的调用情况,那么如果他执行的是一个常量字符串那么肯定不可能是一个命令注入漏洞。因此我们可以同样对他system和popen的第一个参数类型进行限制,帮助我们初步筛选一下目标,减轻人工逆向的工作量。 1.2 针对memmove函数 首先我们来看下memmove函数的函数定义,第一个参数是dst,第二个参数是src,第三个参数是len void * memmove(void *dst, const void *src, size_t len); 通常memmove安全的使用方法有以下两种 调用memmove函数的时候第三个参数是一个固定的值 memmove(dest, src, sizeof(dest)); memmove的dest大小是根据第三个参数的大小申请出来的 dest = malloc(size); memmove(dst, src, size); 我们针对这两种情况进行排除,编写查询命令。其中not (m)-[:dfg]-(n)即是现在第一个参数跟第三个参数之间不存在直接的数据流关系 MATCH (n:identifier{callee:"memmove", index:0}), (m:identifier{callee:"memmove", index:2}) WHERE n....

2023年11月22日 · 6 分钟 · w00d

IoT 设备中的认证绕过漏洞分析

一、前言 在IOT设备中,认证漏洞出现频率较高,能够造成的很大危害。通过认证的绕过,攻击者可以访问到很多敏感接口,甚至可以结合其他漏洞直接获取设备 shell。本文将通过一些设备分析认证过程以及认证绕过。 二、分析 小设备认证可分为两个部分,一是登录逻辑,设备通常会要求用户输入用户名和密码来进行身份验证;二是对路由的鉴权,其作用是限制用户对不同功能和资源的访问权限。 (一)登录 对于IOT设备中的Web界面,通常在未认证前仅能访问登录界面。为了找到后端登陆逻辑,我们可以借助工具如Burp Suite来进行流量抓包分析。 以某设备A为例,用Burp Suite抓包发现,登陆时请求了/cgi/login路由 在/usr/bin/httpd的ida文件中搜索/cgi/login,可以快速定位到注册CGI的函数。其中http_alias_addEntryByArg的功能是为cgi注册处理函数并设置访问所需要的权限。因此登录的逻辑http_rpm_login中。 有的设备会有专门的cgibin来处理cgi。例如某设备B在cgibin的main函数中使用strcmp比较请求的cgi,如果是authentication_logout.cgi就会进入登录逻辑。 还有一些设备的路由则是在配置文件中定义,下图是一个nginx+lua的路由器的配置文件,其中定义了在在访问/authenticate时,在content_by_lua阶段加载web模块处理登陆请求。 (二)鉴权 一般来讲,http对路由都会有访问限制,一般在配置文件或者httpd初始化的时候会定义访问规则。 以某设备A为例,httpd在初始化时调用http_alias_addEntry_ByArg注册CGI处理函数。http_alias_addEntry_ByArg的最后一个参数,表示访问这个路由需要的权限。g_http_author_admin、g_http_author_default、g_http_author_all分别表示访问该CGI需要超级用户权限、普通用户权限、无需权限。 httpd中每个请求都会通过http_author_hasAuthor鉴权,参数a1是一个全局变量,记录会话相关信息,其中的user_id表示该会话登录的用户,默认为0,在登陆成功后会赋值;a2是包含访问的路由,对应的处理函数和访问所需权限信息的结构体。该函数通过user_id判断a2->author对应bit是否为1进而确定当前用户是否有权限访问。 在某设备C中则是为路由鉴权定义了一个mime_handlers结构体数组, mime_handler定义如下,patten是匹配的模式,handler就是路由对应的处理函数。第四个参数auth表示访问这个路由是否需要鉴权。 struct mime_handler { char *patten; // **.cgi **.html char *mime_type; void *handler; int auth; }; 每次httpd接收到请求时会做如下处理:遍历mime_handlers,获取对应的patten字段,调用match_one匹配,匹配成功则获取对应的handler。最后在调用handler前根据auth字段判断是否需要鉴权。 这里有一个点,匹配所用到的patten有些是只匹配文件扩展名,例如对于**.cgi,*表明可以匹配0个或多个字符,不管.cgi前有多少个字符都会匹配进去,有可能后续会造成溢出。 在某设备D中,httpd使用strstr来匹配请求的是否是不需要认证的路由,当匹配到白名单路由时设置do_not_need_auth为1,未匹配到白名单则需要认证。 在某设备E中,在配置文件nginx.conf中定义,access_by_lua阶段加载sessioncontrol模块,重新加载用户信息,获取会话管理器mgr,检查请求并处理认证。 三、绕过 下面通过一些真实漏洞分析认证绕过。 登录功能对于用户名/密码处理不恰当 最简单的绕过方式是首先登陆时有默认密码,有的是硬编码在程序中,或者调试可以发现。 案例一:CVE-2020-8864 D-LINK DIR-882设备,在登陆时密码比较的逻辑中,28行获取我们输入的密码,第47行会调用strlen获得我们输入的密码的长度,之后使用strncmp进行比较,如果我们输入空密码,strncmp的第三个参数为0,返回值一定是0,表示比较成功,即可绕过认证。 漏洞修补:比较前判断用户输入密码是否为空 会话管理存在问题,控制 Cookie 值绕过会话检查。 案例二:CVE-2021-32030 ASUS RT-AX56U设备,需要鉴权的接口都会从请求获取cookie参数,之后传入auth函数。auth函数中,从nvram获取ifttt_token。 在默认情况IFTTT没有开启,ifttt_token为空,通过请求中传入空的cookie可绕过认证。 漏洞修补:比较cookie前判断cookie是否为空 案例三:CVE-2021-35973 Netgear wac104设备,在访问需要认证的cgi时会对session进行认证,在第42、49行首先从POST请求中获取id和sp字段的值,之后第53行snprintf将/tmp/SessionFile和sp_from_post拼接在一起作为get_id_from_session_file的参数。 get_id_from_session_file中,首先返回值赋值为0,打开session_file, 从sesseion_file读取id,如果文件不存在则直接接返回初始化为0的id。session_file用户可控的,通过构造id=0&sp=AAA这种,把sessionfile设置成一定不存在的文件路径,那么返回值就一定是0,可绕过id_from_post == id_from_session_file的检查。 漏洞修补:判断session文件是否存在 对用户访问的资源路径处理不恰当,访问到敏感接口。 案例四:CVE-2021-35973 Netgear wac104设备,httpd中data段存放着无需认证的页面 在判断是否需要路由认证时使用strstr来匹配,如果匹配到了就设置do_not_need_auth为1,表示请求的页面不需要认证。 绕过方式是使用/AAA%00currentsetting.htm请求,AAA是需要认证的页面,因为匹配使用的是strstr,可以成功匹配。在成功之后整个url会解码,%00截断,实际访问/AAA页面,从而无需认证也能访问需要认证的页面。 漏洞修补:url解码前检测%00 案例五:CVE-2021-20090 同样有一个白名单,...

2023年11月22日 · 2 分钟 · noir

Exchange Server(CVE-2023-36439)远程代码执行漏洞分析

0x01 漏洞描述 2023年11月微软发布的安全更新中,修复了笔者报送的CVE-2023-36439。 利用该漏洞,在与Exchange服务器位于同一内部网络的情况下,经过身份验证的攻击者可以通过PowerShell远程会话实现远程代码执行。攻击者利用CVE-2023-36439可以在服务器邮箱后端获得NT AUTHORITY\SYSTEM的远程代码执行权限。 0x02 背景介绍 Exchange 命令行管理程序基于Windows PowerShell技术构建,并提供强大的命令行界面,可实现 Exchange 管理任务的自动化。 可以使用 Exchange 命令行管理程序 来管理 Exchange 的各个方面。 例如,可以创建电子邮件帐户、创建发送连接器和接收连接器、配置邮箱数据库属性以及管理通讯组。 本漏洞位于Exchange针对Powershell数据的反序列化过程中,理解proxynotshell相关漏洞原理有助于理解本漏洞触发逻辑,相关分析可参考《CONTROL YOUR TYPES OR GET PWNED: REMOTE CODE EXECUTION IN EXCHANGE POWERSHELL BACKEND》。 0x03 漏洞分析 本漏洞编号在11月发布,但漏洞在10月补丁中已经被修补。同时11月补丁中提到新增了“Serialized Data Signing feature”机制来缓解反序列化相关漏洞问题。 所以在11月补丁的SerializationTypeConverter.cs 中可以观察到针对被反序列化数据的校验: 而在10月补丁中,通过对不同版本ChainedSerializationBinder.cs进行对比可直观发现以下结果: 在BuildDisallowedTypesForDeserialization函数中新增了黑名单类型System.Xaml.XamlServices。 System.Xaml.XamlServices.Parse方法与常见的XamlReader.Parse其实在功能、危害及利用方法上其实没有本质区别。 比如执行以上代码将调用计算器,所以本漏洞实际上是CVE-2022-41082的一个变种。 但其实从CVE-2022-41082以后,增加了ValidateTypeToDeserialize函数对类型进行黑名单校验;在CVE-2023-21529、CVE-2023-28310 以后增加了vistor模式的递归黑名单校验;在CVE-2023-36745、CVE-2023-35388等漏洞后增加了vistor模式的白名单校验,为什么这个漏洞还能够触发? 以下是Exchange反序列化时,白名单校验的逻辑 可以看到当typeToDeserialize.IsAbstract为true,且类型名称不为System.Type时,认为类型合法。 可以看到XamlServices并没有被声明为Abstract,但IsAbstract的属性为true 这是因为在C#中,如果一个类被声明为static,则它的IsAbstract属性会是true。在C#中,静态类在概念上是抽象的,不能被实例化。 所以XamlServices以这种‘反直觉’的方式成为了漏网之鱼,只需要简单替换目标类,利用方法与CVE-2022-41082完全一致。 0x04 总结 本文分析了CVE-2023-36439的补丁及漏洞成因,同时简单统计可以发现关于Exchange Powershell模块已经披露了超过10个相关漏洞,并且大部分都可以通过变种分析来发现,文中提到的多个漏洞编号其实均为CVE-2022-41082(proxynotshell)的变种漏洞,同时比如10月补丁的CVE-2023-36778其实也是CVE-2022-41076的相似漏洞。通过本文希望能帮助读者更好理解Exchange Powershell模块的相关漏洞原理。

2023年11月17日 · 1 分钟 · m4yfly

WAF防护绕过技巧分析

一、WAF介绍与分类 (一)WAF简介 Web应用防护系统(Web Application Firewall,网站应用级入侵防御系统),是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的产品。 市场上的WAF产品有很多,像腾讯云,阿里云,长亭等,目前世界上常年排名第一的是以色列的 Imperva。 (二)WAF分类 规则实现 语义分析引擎WAF,国内大多数都是正则引擎,此外还有机器学习引擎。 部署方式 网络层WAF、应用层WAF、云WAF WAF部署方式 WAF大多是串联在这个链路中,起到一个阻断作用。就比如在Web Server和CGI之间的WAF,CGI这里特指PHP和ASP,像JSP一般就统一tomcat中间件了,就不需要CGI层了。 云部署一般先会起一个高防IP,然后用这个IP去连接WAF集群,一般来说都是从四层的流量解除七层的流量,然后再将正常的流量向后端转发,像这些企业A企业B可能在云上也可能不在。 二、网络层WAF Bypass (一)分包分组 通过调整MSS控制分包 控制MSS去调整TCP分包的大小 单个TCP会话可能含有多个HTTP会话:比如TCP先建立一个三次握手,建立之后发送多个HTTP请求,并没有断开,一般的设备都会去很好的解析处理,但是有一些古老的设备只会去解析第一个,现在已经很少了。 单个TCP包发送多组HTTP报文(Pipeline技巧以及HTTP请求走私):就是在DATA部分写多个http请求,有的设备就会认为第一个正常,那么后面的就类似于body部分,就会出现解析错误。 HTTP请求走私和Pipeline的区别就是请求走私利用不同的Content-Length引发歧义,比如下面这个,第一个content-length是包括了下面两个,或者content-length写一个1或者2,到底Web Server会取哪一个,需要针对不同的去研究,所以取值的解析差异,就会认为他是一整个或者是三个,利用这种方式就可以去迷惑WAF。 在标准的HTTP走私里面,一般content-length和Transfer-Encoding只会采纳一个,大部分优先是 Transfer-Encoding: chunked,当然也有一些两个都支持,就会出现一些问题。 chunked 利用chunked切分,比如下面是个最简单的chunked,对关键字进行一个拆分。 这里的5,4,3是以16进制写的,最后以0来结尾,如果是10个字符的话就要写A。 这种是只针对于网络层,应用层就不会出现这种问题,因为应用层是在完成chunked组包之后,才去解析,所以对应用层无效。 三、应用层WAF Bypass (一)multipart/form-data 理论知识 HTTP协议POST请求,除了常规的application/x-www-form-urlencoded以外,还有multipart/form-data这种形式,主要是为了解决上传文件场景下文件内容较大且内置字符不可控的问题。multipart/form-data格式也是可以传递POST参数的。对于Nginx+PHP的架构,Nginx实际上是不负责 解析multipart/form-data的body部分的,而是交由PHP来解析,因此WAF所获取的内容就很有可能与后端的PHP发生不一致。 使用以下脚本来进行测试 <?php echo file_get_contents("php://input"); var_dump($_POST); var_dump($_FILES); ?> 正常POST请求如下: change body encoding,如下: 只有input不太一样,一个有f=1一个没有,参数并没有进入Files数组,而是进入了_POST数据。那么,何时是上传文件?何时是POST参数呢?这个关键点在于有没有一个完整的filename=。这9个字符是经过反复测试的,缺一个字符不可,替换一个字符也不可,在其中添加一个字符更不可。 加上filename=之后: 可以看到这次并没有传给POST数组,而是传给了FILES数组变成了一个文件。 Bypass WAF的核心思想在于,一些WAF产品处于降低误报考虑,对用户上传文件的内容不做匹配,直接放行,比如一些压缩包图片之类的,在二进制流下面任意字符是不可控的,所以里面出现一些危险函数是很正常的。事实上,这些内容在绝大多数场景也无法引起攻击。所以让POST过去的数据去过那些规则,让FILES的只要符合白名单即可。 但关键问题在于,WAF能否准确有效识别出哪些内容是传给POST数组的,哪些传给_FILES数组?如果不能,那我们是否就可以想办法让WAF以为我们是在上传文件,而实际上却是在POST一个参数,这个参数可以是命令注入、SQL注入、SSRF等任意的一种攻击,这样就实现了通用WAF Bypass。 基础案例 0x00截断filename 截断之后发现传给了POST数组 有的WAF在处理包之前会将00删掉,再去解析会产生差异,所以有的地方00是不能删的,所以会产生bypass 双写上传描述行 双写后,一些WAF会取第二行,而实际PHP会获取第一行 双写整个part开头部分 可以看到取的还是第一行,只不过会将第二部分全部当成f的值,这里做SQL注入比较麻烦,需要将前面全都闭合掉,但是命令注入就很简单,直接将1给改成payload即可优先执行。 这里可以延伸出构造一个假的part 构造假的part 和上一个类似,少了一个换行,这样原本干扰的部分就不会取了 双写boundary 可以看到是以a为主 双写Content-Type 还是以a为主...

2023年11月08日 · 1 分钟 · ink

伪随机数问题浅析

0x01 前言 随机数在许多科学和工程领域扮演着重要角色,尤其在计算机科学和信息安全领域,它的重要意义更是不可小觑。在这个全球数字化的时代,数据是我们经济和生活的核心,数据的安全和保密显得尤为重要。我们使用密码保护我们的银行账户、电子邮件、社交媒体账户,我们使用加密技术保护我们通信的隐私性。在这些过程中,随机数是其中最重要的一部分,它用于密码生成、数据加密、身份验证和网络协议安全,是保证电子交流安全的令牌。如果我们不能保证所生成的随机数实际上是随机的,那么它们就可能被预测,这将让我们面临安全风险。因此,在探讨随机数的同时,我们须深化理解随机性的安全性,以便更有效地使用随机数,保护自身和数据免受攻击。 本次分享的两个案例(CVE-2023-42820和CVE-2022-35890)均是由于随机数使用不当从而导致了更加严重的安全问题。 0x02 随机数相关基础知识 根据密码学原理,随机数的随机性检验可以分为三个标准: 统计学伪随机性:在给定的随机比特流样本中,1的数量大致等于0的数量,满足这类要求的数字在人类“一眼看上去”是随机的 密码学安全伪随机性:给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分 真随机性:随机样本不可重现 相应的,随机数也分为三类: 伪随机数:满足第一个条件的随机数 密码学安全的伪随机数:同时满足前两个条件的随机数,可以通过密码学安全伪随机数生成器计算得出 真随机数:同时满足三个条件的随机数 密码学安全伪随机数生成器(CSPRNG) 相较于统计学伪随机数生成器和更弱的伪随机数生成器,CSPRNG所生成的密码学安全伪随机数具有额外的伪随机属性,简单来说CSPRNG本质上属于一种单向函数 这是一个使用python random库生成随机数的例子 >>> import random >>> random.seed(123) >>> random.random() 0.052363598850944326 >>> random.random() 0.08718667752263232 >>> random.seed(123) >>> random.random() 0.052363598850944326 >>> random.random() 0.08718667752263232 >>> random.random() 0.4072417636703983 >>> random.seed(123) >>> random.random() 0.052363598850944326 对于随机数的使用,一般是先播种,然后使用rand来获取随机数。不播种会使用默认的种子,不同的语言不通版本种子可能不一样。这种通过rand出来的随机数,就是伪随机数,只要种子固定那么每次生成的随机数序列就会一样,同时通过上面的例子,可以发现以下特点: 在播种后会重置随机序列 random.seed()进行播种时并没有产生新的对象,就会对后面的random产生影响,那么推断播种后种子对播种时的整个进程生效 对于Java这种有新对象生成的语言来说,如果每次都是调用的同一个对象,那么与上面的情况一致,播种后会对这个对象后面生成的随机数产生影响 public class A{ public Random random; public void init(){ long seed = 123456L; this.random = new Random(seed); } public static void main(){ this....

2023年11月03日 · 5 分钟 · wangyao04

Windows内核竞态条件漏洞研究

一、研究背景 (一)操作系统内核漏洞 操作系统是计算机系统的核心软件,其主要功能在于管理计算机系统中的各种软硬件资源,并为计算机用户和用户程序提供访问这些资源的统一抽象。为达到这一设计目标,操作系统内核通常运行在称为内核态的高特权级执行环境中。一旦操作系统内核被恶意攻击者非法侵入,攻击者便可立即拥有对整个计算机系统的控制权,造成极大危害。因此,针对操作系统内核的漏洞挖掘一直是学术界和工业界的研究重点。 Windows操作系统是桌面计算机领域最广泛应用的操作系统之一,在网络空间中扮演着至关重要的角色。与之对应的,Windows操作系统中存在的安全漏洞也往往具有广泛的影响和严重的潜在危害。攻击者可以利用这些漏洞来进行大规模的网络攻击,给网络安全带来严重的威胁。例如,在2017年流行的WannaCry勒索病毒攻击,就是利用了MS17-010“永恒之蓝”漏洞,其受害者遍布全球多国,造成了巨大的损失。 在Linux操作系统上,以Syzkaller为代表的模糊测试工具可以7x24小时不间断地对内核进行漏洞挖掘,并自动化地生成漏洞报告供维护者查阅。然而,在Windows操作系统上,还没有出现影响力和测试效果能够比拟Syzkaller的开源工具。造成这一差异的原因是多方面的,例如,研究人员可以通过对Linux源码进行静态分析得到供Syzkaller使用的Syzlang模版,其中包含对系统调用接口的完整描述,由此可以驱动模糊测试。但在Windows上,由于内核是闭源的,对其系统调用接口的分析过程更为复杂和困难。 通过分析近年来披露的Windows内核态漏洞,我们发现,这些漏洞大多是由独立的研究人员或安全研究团队发现,并且极大地依赖于专家知识,只在特定的情况下使用了模糊测试等自动化方法来辅助漏洞挖掘。奇安信天工实验室近年来在Hyper-V中发现的漏洞,也同样离不开安全研究员对Hyper-V整体架构和漏洞模式的深入理解。 有鉴于此,笔者也针对近年来披露的Windows内核态漏洞进行了人工的分析和研究,并主要聚焦于竞态条件这一漏洞类型。本文便是对相关研究发现的总结。 (二)竞态条件漏洞 竞态条件是计算机科学中的一个重要概念,它指的是在多线程或多进程环境中,由于不恰当的同步操作或竞争资源的访问而导致的不确定性行为。在现代操作系统中,多线程的程序调度是至关重要的一项任务,它直接影响了计算机系统的性能和资源利用效率。多线程编程允许程序同时执行多个任务,从而提高了系统的响应速度和并发处理能力。然而,为了有效地管理这些线程,操作系统必须具备高效的调度机制,决定哪个线程获得CPU时间片,以确保各个线程能够合理地分享计算资源。这一调度决策是基于一系列算法和策略进行的,涉及到线程的优先级、状态管理、抢占机制以及资源争用解决等多个方面。 这一调度机制也导致多个线程或进程在争夺资源的同时,执行顺序并不确定,因此可能会产生意想不到的结果。为了避免问题,多线程场景下对关键资源的访问需要利用加锁、同步等机制来保证安全。倘若多个线程同时访问共享变量或资源,而没有适当的同步机制来保护这些资源,这可能导致数据损坏、程序崩溃或不一致的结果,从而带来严重的安全和可靠性问题。 图1:典型的竞态条件成因,两个线程无保护地访问同一个内核对象 如图1所示,漏洞CVE-2022-29142的原因正是两个线程可以同时访问同一个内核对象,如果其中一个线程试图关闭该对象的句柄,另一个线程便可能访问已被释放的指针。 本文将会具体介绍竞态条件漏洞带来的潜在风险,并描述复现真实存在于Windows内核中的竞态条件漏洞时的发现。 二、漏洞分析采用的关键技术 在进行针对Windows内核的漏洞分析和研究时,主要采用的关键技术包括:补丁对比分析、二进制逆向分析、竞态条件构建和调试等。 (一)补丁对比及二进制逆向分析 通过在CVE数据库中的检索,发现近年来披露的Windows内核漏洞中不乏用户提权和任意代码执行等高危漏洞。然而,由于微软积极控制漏洞的影响,相关漏洞的公开PoC程序数量相对较少。对于那些没有公开PoC的漏洞,往往只能获得漏洞发现者通过博客或社交媒体透露的少量信息,难以由此开展系统性的漏洞研究。考虑到这些漏洞的修复补丁存在于Windows安全更新中,通过对补丁进行分析,包括进行补丁的解包和二进制对比等,能够有效地从中提取出更新内容,识别受影响的模块,并可以进一步地从中提取关键的补丁点,由此分析补丁所修复的漏洞。 为了能够解析微软的Windows安全补丁,首先需要了解补丁的格式以及获取方法。打包补丁的文件格式包括:.MSU(Microsoft Standalone Update)和.CAB(Cabinet)格式。补丁一般会作为 Windows 更新的一部分自动分发到用户设备上,但也可以直接从微软的更新目录中下载独立的补丁。此前,微软主要提供顺序的更新包,它们必须依次安装到用户的系统中。如今,更新以累积的方式提供,这意味着基本系统版本中的所有必需更新都包含在补丁包中,这也允许用户平滑地升级系统版本。此外,出于节省带宽等考虑,许多更新以增量的方式分发,即:更新包中只包含对特定二进制目标的修补方式,而不包含全部的文件。这也进一步增加了补丁分析的难度。 对于每次安全更新,具体的补丁文件可以从Microsoft Update Catalog上获取。.MSU格式的补丁在使用expand.exe程序解包后,将能够获得.CAB格式的补丁文件,且这些文件按照指令集和二进制差异类型进行命名。对于补丁内容的进一步提取,将依赖于微软提供的msdelta.dll库。该库中提供了ApplyDelta系列函数用于执行Windows系统更新。通过C或Python语言调用相关库函数,即可实现打补丁的过程,获得补丁之后的二进制文件。 图2:漏洞CVE-2023-21537补丁对比 最后,通过BinDiff或Diaphora等二进制对比工具,即可完成对补丁内容的分析,并由此定位到漏洞点。如图2所示,以漏洞CVE-2023-21537为例,通过对比分析补丁前后的函数控制流图,可以发现补丁新增了参数检查的分支(见红色框)。在确定可能的漏洞点后,即可开展人工的逆向分析。 (二)Windows内核调试 在成功确定漏洞点后,下一步是构造PoC程序,并触发漏洞行为,例如使内核出现崩溃,造成蓝屏死机(Blue Screen of Death)。再此基础上,可以进一步构造漏洞利用的方式,例如,利用释放后使用(Use after free)漏洞来覆盖关键的内核数据结构,实现进程提权的效果。 为了触发内核中的漏洞代码的执行,需要构造用户态程序执行系统调用或驱动程序的IoControl调用。这些函数调用往往需要大量的参数,并且,参数需要满足一定的约束条件。在实际的测试中,发现通过人工构造的参数难以一次性通过检查,必须不断进行调试并修改PoC程序。 微软提供了WinDbg程序用于支持Windows内核调试,但由于在内核函数中触发断点等操作会中断整个系统的执行,因而必须在另一台计算机上运行WinDbg,并通过TCP连接至待调试的计算机。在实际的实验中,相关的内核调试借助Hyper-V虚拟机完成。经笔者测试,运行在Hyper-V虚拟机中的Windows系统开启内核调试模式并设置端口和密钥参数后,即可在Host上通过WinDbg程序开启TCP连接进行内核调试。 三、典型漏洞分析 笔者总共分析和研究了10个近年来被披露并分配了CVE编号的Windows内核竞态条件安全漏洞,具体的漏洞编号、内核模块和漏洞类型情况如表1所示。下面将通过案例分析介绍其中的典型漏洞,以及对未来针对此类漏洞进行自动化挖掘的启发。 CVE ID 内核模块 漏洞类型 CVE-2018-7249 secdrv.sys UAF CVE-2018-8410 ntoskrnl Double dereference CVE-2018-8611 ntoskrnl UAF CVE-2020-1015 UMPS UAF CVE-2021-26868 win32k UAF CVE-2021-40449 win32k UAF CVE-2021-41335 ntoskrnl OOB CVE-2022-29142 ntoskrnl UAF CVE-2023-21536 ETW UAF CVE-2023-21537 mqac....

2023年11月01日 · 1 分钟 · mimi

Microsoft Hyper-V 虚拟 TPM 设备漏洞分析

一、漏洞描述 2023年10月微软发布的安全更新中,修复了2个由笔者报送的Hyper-V虚拟TPM设备漏洞。本次修复的Hyper-V虚拟TPM组件的漏洞可以通过远程访问虚拟机的方式触发漏洞,造成宿主机拒绝服务或者远程代码执行,对宿主机上的其他虚拟机或业务造成损失。 二、背景介绍 Hyper-V的虚拟TPM组件旨在为虚拟机提供模拟的TPM设备,虚拟TPM设备可以为依赖TPM设备的服务或者操作系统(例如Windows 11)提供支持。 漏洞位于vmsp.exe进程中的TpmEngUM.dll二进制文件中,本次介绍的两个虚拟TPM组件的漏洞就是位于TpmEngUM.dll这个二进制文件中。 vmsp.exe进程与vmwp.exe进程相似,都是一个虚拟机实例启动一个进程。但是不同的是vmsp.exe进程是隔离用户模式(IUM)进程,也就是说vmsp.exe进程无法在windows用户态下被正常attach。所以在调试上,针对vmsp.exe进程的调试就需要额外的“手脚”,这里我们引用Quarkslab博客的文章(https://blog.quarkslab.com/debugging-windows-isolated-user-mode-ium-processes.html),感兴趣的读者可以去了解并实践下,这里不做讨论。 三、环境搭建 虚拟TPM组件漏洞的触发需要在Hyper-V虚拟机设置中的“安全”设置中,勾选“启用受信任的平台模块”。 四、漏洞分析CVE-2023-36717 该漏洞是一个拒绝服务漏洞,当这个漏洞被触发时会导致宿主机vmsp.exe进程进入死循环,并占用大量CPU计算资源。由于vmsp.exe进程是IUM进程,所以当漏洞被触发后,管理员无法从用户态结束掉这个进程,这种情况下除非重启宿主机操作系统否则计算资源一直无法被释放。 这个漏洞位于TpmEngUM!TPM2_ECDH_KeyGen函数中。 __int64 __fastcall TPM2_ECDH_KeyGen(unsigned int *a1, __int64 a2) { OBJECT *v3; // rax OBJECT *v4; // rsi unsigned int v5; // eax unsigned int v6; // ebx unsigned __int16 v8[28]; // [rsp+20h] [rbp-58h] BYREF v3 = ObjectGet(*a1); v4 = v3; if ( v3->public_type != 0x23 || (v3->public_objectAttributes & 0x10000) != 0 || (v3->public_objectAttributes & 0x20000) == 0 ) { return 0x19Ci64; } while ( !...

2023年10月25日 · 3 分钟 · hongzhenhao

CVE-2023-0179 Linux内核提权

0x00 前言 2022年7月为天府杯准备的Linux提权漏洞,但是22年天府杯没办,23年1月被外国人报了。 思路来源于这篇文章,在看到这篇文章后决定去好好过一下netfilter相关模块。 文章链接:How The Tables Have Turned: An analysis of two new Linux vulnerabilities in nf_tables 0x01 背景 该漏洞位于Linux内核中netfilter模块对vlan进行处理的相关代码中,由于整型溢出导致的栈溢出,最后是ROP修改modprobe_path路径完成提权,在Ubuntu下测试可以稳定触发,提权成功率百分之百。 0x02 漏洞成因,加还是减 下面是漏洞代码,处理vlan相关的部分代码。 /* add vlan header into the user buffer for if tag was removed by offloads */ static bool nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u8 offset, u8 len) { int mac_off = skb_mac_header(skb) - skb->data; u8 *vlanh, *dst_u8 = (u8 *) d; struct vlan_ethhdr veth; u8 vlan_hlen = 0; if ((skb->protocol == htons(ETH_P_8021AD) || skb->protocol == htons(ETH_P_8021Q)) && offset >= VLAN_ETH_HLEN && offset < VLAN_ETH_HLEN + VLAN_HLEN) vlan_hlen += VLAN_HLEN; vlanh = (u8 *) &veth; if (offset < VLAN_ETH_HLEN + vlan_hlen) { u8 ethlen = len; if (vlan_hlen && skb_copy_bits(skb, mac_off, &veth, VLAN_ETH_HLEN) < 0) return false; else if (!...

2023年10月18日 · 4 分钟 · lm0963