被丢过来一个设备和一篇论文,说让做个隐藏摄像头的演示平台,感觉论文里面写设备分析的漏洞内容比较少见,就进行分析了下。
使用方式
设备使用方式有
SD卡离线使用
WLAN联网使用app远程观看图像
分析流量
尝试对app流量分析,发现,指令、数据均使用UDP协议传输,在应用层使用ACK和重传机制确保数据的可靠传输,指令数据包的内容使用JSON格式的Key-Value格式,并且APP和摄像头间的指令和数据均使用明文传输,极易被攻击
进一步分析发现每一条指令都会带上密码字段,如果‘pwd’(密码)正确,摄像头执行‘GetDevStream’指令,然后返回实时视频流给APP;如果‘pwd’错误,摄像头拒绝执行指令,丢弃该数据包或返回错误信息,但是实际上发现该系统的鉴权由APP客户端完成,并且只有在连接摄像头时会验证密码。
在APP连接摄像头时,发送一条‘LoginDev’的指令摄像头验证指令中的‘pwd’密码是否正确,如果正确返回的结果中‘result’为0,如果错误返回的结果中‘result’为-1。
LookCam APP验证‘LoginDev’指令的返回结果,如果result为-1就在软件中显示“密码错误”,禁止继续对摄像头进行操作
如果劫持APP的检测函数,或者修改APP的代码绕过对“result”的检测,会发生什么?
apk简单逆向
使用逆向分析工具Jadx对LookCam的安装包进行反编译,在代码中查找关键字‘LoginDev’,最终定位到一个关键函数“LoginDevice”该函数的功能是发送登录请求,并判断摄像头返回的结果。如果摄像头返回的“result”为 0,就更新设备的State为 1,否则更新设备的State为 2 或 4(1对应的状态为成功登录)如果将该函数修改为无论“result”的值为多少都更新设备的State为1,就实现了在不知道密码的情况下“连接设备”实现该功能的方法有很多,比如使用Frida动态插桩工具重载LoginDevice函数
简单编写Frida脚本,测试可以直接输入设备码即可连接返回视频流
进一步分析LookCam的代码,找到APP和摄像头通信的全部API如下图所示。包含获取视频信息、下载文件、配置网络、获取设备信息等等查找API接口的实现方式,发现具体的对指令进行编码、发送UDP数据包等功能由Native层完成,其中与摄像头通信的so库为‘libPPCS_API.so’so依赖库使用C++编写,使用IDA或Ghidra进行反汇编分析
平台模拟
使用IDA对该库文件进行分析,可以还原APP和摄像头完整的通信过程,包括设备发现、握手建立通信“连接”、定时发送心跳包维持“连接”等很容易使用Python编写一个模拟程序,实现与APP相同的功能,比如发送指令、下载文件通过该模拟程序可以构造任意指令发送给摄像头,可以更便捷地调试摄像头接口
image6.png
硬盘挂载
分析发现‘DownloadFile’接口,“path”参数为要下载的文件的位置。摄像头固件并没有对path进行限制,导致可以下载任意文件。
构造指令{ “cmd”: “DownloadFile”, “path”: “/proc/mounts”,}可以下载mounts文件,包含系统的硬盘挂载信息
从mounts文件中可知,“/dev/root”、“/dev/mtdblock5”等设备分别对应系统的“/”和“/usr”等挂载点使用‘DownloadFile’接口下载这些文件,在Kali中使用mount命令挂载文件系统,可以获取摄像头的文件系统
shell注入
对摄像头的文件系统进行分析,可以在“/usr/sbin“目录下发现许多shell脚本,经测试发现这些脚本存在严重的安全漏洞
脚本文件“station_connect.sh“的功能是连接Wi-Fi,其中部分代码如下:
该脚本使用了“sh –c”来执行命令,并且命令中有变量“SSID”、“PSK”等,易分析得到这两个为待连接Wi-Fi的名称和密码
在“PSK”中使用 ‘&& 即可打断 wpa_cli 程序的执行,注入恶意代码。
比如PSK为时‘&& echo -e “1234\n1234” | passwd root会更新root用户的密码为1234
或者反弹shell,拿到摄像头的控制权限
Telnet
使用nmap扫描摄像头的开放端口,找到23、21Shell注入修改root的密码后就可以直接连接摄像头的Telnet和Ftp服务密码信息存储在”/etc/shadow”文件中,从前面挂载的文件系统中可知该文件的实际位置是“/etc/jffs2/shadow”从mounts文件中可知“/etc/jffs2”分区的挂载格式为jffs2因此对root用户的密码修改是永久有效的,即使之后摄像头按下重置键,root密码也不会重置
P2P将摄像头暴露在公网下
摄像头在配置完网络后就会定期向服务器发送一个心跳包,服务器会记录摄像头端的IP和端口数据其他用户知道摄像头的序列号后,便可向服务器请求获取摄像头的地址,然后就可以通过这个地址和端口向摄像头发送数据攻击者完全可以利用P2P服务器与摄像头建立连接,然后以摄像头为跳板去攻击摄像头所在的内网但摄像头的序列号足够长,整个序列空间过大以至于攻击者很难通过枚举序列号来找到全网的在线摄像头