CDC

Place to Be & Show Yourself

机甲大师S1 Python沙箱逃逸

机甲大师 ROBOMASTER S1

机甲大师 ROBOMASTER S1是DJI大疆创新推出的一款教育机器人,基于RoboMaster比赛打造。
拥有麦克纳姆轮全向底盘,增稳云台和低延时图传系统。可以以第一人称视角驾驶并发射水弹。
虽然按RC模型来说属于室内FPV遥控车,但是机甲大师S1还支持Scratch图形编程和Python编程,并内置目标检测算法,可以实现自动驾驶(但也就巡线那种程度)。极大增强了可玩性。

亮点与局限

ROBOMASTER S1的硬件设计优秀,做工考究。电源及动力系统集成度高,并且预留了螺丝孔和通信接口,改装潜力巨大。
在客户端提供的编程环境中,还自带PID控制器、IMU惯导和目标检测算法模块,作为教育(玩具)机器人来说完成度非常高。
但是
1. 仅限在客户端中编写程序,无法实现模块化开发。
2. 虽然支持Python3.6,但是限制了内建函数和标准库的使用。
3. 未开放所有的硬件,已开放的模块中,API接口的性能较差。
4. 过程式编程范式虽然简单易懂,但不适合进行机器人开发。
总之
1. 需要完整的Python执行环境和全套标准库。
2. 能够访问底层硬件,比如控制GPIO的边沿。
3. 需要文件读写和网络通信的权限。

环境探索

硬件接口
ROBOMASTER S1采用WiFi与客户端通信。图传和脚本上传功能基于udp,并在21号端口监听ftp(估计用于固件升级)。主板分为两个部分,运动控制器和智能中控。
运动控制器,主要负责电源和电机。上面的USB处于串口模式,开启debug后能输出日志。
智能中控,负责通信和图像处理,也是Python脚本执行的地方。上面有SD卡插槽,Type-C和Micro-USB,开启debug后Micro-USB能连接adb。但是售卖的量产机型无法直接进入debug模式。
运行环境
抓包ROBOMASTER S1与客户端的通信后发现,客户端中的Scratch被编码为含有Python语句片段的XML。脚本在智能中控中运行,当ROBOMASTER S1运行Python脚本时,会向客户端回传脚本执行时产生的日志。执行:

《机甲大师S1 Python沙箱逃逸》
可知其Python运行时为CPython,而非PyPy和MicroPython。并且导入了用于硬件控制的模块。
同时修改了执行环境的模块命名空间,屏蔽了部分Python内建函数,并限制了import语句能够导入的模块。

沙箱逃逸与任意代码执行

在Python中,模块的命名空间基于字典(hash表)实现,使用import语句可以导入其他模块,具体来说是调用内建函数__import__实现模块导入。
在CPython的实现中,内建函数位于内置命名空间中,可从模块命名空间的__builtins__属性处访问。默认情况下,该属性关联至标准库builtins模块的__dict__属性。
沙箱逃逸
ROBOMASTER S1修改了__builtins__属性和__import__函数,移除了dir,open等内建函数,并设置了模块导入的白名单。但是位于白名单中的模块,其命名空间未被修改,仍然关联至builtins模块。

rm_log无疑是负责日志读写的模块,其至少拥有日志目录的读写权限。期望以该模块为跳板访问ROBOMASTER S1的固件。

遍历固件目录和文件
由于ROBOMASTER S1限制了日志输出的最大字数和行数,且客户端较为简陋,无法显示更多信息。因此需要一种机制能够方便的访问系统目录和文件内容,而标准库的http.server模块提供了简单的文件服务器功能。

遍历系统目录可知,系统为Android4.4,固件被selinux保护,只读;SD卡目录可写。
Python子系统开机即启动,并以root权限运行。
启用debug模式
固件中含有大量用于工厂测试的shell脚本,包括对GPIO,I2C的控制,但是暂时无法确定智能中控和运动控制器的ROM材质(作为量产机应该是只读器件,但是若支持OTA升级又可能是Flash类器件)。
固件通过/proc/cmdline和具有防篡改机制的whitelist判断是否可以进入debug模式。
但是又贴心的提供了adb_en.sh,能够直接启用adb服务并打开串口。因此:

连接智能中控的USB接口,使用adb以root身份登录ROBOMASTER S1的shell。
《机甲大师S1 Python沙箱逃逸》
至此可以在ROBOMASTER S1中使用Python标准库,并访问底层硬件。

总结与展望

ROBOMASTER S1的Python沙箱基于exec,采用模板替换生成脚本文件。还修改了内核调度,似乎是期望提升实时性(然而并不能:响应缓慢,风扇狂转,CPU温度却高达60°C)。

可以看出其原始设计包含车、地面站和视频眼镜(UAV+GND+GLASS),且通信方式采用SDR而非WiFi。应该是面向RC竞技的遥控玩具而非编程教育机器人。其Python部分大量照搬嵌入式C程序的设计范式(还存在诸如文件句柄泄露的问题)

点赞

发表评论

电子邮件地址不会被公开。