HackMyVM Encrypt 通关记录|SSL 证书凭据泄露与 CVE-2026-31431 Copy Fail 内核提权
靶机链接:Encrypt
0x01 基本信息
| 名称 | IP | 说明 |
|---|---|---|
| Kali Linux | 192.168.1.113 | 攻击机 |
| Encrypt | 192.168.1.249 | Debian 13 (trixie) 靶机 |
攻击流程
点击展开
攻击链摘要
| 阶段 | 关键证据 / 操作 | 作用 |
|---|---|---|
| 服务发现 | 22/tcp SSH、443/tcp HTTPS Apache | 确定目标对外暴露的服务端口 |
| 证书信息泄露 | 443/tcp SSL 证书 Subject CN 为 iot:Goat123! | 从 TLS 证书元数据中直接获得明文登录凭据 |
| 初始访问 | sshpass -p 'Goat123!' ssh iot@192.168.1.249 | 成功建立低权限用户 iot 的 SSH 会话 |
| User Flag | 读取 /home/iot/user.txt | 获取第一个用户 Flag |
| 本地信息收集 | Debian 13 (trixie),内核 6.12.74,预装 gcc | 确认系统处于 CVE-2026-31431 易受攻击内核区间 |
| 内核提权利用 | 编译并执行自包含的 copyfail.c | 利用 AF_ALG AEAD + splice() 将 160 字节 SUID Shellcode 写入 /usr/bin/su 的 Page Cache |
| 触发 Root Shell | 执行 /usr/bin/su(从内存中运行篡改后的 ELF 头部) | 获得真实 uid=0(root) 权限并读取 /root/root.txt |
| 痕迹清理与恢复 | echo 3 > /proc/sys/vm/drop_caches | 立即释放被污染的页面缓存,使 /usr/bin/su 恢复原状 |
0x02 侦察与信息收集 (Reconnaissance)
1. 主机发现
在 Kali 中对局域网网段进行探测:
sudo arp-scan -l
输出:
Interface: eth0, type: EN-10MB, MAC: 00:0c:29:ab:cd:ef, IPv4: 192.168.1.113
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.1.249 0c:dd:24:76:71:18 Intel Corporate
1 packets received by filter, 0 packets dropped by kernel
Ending arp-scan: 256 hosts scanned in 1.842 seconds (138.98 hosts/sec). 1 responded
确认靶机 IP 为 192.168.1.249。
2. 端口扫描与服务识别
使用 Nmap 对靶机全端口及服务版本进行全面扫描:
nmap -p- -sV -sC -A -T4 192.168.1.249 -oN nmap_report.txt
关键扫描结果:
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 10.0p2 Debian 7+deb13u2 (protocol 2.0)
443/tcp open ssl/http syn-ack ttl 64 Apache httpd 2.4.67 ((Debian))
| ssl-cert: Subject: commonName=iot:Goat123!
| Issuer: commonName=iot:Goat123!
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2026-05-26T17:58:58
| Not valid after: 2027-05-26T17:58:58
| MD5: 9d69 f384 3471 469e 3dd1 94ad b463 54b9
| SHA-1: 37d1 c506 b5c4 b97c 4bcf 0736 d73e ebdd e1c8 89dd
| SHA-256: 0d9e 4230 6f0e a388 fff5 415a 7ffe d3f1 4fbc a625 48da 865e 678e 14d8 9a42 d398
| -----BEGIN CERTIFICATE-----
| MIIDDzCCAfegAwIBAgIUVb1kn6YtHaUKyanwpBfirAyt1Z0wDQYJKoZIhvcNAQEL
| ...
|_-----END CERTIFICATE-----
|_http-server-header: Apache/2.4.67 (Debian)
|_http-title: Apache2 Debian Default Page: It works
3. Web 服务与证书信息分析
- 访问
https://192.168.1.249,页面为标准的 Apache2 Debian Default Page。 - 重点在于 Nmap 提取的 SSL 证书字段:
Subject: commonName=iot:Goat123!Issuer: commonName=iot:Goat123!
- 证书中的
commonName直接给出了明文形式的凭据iot:Goat123!(用户名:密码)。
0x03 初始立足点 (Initial Foothold)
1. SSH 登录
使用收集到的凭据 iot : Goat123! 登录 22 端口 SSH:
sshpass -p 'Goat123!' ssh -o StrictHostKeyChecking=no iot@192.168.1.249
输出:
Linux encrypt 6.12.74+deb13+1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.74-2 (2026-03-08) x86_64 GNU/Linux
2. 用户权限确认与获取 User Flag
iot@encrypt:~$ id
uid=1000(iot) gid=1000(iot) groupes=1000(iot),100(users)
iot@encrypt:~$ cat /home/iot/user.txt
8a86e2c71318c41c30c442a0605af4e638de10f2476a70d0d054c19070db1a9d
成功获取 User Flag:8a86e2c71318c41c30c442a0605af4e638de10f2476a70d0d054c19070db1a9d。
0x04 本地枚举与漏洞分析
1. 系统与权限排查
执行常规系统枚举:
iot@encrypt:~$ sudo -l
[sudo] password for iot:
iot is not in the sudoers file.
iot@encrypt:~$ uname -a
Linux encrypt 6.12.74+deb13+1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.74-2 (2026-03-08) x86_64 GNU/Linux
iot@encrypt:~$ which gcc python3
/usr/bin/gcc
本次编译与运行环境
iot不在 sudoers 中。- 靶机未安装
python3,但安装了gcc(/usr/bin/gcc),支持在本地直接编译 C 源码。 - 内核版本为
6.12.74,Debian 13 (trixie)。
2. 漏洞定位:CVE-2026-31431 ("Copy Fail")
该内核版本存在 Linux 内核本地提权漏洞 CVE-2026-31431(代号 Copy Fail)。
漏洞核心机制
- 接口缺陷:Linux 内核通过
AF_ALG套接字向用户态提供加密子系统接口(algif_aead/authencesn)。 - In-place 写入行为:在使用
authencesn(hmac(sha256),cbc(aes))进行 AEAD 解密操作时,如果输入数据是通过splice()系统调用从文件管道喂入的,内核在执行解密时会将解密结果直接就地写回源文件在内存中的 Page Cache(页面缓存)。 - 绕过写权限检查:由于写操作发生在内核 Page Cache 层面,并不经过普通用户态的文件写权限校验(类似 Dirty Pipe 机制),因此普通非特权用户可以对任意只读文件(包括 SUID 程序)在内存中的缓存页面进行精确篡改。
- 利用链设计:
- 目标文件选择具备 SUID root 权限的二进制程序
/usr/bin/su。 - 构造一个 160 字节的独立 x86_64 ELF 头部与 Shellcode(功能为调用
setuid(0)并执行execve("/bin/sh"))。 - 以 4 字节为一个分块(Chunk),循环 40 次将这 160 字节覆写到
/usr/bin/su的 Page Cache 起始位置。 - 覆写完成后,调用
/usr/bin/su,内核从 Page Cache 中读取并执行篡改后的 ELF 代码,由于其具备 SUID 标志,进程直接以 root 权限生成/bin/sh。
- 目标文件选择具备 SUID root 权限的二进制程序
编写与移植利用代码的关键要点
在移植此漏洞利用代码时需注意以下关键细节:
- IV cmsg 长度:
ALG_SET_IV的控制消息长度必须精确为 20 字节(CMSG_LEN(20)),包含 16 字节 IV 长度声明与 19 字节零填充。 msg_controllen精确截断:sendmsg发送的控制消息链必须精确计算 3 个 cmsg 的总长度,避免多余空字节导致内核返回EINVAL。MSG_MORE标志:sendmsg必须携带MSG_MORE(0x8000) 标志,以保持 AEAD 解密请求处于接收状态,否则后续splice()会因为没有活动请求而报错Invalid argument。
0x05 权限提升利用 (Privilege Escalation)
1. 利用代码准备
由于靶机未安装 Python3,但预装了 gcc,我们使用自包含 160 字节 SUID Shellcode 的独立 C 语言利用程序进行提权。
完整利用源码见附件:copyfail.c
核心实现要点:
- 内嵌 Payload:内嵌 160 字节的独立 x86_64 ELF 头部与机器码,功能为
setuid(0)后调用execve("/bin/sh", NULL, NULL)。 - AEAD 接口解密:通过
AF_ALG绑定authencesn(hmac(sha256),cbc(aes)),配置ALG_OP_DECRYPT模式及 20 字节 IV。 - Page Cache 覆写:利用
sendmsg(..., MSG_MORE)保持会话,并以 4 字节为步长通过splice()将目标文件/usr/bin/su的内容喂入套接字,触发内核将构造的 ELF 代码就地覆写至内存中的 Page Cache。
2. 上传、编译与触发漏洞
在 Kali 上将 copyfail.c 传输至靶机 /tmp 目录,并在靶机上编译执行:
# 从 Kali 上传源码至靶机
sshpass -p 'Goat123!' scp /project/www.beehack/www.beehack.com/static/files/hackmyvm/encrypt/copyfail.c iot@192.168.1.249:/tmp/copyfail.c
# 在靶机上编译并执行
iot@encrypt:~$ gcc -O2 /tmp/copyfail.c -o /tmp/copyfail
iot@encrypt:~$ /tmp/copyfail
执行过程与输出:
[+] Overwrite complete. Spawning root shell via /usr/bin/su ...
# id
uid=0(root) gid=1000(iot) groups=1000(iot),100(users)
# whoami
root
已成功获得真实 uid=0(root) 的 root shell!
3. 获取 Root Flag
# cat /root/root.txt
bc06e6ee33aee532901fc6cd2926ea0789751a6bfd47f7dea5654cdf68418b85
成功读取 Root Flag:bc06e6ee33aee532901fc6cd2926ea0789751a6bfd47f7dea5654cdf68418b85。
页面缓存释放的适用范围
以下命令需要 root 权限,用于尝试释放干净的页面缓存及可回收的 slab 对象;它不是针对 /usr/bin/su 的恢复操作,也不保证该程序已恢复原始状态。释放缓存可能增加后续 I/O 与 CPU 开销,执行后仍需单独验证程序状态:
echo 3 > /proc/sys/vm/drop_caches
0x06 最终成果 (Final Flags)
User Flag
- 路径:
/home/iot/user.txt - 内容:
8a86e2c71318c41c30c442a0605af4e638de10f2476a70d0d054c19070db1a9d
Root Flag
- 路径:
/root/root.txt - 内容:
bc06e6ee33aee532901fc6cd2926ea0789751a6bfd47f7dea5654cdf68418b85
凭据与阶段成果汇总
| 项目 / 阶段 | 凭据或结果 | 说明 |
|---|---|---|
| HTTPS SSL 证书 | iot:Goat123! | 443 端口证书 CommonName 字段泄露凭据 |
| SSH 登录 | iot / Goat123! | 获取低权限交互 Shell |
| User Flag | /home/iot/user.txt | 包含 Flag 1 哈希 |
| 提权漏洞 | CVE-2026-31431 (Copy Fail) | Linux 内核 AF_ALG / splice Page Cache 写入缺陷 |
| Root Shell | /usr/bin/su SUID 内存劫持 | 获得 uid=0(root) 真实特权 |
| Root Flag | /root/root.txt | 包含 Flag 2 哈希 |
0x07 提权原理与技术复盘
| 关键组件 / 步骤 | 原理与作用 |
|---|---|
socket(AF_ALG, SOCK_SEQPACKET, 0) | 创建 Linux 加密算法套接字,绑定 authencesn(hmac(sha256),cbc(aes)) AEAD 算法 |
ALG_SET_OP = ALG_OP_DECRYPT | 设定操作模式为解密,触发内核在解密流程中的写回行为 |
ALG_SET_IV = 20 bytes | 严格设置 20 字节 IV 控制消息,保证内核参数校验通过 |
sendmsg(..., MSG_MORE) | 保留 AEAD 会话处于数据接收状态,允许后续 splice() 传递文件流 |
splice(fd -> pipe -> opfd) | 将 /usr/bin/su 的数据分块送入套接字,内核直接就地解密覆盖源文件 Page Cache |
| 160 字节 ELF Stub | 紧凑的独立 x86_64 二进制头部,包含 setuid(0) 与 execve("/bin/sh") 调用 |
system("/usr/bin/su") | 调用具备 SUID root 的文件,内核直接加载执行缓存中的 Payload 产生 root shell |
echo 3 > /proc/sys/vm/drop_caches | 丢弃页面缓存,干净无损地还原目标程序,不留物理文件损坏 |
0x08 防御与安全加固建议
- 证书信息脱敏与管理:
- 严禁将用户名、密码、API Key 等任何敏感凭据写入 SSL/TLS 证书的
Subject、Issuer、Common Name或SAN等公开字段。
- 严禁将用户名、密码、API Key 等任何敏感凭据写入 SSL/TLS 证书的
- 凭据安全与认证加固:
- 禁用密码弱口令,强制使用基于非对称密钥(如 ED25519 / RSA-4096)的 SSH 认证,并禁用基于密码的 SSH 登录。
- 内核安全补丁升级:
- 及时将 Linux 内核升级到已合入 CVE-2026-31431 修复补丁的发行版版本,修复
algif_aead中的 page cache write-back 漏洞。
- 及时将 Linux 内核升级到已合入 CVE-2026-31431 修复补丁的发行版版本,修复
- 系统调用与模块隔离:
- 在不需要用户态加密接口的环境中,通过 Seccomp、AppArmor 或 SELinux 禁用普通用户创建
AF_ALG(Address Family 38) 套接字,阻断此类提权攻击面。
- 在不需要用户态加密接口的环境中,通过 Seccomp、AppArmor 或 SELinux 禁用普通用户创建
0x09 附件脚本
| 附件文件 | 说明与用途 |
|---|---|
| copyfail.c | 针对 CVE-2026-31431 (Copy Fail) 漏洞的独立 C 语言提权利用源码,内嵌 160 字节 SUID /bin/sh ELF stub,通过 AF_ALG AEAD authencesn 与 splice() 将载荷写入 /usr/bin/su 的 Page Cache 获取 root 权限。 |