天天看点

智能家居网络安全攻与防

物联网将会成为继互联网之后的下一个暴发点,目前以有不少公司已进入该领域。

智能家居作为物联网中最具有潜力的领域,网络安全是必须引起重视的课题。在互联网领域中,用户去安全性的敏感度并不是那个高。但是在智能家居领域中,如果系统被黑客攻击:半夜房门自动打开、无故解除安防系统、灯不亮等严重威胁到了用户的财产人身安全。

所以,智能家居想发展,安全性是决不可忽视的关键要素。

任何信息在网络上传播能是能被第三者监听的。

一个局域网就像是一间会议室,里面坐了几个人,大家坐在一起相互交流。同时只允许一个人发言,不管是谁说话都能被在场的所有人听见。

通常情况下,只有被交流的对象才会在意对方说的话,其他人不会留意。

比如:屋子里有a,b,c,d四个人。如下是a与b之间的对话:

a:嘿b

b:嘿a

a:“告诉我银行卡密码吧”

b:“123321”

由于a不是对c与d说的话,c与d自然忽略这句话,但是他们是能听得见的!

如果d是一个不怀好意的人,刻意留心他们的对话,是很容易窃听到关键信息的。

而且网络里还有arp诈骗等手段,网络安全是岌岌可危的。

怎么办?两种思路:

就是不允许其它结点加入到局域网中来。

在wifi普及面非常广的时代,家家都有无线路由器,这要求用户严守wifi密码,严防泄漏。

这比较难,有时候wifi密码会在用户不知情的情况下泄漏。比如市面上存在一种叫“wifi万能钥匙”,这就是一种盗取用户已登陆wifi结点密码并共享给其它人的工具。这说明这个方法很难把控。

至于如何在这方面有所提升,已超出了我们智能家居所负责的领域。暂不讨论~

做不到被听到,那就不让第3个人听懂也行。会议室里有a,b,c 3个人,a与b对英语交流,c在旁听到了,但不知道他们在说什么。

这是我们在安全方面可以做的。

该智能家居系统组织如下:

智能家居网络安全攻与防

server: 云端服务器

smarthost: 智能主机,负责将以太网中的数据能过zigbee数据转发给device

device: 设备结点,常见的有灯、窗帘、门磁感应器,与smarthost通过zigbee连接

client: 手机应用,有android客户端与ios客户端。接受用户的指令。当client与smarthost在同一局域网中,client通过wifi与smarthost进行交互;如果不在同一个局域网,则通过与server进行转发。

假设局域网中来了一个不速之客hacker,它启图操控家居设备。

如果client与smarthost之间的通信是明文的,那么没有安全性可言。只要黑客进入了家里的局域网,对网络包进行监听,很轻易地操控家里的设备。

client--&gt;smarthost: <code>login: account john, password abc</code>

smarthost--&gt;client: <code>ok</code>

client--&gt;smarthost: <code>open the door</code>

smarthost--&gt;client: <code>done</code>

hacker监听到上面的通信,hacker可以进行模拟client进行登陆

hacker--&gt;smarthost: <code>login: account john, password abc</code>

smarthost--&gt;hacker: <code>ok</code>

hacker--&gt;smarthost: <code>open the door</code>

smarthost--&gt;hacker: <code>done</code>

于是门开了。

由于是明文,稍有头脑的hacker就能分析出client与smarthost的通信协议。在盗取了用户的帐号与密码之后,hacker就可以完全掌据整个家居系统。

防预级别:v 只能抵挡没有网络基础的攻击

由于上面问题的是明文数据传输,容易被hacker分析。于是在上一版本的基础上使用特定的密钥对数据进行加密。

如下用()表示其中的内容是用static_key加密的

client--&gt;smarthost: <code>(login: account john, password abc)</code>

smarthost--&gt;client: <code>(ok)</code>

client--&gt;smarthost: <code>(open the door)</code>

smarthost--&gt;client: <code>(done)</code>

由于上面是用密文进行通信的,hacker不知道其容易是什么意思。但是,他知道只要把上面的话录制下来,重复播放一便就可以伪装client开门了。

hacker--&gt;smarthost: <code>(login: account john, password abc)</code>

hacker--&gt;smarthost: <code>(open the door)</code>

结果门开了。

其实hacker不知道client与smarthost的具体内容是什么。他可能猜到是在登陆系统,然后是发命令开门的动作。但他无法得知通信的结构,也无法获取用户的帐号与密码。它只能说模仿client的“发音”与smarthost进行对话,达到控制设备的目的。

针对上面hacker的攻击,我们做了改进。通常,hacker不会在监听到了命令之后立即执行。而是在等主人不在家了再执行上面的开门命令。那么,我们在密文域中加一个字段:timestamp(时间戳)。

client--&gt;smarthost: <code>(201509261543, login: accout john, password abc123)</code>

smarthost接收到命令,当前系统时间为2015-09-26 15:44,与client提供的命令误差在5分钟以内,通过检查。

smarthost--&gt;client: <code>(201509261544, ok)</code>

client接收到命令,当前系统时间为2015-09-26 15:43,与client提供的命令误差在5分钟以内,通过检查。

client--&gt;smarthost: <code>(201509261548, open the door)</code>

smarthost接收到命令,当前系统时间为2015-09-26 15:49,与client提供的命令误差在5分钟以内,通过检查。

smarthost--&gt;client: <code>(201509261549, ok)</code>

client接收到命令,当前系统时间为2015-09-26 15:48,与client提供的命令误差在5分钟以内,通过检查。

hacker监听到了上面的整个过程,在主人离开了家,在21:09实施攻击。

hacker--&gt;smarthost: <code>(201509261543, login: accout john, password abc123)</code>

smarthost接收到命令,当前系统时间为2015-09-26 21:09,与hacker提供的命令误差超出5分钟,丢弃。

攻击失败。

由于hacker不知道static_key,不知道client--&gt;server的明文是什么。所以他无法提取其中的帐号与密码信息。同时,他也没有办法更改密文中的timestamp。所以,无法成功突破。

通抵御普通的hacker攻击在时间间隔较长的指令伪装攻击。

上面的方式能抵挡超过5分钟的命令伪装,但是不能解决5分钟内的命令伪装问题。于是,我们在上一版的基础上,在指令中加添了serial域,即序列号,用于防止短时间内的重复指令。

在通信中,我们会随机生成一个serial:xxxxxxx,接收方收到指令后,会去查 serialtable看5分钟内有没有xxxxxxxxx存在。

如果没有找到,则处理该命令,然后将xxxxxxx加入到serialtable中。 如果找到,则丢弃该指令。

由于系统只保存5分钟的serial,不会有太大的查表负担。

如此与时间戳结合使用,便可以彻底解决hacker伪装命令的问题。

与timestamp相似,由于hacker无法获得明文,所以他没有办法修改里面的timestamp与serial。将已发送过的数据包再发一次,必然导致失败。

上面的安全措施看起来比较完善了。但是,它有3个前提条件:

加密算法过于强硬,无法逆运算

暴力破解代价大

第三方无法获得通信的加密算法与密钥

对于问题1,我们可能采用国际上公认的加密算法进行加密,如openssl中的aes。

对于问题2,我们可以使得加密的密钥过于复杂,比如128字节的密钥进行加密。如果使用暴力破解,其代价太大。

问题3是最大的问题。

有句话叫作:“日防夜防,家贼难防”,由于用于加密的密钥是写在代码里的。开发工程师是再清楚不过了,加密的密钥非常容易泄漏。

一旦static_key泄密,那么所有的加密如同没有加密!hacker所向披靡如入无人之地

不允许普通的开发工程师涉及加密算法与加密密钥。将加密算法的设计实现工作交给公司核心人士去实现。其它普通的研发工程师只能拿到一个二进制的静态库或动态库。

但这也有一点需要注意的,不管是生成什么样的加密过程,加密的密钥必须不能是明文。比如:

因为生成的二进制文件里有保存明文,可以轻易地用工具搜出来。如:

就会列出库中的所有明文。好奇心强的工程师很容易地就从中找出你的加密密钥了。

就算工程师没有泄密,hacker自己去买台smarthost,对程序用<code>strings</code>分析,也是能很轻松找出static_key的。

必须是动态生成的。如:

这样,不能轻而易举地获取到。但是,这也不是说获取不到了,只要单步跟踪调试,也能获取,只是麻烦了点。

信条:不能将加密算法设计者自己挡在外的加密算法不是好算法!

摒弃static_key的加密方法,每个产品在出厂时都有一个特有密钥unique_key,并且在服务器的数据有表。

以下以[]表示被unique_key加密的数据

用户购买了smarthost后,smarthost首次启动,登陆server。

smarthost--&gt;server: <code>(uid=xxxxxxxx)[timestamp=201509291255, serial=82342, i am smarthost, model=m1, log in]</code>

注意:smarthost在介绍自己uid时是用static_key加密,之后使用unique_key加密。

server--&gt;smarthost: <code>[allow]</code>

server从数据包中提取了uid,从数据库中查找到对应uid的unique_key,用unique_key加密回复的数据。

之后的数据包都是用smarthost的unique_key进行加密。

如此,只有数据库的super administor有权限得知对应uid smarhost的unique_key。

用户要使用client绑定smarthost,但client本身不知道smarthost的uid,也不知道smarthost的unique_key。如何与smarthost通信?

在 smarthost 的背后有一个二维码,就是该smarthost的unique_key。用户用client上的二维码扫扫功能,获取该smarthost的unique_key。

通信过程:

搜索smarthost

client用udp广播数据包:<code>[timestamp=201509291255, serial=24234, tell me your ip address]</code>

smarthost收到数据包后,用unique_key进行解密,验证timestamp域,发现结果正常 ,表示解密成功,证明该数据包正是发给自己的。于是回复udp包:<code>[timestamp=201509291255, serial=3234, ip_address=192.168.x.x]</code>

client收到udp数据包,用unique_key进行解密,得到了smarthost的ip地址。

如果同时出现2个以上的smarthost,只有使用了对应unique_key的smarthost才能通过timestamp验证(错误的unique_key解密所得的timestamp是没法通过时间戳验证的)。

绑定smarthost

后面的与主机交互过程都使用unique_key进行加密。

用password的md5sum当作unique_key进行通信,默认带timestamp与serial验证。

注册帐号

client--&gt;server: (regist: account=lucy, password=98789) server--&gt;client: (done)

服务器在接收到该注册信息后,会将password的md5sum作为unique_key与client进行数据加密。以下以[]表示用unique_key加密的数据。

在注册时,加密等级是很低的。

登陆

client--&gt;server: (login: account=lucy)[timestamp=201509292100] 告诉server自己的account,然后server根据account到数据库查

表,获得unique_key,并用其解密timestamp,再进行时间域校验。通过则表示登陆成功,否则表示失败。

server--&gt;client: [timestamp=201509292100, ok]

对于不了解通信协议的hacker,即使使用包伪装与重发包的方式已经是束手无策了。

这里的hacker,是指协议的设计者或对协议非常熟悉的人,假设他们:

已获得static_key与加密解密算法

不能接触到服务器与机密数据

不能接触到用户手上的smarthost

行动:

假设hacker已通过某种方法加入了smarthost的局域网。

通过监听器,捕获到了smarthost的登陆包,得到smarthost的uid。由于没有unique_key,得不到smarthost与服务器的通信内容。但他知道密文解密后的明文内容,可能使用暴力破解法进行破解。但是时间成本太高。

如果监听到client的注册过程就可以,因为注册数据包是用static_key加密的,可以破解。hacker可以获得用户的密码,进而算出md5sum的unique_key的。用这个来伪装真正的client,对smarthost进行操控。

此方法的关键点在于要抓到注册数据包,一个用户只有一次,而且要在与hacker所在局域网中进行才有可能被抓到。如果打算对smarthost进行攻击时,用户早都已经注册了帐户。

诱使用户使用盗号码木马app,从client的手机中窃取client保存在手机系统中的文件。从而获取client的帐号密码,以及smarthost的unique_key。

从上可得出,通过监听方式来破解似乎只有暴力破解法了。而更可行的破解方案还是盗号木马。

因为我们总得在手机上保存主机的unique_key与用户的帐号与密码。否则就得每次让用户去扫smarthost背后的二维码,每次都让用户重新输入帐号密码登陆。用户肯定受不了。

关于上面的安全性问题该如何解决,博主还没有想到合理的解决方案,欢迎讨论。上面的讨论如有纰漏,欢迎指正。

博主从事智能家居领域研发,欢迎关注!

继续阅读