Schnelder - 500NAC 固件分析

阅读量223103

|评论2

|

发布时间 : 2020-08-19 15:30:12

 

一、固件基本信息

设备简介:5500NAC 是一个自动化的逻辑控制器,主要应用在楼宇控制系统,配备WEB界面以及cubs/MODBUS/Bacnet通信协议

获取方式:固件可以通过官网直接下载,附件中也包含固件。

固件压缩包文件名:5500NAC_Firmware_V1.6.0.zip

固件大小:8402400 字节 (8205 KiB)

SHA256:  81D2B46A6505B28D94DB9C7C9CF16EB38CC316747A1CCB93A3FBCE2C4487245E

固件文件分析:解压后可获得 .img 系统镜像 binwalk 可直接解压出文件系统

 

二、固件分析

1.固件文件系统分析

使用 binwalk 对其分析并尝试解压,获取文件系统

2.敏感信息发现

查看 /etc 文件夹中各类配置文件,发现了多个服务的默认账户信息

3.业务代码解密&审计

经分析,该固件业务功能采用Lua编写,查看/lib/ 文件夹发现大量.lua 文件

打开某些文件,却发现是各种乱码,编辑器提示是编码问题,换了各种编码后发现并不能改变乱码现象

随后想到,lua 存在各种加密和编译方式(但编译后后缀大都会发生改变如 luac),审计发现开头标志位 LJ 到网上各种搜资料,最终在看雪一篇文章中发现了蛛丝马迹

在确定为 luajit 编译后从安全客一篇文章中获悉了 luajit 的反编译方法{传送门},在这里我重点演示一下,使用 ljd 直接反编译 luajit 伪码的流程。

    • 在不同的版本中,Opcode 的不同会导致解析结果的不同,所以要首先要确定固件中的lua文件是由哪个版本的luajit以及lua编译的(否则会出错)
    • 在 /usr/bin 中找到 luajit文件

使用ghidra反汇编 luajit 查找关键字符串 lua 确定了 luajit 以及 lua 的版本

从 luajit 官网下载相对应版本的demo 查看/src/lj_bc.h头文件中的opcode

在 ljd 工具目录下 有两处代码引用了 Opcode 分别是 ljd/ljd/bytecode/instructions.py 和 ljd/ljd/rawdump/code/py

对比 lj_bc.h 中的 Opcode 定义一个一个改就可以了,ljd 默认是 2.1.0版本的,多的注释,少的加上。

由于我要反编译许多源码,所以临时改了一下 /ljd/main.py 使其可以支持多文件,并且将反编译出来的demo 写入新的文件demo如下(这里我反编译的目录是固件里的/lib目录):

import os
import re
import ljdmain
import sys def get_filelist(dir): ##获取包含绝对路径的文件列表 Filelist = []
for home, dirs, files in os.walk(path): for filename in files: #文件名列表, 包含完整路径 Filelist.append(os.path.join(home, filename)) return Filelist def mkdir(path): ##创建文件夹# 引入模块
import os# 去除首位空格 path = path.strip()# 去除尾部\ 符号path = path.rstrip("\\")# 判断路径是否存在# 存在 True# 不存在 False isExists = os.path.exists(path)# 判断结果
if not isExists: os.makedirs(path) print path + ' 创建成功'
return True
else :#如果目录存在则不创建, 并提示目录已存在 print path + ' 目录已存在'
return False# 调用函数if __name__ == "__main__": path = '/home/murkfox/ljd/lib'##
把固件中lib目录复制到了ljd工具目录下Filelist = get_filelist(path)## 获取被反编译的源码目录结构
for file in Filelist: ##创建空文件, 如果目录不存在就创建目录( 将输出重定向至创建的空文件中) fil = file.split("/") fil[4] = "libdec"
ffi = ""
mkpath = ""
for i in range(len(fil)): if i > 0: ffi = ffi + "/" + fil[i]
if i < len(fil) - 1: mkpath = mkpath + "/" + fil[i]# mkpath = mkpath + "/"#
print(mkpath)# mkdir(mkpath) if re.search(r "\.lua", file): ##遍历要反编译的目录, 找到需要被反编译的文件 mkdir(mkpath) with open(ffi, "w") as fl: ##反编译文件, 并将反编译demo输出至对应文件
try: fl.write("## Dec file \n") sys.stdout = fl ljdmain.main(file) fl.close() except: pass

如下是被逆向出来的目录以及文件内容

很多从代码审计来看,程序多处操作都是直接通过系统命令完成操作测试文件上传处的命令执行成功

由于设备为linux系统,在ping 命令没有加 -c 导致ping 程序一直执行,引发了拒绝服务,设备直接下线。

也发现了许多有趣的地方

本文由Murkf0x原创发布

转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/214730

安全客 - 有思想的安全新媒体

分享到:微信
+11赞
收藏
Murkf0x
分享到:微信

发表评论

内容需知
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全客 All Rights Reserved 京ICP备08010314号-66