标签 ComfyUI-Manager 下的文章


一、前言

1.1、组件信息

ComfyUI-Manager 是一个旨在提升 ComfyUI 可用性的扩展。它提供管理功能,用于安装、移除、禁用和启用 ComfyUI 的各种自定义节点。此外,该扩展还提供了枢纽功能和便捷功能,方便访问 ComfyUI 内的各种信息。

1.2、影响版本

ComfyUI-Manager < 3.39.2

ComfyUI-Manager < 4.0.5 

二、漏洞分析

2.1、RCE链分析

2.1.1、环境搭建

python3 -mpip installvirtualenv
git clone https:
cdComfyUI/custom_nodes
git clone -b3.39.1 https:
cd ..
python -mvenv venv
source venv/bin/activate
python -mpip installtorch torchvisiontorchaudio --extra-index-urlhttps:
python -mpip install -rrequirements.txt
python -mpip install -rcustom_nodes/comfyui-manager/requirements.txt
cd ..
pythonmain.py --preview-methodauto --cpu

2.2.2、CRLF分析



漏洞commit

https://github.com/Comfy-Org/ComfyUI-Manager/commit/f4fa394e0f03b013f1068c96cff168ad10bd0410

a、sink分析

根据漏洞commit,我们很快就能确定出漏洞函数(write_config)。如图所示,很经典的CRLF漏洞修复处理(处理掉\r、\n、\x00字符),然后再安全写入到文件到中去。



b、data flolw & souce分析

这里的数据流分析很简单,所以跟source一起分析了。

api server服务基本都集中在:ComfyUI-Manager/glob/manager_server.py文件中,所以我们基本上分析这个python文件souce即可。

在该文件中/manager/policy/component这个api接口就使用了write_config函数。



其中通过set_component_policy函数进行改动core.config的配置



c、完整链路 & PoC

api接口manager/policy/component(component_policy) -> 通过set_component_policy赋值带入CRLF -> core.write_config写入值造成CRLF注入。

这里构造构造注入ini配置文件需要注意一下。



这里需要注意'\r'作为换行,而不是\n作为换行(使用了python的ConfigParser),因为会替换\n为\n\t导致CRLF后的属性注入失败。


并且这里有多个注入点我们使用manager/db_mode就是为了注入在原有配置的security_level后面,我们使用PoC如下:



完成注入



2.2.3、RCE链分析

上面仅仅完成了配置文件的注入,可以配置文件的修改有什么作用呢?并且服务ComfyUI-Manager是否会自动更新配置呢?

a、sink点1 - 重启服务

发现/manager/reboot接口不需要任何身份验证,即可执行重启服务,也就是可以直接加载配置文件了。



这里的身份验证比较简单,查询配置中的security_level等级,如果配置中的等级低于接口的等级接口就允许(配置文件中默认是normal),也就是/manager/reboot接口默认有权限。



b、sink点2 - 执行远程python文件

前面做了那么多的铺垫,其实就是为了进行权限绕过使用/customnode/install/git_url接口:我们通过配置文件覆盖,重启服务,成功将安全等级降级为weak也就是可以使用该接口。



分析这个接口时候,发现core.gitclone_install(url)函数后端会再使用execute_install_script函数,最终调用[sys.executable, "install.py"]命令。





我们在github上创建一个空的项目,新建一个install.py文件

最终进行加载即可



三、总结

3.1、漏洞总结

1、修改配置文件,为了降低程序运行的等级

2、重启系统,为了重启加载配置生效

3、运行敏感函数,能够进行RCE

3.2、最后

python的ini-format居然是\r进行分割,纠结了很久。