硬件辅助虚拟化及Fuzzing工作研究

一、前言 在IaaS的云平台架构中,VMM(Virtual Machine Manager,也称为Hypervisor)将宿主机物理资源分配给多个客户机使用,租户拥有对客户机的控制权。VMM在不同的客户机之间实现隔离,保证租户之间互不影响。但恶意的租户可能会利用VMM的安全漏洞,逃逸到宿主机上,并进一步危害宿主机上的其他客户机,因此,在攻击者之前发现并修复VMM中的漏洞,是保证云安全的重要工作之一。 下面将依次介绍,虚拟化的背景知识、现有对VMM进行模糊测试的工作、以及VMM相关CVE的case study。 二、硬件辅助虚拟化(以Intel VT为例) 2.1 VT-x (Virtualizition Technology for X86):CPU虚拟化 处理器引入了两种操作模式: VMX Root Operation:VMM(虚拟机监控器)运行的模式,简称根模式。 VMX Non-Root Operation:Guest(客户机)运行的模式,简称非根模式。 每种模式都对应着不同的ring0-ring3特权级别。当处理器从非根模式切换到根模式时,称为VM-Exit;而当处理器从根模式切换到非根模式(例如,VMM调度某个客户机运行)时,称为VM-Entry。 此外,Intel VT-x引入了VMCS(Virtual Machine Control Structure),该结构用于保存虚拟CPU的状态信息。例如,在模式切换时,VMCS会保存处理器状态,如RIP(指令指针)的值,以及两种模式下控制寄存器的值等。VMM可以通过修改VMCS中的内容,来影响CPU的行为。 VT-x还新增了一些指令,用于虚拟化控制: VMLAUNCH/VMRESUME:用于触发VM-Entry。 VMREAD/VMWRITE:用于读取或写入VMCS。 VMXON/VMXOFF:用于进入或退出VMX模式(是否可以执行VMXON取决于处理器的支持)。 VMX的lifecycle如下图所示,首先,软件通过执行VMXON指令进入根模式。在此模式下,VMM可以通过VM Entry(使用VMLAUNCH和VMRESUME指令)加载客户机运行,处理器切换到非根模式。当遇到客户机无法处理的情况,会通过VM Exit将控制权转交给VMM,处理器切换回根模式。VMM可以根据VM Exit的原因采取相应的操作,处理后再通过VM Entry重新加载客户机运行。最后,VMM可以通过执行VMXOFF指令退出VMX操作模式,结束VMX的lifecycle。 VCPU VCPU描述符类似进程描述符,本质是一个结构体,除了VMCS以外,这个结构体还包含VCPU标识信息(例如属于哪个客户机)、VCPU状态信息(例如睡眠还是运行)等,主要供VMM调度时使用。VMM创建客户机时,首先要为其创建VCPU,客户机的运行就是VMM调度不同的VCPU运行。 VCPU的创建 创建VCPU描述符实际上是分配相应大小的内存并进行初始化,具体的初始化内容包括: 分配VCPU标识:标识该VCPU所属的客户机。 初始化虚拟寄存器组:主要就是指初始化VMCS的相关域。 初始化VCPU的状态信息。 初始化额外部件:包括未被VMCS覆盖的寄存器和虚拟LAPIC等部件的配置。 初始化其他信息:根据VMM实现的不同,对VCPU的私有数据进行初始化。 其中,VMCS初始化包括以下几个部分: 客户机状态域:根据物理CPU初始化的状态来设置。例如,物理CPU加电后跳转到BIOS,GUEST RIP字段会设置为虚拟机BIOS的起始地址。 宿主机状态域:参考VMM运行时CPU的状态,用于描述VM-Exit时,CPU切换回根模式时的寄存器值。例如,HOST RIP通常设置为VMM中VM-Exit处理函数的入口地址。 VM-Execution控制域:设置哪些特权指令会触发VM-Exit。 VM-Exit控制域:通常由VMM设置,控制一些字段,如Acknowledge interrupt on exit,有助于快速响应外部中断。 VCPU的运行 当VMM调度VCPU到物理CPU上运行时,需要进行上下文切换,既包括硬件自动切换(VMCS部分),也包括VMM软件切换(非VMCS部分,如浮点寄存器)。具体步骤如下: VMM保存自己的上下文:VMM保存VMCS中未包含的寄存器内容。 加载VCPU上下文:VMM将VCPU中由软件切换的上下文加载到物理CPU。 执行VMLAUNCH/VMRESUME:VMM通过执行VMLAUNCH/VMRESUME指令触发VM-Entry,CPU自动将VCPU中的VMCS部分加载到物理CPU,并切换到非根模式。 \ VCPU的退出 与进程类似,VCPU作为调度单位不会一直运行,它会因为执行特权指令、物理中断等原因发生退出,这种退出称为VM-Exit。发生VM-Exit时,VMM的处理流程如下: VM-Exit发生时,CPU自动进行部分上下文切换。 CPU切换到根模式,并执行VM-Exit的处理函数。 \ 当发生VM-Exit时,相关的处理函数由VMM实现。该处理函数负责根据触发VM-Exit的原因采取相应的处理。虽然VM-Exit的原因可能各不相同,但这些原因的代码可以在Intel的开发者手册中找到。下图截取了手册中的部分exit reasons。 \ VCPU的再运行 当VMM处理完VM-Exit后,会重新调度VCPU继续运行。如果VCPU继续在同一物理CPU上执行,可以通过VMRESUME指令实现VM-Entry。若VCPU被调度到另一物理CPU上运行,由于VMCS与物理CPU是一对一绑定的,VMM需要将VMCS重新绑定到新的物理CPU,然后通过VMLAUNCH指令触发VM-Entry。...

2024年12月18日 · 4 分钟 · tiangong

vCenter漏洞分析:CVE-2024-37079 & CVE-2024-37080

一、前言 CVE-2024-37079 和 CVE-2024-37080 是两个存在于DCERPC组件中的漏洞,攻击者可以通过构造恶意请求,在远程触发 vCenter Server 上的任意代码执行。这些漏洞位于 DCE/RPC 协议中,具有 vCenter Server 网络访问权限的远程攻击者可以通过发送特制的网络数据包,在 DCERPC 协议实施过程中触发堆溢出漏洞,从而实现远程代码执行。。目前两个漏洞已报送厂商并于6月份修复完成。本文将详细讲解两个漏洞的成因。这两个漏洞已于2024年6月报送厂商并修复完成。本文将详细分析这两个漏洞的成因。 二、DCE/RPC协议介绍 DCE/RPC协议(Distributed Computing Environment / Remote Procedure Call)源于20世纪80年代,由Open Software Foundation(OSF)开发,作为开放分布式计算架构的一部分。其最初设计目的是为跨网络的异构计算机系统提供一种统一的远程过程调用(RPC)机制,从而简化不同系统之间的通信。随着网络技术的发展,DCERPC逐渐被广泛应用,特别是在Unix、Windows NT等系统中。微软在采用DCERPC协议的基础上进行了扩展,用于Windows系统中的重要服务和应用程序,尤其在Windows NT中用于SMB(Server Message Block)协议。由于微软的广泛采用,DCE/RPC成为了企业网络和操作系统中不可或缺的通信协议。 DCE/RPC协议为了实现远程过程调用,使用接口定义语言(IDL)定义接口。在IDL代码中定义了UUID,版本,接口,方法,参数,返回值以及使用到的复杂数据类型等信息。服务端和客户端通过共享这些信息完成远程过程调用的通信,其中UUID作为接口标识用于客户端向服务端发送绑定请求,建立上下文。 DCE/RPC远程过程调用通信的流程(如图一)通常如下: 客户端初始化请求:客户端向服务器发起绑定请求(Bind),选择所需的远程接口,提供接口UUID和版本号,并协商通信协议和数据传输语法(如NDR)。 服务器响应绑定:服务器接收到客户端的绑定请求后,确认是否支持请求的接口UUID、版本号和传输语法。如果支持,返回绑定确认(Bind Ack),否则返回绑定失败(Bind Nack)。 客户端发送调用请求:在成功绑定后,客户端构造远程过程调用的请求(Request)消息,包含所调用的方法及其参数,并将这些参数进行编组(序列化)。 服务器处理请求:服务器接收到请求消息后,解组请求中的参数,调用相应的本地方法进行处理。处理完成后,服务器将结果重新编组并发送响应(Response)消息。 客户端接收响应:客户端接收到响应消息后,解组数据并获取调用结果。如果调用过程中发生错误,服务器会返回故障消息(Fault),客户端需进行相应处理。 上下文修改请求:如果客户端需要更改通信中的上下文(如修改接口、更新权限或改变数据传输语法),客户端可以发送Alter Context Request,请求修改现有的上下文参数。 上下文修改响应:服务器接收到Alter Context Request后,检查请求的上下文修改是否有效。如果上下文修改成功,服务器返回Alter Context Response,确认新的上下文已生效。如果修改失败,服务器返回错误信息,客户端可以重新发送修改请求或终止会话。 客户端解除绑定:在完成所有调用后,客户端可以选择发送解除绑定请求(Unbind),通知服务器结束通信。 三、漏洞分析 2.1 CVE-2024-37079 CVE-2024-37079出现在bind认证数据包的响应处理过程中。负责处理认证的函数rpc__cn_assoc_process_auth_tlr 的函数声明如下,其中参数header_size 为((pres_cont_list->n_context_elem - 1) * 0x18) + 0x1c + 0x20 INTERNAL void rpc__cn_assoc_process_auth_tlr ( rpc_cn_assoc_p_t assoc, rpc_cn_packet_p_t req_header, unsigned32 req_header_size, rpc_cn_packet_p_t resp_header, unsigned32 *header_size, unsigned32 *auth_len, rpc_cn_sec_context_p_t *sec_context, boolean old_client, unsigned32 *st ) pres_cont_list->n_context_elem 的值来源于与数据包的Num Ctx Items字段...

2024年12月11日 · 4 分钟 · zhz

系统文件管理行为漏洞导致本地提权

一、前言 近期,符号链接在本地提权利用中的比重逐渐增加。无论是macOS、Windows、Linux操作系统,还是其第三方安装的应用程序,都可能使用符号链接。越是底层的函数调用,开发者越需要关注相关漏洞模式及函数参数传递的安全性。 一个漏洞的产生通常是由于在使用API函数时未充分考虑潜在的漏洞模式。如果在执行过程中存在恶意行为对这些函数进行修改,防护措施不严格会导致执行流程走向错误的分支,最终被攻击者利用。下面将以open和rename两个基础函数为例,介绍多个相关漏洞。 二、函数介绍 2.1 OPEN函数 open函数是C语言中的一个基础函数,主要用于打开文件并返回一个文件描述符。其他函数可以通过这个文件描述符对文件或目录进行读写操作。其函数原型如下: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); open函数存在三个参数: mode: 可以在调用时省略第三个参数mode,在创建新文件的时候,会通过此参数修改新文件的文件属性; pathname: 用于一个指向文件或者文件夹的路径,可以为绝对路径也可以为相对路径; flag: 作为open函数最重要的一环,参数flag能赋予的值有各种,不同的flag字段代表着不同的功能。 2.2 RENAME函数 rename函数作为C语言中的一个基础函数,主要用于处理文件或目录的移动和重命名。该函数不会修改文件或目录的属性。其函数原型如下: #include <stdio.h> int rename(const char *oldpath, const char *newpath); rename函数只有两个参数,一个是指向旧文件的字符串指针,另一个是指向想要修改后的新文件字符串指针。无论是哪一个参数,它都不会去检测访问路径是否是符号链接,即目录是通过符号链接访问的依旧会执行。反之,若是指向的最终文件/目录是符号链接,rename不会对其访问,只有在访问过程中的目录路径属于符号链接时才会进入。 三、行为检测与漏洞分析 通常,对于系统调用号的检测,在Linux上有成熟的方法。在macOS上,也有专门用于监控文件行为的系统命令fs_usage。fs_usage可以实时监听系统用户态上对文件的各种操作行为,包括文件状态获取、读写操作以及页面交换等。通过使用fs_usage,开发者和安全研究人员能够详细地跟踪和分析文件相关的系统活动,从而更好地理解和诊断文件操作中的问题。 如上图所示,可以配合grep命令获取对应进程的相关行为。通过该命令,可以简化对文件流处理的追踪,直接从所执行的系统行为或系统调用中定位到具体的代码。 对于编程语言而言,它们提供了许多封装好的API函数。在Objective-C和Swift中,也有相当多的函数底层实现可以进行分析。这些封装好的API函数不仅简化了开发过程,还为开发者提供了强大的功能。通过对这些底层实现的分析,可以更好地理解其工作原理,并在必要时进行优化或调试。 此处编写一个使用moveItemAtPath:toPath:函数的示例代码,并为rename函数设置断点。通过这种方式,可以发现最终实现也会调用rename函数。 3.1 CVE-2020-9900 文件写入自定义目录 在macOS系统中,后台存在一个以root权限启动的进程,即CrashReporter。该进程负责收集系统各种崩溃报告和日志,并将其存放于/Library/Logs/DiagnosticReports和~/Library/Logs/DiagnosticReports目录中。这两个目录的所属用户是_analyticsusers,而默认用户通常属于admin用户组,因此默认用户拥有读写上述两个目录的权限。 如上图所示,系统会根据报告生成的时间和进程名等字段,将崩溃报告存放于指定目录中。在这些目录中,存在一个名为Retired的子目录。报告的存放时间是有期限的,当报告超过这个期限时,另一个以root权限启动的进程SubmitDiagInfo会将旧报告移动到Retired目录中。由于SubmitDiagInfo同样是以root权限运行的进程,在没有沙箱等安全规则干扰的情况下,它在访问相关root权限的目录或文件时不会因为权限不足而受到限制。 fmyy@Macbook_M1 DiagnosticReports % ps -ef |grep SubmitDiagInfo 0 1043 1 0 一10上午 ?? 0:03....

2024年12月04日 · 3 分钟 · fmyy

CVE-2018-9568漏洞分析和利用

一、前言 CVE-2018-9568是一个Linux内核中的类型混淆漏洞,Zer0Con2019有研究人员分享了利用该漏洞root Android的思路,并给漏洞命名为WrongZone。这是一个影响范围较广的漏洞,本文记录了学习分析该漏洞及在 x86_64 Linux 完成利用的过程。 二、漏洞分析 2.1 补丁 该漏洞的补丁链接:commit 9d538fa60bad4f7b23193c89e843797a1cf71ef3 diff --git a/net/core/sock.c b/net/core/sock.c index 9b7b6bbb2a23e7..7d55c05f449d30 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1654,6 +1654,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sock_copy(newsk, sk); + newsk->sk_prot_creator = sk->sk_prot; + /* SANITY */ if (likely(newsk->sk_net_refcnt)) get_net(sock_net(newsk)); 补丁代码很简单,只有一行赋值代码,因此sk_prot和sk_prot_creator是该漏洞的关键。 sk_prot与sk_prot_creator 它们都是struct sock结构体的成员: struct sock { /**/ struct sock_common __sk_common; /**/ #define sk_prot __sk_common.skc_prot /**/ struct proto *sk_prot_creator; }; struct sock_common { /**/ struct proto *skc_prot; /**/ }; sk_prot_creator和sk_prot(即skc_prot)在源码中的定义如下:...

2024年11月27日 · 4 分钟 · clingcling

DataCon 晚自习:浅谈大模型辅助漏洞挖掘

一、前言 大语言模型(LLM)近期成为安全研究和竞赛中的热门话题,涵盖了大模型在安全领域的应用以及自身的安全性等方向,这一趋势为许多非大模型安全研究领域的研究者提供了了解和探索的机会。 得益于强大的上下文理解与模式识别能力,大模型被认为具备从已知漏洞中学习特征并检测、修复未知漏洞的潜力。目前,大多数基于大模型的漏洞检测和修复方案集中在函数级别,只处理小范围的代码片段,不过也有少量研究开始探索代码库级别的问题。 本次 DataCon 聚焦于真实漏洞环境,提供了和漏洞相关的完整程序代码,要求参赛者"结合大模型技术自动化识别出漏洞样例中存在的安全隐患"。为此,本文将从函数级别和代码库级别两个方面简要分析和梳理当前研究进展,并结合代码库级别漏洞检测的需求,探讨未来的研究方向。 二、函数级别漏洞检测 本节主要参考 Large Language Model for Vulnerability Detection and Repair: Literature Review and the Road Ahead,未注明来源的研究方法,可在该综述中查阅 从提升大模型漏洞挖掘能力的角度,主要可以将当前研究分为三种方法:微调、提示工程和检索增强生成(RAG)。微调通过在漏洞数据上的定向训练来调整模型的参数;提示工程则以黑盒的方式,通过精心设计的 prompt 来优化模型在具体应用场景中的输出效果;RAG 从数据库中检索相关知识并整合到 LLM 的上下文中,同样不需要修改 LLM 的参数。 2.1 微调 一般的微调训练包含以下几个步骤:数据准备、模型设计、模型训练和模型优化。根据不同研究方法主要针对的训练阶段,可以划分为以下几个类别: 以数据为中心的创新(数据准备) 漏洞数据集通常存在标签不平衡和标签不正确的问题。一些研究通过数据采样、伪标签生成以及反事实数据生成等方法,尝试针对这些问题提出解决方案。 结合程序分析方法(数据准备) 一些研究将程序分析工具的结果引入模型的预训练或微调阶段,以帮助 LLM 更好地理解代码逻辑和数据依赖关系。例如: 可以提取抽象语法树(AST)和程序依赖图(PDG)来进行语句级控制依赖和数据依赖的预训练。 利用程序切片提取控制和数据依赖信息,将控制流图(CFG)分解为执行路径,为模型提供漏洞检测的支持。 结合其他深度学习模型(模型设计) 通过 Bi-LSTM (双向长短期记忆网络)处理分段后的代码输入克服了 LLM 的长度限制;亦或是通过 GNN (图神经网络)提取代码的图结构特征来补充 LLM 对代码结构的理解。 针对特定领域进行训练(模型训练) 通过在特定编程语言和特定漏洞类型的数据上进行预训练,使用如掩码语言模型、对比学习、程序依赖预测和漏洞语句标注等不同的预训练目标,可以增强模型对特定编程语言、特定漏洞模式以及复杂代码依赖关系的理解能力。 因果学习(训练优化) 通过识别和剔除那些与漏洞标签存在虚假相关的非稳健特征,进而使用因果推理算法来提升模型的因果推理能力。 其中,相比于其他方法更像是在解决一些大模型的通病,“结合程序分析方法"以及"针对特定领域进行训练"两类方法,则更依赖研究者对程序分析和漏洞挖掘领域的深入理解。限于时间原因笔者没能深入了解相关方法的研究细节,感兴趣的读者建议阅读相关论文。 2.2 微调:如何训练自己的模型 那如果我们想要微调自己的大模型,有哪些需要关注的问题呢?首先是选择使用的研究方法:根据数据规模、数据是否标记、模型选择和预算,可以划分为如图所示的模型训练方法。**CPT(持续预训练)**使用大量未标记的特定领域数据对已经预训练的大模型进行进一步训练;**SFT (有监督微调)**更专注于增强特定任务的性能,使用有标签的数据进行训练。**FULL(全参数微调)**细化所有参数,需要大量的计算能力和时间;相比之下,**PEFT(参数高效微调)**通过仅微调少量模型参数大大降低了计算成本,常见的 LoRA (Low Rank Approximation)就属于 PEFT 方法。在针对于漏洞检测的领域,许多研究采用了 SFT 和 PEFT。 此外,在一个不考虑特殊优化方法的微调过程中,还要涉及模型选择和数据集选择:...

2024年11月20日 · 4 分钟 · eeuk

Resin url解析特性导致权限认证绕过分析

一、前言 权限认证是一种用于控制系统资源访问的安全机制,如果权限认证存在缺陷,将对Web应用的保密性、完整性、可用性造成严重影响。 此次分享的内容是之前挖掘国内某OA漏洞时,受tomcat下路由分发特性导致认证绕过思路影响去分析的。旨在讨论Resin URI规范化特性导致的权限认证绕过问题。 二、Servlet URL匹配模式 在 java 应用中通常通过xml声明Servlet <Servlet> <!-- 唯一标识这个 Servlet 的名称 --> <Servlet-name>helloServlet</Servlet-name> <!-- Servlet 类的全限定名 --> <Servlet-class>com.Mmuz.helloServlet</Servlet-class> <!-- 初始化参数(可选) --> <init-param> <param-name>xxx</param-name> <param-value>Hello, World!</param-value> </init-param> <!-- Servlet 加载顺序(可选) --> <load-on-startup>1</load-on-startup> </Servlet> <!-- URL 映射配置 --> <Servlet-mapping> <!-- 引用上面定义的 Servlet-name --> <Servlet-name>helloServlet</Servlet-name> <!-- 定义 URL 映射路径--> <url-pattern>/hello/1.Servlet</url-pattern> </Servlet-mapping> 也可以在类定义出上使用Servlet规范中定义的WebServlet注解去声明。 Servlet声明时可以不同类型的urlpattern,当路由请求时,Servlet 会根据不同的URL模式进行匹配。匹配方式主要有4种,优先级是精确匹配 > 路径匹配 > 后缀匹配 > 缺省匹配 精确匹配 uri必须和url-pattern完全一致,如 /hello/1.Servlet 最长路径匹配 也叫路径匹配,指以*结尾的url-pattern,示匹配以该路径开头的所有请求,越长的路径匹配优先级越高。 /hello/* * 由于Resin中会将*转换为 /*,所以*是路径匹配 /* /hello/a* 匹配/hello/a/x 后缀匹配...

2024年11月13日 · 8 分钟 · mmuz

用Joern进行PHP漏洞复现与挖掘

Joern是源码级的静态分析工具,支持多种语言(二进制有ghidra支持),接下来将从Joern的基本概念,Joern的基本使用,到使用Joern来进行PHP漏洞复现,在到实际使用过程中遇到的问题和解决方案(降低误报率) 来进行介绍。 一、Joern的基本概念 在使用Joern对代码进行分析时,其主要步骤是将项目代码转换为代码属性图(CPG),再提供查询接口来供用户基于CPG进行漏洞挖掘。 Robust parsing ; Code Property Graphs ; Taint Analysis ; Search Queries ; Extendable via CPG passes Joern的官方文档中介绍其核心特点有: 强大的解析能力,指的是Joern内含多种解析器,支持将多种语言转换为代码属性图(CPG) Joern中的代码属性图是其进行静态分析的根基,该数据结构包含程序语法、控制流和数据流的相关信息 污点分析,Joern提供污点分析引擎,用户可以通过定制化的方式来对攻击者可控数据进行分析此外灵活搜索查询和CPG可扩展也是Joern的优点。对于图CPG节点和CPG图本身,Joern支持用户对其灵活的访问和修改 上图展示了用户使用Joern来进行漏洞挖掘的完整逻辑: 首先项目导入,Joern会根据用户提供的项目路径和路径下的文件名后缀来对项目进行解析生成代码属性图,比如项目中如果主要是cpp文件,Joern就会将项目识别为c++项目 生成的代码属性图将加载到Joern的shell中,shell会提供访问代码属性图的接口 用户依据自己积累的漏洞模式,通过查询的方式,对目标项目进行漏洞挖掘。比如通过设置source点和sink点,来进行污点传播分析(在第二节中介绍) Joern输出具有漏洞模式的代码传播路径,快速的帮助用户定位可能存在漏洞的地方,此时需要用户通过审计以及编写poc的方式确认漏洞是否存在 二、Joern的基本使用 使用静态分析工具常见的要求是分析程序从source点到sink点的传播路径,也就是污点传播分析。 这里的source点从宏观上讲,指的是程序中攻击者的可控输入点,具体来说如在php中的$_GET $_POST $_SERVER, 设备固件中HttpGetEnv中的返回值,main函数中的argv等。 sink点指的是程序中的污点,当攻击者输入可以进入到污点将发生安全风险,如危险函数system popen mysql_queryi的输入参数,不局限于危险函数,有特征的字符串拼接也可以设置为sink点,如"SELECT UPDATE INSERT",当程序中有sql query语句拼接特征的代表有注入风险可能。 接着将从Joern官网的例子来演示用Joern进行污点传播分析的基本使用 https://docs.Joern.io/cpgql/data-flow-steps/ //目录 :c/X42.c #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char buffer[10]; if (argc > 1 && strcpy(buffer, argv[1]) == 0) { fprintf(stderr, "It depends!...

2024年11月06日 · 4 分钟 · cynault

Rust的安全幻影:语言层面的约束及其局限性

一、Rust 简介 Rust语言自其发布以来就备受人们关注,作为一门现代的系统级编程语言,Rust在安全性方面引起了人们的极大兴趣。它与其他语言相比,引入了一系列创新的安全特性,旨在帮助开发者编写更可靠、更安全的软件。在这个基础上,许多大厂开始纷纷在自己的项目中引入Rust,比如Cloudflare的pingora,Rust版的git – gitxoide,连微软都提到要将自家的win32k模块用rust重写,足以见得其火爆程度。 之所以人们对Rust那么充满兴趣,除了其强大的语法规则之外,Rust提供了一系列的安全保障机制也让人非常感兴趣,其主要集中在以下几个方面: 内存安全:Rust通过使用所有权系统和检查器等机制,解决了内存安全问题。它在编译时进行严格的借用规则检查,确保不会出现数据竞争、空指针解引用和缓冲区溢出等常见的内存错误。 线程安全:Rust的并发模型使得编写线程安全的代码变得更加容易。它通过所有权和借用的机制,确保在编译时避免了数据竞争和并发问题,从而减少了运行时错误的潜在风险。 抽象层安全检测:Rust提供了强大的抽象能力,使得开发者能够编写更加安全和可维护的代码。通过诸如模式匹配、类型系统、trait和泛型等特性,Rust鼓励使用安全抽象来减少错误和提高代码的可读性。 Rust强大的编译器管会接管很多工作,从而尽可能的减少各种内存错误的诞生。 二、Rust 不会出现漏洞吗? 在 Rust 的各类机制下,开发人员在编译阶段被迫做了相当多的检查工作。同时在 Rust 的抽象机制下,整体的开发流程得到了规范,理论上应该是很难再出现漏洞了。然而,安全本质其实是人,错误本质上是由人们的错误认知引发的。即便是在 Rust 的保护之下,人们也是有可能犯错,从而导致新的问题的出现。对于这种场景,我们可以用一种宏观的方法论来概括,那就是认知偏差。这里可以用一个图来大致描述一下这个认知偏差: 换句话说,在使用Rust开发中,人们认为Rust能够提供的防护和Rust实际上提供的防护,这两者存在一定的差异。具体来说,可以有一下几种场景: Rust 检查时,能否防护过较为底层的操作状态? Rust 自身特性是否会引入问题? Rust 能否检查出作为mod 或者 API被其他人调用时,也能完全保护调用安全吗? 为了能够更好的了解认知差异,接下来我们就介绍几种比较典型的 Rust 下容易出现的漏洞。 三、漏洞案例一:对操作系统行为错误的认知 再进行开发过程中,Rust 通常会需要与操作系统底层进行交互。然而在这些操作过程中,本质上是对底层的API 或者对底层操作系统的操作,此时考察的是开发者对于操作系统的理解。而Rust编译器的防护机制并无法直接作用于这些底层的操作系统对象,从而会导致错误的发生。 一种常见的认知偏差就是默认操作系统提供的特性,比如说接下来要提到的特殊字符过滤规则。 3.1 BatBadBut(CVE-2024-24576) 在2024年4月,安全研究员RyotaK公开了一种他发现现有大部分高级语言中常见的漏洞类型,取名为BatBadBut,其含义为batch文件虽然糟糕,但不是最糟糕的。 batch files and bad, but not the worst 在Windows下,想要执行bat文件就必须要启动一个cmd.exe,所以执行的时候通常会变成cmd.exe /c test.bat。 每个高级语言在Windows平台下需要创建新的进程的时候,最终都会调用Windows的APICreateProcess。为了防止命令注入,它们大多数会对参数进行一定的限制,然而Windows平台下的CreateProcess存在一定的特殊行为,使得一些常见的过滤手段依然能够被绕过。作者给了一个nodejs的例子,在nodejs中,当进行进程创建的时候,通常是这样做的 const { spawn } = require('child_process'); const child = spawn('echo', ['hello', 'world']); 这种做法通常是没问题的,此时由CreateProcess创建的进程为echo,参数为后续的两个参数。同时,这个调用过程中伴随的如下的过滤函数,会将"过滤成\" /* * Quotes command line arguments * Returns a pointer to the end (next char to be written) of the buffer */ WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) { /* * Expected input/output: * input : hello"world * output: "hello\"world" * output: "hello world\\" */ } 此时,上述的指令会形成如下的指令:...

2024年10月30日 · 7 分钟 · l1nk

探索Clang Static Analyzer:使用方法与源码解读

一、前言 静态分析技术因其在学术研究和工业应用中的广泛用途而备受关注。尽管静态分析技术已经取得了长足的进步,但现有的静态分析框架仍然存在易用性方面的挑战。本文主要介绍了 Clang Static Analyzer(CSA)的使用方法,对部分检查器的源代码进行了浅析,并探讨了其设计思想。希望通过本文,能够帮助那些希望深入了解静态分析技术的同学更好地掌握相关知识。 二、CSA 工作原理 CSA 分析器的设计灵感来自几篇基础性的研究论文 (Precise interprocedural dataflow analysis via graph reachability, T Reps, S Horwitz, and M Sagiv, POPL ‘95, A memory model for static analysis of C programs, Z Xu, T Kremenek, and J Zhang)。 分析器基本上是一个源代码模拟器,它能跟踪可能的执行路径。程序的状态由状态(ProgramStateRef)进行封装。在 CSA 术语中对应 ExplodedNode。 分析器通过对分支进行推理,找出多条路径,然后对状态进行分叉。在真分支上,假设该分支的条件为真,而在假分支上,假设该分支的条件为假。这种"假设"会对程序的值产生约束,这些约束被记录在程序状态(ProgramState)中并由约束管理器管理。如果假设分支的条件会导致约束条件无法满足,那么该分支将被视为不可行,该路径将被删除,这就是路径敏感性。CSA 通过缓存节点来减少指数级爆炸,如果新节点的状态和程序点与现有节点相同,路径就会被"缓存",我们只需重新使用现有节点即可。 更详细的工作原理可以参考 CSA README.md。 总而言之,Clang Static Analyzer(CSA) 是基于 Clang AST(编译器前端) 实现的源代码静态符号执行工具。支持分析 C,C++,和 Objective-C 。基于静态符号执行技术实现了路径敏感技术,也支持过程间分析。工具被集成进 llvm-project,有长期的维护和发展。如果你对符号执行比较熟悉,会注意到其与 KLEE,Angr 的诸多相似之处。 三、CSA 安装指南 clang is all you need。...

2024年10月23日 · 9 分钟 · R0g3rTh4t

Ivanti Avalanche WLAvanacheServer组件漏洞分析

一、前言 Avalanche Web 应用程序无法独立执行任务,但是它可以自由地使用不同的服务来执行任务。信息路由(也称为 InfoRail 服务)位于两者之间,负责在服务之间分发消息。Web创建一条消息并将其发送到 InfoRail 服务,后者将其转发到适当的目标服务。目标服务处理该消息并再次通过 InfoRail 服务将响应返回给 WebWLAvanacheServer是其中的移动设备服务,默认开启在1777端口上。WLAvanacheServer这个组件首次漏洞公开时间是2023年,成为了Avalanche的新攻击面,本文主要对WLAvanacheServer这个组件进行漏洞分析。 二、消息结构 这里是在6.4.0这个版本上分析消息结构,整个消息结构由三个主要部分组成: preamble header payload 下面是一个详细的消息内存结构: 0:039> dc 0242e8c0 0242e8c0 60000000 21000000 21000000 00000000 ...`...!...!.... 0242e8d0 03000000 05000000 10000000 656e7770 ............pwne 0242e8e0 34313464 34313431 34313431 34313431 d414141414141414 0242e8f0 00000031 00000003 00000005 6e777010 1............pwn 0242e900 32346465 32343234 32343234 32343234 ed42424242424242 0242e910 00003234 00000000 00000000 00000000 42.............. 0242e920 f57527e1 08202df9 0056a528 007713b0 .'u..- .(.V...w. 2.1 preamble 它的长度为16字节,主要由以下部分组成: MsgSize:整个消息的长度 HdrSize:消息头的长度 PayloadSize:消息的payload长度 unk:这里目前不知道是做什么的,应该是某个标志,不影响分析 2....

2024年10月16日 · 9 分钟 · z1r0