题源:BUUCTF

题目考点

  • 对陌生usb协议的分析(数位板usb协议)
  • unicode编码转emoji
  • 基于emoji的aes加解密

题目描述

达芬奇偷偷把key画了下来,你能找到key然后解开密码吗?

题目详解

附件中给了一个流量数据包和一个txt,逐个进行分析

flag.txt

U+1F643U+1F4B5U+1F33FU+1F3A4U+1F6AAU+1F30FU+1F40EU+1F94BU+1F6ABU+1F606U+1F383U+1F993U+2709U+1F33FU+1F4C2U+2603U+1F449U+1F6E9U+2705U+1F385U+2328U+1F30FU+1F6E9U+1F6A8U+1F923U+1F4A7U+1F383U+1F34DU+1F601U+2139U+1F4C2U+1F6ABU+1F463U+1F600U+1F463U+1F643U+1F3A4U+2328U+1F601U+1F923U+1F3A4U+1F579U+1F451U+1F6AAU+1F374U+1F579U+1F607U+1F374U+1F40EU+2705U+2709U+1F30FU+23E9U+1F40DU+1F6A8U+2600U+1F607U+1F3F9U+1F441U+1F463U+2709U+1F30AU+1F6A8U+2716

U+开头,很明显的unicode编码,查一下就可以发现是编码的内容是emoji

在这个网站可以在线转换 → https://r12a.github.io/app-conversion/

image-20200707163150842

k3y.pcapng

打开流量包,大致翻一下可以发现其中有sub协议的数据,在协议分级中还可以看到有jpg的身影,不过在此题中只是个烟雾弹,并没有什么用,重点还是在usb流量上,所以需要对其进一步分析

1. 判断usb设备

usb设备建立连接时会发送包含设备信息的包,搜索关键字DESCRIPTOR

注:详细usb协议可见文档3.6小节

image-20200707170112124

可以看到有名为Wacom PTH-660的设备,查一下可以知道是一种数位板

2. 过滤有效流量

利用tshark将usb流量数据导出

tshark -r k3y.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > usb.txt

打开得到的txt,观察可知有好几种不同长度的数据,其中出现次数最多的是长度为54的数据,推测其为有效的流量数据,写脚本将长度为54的数据过滤出来

f = open('usb.txt','r')
fi = open('out.txt','w')
while 1:
    a = f.readline().strip()
    if a:
        if len(a) == 54:
            fi.write(a)
            fi.write('\n')
    else:
        break

fi.close()

3. 分析数据

文档中有数位板相关数据的格式,也给了三种数位板的例子

image-20200707173426274

搜索本题用的数位板的型号,发现是具有压感的一种,所以参考Figure 19

image-20200707173558748

上图中提到了x、y坐标相关的数据格式,再结合题目描述,很容易想到本题通过数位板画出相关信息,而且上图中也可以看到x、y坐标的数据是以小端序形式体现的

image-20200707174032376

观察过滤出的有效数据,猜测坐标存储位置

image-20200707174322917

以上图为例,红色框中为x坐标信息,黄色框中为y坐标信息,橙色框为压感信息,当压力值为00时说明此时没有在画图,因此可以通过筛选压力值来更精准作图

其中坐标数据以16进制形式储存,由于小端序,所以在转化成10进制时需要进行换算,以2650为例,换算成十进制就是int('26',16)+int('50',16)*256,其中256即2^8

4. 依据坐标画图

先写脚本将16进制数据转换成10进制,同时将其写入文件变成gnuplot可识别形式

# x:[4:6],[6:8]
# y:[10:12],[12:14]
# 压感:[16:18]
f = open('out.txt','r')
fi = open('xy.txt','w')
while 1:
    a = f.readline().strip()
    if a:
        if a[16:18] != '00':
            x = int(a[4:6],16) + int(a[6:8],16)*256
            fi.write(str(x))
            fi.write(' -') # 纵坐标前加负号使图像垂直翻转
            y = int(a[10:12],16) + int(a[12:14],16)*256
            fi.write(str(y))
            fi.write('\n')
    else:
        break

fi.close()

再利用plot命令画图:plot "xy.txt"

image-20200707193256461

得到字符串:MONA_LISA_IS_A_MAN

解emoji加密

flag.txt中的emoji,很明显是将flag经过某种加密得到的,而刚刚得到的字符串结合流量包的名字,可以推断是作为key存在的

需要字符串key的emoji加密,最常见(好像也是唯一的?)的便是emoji-aes加密

戳此网址进行在线加解密 → https://aghorler.github.io/emoji-aes/#

image-20200707194345278

解密即可得到flag

flag

RoarCTF{wm-m0de3n_dav1chi}