作者:Murkf0x
本文为作者投稿,Seebug Paper 期待你的分享,凡经采用即有礼品相送!
投稿邮箱:[email protected]
厂商:Schnelder 涉及产品型号:NetBotz 750 固件版本:v5.2.0
一、固件基本信息
- 设备简介:
- NetBotz 750用于从网络机柜到数据中心的性能安全和环保系统监测。从边缘网络到数据中心的监测、感应和环境监控 获取方式:固件可以通过官网直接下载,附件中也包含固件。 固件包文件名:NBRK075x_Build_5.2.0.3061.sedp
- 固件大小:
- 263927026 字节 (251 MiB)
- SHA256:
- E4A38B9ECABA04CDC88368A26C9150DBA7B8A08017F6DC06B4D03FC8F11863A9
- 固件文件分析:
- sedp后缀文件可直接使用zip方式解压即可获得相关系统镜像
二、固件分析
固件包下载到本地后,发现后缀名为sedp
,尝试解压,发现可以使用zip方式进行解压
root.img
为文件系统镜像,使用binwalk
进行分析
获悉,该固件文件系统为 EXT3 可以直接使用 binwalk
解压
/com
以及 /sun
其中都是 java 的 class 文件 ext-root
为文件系统
通过/etc/issue
确定系统版本(大多数以linux为核心构建的工控固件系统都可以通过该文件确定系统版本)
Poky 说白了就是使用Yocto Project基于linux构建的一个定制系统。(Yocto Project 是一个开源协作项目,它提供了一些模板、工具和方法来支持面向嵌入式产品的自定义 Linux 系统,不管硬件架构是什么。)
查看 /netbotz_app
目录下文件,发现是WEB服务目录
先看一下这个根目录的/start.sh
通常来讲这样的启动脚本会告诉我们,应用运行过程中依赖有哪些组件。
我们注意到,netbotz 是一个java 应用,使用的数据库是postgresql
,然而/opt/ 这个目录压根就没有,所以有关这个数据库的配置信息以及数据库文件到底在哪里,是一个问题。继续往下分析
由此我们可以判断出,数据库开放端口以及用户名,但数据库用户名依然无从知晓。继续分析其他文件,由于此时关注点集中在数据库组件上,我们注意到了一个文件 /upgradedb.sh
,这是一个用于更新数据库的脚本。
用户名和密码被我们找到了。
继续分析/webapps/se-netbotz_app/
目录下的WEB服务
通常我们在分析java WEB应用时会先查看相关配置文件/META-INF/META-INF.MF /WEB-INF/web.xml
META-INF 会保存程序入口以及程序版本等相关信息, 每个jar 都会有这个文件夹,里面的 MANIFEST文件 记录这些信息。
web.xml文件是我们开发Web程序的一项很重要的配置项,里面包含了我们各种各样的配置信息,比如欢迎页面,过滤器,监听器,启动加载级别等等。在服务器启动时,第一步便会加载项目的web.xml文件,然后通过其中的各种配置来启动项目。
探查其他,未发现有效信息。转而对该应用进行反编译。Java对包的命名相对来讲比较严格,通常,包的命名中就包含相关应用的信息。比如
包的命名中包含应用的名字netbotz
,说明该包内所含代码与引用相关,通常来讲,不加后缀的包,为应用主程序。
由于程序未被加密,直接使用 JD-gui
加载jar包,找到应用入口类。
在props中也发现了数据库配置信息
并且,在包的命名中,公认的命名方式是 com/org.公司名.项目名.业务名全小写,因此我们可以判断出来jar包中所包含的各项功能的代码范围。当然,如果想要快速的审计某个漏洞的话,还需要关键词搜索,来定位相关demo。
比如说,我们可以尝试搜索一些执行系统命令的关键词
从代码中可以看出,这是一条被拼接出来的系统命令语句,用于操作ssl证书库的更新。其中
大概可以被我们操控(密码需要我们输入吧。目录需要我们指定吧)
从上述代码中可以看得出来,最终被拼接进系统命令的 passwordStr
是 从 password
处获取到,而其中只不过执行了一个方法==String.valueOf)()==
,这个方法只是一个数据类型转换,其作用是强制把其他数据类型转换成字符串,但这并不会对我们插入想执行的系统命令有所限制,password
则是 changeit
这个字符串执行了 toCharArray()
方法得来,但 toCharArry()
方法只是一个字符串转换成一个 Character
型的字符数组,并且这里面的字符是原封不动的拿进去的,意思就是说,包含一切字符均转换成相应的字符数组。,也不会对我们的输入进行过滤。所以,只需要我们把这个密码改成一个命令注入语句,就可以实现命令注入。
同理我们找到设备HTTP 代理设置处
这条被拼接的系统命令执行中,proxyUserPassword
也是我们可以操控的地方
通过上述代码,可以发现,ProxyUserPassword
除了进行了空值校验外,也并没有进行任何过滤,是直接由proxyUser + ":" + proxyPassword + "@"
拼接成
而我们可以设置的用户名和密码,则是通过 ProxyConfig 类实例化得到
也并没有限制,所以我们至少可以通过自定义 username 值 来进行拼接执行命令。 当然,在进行命令注入挖掘过程中,如果没有全局的参数过滤,那基本就是全军覆没了,比如
这里执行的网络参数设置中,deviceName 也没有任何过滤。在相关应用开发过程中,应慎用系统命令执行,尤其是用户可控数据的拼接,如果用户所能控制的数据传入,使其通过恶意构造执行系统命令,后果不堪设想啊。
PS : 将漏洞反馈厂商后。厂商表示,所传输数据通过Rest_Api 进行处理,是进行了相关参数的过滤。但笔者并没有找到相关证据。厂商也正在对代码进行分析,也欢迎各位同好进行相关分析。
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1170/