dolphin attack是一种超声波攻击,它通过注入人耳无法识别的 20kHz+ 超声波控制语音助手(如 Alexa、Siri),间接实现语音触发与信息获取。
参考https://cool-y.github.io/2021/01/08/dolphin-attack-practice/
学习一下如何对该攻击方法进行复现。该同学与作者进行了一番交流,一些问题总结如下。
- Q: 使用便携式设备攻击的时候,三星Galaxy S6 Edge发送的高频声音信号是怎么生成的呢?是预先使用专业设备调制好的信号保存为mp3吗?
- A: 通过软件调制,生成.wav的超声波音频文件,再通过三星手机播放的。
- Q: 用的是什么软件进行调制?
- A: 用过matlab和python,都是可以的
一、语音命令生成
https://ttstool.com/ 微软的TTS接口生成的是mp3格式音频,一般来说我们使用python处理音频都是针对wav格式。 https://www.aconvert.com/cn/audio/mp3-to-wav/ 我们可以通过这个网站对格式做转换。 xiaoyi.wav 这个网站的采样率最高只能达到96000hz 6wxmu-crusr.wav
由于华为手机直接录制音频是m4a,所以还要准备一个m4a转wav的网站。
https://cdkm.com/cn/m4a-to-wav#google_vignette
https://www.freeconvert.com/zh/m4a-to-wav
二、语音命令调制
生成语音命令的基带信号后,我们需要在超声载波上对其进行调制,以使它们听不到。 为了利用麦克风的非线性,DolphinAttack必须利用幅度调制(AM)。
AM调制
使载波的振幅按照所需传送信号的变化规律而变化,但频率保持不变的调制方法。调幅在有线电或无线电通信和广播中应用甚广。调幅是高频载波的振幅随信号改变的调制(AM)。其中,载波信号的振幅随着调制信号的某种特征的变换而变化。例如,0或1分别对应于无载波或有载波输出,电视的图像信号使用调幅。调频的抗干扰能力强,失真小,但服务半径小。
假设载波uc(t)和调制信号的频率分别为ωc和Ω,在已调波中包含三个频率成分:ωc、ωc+Ω和ωc-Ω。ωc+Ω称为上边频,ωc-Ω称为下边频。
使用python来进行调制即可。
wave包最多能读取的wav音频采样率为48khz,当超过这个值时,wave就不再支持(wave.Error: unknown format: 65534)。如果载波频率为30khz左右,这就要求音频文件的采样率高于60khz才能保证不失真。所幸scipy.io.wavfile支持高于48khz的wav文件读取。 使用以下Python程序来生成调制的AM和AM-SC音频,AM是广播无线电调制的“正常”声音,它加上了载波;AM-SC则只是载波与原始信号的乘积。
# coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import os
import wave
import struct
import math
from pydub import AudioSegment
import scipy.io.wavfile
def main():
test = scipy.io.wavfile.read("xiaoyi.wav")
nframes = len(test[1])
waveData = np.fromstring(test[1],dtype=np.short)#将原始字符数据转换为整数
#音频数据归一化
maxW = max(abs(waveData))
waveData = waveData * 1.0/maxW
#将音频信号规整乘每行一路通道信号的格式,即该矩阵一行为一个通道的采样点,共nchannels行
Tdata = np.reshape(waveData,[nframes,1]).T # .T 表示转置
am = wave.open("am.wav", "w")
amsc = wave.open("amsc.wav", "w")
carrier = wave.open("carrier3000.wav", "w")
for f in [am,amsc,carrier]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(96000)
for n in range(0, nframes):
carrier_sample = math.cos(30000.0 * (n / 96000.0) * math.pi * 2)
signal_am = signal_amsc= waveData[n] * carrier_sample
signal_am += carrier_sample
signal_am /= 2
am.writeframes(struct.pack('h', signal_am * maxW))
amsc.writeframes(struct.pack('h', signal_amsc * maxW))
carrier.writeframes(struct.pack('h', carrier_sample * maxW))
if __name__=='__main__':
main()
三、UltraDolphin
针对dolphin attack的延申,发现了一个新项目,能够针对性地完成音频处理,将音频调制到超声波。
https://github.com/scs-labrat/UltraDolphin
使用方法
git clone https://github.com/yourusername/UltraDolphin.git
cd UltraDolphin
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
pip install -r requirements.txt
python ultradolphin.py
出现提示时输入音频文件的路径:
Enter the path to the audio file: path/to/your/audiofile.wav
该脚本将处理音频并生成以下文件:
audible_artifacts.wav:包含从超声波信号中提取的可听见的伪影。modulated_25kHz_signal.wav:包含已调制的超声波信号。
该脚本还将绘制信号处理各个阶段的频谱。