Arduino+Avr libc制作Badusb原理及示例讲解 | 长文含视频

一、 前言

2014年美国黑帽大会上研究人员JakobLell和Karsten Nohl展示了badusb的攻击方法后,国内与badusb相关的文章虽然有了一些,但是大部分人把相关文章都阅读后还是会有种“不明觉厉”的感觉,badusb仍有一层朦胧的面纱。经过一段时间的学习和研究后,笔者希望通过自己的一些心得体会可以帮助其他人更清晰地认识badusb,也希望这篇文章能够起到一定的启发。这篇文章主要分为五个部分——知识扫盲部分、badusb固件编写部分、badusb配置界面部分、技术展望部分和总结部分。

二、硬件准备

本文使用的硬件是Arduino Leonardo开发板,但是不难将Leonardo开发板替换为其它Arduino开发板。

三、知识扫盲

1. 虽然USB协议有一定的漏洞,但是不是任何USB设备都能制作badusb的。制作badusb有两个核心,一个是能够为USB设备编写相应的固件,另一个是能够将编写的固件烧录到USB设备中。要编写相应的固件就需要掌握USB设备中微控制器(或者说芯片)的指令规范文档(如果Intel不提供开发文档,那么除了Intel自己没有人能为Intel处理器编写程序);

而要将固件烧录到USB设备中,要么使用相应的硬件编程器,要么就需要USB设备本身已经存在的bootloader来辅助进行烧录工作(bootloader是USB设备厂商在生产时就放在USB设备中的,网上某些优盘的优盘量产工具也是从厂商流出的,而不是第三方编写的)。

要同时满足两个核心条件还是比较难的,即便是JakobLell和Karsten Nohl公布的badusb利用代码也是针对满足一定条件的优盘,因为流出的优盘量产工具有限(既然有优盘量产工具,可以推测相应的优盘中肯定有bootloader或者类似bootloader的固件存在,那么通过逆向优盘量产工具就可以掌握PC端软件和特定优盘的通信方式,进而实现自己的烧录工具)。

2. Arduino 和 teensy这类开发板之所以容易制作badusb,是因为它们采用的微控制器官方有详细的说明文档。最常用的是atmel公司的微控制器,atmel官网提供了各种开发文档和开发相关的库等。

3. Atmel厂商的微控制器整合了SRAM, FLASH和EEPROM。SRAM就好比电脑的内存,不用关心;FLASH高地址存放的是bootloader,低地址则存放用户烧录的固件,芯片加电时直接执行用户的固件,但是芯片复位时会先执行bootloader(这一点是烧录的关键),再执行用户的固件;EEPROM则主要用来存放数据,用户可以随意修改EEPROM中的数据,固件也可以从EEPROM里读取数据(本文的固件示例和PC端程序都利用了这一特性)。

4. Avr libc是一个开源项目,针对atmel厂商的各种微控制器开发C语言库、编译器、烧录工具等一系列辅助工具,还有针对Windows平台的WinAvr项目。Arduino ide的核心其实也是avr libc。

5. Arduino的开发板有相应的bootloader(在FLASH高地址)可以和avr libc项目中的avrdude.exe软件通信,实现固件的烧写和读取动作。在Arduino开发板复位时,会加载bootloader,这时候就可以利用avrdude.exe和bootloader通信。复位操作可以通过开发板上的复位按钮,或者编程实现软复位操作(如果开发板支持的话)。

6. Intel hex 是一种用于编程器的特殊的文件格式,正是因为这种格式,使得我们可以自由控制数据的存储地址。Intel hex的文件格式解析可以自行网上搜索。

四、知识获取途径

1. USB知识获取

如果只是为了简单了解USB设备为什么可以模拟键盘、鼠标等其它设备,网上有许多博客是关于USB规范详解的,也可以简单地看《USB开发大全》和《USB应用开发实例详解》前面关于USB通用协议部分,如果不是对硬件感兴趣没必要深究。

2. Arduino、Avr libc知识获取

这两样其实都是开源的,所以只要有足够的精力和实力,看源代码深入了解相关知识是没问题的。但是如果只是想体验一下制作badusb,可以只看一下Arduino的官方文档和avrdude.exe的相关文档,看这些文档时也没必要深究每个细节,能一定程度上“照葫芦画瓢”就可以了。

五、Badusb固件编写

这里给的固件示例在执行时会从EEPROM中指定的地址读取数据,根据读取的数据和制定的规则发送相应的按键响应给PC主机。

这里针对这个固件给几个例子帮助理解:

1. 从EEPROM中依次读取到'$'、'r'($r)表示badusb会按下Win+R键。 2. 从EEPROM中依次读取到'$'、'r'、';'($r;)表示badusb会按下Win+R,然后按回车键。 3. 从EEPROM中依次读取到'&'、'5'、'0'、'0'、'&'、'$'、'r'、';'(&500&$r;)表示badusb会按下Win+R键,然后等待500毫秒(保证运行对话框弹出),再按下回车键。 4. 从EEPROM中依次读取到(&500&$rpowershell&400&;Get-Date;)表示badusb先按下Win+R键,等待500毫秒后输入powershell,按回车键后等待400毫秒,再输入Get-Date,最后按下回车键

六、Badusb配置界面

所谓的Badusb配置界面,就是avrdude.exe的UI界面精简版,再额外提供了控制Badusb执行的动作的功能(本质就是修改了EEPROM特定地址的数据,因为固件是根据EEPROM中的数据执行动作的)。

图1 PC程序界面

这个程序主要就是avrdude.exe的UI界面,只有executable处和address处是为了自定义Badusb动作设计的。partno的选项和programmer的选项是解析选定的avrdude.conf得到的,所以不选择avrdude.conf的话partno和programmer的下拉框将为空;端口号是通过注册表获取到的。

当点击upload按钮或者dump按钮时,先利用编程方式实现复位操作(后面会解释怎么实现的),在短暂的暂停后使用CreateProcess执行avrdude.exe程序;而如果用户在executable处输入了字符串,PC程序会根据用户输入的字符串和Address处给定的地址生成intel hex格式的文件(还记得前面知识扫盲部分提到的intel hex格式?熟悉了intel hex的格式后,完全可以自己写出生成hex文件的代码,所以这里就不贴出代码了),再调用avrdude.exe把生成的intel hex文件烧录到eeprom。下面给个具体的演示。

图2 烧录固件并指定Badusb执行动作

Executable处输入的字符串指示badusb执行的动作,这里badusb先按下Win+R键,等待500毫秒后输入powershell,按下回车键,等待600毫秒后输入Get-Date然后按下回车键,再输入echoabcdefghijklmnopqrstuvwxyz按下回车键,最后再次输入Get-Date和回车键。至于界面中其它一些零碎的参数笔者怎么知道的后面会说,实在不行完全可以一个一个尝试。

效果演示视频链接:https://v.qq.com/x/page/l03900zm1pe.html

视频没有演示badusb的危害多大(比如从服务器下载木马执行、窃取个人信息等),毕竟这些更多的属于powershell脚本知识、cmd命令之类的,不是这篇文章的目的。

演示视频中主要经历了以下几个阶段:

1. 选择了avrdude.conf文件后partno和programmer下拉框会展示avrdude.exe支持的芯片型号和编程器(编程器本质上是和bootloader通信的协议)。 2. 插上开发板(有提示音)后,port下拉框会展示开发板的串口号。 3. 在executable编辑框中输入badusb需要执行的按键序列"&500&$rcmd",再选择要烧录到FLASH的固件(只需要烧录一次固件,以后都不需要了),点击upload后两次弹出命令窗口进行烧录(第一次烧录固件,第二次向EEPROM中写入数据),发现开发板重启后弹出了运行对话框并输入了"cmd"。 4. 修改executable编辑框的内容为"&500&$rcmd;"(多了一个分号,也就是多按了一个回车键),再次点击upload(因为没有选择固件,所以不会进行固件的烧录,只会修改EEPROM的数据),发现开发板重启后弹出运行对话框紧接着迅速弹出了命令窗口。 5. 之后又修改了两次executable编辑框的内容并烧录以修改EEPROM的数据,发现一次是只弹出了powershell窗口,一次是弹出了powershell窗口后又执行了三条powershell指令。

七、技术展望

这次的示例只是展示了利用arduino leonardo开发板模拟usb键盘,而windows一旦锁屏,模拟成键盘鼠标之类的badusb就失效了。而有人发现在锁屏状态下插入网卡会让windows操作系统发送dhcp请求给新插入的网卡分配ip,那么是不是可以让usb设备模拟成网卡兼dhcp服务器兼dns服务器,达到在锁屏状态下通过badusb劫持流量、窃取信息的目的?虽然有局限性,但是也说明了一个问题——badusb不只是简单地利用usb协议的漏洞,还可以结合操作系统的一系列特性(缺陷?)在看似不可能的环境下执行,badusb的技术还有很多可以探索的地方。

八、总结

1. 理一下思路,要制作badusb,就要保证能编写出相应的固件并能通过某种手段将固件烧录到usb设备中。要想通过这两点,最方便的就是使用arduino或者teensy这类开发板,否则就需要看有没有官方的集成开发环境,比如Cypress官网就提供了详细的开发文档、示例、开发环境等。

2. arduino开发板主要使用的是atmel厂商的微控制器,编译工具和烧录工具也是来自开源项目avr libc。可以在arduino ide中“文件->首选项->设置”勾上显示编译和上传的详细输出,然后使用ide的上传功能上传一个示例代码,在输出窗口就能看到很多有用的信息。附上一个示例:

图3 arduino ide详细输出信息(a)

3. 看到图4的输出信息,应该可以联想到通过软件复位开发板其实是通过以1200bps速率和开发板进行串口通信,再进一步去看Windows串口通信时发现还需要设置几个其他参数,这时候怎么办呢?只能看arduinoide是怎么设置那些参数的,通过以下几个步骤寻找到arduino ide设置相关参数的源代码(arduino ide的源代码github上有):

①在源代码根目录使用findstr /Sn /c:"Foundupload port"查找含有字符串“Found upload port”的文件,发现路径为arduino-core\src\cc\arduino\packages\uploaders\SerialUploader.java:276:(findstr是Windows提供的在文档中查找字符串的工具)

②查看Serial Uploader代码,发现字符串“Found upload port”在waitForUploadPort方法中,进一步发现调用了waitForUploadPort方法的是uploadUsingPreferences方法,在uploadUsingPreferences方法中发现调用了Serial.touchForCDCReset方法,通过方法名字猜测这个函数和开发板复位有关。

③再次使用findstr /Sn /c:”touchForCDCReset"找到touchForCDCReset方法的实现是在文件arduino-core\src\processing\app\Serial.java:90:中。

④在Serial.java中发现有这么一行代码:

SerialPort.setParams(1200,8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

到这里可以大胆猜测出利用串口通信的方式复位开发板时除了1200这个参数值外其他参数的值了。

图4 arduino ide详细输出信息(b)

4. 通过图5可以看到arduino ide在调用avrdude.exe烧录固件到我的开发板时的一系列参数(-p就是partno,-c就是programmer,-b就是baudrate,可以发现和我前面演示时设定的参数是一样的,因为我的那些参数就是根据这里显示的设置的)。有兴趣的可以看看“Arduino安装路径\hardware\arduino\avr”目录下的boards.txt、platform.txt和programmers.txt,应该会有很多收获。

5. 想利用arduino开发板制作有用的,或者扩展性强的badusb,需要理清以下逻辑:

①arduino开发板使用的主要是atmel厂商的微控制器,而atmel厂商的微控制器集成了SRAM,FlASH和EEPROM,其中arduino开发板中的FLASH高地址存放了某种bootloader,低地址则存放用户上传到开发板的固件;arduino开发板的EERPOM可以根据自己的情况使用。

②arduino开发板复位时,先启动bootloader,一段时间(通常是几秒)后启动用户的固件。而avrdude.exe烧录过程其实就是在复位时和arduino开发板的bootloader通信,所以只有在bootloader启动阶段利用avrdude.exe才能成功烧录。一定要把握好时间。

③固件程序可以从eeprom或flash中读取数据,而intelhex格式文件可以控制将数据写入特定存储器的特定地址,利用这一点可以极大的扩展badusb的功能,而且将要执行的指令放在flash或者eeprom中也能在一定程度上起到隐藏效果。

Arduino+Avr libc制作badusb效果展示: 看不到视频?

https://v.qq.com/x/page/l03900zm1pe.html

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-04-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SAP最佳业务实践

SAP最佳业务实践:ETO–项目装配(240)-17子装配的零件生产

子装配的零件生产 子装配的库存采购无 QM 的采购 (130) 用于制造最终产品的所有原材料(除了长提前期组件)必须已在库存中。 在实际业务情况中,原材料通常从...

3964
来自专栏云计算教程系列

如何在Ubuntu上搭建方舟:生存进化服务器

《方舟:生存进化》(英语:Ark: Survival Evolved)是一款由Studio Wildcard制作与发行的生存类沙盒动作冒险游戏,使用虚幻4引擎打...

1.8K3
来自专栏技术杂文

你信任的公司正在窃取你的信息

通常来讲,“购买新产品” 指的是这样的交易过程:购买食物时,可以先确认食材然后购买它,即使难吃也不会要了你的命;购买汽车时,首先它得符合所有安全标准;为特定目的...

1193
来自专栏安智客

《密码模块安全要求》与《密码模块安全检测要求》

信安标委最近对大量的信息安全行业规范进行征集意见,3月份的时候安智客介绍过行业标准密码模块安全安全要求,不过这个标准现在上升到了国家标准,说明很重要!安智客今天...

2243
来自专栏编程一生

业务高速增长场景下的稳定性建设实战

2642
来自专栏顶级程序员

微软一脸懵逼:32TB的Win10源码泄露!

综合自:36氪、 Solidot、快科技、程序猿等媒体 黑客泄露微软 Win 10 大量源代码,数据超过 32 TB 据 theregister 报道,已经有多...

4637
来自专栏SAP最佳业务实践

SAP最佳业务实践:生产订单拆分-按库存生产(248)-3生产订单处理1

image.png 生产订单处理 MD04创建生产订单 创建不含外部处理工序的生产订单。 已生成装配成品 (F248-1) 的生产订单。 后勤®生产 ®物料需...

2983
来自专栏FreeBuf

一种常规Android脱壳技术的拓展(附工具)

最近在做移动安全测试的项目时,遇到了最新的某数字壳,好久都没脱壳了,记得上次脱壳还是zjdroid通杀的时候。秉着安全研究的精神,趁此机会,又把最新的加固与脱壳...

3418
来自专栏Spark学习技巧

干货!一次kafka卡顿事故排查过程

由于一次功能上线后,导致某数据量急剧下滑,给我们紧张的呢!排查过程也是个学习过程!抛开结果,方法论可供参考~

884
来自专栏草根博客站长有话说

降低 CDN 付费 HTTPS 流量消耗实践总结

从明月下定决心开始使用又拍云 CDN 的时候,就有一个问题困扰着我,那就是 CDN 流量消耗是越来越大,最夸张的时候一天流量消耗达到了惊人的 2G 多了,这对于...

2273

扫码关注云+社区

领取腾讯云代金券