HITBCTF2018-reverse-hex

reverse

hex

下载hex文件,file一下,发现是文本文件,打开看了一下,暂时看不懂,binwalk一下,显示Intel hex file,google Intel hex 文件,根据hex维基百科,明白了文本文件的内容。之后各种google,发现了hex2bin这个windows hex转bin的工具。strings一下bin文件,发现关键内容arduino micro。

然后又是一顿google,确定了arduino micro板子使用的是atmega32u4,编译器是arduino avr,于是乎,加载进ida,由于ida没有atmega32u4,我选择的是atmega32_L,阅读atmega32 datasheet指令集开始看代码。各种call表示看不懂啊,特别是关键的setup()和Loop函数。

后来又是一顿google,找到了badusb,了解了原来这是badusb,尝试着使用Arduino IDE自己编译文件来和题目二进制文件进行对比。理解了关键的函数Keyboard_Press,Keyboard_release和delay。于是乎,我们的目的只要搞懂这个badusb插上电脑以后,做了什么,大概就能得到flag了吧。

附上部分关键处的汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
ROM:09F0 ldi     r22, 0x20 ; ' '
ROM:09F1 ldi r24, 0x77 ; 'w'
ROM:09F2 ldi r25, 1
ROM:09F3 call Keyboard_press
ROM:09F5 ldi r22, 0xF4
ROM:09F6 ldi r23, 1
ROM:09F7 ldi r24, 0
ROM:09F8 ldi r25, 0
ROM:09F9 call delay
ROM:09FB ldi r22, 0x20 ; ' '
ROM:09FC ldi r24, 0x77 ; 'w'
ROM:09FD ldi r25, 1
ROM:09FE call Keyboard_release
ROM:0A00 ldi r22, 0x88
ROM:0A01 ldi r23, 0x13
ROM:0A02 ldi r24, 0
ROM:0A03 ldi r25, 0
ROM:0A04 call delay
ROM:0A06 ldi r22, 0x20 ; ' '
ROM:0A07 ldi r24, 0x77 ; 'w'
ROM:0A08 ldi r25, 1
ROM:0A09 call Keyboard_press
ROM:0A0B ldi r22, 0xF4
ROM:0A0C ldi r23, 1
ROM:0A0D ldi r24, 0
ROM:0A0E ldi r25, 0
ROM:0A0F call delay
ROM:0A11 ldi r22, 0x20 ; ' '
ROM:0A12 ldi r24, 0x77 ; 'w'
ROM:0A13 ldi r25, 1
ROM:0A14 call Keyboard_release
ROM:0A16 ldi r22, 0x88
ROM:0A17 ldi r23, 0x13
ROM:0A18 ldi r24, 0
ROM:0A19 ldi r25, 0
ROM:0A1A call delay
ROM:0A1C ldi r22, 0x24 ; '$'
ROM:0A1D ldi r24, 0x77 ; 'w'
ROM:0A1E ldi r25, 1
ROM:0A1F call Keyboard_press
ROM:0A21 ldi r22, 0xF4
ROM:0A22 ldi r23, 1
ROM:0A23 ldi r24, 0
ROM:0A24 ldi r25, 0
ROM:0A25 call delay
ROM:0A27 ldi r22, 0x24 ; '$'
ROM:0A28 ldi r24, 0x77 ; 'w'
ROM:0A29 ldi r25, 1
ROM:0A2A call Keyboard_release
ROM:0A2C ldi r22, 0x88
ROM:0A2D ldi r23, 0x13
ROM:0A2E ldi r24, 0
ROM:0A2F ldi r25, 0
ROM:0A30 call delay
ROM:0A32 ldi r22, 0x23 ; '#'
ROM:0A33 ldi r24, 0x77 ; 'w'
ROM:0A34 ldi r25, 1
ROM:0A35 call Keyboard_press
ROM:0A37 ldi r22, 0xF4
ROM:0A38 ldi r23, 1
ROM:0A39 ldi r24, 0
ROM:0A3A ldi r25, 0
ROM:0A3B call delay
ROM:0A3D ldi r22, 0x23 ; '#'
ROM:0A3E ldi r24, 0x77 ; 'w'
ROM:0A3F ldi r25, 1
ROM:0A40 call Keyboard_release
ROM:0A42 ldi r22, 0x88
ROM:0A43 ldi r23, 0x13
ROM:0A44 ldi r24, 0
ROM:0A45 ldi r25, 0
ROM:0A46 call delay
ROM:0A48 ldi r22, 0x23 ; '#'
ROM:0A49 ldi r24, 0x77 ; 'w'
ROM:0A4A ldi r25, 1
ROM:0A4B call Keyboard_press
ROM:0A4D ldi r22, 0xF4
ROM:0A4E ldi r23, 1
ROM:0A4F ldi r24, 0
ROM:0A50 ldi r25, 0
ROM:0A51 call delay
ROM:0A53 ldi r22, 0x23 ; '#'
ROM:0A54 ldi r24, 0x77 ; 'w'
ROM:0A55 ldi r25, 1
ROM:0A56 call Keyboard_rel

直接获取所有的操作太累了,我选择idapython获取所有打印的字符,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import idautils
import idaapi
import idc
'''
start = idc.SelStart()
end = idc.SelEnd()
'''
'''
cur_addr = 0x94C
for disass_addr in list(idautils.FuncItems(func)):
if idc.GetMnem(disass_addr) == 'ldi':
if idc.GetOpnd(disass_addr,1) == ' ':

'''
str1 = ''
count = 0
cur_addr = 0x94C
for disass_addr in list(idautils.FuncItems(cur_addr)):
if idc.GetMnem(disass_addr) == 'ldi':
tmp = idc.GetOperandValue(disass_addr,1)
if tmp == ord(' '):
count += 1
if count == 2:
str1 += ' '
count = 0
elif tmp == ord('$'):
count += 1
if count == 2:
str1 += '$'
count = 0
elif tmp == ord('#'):
count += 1
if count == 2:
str1 += '#'
count = 0
elif tmp == ord('&'):
count += 1
if count == 2:
str1 += '&'
count = 0
elif tmp == ord(':'):
count += 1
if count == 2:
str1 += ':'
count = 0
elif tmp == ord('|'):
count += 1
if count == 2:
str1 += '|'
count = 0
elif tmp == ord('!'):
count += 1
if count == 2:
str1 += '!'
count = 0
elif tmp == ord(';'):
count += 1
if count == 2:
str1 += ';'
count = 0
elif tmp == ord('@'):
count += 1
if count == 2:
str1 += '@'
count = 0
elif tmp == ord('.'):
count += 1
if count == 2:
str1 += '.'
count = 0
elif tmp == ord('%'):
count += 1
if count == 2:
str1 += '%'
count = 0
elif tmp == ord('`'):
count += 1
if count == 2:
str1 += '`'
count = 0
elif tmp == 0xB0:
count += 1
if count == 2:
print str1
str1 = ''
count = 0

最后得到打印出来的flag:flag{520}

flag

emmmmm,这个我实在是看不懂画了什么,从出图到得到flag,有差不多9个小时,感谢看出flag的@pinko大佬(第一行右移两位),同时感谢客服大佬@Swing的耐心解答(还是想吐槽一下下:-( )

google中的关键连接:

pwnhub-key

badusb

arduino-IDE

baduse-code

USB-Rubber-Ducky

pwnhub-key-bluereader