sherlly | 发布于 2018-02-06 00:30:23 | 阅读量 565 | arduino 固件逆向 badusb
发布于 2018-02-06 00:30:23 | arduino 固件逆向 badusb

题目

题目下载地址:

链接: https://pan.baidu.com/s/1i6BhAIh 密码: m4dh

注意!Flag 形式为 flag{xxxxxxx}

初步分析-信息搜集

题目提供了hex文件,通过hex2bin工具转换得到bin文件,strings可得知固件是arduino micro,而且通过"CATERINA"特征可知hex带了bootloader引导程序,通过网上查资料,可以知道,arduino micro板子使用的是atmega32u4,编译器是arduino avr,属于avr单片机。

可惜IDA关于avr设备的配置文件中并没有atmega32u4的型号信息,在github找到别人补充的atmega328的型号信息,比较了一下二者的区别,好像不大...(同属于avr5架构)

IDA载入分析

IDA载入key.bin,选择好相应的型号信息:

emmm开始强行分析,IDA解析出来的函数只有这几个(已重新命名):

猜想程序实现

考虑到strings bin文件时发现了以下字符串,猜想程序是调用了记事本程序(notepad)写入了后面的算式,但是算式按顺序得到的是不合法的,所以程序应该是对存储算式的位置进行了乱序操作。

再加上使用的是arduino micro的板子,google+github一番不难发现,题目应该是类似于badusb的项目。即将程序写入固件后,将USB插入电脑实现自动调用记事本程序写入特定字符串的操作,找到badusb的一个示例ino代码:

可以看到,通过调用keyboard实现了写入字符串的操作。

对照示例代码恢复IDA函数

通过arduino编译该代码,转bin后载入IDA和题目文件比对:

从而确定了keyboard.press keyboard.release keyboard.println delay等函数并修改相应命名,对照keyboard.h可以知道相应键值的调用:

   

经过比较及查找资料,可知println读取的数据是从RAM获得,而__RESET函数中就包含了初始化RAM的工作。RAM由0x100个字节(包含通用及IO寄存器信息)加上从程序0x1e32开始的(0x210-0x100)字节组成:

这里偷懒没有新建RAM,所以println[x]实际位置应该是(偏移量x-0x100+0x1e32)而得。

恢复程序执行逻辑

最后整理得到程序执行的主要操作:

setup:
KEY_LEFT_GUI + r  ;win + R
KEY_LEFT_SHIFT
println[0x13d]  ;notepad
KEY_RETURN
println[0x1c3]
println[0x145]
println[0x1f8]
println[0x1e3]
KEY_BACKSPACE
KEY_BACKSPACE
println[0x14a]
println[0x14f]
println[0x153]
println[0x176]
println[0x209]
KEY_BACKSPACE
println[0x163]
println[0x158]
KEY_BACKSPACE
KEY_BACKSPACE
println[0x15b]
println[0x161]
println[0x165]
println[0x16a]
println[0x1a6]
println[0x170]
println[0x20d]
println[0x174]
println[0x178]
println[0x17d]
println[0x1f8]
println[0x181]
KEY_BACKSPACE
KEY_BACKSPACE
KEY_BACKSPACE
println[0x17f]
println[0x168]
println[0x185]
println[0x1a7]
KEY_BACKSPACE
println[0x148]
println[0x18b]
KEY_BACKSPACE
KEY_BACKSPACE
KEY_BACKSPACE
println[0x18f]
println[0x193]
println[0x161]
println[0x17f]
println[0x197]
println[0x19a]
println[0x19e]
println[0x198]
println[0x1e3]
println[0x1a4]
println[0x1a9]
println[0x195]
println[0x193]
println[0x1ad]
KEY_BACKSPACE
KEY_BACKSPACE
println[0x17f]
println[0x17d]
println[0x1f8]
println[0x165]
println[0x1b0]
KEY_BACKSPACE
KEY_BACKSPACE
println[0x1f7]
println[0x1b3]
println[0x1f8]
println[0x1b7]
println[0x1bc]
println[0x1c0]
println[0x1c6]
println[0x1c9]
println[0x1f0]
println[0x17f]
println[0x198]
KEY_BACKSPACE
println[0x1cf]
println[0x1d3]
println[0x17f]
println[0x1d8]
println[0x1f8]
println[0x1db]
println[0x1e0]
println[0x1e6]
KEY_BACKSPACE
KEY_BACKSPACE
println[0x1e9]
println[0x1ef]
println[0x1f5]
println[0x1fa]
println[0x200]
println[0x206]
println[0x17f]
KEY_BACKSPACE
println[0x198]
println[0x195]
println[0x209]
println[0x20b]
println[0x195]

loop:
KEY_BACKSPACE

得到结果

对照可得最终算式为:

3*11*13*433*48733*(2*2*11*(2*3*5*239*19819+1)*(2*7*(2*3*5*13*31*59+1)*(2*7*23*67*67*71*193+3)+1)*(2*3*3*5*307*33967*325333*847543*(2*2*5*5*211*263*134047*741593*(2*2*3*3*19*710989+1)+7)+1)+1) 

结果为777244835068427269409266752070441324651107168602972404958305900020193672615323726717,hex转换得flag。

flag{th3r3_ar3_s0m3_amaz1n9_th1ngs}

题目ino代码(猜测)

#include <Keyboard.h>

void setup() {  //初始化
  Keyboard.begin(); //开始键盘通讯
  delay(3000);//延时
  Keyboard.press(KEY_LEFT_GUI);//win键
  delay(500);
  Keyboard.press('r');//r键
  delay(500);
  Keyboard.release(KEY_LEFT_GUI);
  Keyboard.release('r');
  delay(500);
  Keyboard.press(KEY_LEFT_SHIFT);
  delay(500);
  Keyboard.release(KEY_LEFT_SHIFT);
  delay(500);
  Keyboard.println("3*");
  delay(500);
  Keyboard.println("11*1");
  delay(500);
  Keyboard.println("3");
  delay(500);
  Keyboard.println("*7");
  delay(500);
  Keyboard.press(KEY_BACKSPACE);
  delay(500);
  Keyboard.release(KEY_BACKSPACE);
  delay(500);
  Keyboard.println("*433");
  delay(500);
  Keyboard.println("*48");
  delay(500);
  Keyboard.println("733*");
  delay(500);
  Keyboard.println("(");
  delay(500);
  Keyboard.println("+");
  delay(500);
  Keyboard.press(KEY_BACKSPACE);
  Keyboard.release(KEY_BACKSPACE);
  delay(500);
  Keyboard.println("2");
  delay(500);
  Keyboard.println("5)");
  delay(500);
  Keyboard.press(KEY_BACKSPACE);
  Keyboard.release(KEY_BACKSPACE);
  delay(500);
  Keyboard.press(KEY_BACKSPACE);
  Keyboard.release(KEY_BACKSPACE);
  delay(500);
  Keyboard.println("*2*11");
  delay(500);
  Keyboard.println("*(2");
  delay(500);
  Keyboard.println("*3*5");
  delay(500);
  //SNIP...
  Keyboard.println("*239*19819+1)*(2*7*(2*3*5*13*31*59+1)*(2*7*23*67*67*71*193+3)+1)*(2*3*3*5*307*33967*325333*847543*(2*2*5*5*211*263*134047*741593*(2*2*3*3*19*710989+1)+7)+1)+1)");
  delay(500);
  Keyboard.end();   //结束键盘通讯
}
void loop()//循环
{
  Keyboard.press(KEY_BACKSPACE); //删除记事本内容
  delay(500);
  Keyboard.release(KEY_BACKSPACE);
  delay(500);
}

 


内容更新于: 2018-02-06 20:39:11
链接地址: http://blog.leanote.com/post/sherlly/pwnhub-%E3%80%8A%E8%A1%80%E6%9C%88%E5%BD%92%E6%9D%A5%E3%80%8B-key-writeup


上一篇: HEX文件初探

下一篇: MHN中心服务器搭建与树莓派蜜罐部署

565 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航