0x0 引言

关于从键盘中还原出数据目前有两种思路:

  1. 基于特定的键盘进行深度学习(高度依赖键盘菜鸡样本)
  2. 基于密码替换

    1. 按照基础规则对声音进行定义
    2. 然后使用密码学中的替换来重新组合/解密
    3. 基于算法的衍生,不需要机器学习
    4. 有一定的错误,需要重新排版

0x1 样本概述

  • 这里以一道具体的ctf题目来作为样式
  • 这道题给了一个wav文件,文件中只有键盘敲击的声音
  • 考点在于如何从键盘敲击声中提取出用户输入的字符

解题思路:

  1. 首先以声音分片为单位对每一个键盘敲击做签名
  2. 给每一个键盘签名分配一个字符(可以随意分配)
  3. 利用签名以及对应的字符替换原始的声音分片
  4. 这时就把原始声音转换成了字符串
  5. 只要解决了密码学中的字符替换算法就可以还原出这个声音

0x2 算法实现

首先利用decode.py对每一个声音分片做一个标记:

# -*- coding: utf-8 -*-

from scipy.io import wavfile
samplerate, data = wavfile.read('../output.wav')

i = 0
countsilent = 0
samplefound = 0

avg = []
start = 0
end = 0
avg.append([0])

for sample in data:
    i+=1
    # 如果声音大小<100 就作为一个静默声音分片
    if(sample[1]<100):
        countsilent += 1 #静默声音分片+1
    
    # 按键声 开始
    if(countsilent > 10000 and sample[1]>100):
        countsilent = 0
        #print(str(i)+": sample found")
        start = i
        samplefound = 1
    # 按键声 结束
    if(countsilent > 8000 and samplefound==1):
        samplefound = 0
        # print(str(i)+": sample ended")
        end = i
        # 签名=(按键声音分片值之和)/按键声音分片数量
        avg[len(avg)-1]=avg[len(avg)-1]/(end-start)
        print("avg: "+str(avg[len(avg)-1]))
        avg.append([0])
    # 将某个按键的有效声音分片加起来
    if (samplefound == 1):
        avg[len(avg)-1] += sample[1]
  • 为每一个按键声音做签名
  • 签名=(按键声音分片值之和)/按键声音分片数量
  • 运行程序将结果输出到文件python3 decode.py >avg

接下来使用文件replace.pyavg做字母赋值:

# -*- coding: utf-8 -*-
alphabet = "abcdefghijklmnopqr stuvwxyz"
avg = {}

i=0

res=""

with open("avg") as file:
    for line in file:
        value = line.rstrip()[6:-1]
        #print(value)
        # 该签名没有对应的字母的话就给他分配一个
        if str(value) not in avg:
            avg[str(value)]=alphabet[i]
            i+=1
        res+=avg[str(value)]
print(avg)
print(res)
  • 到这里位置就获得传统密码学中密码替换加密后的密文
  • 密文如下
abcdefgdbfedhcijkdlkdfdhmnibadklacdabcdojkdpnkfqqgdrccqcedabmljibdabcdmfnkdplmdabcdpnmoadan cdnkdfdsccqdfkedabcdpqfidnodrhtapdlrckdhmftcd ctbfkntfqdqcghlfmeodfmcdqljedtqlocdhmftcdfkedabcdhnmeodscmcdonkinkidnkdnaodsfm abdabcmcdsfodkldsfgdaldfkantnrfacdsbfadsfodfhljadaldbfrrck

0x3 密码替换

thesdayshadsbegunsonsasbrightsnotesthesmunsfinallyspeeledsthroughsthesrainsforsthesfirmtsti
esinsasweelsandsthesflagsimspbctfsopensbraces
echanicalsleyboardmsaresloudsclomesbracesandsthesbirdmsweresmingingsinsitmswar
thsthereswamsnoswaystosanticipateswhatswamsaboutstoshappen
  • 看起来好像有问题,但是对照原始字符串你会发现基本上是对的
THE DAY HAD BEGUN ON A BRIGHT NOTE 
THE SUN FINALLY PEELED 
THROUGH THE RAIN FOR THE FIRST TIME IN A WEEL AND 
THE FLAG IS PBCTF OPEN BRACE 
MECHANICAL LEYBOARDS ARE LOUD CLOSE BRACE AND 
THE BIRDS WERE SINGING IN ITS WARMTH THERE WAS NO WAY TO ANTICIPATE WHAT WAS ABOUT TO HAPPEN
  • 最终的flag是pbctf{mechanical_keyboards_are_loud}
Last modification:October 22, 2021
如果觉得我的文章对你有用,请随意赞赏