原文链接:https://securelist.com/biometric-terminal-vulnerabilities/112800/
生物识别终端提供了一种独特的方法来解决安全性和可用性之间的冲突。这类工具通过独特的生物特征识别一个人。然而,生物识别终端和任何其他技术一样都有其弱点。本文从红队的角度探讨了生物识别终端的安全性,并使用流行的混合终端模型作为例子来演示终端分析方法。这些方法都很常见,适用于分析任何类型的设备。
本文讨论了生物识别终端对门禁系统的好处,分析了全球主要供应商ZKTeco的生物识别终端的漏洞。本文对安全研究人员和架构师都很有用。
我们已将发现的所有漏洞和安全问题通知到供应商。每个漏洞都已注册一个 CVE 条目:CVE-2023-3938、CVE-2023-3939、CVE-2023-3940、CVE-2023-3941、CVE-2023-3942、CVE-2023-3943。
生物识别终端介绍
在安全环境下,生物识别终端主要用于身份识别。生物识别终端通过对人类独特的身体特征(如指纹、声音、面部特征或虹膜)进行分析以实现身份识别。
生物识别终端具有两个特征。首先,它既可以获取生物特征数据,也可以验证数据。其次,生物识别终端可以连接到其他终端(如电子通行证读取器),或使用内置硬件支持其他身份验证方法。
生物识别终端的主要目的是控制对某片区域或地点的访问。因此,这类终端常被用于限制对机密数据存放场所(例如服务器机房或行政办公室)的访问,或控制对危险设施场所(例如核电站或化工厂)的访问。
这类终端还有一个很常见的功能是记录员工的工作时间以提高员工的生产力并降低其迟到早退的可能性。
在安全性方面,生物识别终端具有以下优势:
- 高度准确的识别:每个人的生物特征数据都是独一无二的,这使其成为一种可靠的身份验证方式。
- 安全:生物特征数据难以伪造或复制,这增加了系统安全性。
- 用户友好:生物特征识别不需要用户记住密码或携带门禁卡。
- 效率:生物识别终端可以快速处理大量数据,以减少等待时间。
不过这些设备也存在缺点:
- 成本:生物识别终端通常比传统的访问控制系统更昂贵。
- 错误风险:尽管生物特征数据是唯一的,但在某些情况下,系统会错误识别指尖受损的个人等。
- 隐私:有些人可能担心他们的生物特征数据在未经他们同意的情况下被存储和使用。
- 技术限制:一些生物识别方法对技术要求更高(如人脸识别在弱光条件下、被识别者戴着面具等情况下识别效率会降低)。
生物识别终端对于渗透测试人员来说是一个有趣的目标。这些设备常位于物理边界和网络边界的交汇处,在分析这两个边界的安全性时,终端所存在的漏洞会带来风险。
在安全测试方面可以围绕以下目标进行测试,包括:
- 身份验证绕过和物理访问违规
- 生物特征数据泄露
- 获取设备的网络访问权限并利用该访问权限进一步开展攻击
现在我们已经了解了生物识别终端的功能、优缺点以及与之相关的安全分析目标,我们可以基于此去分析特定的设备。
对本次测试设备的简要概述
本次进行测试的设备是ZKTeco(熵基科技股份有限公司,前称中控智慧科技股份有限公司)生产的混合生物识别终端。根据全球分销商的不同,设备可能有不同的名称,其具体外观如下。
该设备具有多个物理接口,支持四种身份验证方法,分别为生物识别(面部识别)、密码、电子通行证和二维码。
设备存在以下物理接口:
- RJ45
- RS232
- RS485(未使用)
- Wiegand In/Out
普通用户(非特权用户)与设备交互的功能较少:只能点击下图屏幕中按钮。
点击键盘按钮就会提示输入PIN码,在本次测试中,PIN码是用户的唯一ID。
如果输入了有效(现有)的 ID,屏幕将显示可用的用户特定身份验证选项。下图示例显示ID为1的用户,并且提供两种身份验证方法:生物识别和密码。
这就是非管理员或未经身份验证的用户可以使用终端执行的操作范围。
管理员可用的选项相对而言更加有趣。有了管理员权限,我们可以操控设备的所有设置。下图显示了最大访问权限的菜单。
管理员菜单可用于添加新用户、管理其访问级别、更改网络以及面部终端设置。可以说管理员权限可以达成上一节中列出的所有安全测试目标。不过获取该级别的访问权限需要通过管理员身份验证。
黑盒分析
电路分析
我们的工程分析将从黑盒分析开始,即电路分析。下图显示了我们感兴趣的电路板及其以下组件。
- SOC(HI 3516 DV300);
- RAM(K4B4G16E-BCMA,4GB);
- Flash memory(THGBMJG6C1LBAI、8Gb、BGA-153);
- UART(通用异步收发传输器)。
您可能会注意到电路板上有许多测试点。我们只对标有数字 4 的测试点感兴趣,因为这些是通用异步接收器-发送器 (UART)的位置,我们可以使用UART与设备进行通信。标有数字 3 的闪存也很有趣,因为它以未加密的形式保存了整个固件。
为了检查我们是否正确识别了 UART,我们使用示波器连接到已经确定的 TX 端口,设备可通过该端口向外部发送数据。
计算 UART 数据速率并将示波器设置为该值后,我们看到这确实是一个 UART,并且设备正在通过它发送启动日志。
接下来,我们使用 PC 连接到 UART,这有助于我们查看完整的启动日志并将引导加载程序识别为 U-Boot。
引导加载程序配置可防止任何中断启动(bootdelay = -2)或以任何其他方式与其交互的尝试。然而,在设备启动后等待了一段时间后,我们发现 UART 的波特率(比特/秒)从 57,600 切换到 115,200,因为设备开始发送统一的数据包,这表明使用了未知协议。
每个数据包都以 0x53 0x53 字节开头,第五个字节始终与最后一个字节相同。在线搜索这两个字节无相关内容,向设备发送格式相似的数据包也无果。
网络分析
另一种黑盒分析是扫描网络端口。我们可以使用 Nmap查看哪些端口是开放的,并尝试识别在这些端口上运行的服务及其版本。下面的屏幕截图显示了生物识别终端上开放的TCP端口。
你可能会注意到,该设备在非标准端口上支持 SSH。理论上,如果我们掌握了正确的凭证,我们就可以连接到该端口。我们可以通过暴力破解从固件中提取这些凭证。
此外,还有两个服务无法自动识别。在端口 6668/TCP 上运行的服务是涂鸦服务器(Tuya),但我们无法找出它的用途。在端口 4370/TCP 上运行的服务更有趣,因为它使用了供应商的许多设备支持的专有协议。在网上搜索该协议后,我们发现有文档可用,这让我们的分析变得容易得多。
相机和二维码终端分析
我们对设备的概述提到它支持二维码身份验证。我们决定看看如果我们向设备提供的二维码包含可能破坏处理逻辑的恶意数据会发生什么。我们能够通过让设备扫描包含恶意 SQL 代码的二维码来获得结果。
基本的 SQL 注入使得设备将我们识别为有效用户。
我们还注意到,让设备扫描包含 1 KB 或更多数据的二维码会导致设备紧急重启,这表明设备的一些组件已经溢出。有关此内容的更多信息,请参阅逆向工程和固件分析部分。
获取并解压固件
供应商的网站不允许任何人下载最新版本的固件。您可以下载包含更新算法的 PDF 文件,但该文件受密码保护,我们未在任何公共网站上找到该密码。
因此,我们有两种获取固件的方式:移除闪存并使用编程器将其转储,或者尝试在网上找到副本。
在网上搜索固件
要开始搜索固件,我们需要找出它的名称和大致版本。我们正在分析一个刚开箱未使用的设备,因此我们拥有管理员访问权限。因此,我们可以查看设备详细信息并找到当前固件版本。
我们拥有的版本是 ZAM170-NF-1.8.25-7354-Ver1.0.0。我们使用该字符串及其部分内容进行网络搜索。
在运行了一些复杂的 Google 搜索查询后,我们在国际分销商的网站上找到了一些与我们的终端非常相似的设备。
我们还找到了固件,尽管它是一个早期版本。
固件足以让我们弄清楚更新是如何进行的。下载并分析固件后,我们发现更新实际是一个文本文件的部分内容,文件需要通过专门的软件进行转换。
转换过程不太复杂,只需将“DataX”变量中包含的十六进制文本记录转换为字节格式以生成固件。
对该文件进行快速分析后发现文件已被加密。这促使我们检查了更新压缩包中的其他文件。仔细检查后发现,该设备支持部分固件更新,仅影响某些库和可执行文件。我们还找到一个更小的更新包文件。
通过对“standalonecomm”可执行文件的快速分析,我们发现该文件处理了在端口 4370/TCP 上收到的请求。该可执行文件还具有固件更新功能。该处理器还调用了可执行文件外部的“zkfp_ExtractPackage”文件提取函数。
我们在其他更新文件中都找不到这个函数,所以我们只能在网上搜索。我们找到了一个在头文件中包含这个函数的存储库。
我们在同一个存储库内找到了一个实现该功能的so库。
分析extract函数后,我们发现该函数也用于解密固件。下图为解密代码。
加密使用 XOR 算法,密钥由更新文件的最后 16 个字节和文件大小组成。现在我们似乎已经拥有了生成密钥和解密固件所需的所有数据。解密后,该文件仅包含部分可执行文件、库和配置文件的更新。
这不是什么大问题,因为我们正在寻找的可执行文件(处理端口 4370/TCP 上的传入数据)就在下载的压缩包内容中。我们仍然想要完整的固件,所以我们尝试了另一种选择:读取闪存。
从闪存中获取固件
正如本节开头所述,可以从电路板上的闪存中提取固件副本。
该内存是 BGA-153 封装的 eMMC控制器,在网上很容易找到编程器。读取闪存后,我们得到一个包含多个section的文件,如下所示。
这些section的名称是不言自明的,但我们仍然运行了binwalk工具以确保它们是正确的。binwalk 输出如下所示。
除了所有可执行文件和 Linux 内核之外,闪存还包含系统仅有的两个用户的凭证。
假设用户通过 SSH 访问设备,我们尝试暴力破解哈希值以获取他们的密码。我们成功获取了用户“zkteco”的密码,该用户确实可以通过 SSH 访问终端。
不幸的是,该用户没有最高权限,但我们仍然可以访问一些敏感的系统文件和正在运行的服务列表。
主要服务名为“main”。它控制屏幕上显示的所有内容,并通过名为“hub”的服务与其他必要服务进行通信。后者是一种消息代理,为服务通信提供方便的接口。另一个值得关注的服务是“pushcomm”:一个HTTP 客户端,可向设备指定的服务器发送请求。换句话说,如果攻击者可以让设备与他们控制的 Web 服务器通信,则可以使用客户端攻击设备。请继续阅读以了解可以使用此方法实施的攻击。另请注意,所有服务都以最高权限运行,这使得劫持设备变得容易得多,因为任何允许代码或命令执行的漏洞都会让攻击者获得最高权限。
分析端口 4370/TCP 上的协议
我们选择standalonecomm服务作为分析的主要对象,因为它在端口4370/TCP上实现了供应商的专有协议,并且包含攻击者感兴趣的可能未正确实现的命令。
正如本文开头所提到的,协议文档可从GitHub存储库获取,这大大简化了分析,因为人们可以将知识应用到反汇编代码中以找到感兴趣的命令。
协议结构相当简单和典型。数据包由标头和有效载荷(payload)组成。有效载荷也分为标头和数据,后者主要由命令决定。有效载荷一般是一个四字节数字或者是一个字符串或数据集。协议设计的详细描述可以在公开的文档存储库中找到。
协议认证及其问题
该协议的有趣功能包括用户身份验证,这需要知道设备上设置的密码。这种密码由管理员设置,被称作“COMKey”。“COMKey”默认为 0,即没有密码,所有请求都可以在不进行任何身份验证的情况下运行。
COMKey可以是0到999999之间的整数,由于密码数量有限,可以通过暴力破解获取密码。我们在分析设置密码的代码时遇到了这个限制。
用于生成协议认证的“MAC”(消息认证码)的方法也不够安全。生成过程依赖于可逆操作,因此如果我们可以监控网络上的流量,那么一旦客户端认证成功,我们就能够恢复密码。生成代码如下图所示。
SessionId变量是服务器生成并发送给客户端的两字节值,因此它可以根据COMKey计算出MAC并将结果值返回给服务器。
另一个与密码相关的安全风险是COMKey以未加密的形式存储在设备数据库中,因此任意文件读取漏洞会让我们找到它并通过协议进行身份验证。另一种可能的情况是通过 SSH 登录并读取数据库以获取协议密码,而无需进行暴力破解。
下图说明了协议认证机制。
客户端发送连接命令 (CMD_CONNECT),服务器返回两个字节,表示 SessionId,并与 COMKey 组合生成 MAC。客户端使用 CMD_AUTH 命令发送 MAC,服务器验证该 MAC。如果发现 MAC 有效,服务器将使用 CMD_ACK_OK 进行响应,客户端现在可以自由使用当前 TCP 会话中的所有可用服务器命令。
命令处理程序的漏洞分析
身份验证成功后可用的命令都由一个包含ID切换器的大型函数处理。下面是它的图形表示。
该函数的分析并不复杂性,但很消耗时间和精力。
我们挑选出了名称中包含“DOWNLOAD”、“UPLOAD”、“DELETE”或“UPDATE”字样的命令进行分析。
例如,CMD_DOWNLOAD_PICTURE 下载用户图像。它接受文件名作为参数,在插入文件打开函数之前不会以任何方式验证该参数。这允许传递目录遍历字符作为文件名来获取任意系统文件。处理程序代码如下图所示。
该命令可用于获取/etc/shadow,因为standalonecomm以最高权限运行。
在发现更多未经任何过滤就传递文件名的命令后,我们发现了几个文件读取漏洞。我们还发现了一个允许将文件上传到任意路径的函数。鉴于授予该服务的权限,可以利用该函数获得对设备的无限制访问权限。
在对CMD_DELETE_PICTURE进行分析时发现,由于要删除的图像的名称被直接插入到了命令当中传递给“system”函数,因此可以嵌入shell命令。
我们编写了 PoC 脚本来确认该漏洞可以被利用。脚本输出如下。
我们还发现了几个缓冲区溢出漏洞,漏洞与使用strcpy/sprintf 函数以及memcpy函数未验证复制缓冲区大小有关。我们将使用 CMD_CHECKUDISKUPDATEPACKPAGE 处理程序的示例来检查该问题。
产生该漏洞的原因:当从用户网络数据包复制数据时,处理程序会使用用户指定的数据包大小。目标缓冲区位于堆栈中,大小为 1028 字节。用户在数据包中指定更大的数据大小会导致缓冲区溢出。由于可执行文件没有堆栈溢出保护,攻击者可以利用此漏洞调用 ROP 链并执行任意代码,从而打开对设备的远程访问。
最后,我们发现,用户向网络数据包传递的字符串值几乎都被直接插入了数据库查询的地方,造成了许多SQL注入漏洞。
推送通信分析
如上所述,pushcomm服务将请求发送到设备配置中指定的服务器。要设置服务器地址,管理员需转到“COMM”菜单并打开“Cloud Server Setting”。管理员定义了要连接的IP地址和端口,并根据需要启用其他选项。下面的屏幕截图显示了配置菜单。
对可执行文件的分析表明,它容易出现与 standalonecomm 相同的问题。但是,利用这些漏洞需要启动 Web服务器并让设备与其通信。有多种方法可以做到这一点:通过更改数据库或管理菜单中的设置,或通过ARP欺骗。
请注意,pushcomm有一个命令名为“SHELL”,可以运行设备上的任何命令。
执行命令只需启动一个 Web 服务器并实现以下处理器。
总体而言,pushcomm 和 standalonecomm 代码之间存在相当大的重叠,特别是在数据库查询方面。
二维码处理器分析
在前文我们提到,当我们让设备扫描带有 SQL 注入的二维码时,设备会将我们验证为不同的用户。然而,当我们分析代码时,我们发现二维码可以包含的数据大小限制为 20 个字节。这可以防止复杂的 UNION 和 SELECT 注入,这些注入可用于从数据库中的各个字段获取任意数据。设备扫描我们的恶意二维码(在我们的例子中是带有 SQL 注入的代码)时生成的数据库查询显示在下方屏幕截图中。
我们还发现,让设备扫描包含大量数据的二维码可导致设备重启。查看代码后,我们发现这是由于一段等待摄像头数据的代码无法在预定义的两秒内接收数据,因此发送了“reboot”命令来响应它认为的故障。
结论
旨在提高物理安全性的生物识别设备既可以提供方便、有用的功能,又会给用户的IT系统带来新的风险。当生物识别等先进技术被封装在安全性较差的设备中时,这几乎抵消了生物识别身份验证的优势。因此,配置不足的终端很容易受到简单攻击,使入侵者很容易破坏组织关键区域的物理安全。
我们对 ZKTeco 生物识别终端的分析共发现了 24 个漏洞。其中许多漏洞都由数据库的wrapper库造成。我们将这些漏洞概括为“multiple vulnerabilities”,并说明了漏洞类型和原因,最终得出的CVE数量较少。
经统计,得到的漏洞数量如下:
- 6 个 SQL 注入漏洞;
- 7个缓冲区堆栈溢出漏洞;
- 5个命令注入漏洞;
- 4个任意文件写入漏洞;
- 2个任意文件读取漏洞。
漏洞详情可在GitHub 存储库中找到。