PolishDuck
由于出题人水平有限,给各位师傅带来的不必要困扰还请谅解。
Badusb固件
先hex2bin
Arduino Leonardo芯片atmega32u4
Github上找到32u4的datasheet,然后难度就降维了
https://gist.github.com/thecamper/18fa1453091be4c379aa12bcc92f91f0
有了datasheet可以直接ida分析
‘可以装arduino ide自己编译一个相关的固件对比函数,恢复函数名,或者直接找到keyboard的库分析。
找到主函数
size_t Keyboard_::write(const uint8_t *buffer, size_t size) {
size_t n = 0;
while (size--) {
if (*buffer != '\r') {
if (write(*buffer)) {
n++;
} else {
break;
}
}
buffer++;
}
return n;
}
keyboard.cpp源码里可以看到println是根据地址取字符串,也可以解释为什么ldi了好多参数,根据地址位置,推算出字符串位置windows+r 后notepad.exe,开始的地址就是"notepad.exe"的位置,这里引用Nu1L战队师傅的脚本(我写的真的太丑了)
index_table=[320,332, 339, 354, 375, 395, 425, 456, 467, 491, 510, 606, 519, 540, 551, 582, 609, 624, 651, 664, 675, 689, 604, 698, 709, 720, 727, 754, 775, 784, 606, 807,
838, 988, 845, 868, 883, 911, 934, 947, 959, 976, 991, 1007, 1024, 1099, 1043, 1068, 1083, 1103, 1106, 1168, 1119, 1132, 1149, 1166, 1175, 1182, 1205, 1227,
1093, 1093, 1238, 1101, 1101, 1172, 1253, 1103]
import ida_bytes,idaapi
def my_get_str(ea):
#print(hex(ea))
res = ''
i = 0
while True:
tt = ida_bytes.get_byte(ea+i)
if tt ==0 or tt & 0x80 != 0:
break
res += chr(tt)
i += 1
return res
guess_offest = [6480]
for offest in guess_offest:
res = ''
for i in index_table:
res += my_get_str(i+offest)
res += '\n'
print(res+'\n')
开始的内容是逆波兰表达式,但在减法写成了 ‘负数加‘ 不满足中缀表达式 所以符号比数字多,其实可以算脑洞,不过没有必要,所以后期更新了附件,变成了常规的中缀表达式。给各位师傅带来的困扰还请海涵。
Source code example
中缀计算得16进制:
0x686374667***306c3173685f4475636b5f5461737433735f44336c3163693075735f44305f555f5468316e6b3f7d
Decode得flag:hctf{P0l1sh_Duck_Tast3s_D3l1ci0us_D0_U_Th1nk?}
没有Polish的PolishDuck XD,出题人已自裁。