引言:流量分析不仅仅是那些杂乱的http、tcp包,还有挺有趣的键盘、鼠标流量
题目来源攻防世界m0_01
m0_01
拿到这道题,我先用wireshark打开,发现里面是单纯的USB流量

对于USB流量是什么,还请大家百度百度,我这里推荐一个pdf文档,挺权威的,大家可以看看
[usb协议]
通过Tshark提取所有信息
这里有两种命令语句
tshark -r 12.pcapng -T fields -e usb.capdata >usbdata.txt
tshark -r 12.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' >usbdata.txt
前者会在导出的流量中保存空格,后者会帮我们直接将空格过滤掉(用第一个也是可以的,我后面会放一个脚本,帮我们将空格删掉

脚本处理
美化文本处理
#使用脚本删除空行(如果用第二条命令就不用管这个了)
with open('usbdata.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
lines = filter(lambda x: x.strip(), lines)
with open('usbdata.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> //(提供字符串处理函数)
int main() {
FILE *input, *output;//(定义了文件指针)
char line[1024]; // 假设每行最长 1024 字节
input = fopen("usbdata.txt", "r");//(以只读打开了待处理的文本)
if (!input) {
perror("无法打开输入文件");
return 1;
}
output = fopen("temp.txt", "w");
if (!output) {
perror("无法创建临时文件");
fclose(input);
return 1;
}
while (fgets(line, sizeof(line), input)) {
// 移除空行
if (line[0] != '\n' && strlen(line) > 0) {
fputs(line, output);
}
}
fclose(input);
fclose(output);
// 替换原文件
if (remove("usbdata.txt") != 0 || rename("temp.txt", "usbdata.txt") != 0) {
perror("文件替换失败");
return 1;
}
printf("空行已删除。\n");
return 0;
}
#将上面的文件用脚本分隔,加上冒号;
f=open('usbdata.txt','r')
fi=open('out.txt','w')
while 1:
a=f.readline().strip()
if a:
if len(a)==16:#键盘流量的话len为16鼠标为8 (所以在鼠标流量中也能用的脚本)
out=''
for i in range(0,len(a),2):
if i+2 != len(a):
out+=a[i]+a[i+1]+":"
else:
out+=a[i]+a[i+1]
fi.write(out)
fi.write('\n')
else:
break
fi.close()
这就是脚本实现的效果(在那个权威pdf里,我们可以读到这8组字节中,重要的就是第3组了)

接下来我们要按照USB表,输出对应的字符,表格的来源就是那个pdf的第53页

这是提取和转换脚本
#翻译键盘数据1.py
normalKeys={"04":"a","05":"b","06":"c","07":"d","08":"e","09":"f","0a":"g","0b":"h","0c":"i","0d":"j","0e":"k","0f":"l","10":"m","11":"n","12":"o","13":"p","14":"q","15":"r","16":"s","17":"t","18":"u","19":"v","1a":"w","1b":"x","1c":"y","1d":"z","1e":"1","1f":"2","20":"3","21":"4","22":"5","23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>","2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>","3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
shiftKeys={"04":"A","05":"B","06":"C","07":"D","08":"E","09":"F","0a":"G","0b":"H","0c":"I","0d":"J","0e":"K","0f":"L","10":"M","11":"N","12":"O","13":"P","14":"Q","15":"R","16":"S","17":"T","18":"U","19":"V","1a":"W","1b":"X","1c":"Y","1d":"Z","1e":"!","1f":"@","20":"#","21":"$","22":"%","23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>","2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>","3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
output = []
keys = open('out.txt')
for line in keys:
try:
if line[0] != '0' or (
line[1] != '0' and line[1] != '2'
) or line[3] != '0' or line[4] != '0' or line[9] != '0' or line[
10] != '0' or line[12] != '0' or line[13] != '0' or line[
15] != '0' or line[16] != '0' or line[18] != '0' or line[
19] != '0' or line[21] != '0' or line[
22] != '0' or line[6:8] == "00":
continue
if line[6:8] in normalKeys.keys():
output += [[normalKeys[line[6:8]]],
[shiftKeys[line[6:8]]]][line[1] == '2']
else:
output += ['[unknown]']
except:
pass
keys.close()
flag = 0
print("".join(output))
for i in range(len(output)):
try:
a = output.index('<DEL>')
del output[a]
del output[a - 1]
except:
pass
for i in range(len(output)):
try:
if output[i] == "<CAP>":
flag += 1
output.pop(i)
if flag == 2:
flag = 0
if flag != 0:
output[i] = output[i].upper()
except:
pass
print('output :' + "".join(output))
这是输出

发现是一串数字884080810882108108821042084010421
显然又是某种编码,通过观察,发现里面只有0、1、2、4、8
我们可以猜测它是云影密码
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 |
云影密码是用0分割的,比如说884代表8+8+4=20,代表的字符是T
这是解密脚本
def decode(cipher):
charList = [chr(i) for i in range(ord('A'),ord('Z')+1)]
ret = []
plaintext = [i for i in cipher.split('0')]
for i in plaintext:
tmp = 0
for j in range(len(i)):
tmp += int(i[j])
ret.append(charList[tmp-1])
return ''.join(ret)
decoding="884080810882108108821042084010421"
a=decode(decoding)
print(a)
这是输出结果
THISISFLAG
套上flag{}提交即可
看吧,USB流量分析是不是要比一般的流量分析有意思多了
Comments 1 条评论
上面有个c版本的脚本大家略过就行,我只是想应对考试练练而已