Samba远程崩溃或代码执行漏洞(CVE-2015-0240)简要分析
来源:互联网 发布:最牛象棋软件 编辑:程序博客网 时间:2024/06/05 16:06
1.搭建samba环境
注意:在Linux系统上使用源码编译来安装samba必须要将系统自带的全部关于samba的软件均删除,可用如下命令查看已安装的samba软件:
[bb@localhost bin]$ rpm -qa | grep sambasamba-common-3.6.23-14.el6_6.x86_64samba-winbind-3.6.23-14.el6_6.x86_64samba-winbind-clients-3.6.23-14.el6_6.x86_64samba-client-3.6.23-14.el6_6.x86_64
然后直接全部删除:
[bb@localhost bin]$ rpm -qa | grep samba | xargs sudo rpm -e --nodeps
删除完成之后从https://download.samba.org/pub/samba/stable/samba-3.6.23.tar.gz下载源码,解压后进入source3目录,先执行./configure进行配置,然后对Makefile文件稍作更改,在编译选项中加入-g以便gdb对其进行调试。随后就是make编译,make install安装,默认安装路径是/usr/local/samba,安装后目录如下:
[bb@localhost samba]$ lsbin include lib private sbin share swat var
首先进入lib目录,将源码中example目录下的smb.conf.dufault文件复制到当前目录并改名为smb.conf;然后执行以下命令:
[bb@localhost bin]$ sudo vim /etc/ld.so.conf
在打开的文件中添加一行
/usr/local/samba/lib
退出并执行ldconfig更新动态链接库缓存。然后就是到/usr/local/samba/bin目录下执行:
[bb@localhost bin]$ sudo ./smbpasswd -a bbNew SMB password:Retype new SMB password:Added user bb.
然后需要关闭防火墙:
[bb@localhost ~]$ sudo service iptables stop[sudo] password for bb: iptables: Flushing firewall rules: [ OK ]iptables: Setting chains to policy ACCEPT: filter [ OK ]iptables: Unloading modules: [ OK ]
最后则是到sbin目录下启动smbd和nmbd程序,完成后可以看到进程如下:
[bb@localhost sbin]$ pgrep smbd63596360[bb@localhost sbin]$ pgrep nmbd6365
然后我在Windows上登陆便会提示输入用户名和密码,正确之后便能访问bb用户的目录文件:
2.源码分析过程
首先是在redhat的博客https://securityblog.redhat.com/2015/02/23/samba-vulnerability-cve-2015-0240/上看到了漏洞的代码是在_netr_ServerPasswordSet函数中,如下图所示:
其中第一方框处事creds的声明的地方,这里并未对其进行初始化,第二处将creds的地址作为参数,想必是对其进行初始化,第三处则是当第二处的函数netr_creds_server_step_check返回错误也就是验证creds失败则会将creds指向的内存释放,但是释放之前并未对creds指针进行有效性检查。那什么条件会使得netr_creds_server_step_check函数运行失败呢?
下面是netr_creds_server_step_check的代码:
显然schannel_check_creds_state函数用来初始化creds结构指针的,继续看这个函数:
带有方框的两部分都是受客户端的控制并可能导致验证失败的地方,第一处只要客户端的机器没有在服务器上验证通过过就会触发(可以是一个新的计算机名或是伪造一个计算机名),第二处只要随意伪造一个凭证即可触发。现在需要验证这两种情况的可能性。
3.验证POC
在github上https://gist.github.com/worawit/33cc5534cb555a0b710b看到了一个poc。
3.1
首先验证第一个原因,也就是未经过验证的计算机导致崩溃。运行samba服务端,使用gdb attach上去然后在_netr_ServerPasswordSet函数处下断点:
(gdb) cContinuing.Breakpoint 1, _netr_ServerPasswordSet (p=0x7f1ceeb92d10, r=0x7f1ceeb96520) at rpc_server/netlogon/srv_netlog_nt.c:12051205 {
一直运行到根据主机名获取相应凭证的函数,可以看到这里的计算机名就是客户端的ip地址192.168.1.132:
(gdb) sschannel_fetch_session_key_tdb (tdb_sc=0x7fa334355f30, mem_ctx=0x7fa334355e40, computer_name=0x7fa33436d890 "192.168.1.132", pcreds=0x7fff538e2ba8) at ../libcli/auth/schannel_state_tdb.c:128
随后构造一个字符串:
(gdb) n144 keystr = talloc_asprintf(mem_ctx, "%s/%s",(gdb) p keystr$15 = 0x7fa334360650 "SECRETS/SCHANNEL/192.168.1.132"
然后根据这个字符串从tdb中获取相应的凭证:
(gdb) n151 value = tdb_fetch_bystring(tdb_sc->tdb, keystr);
继续跟踪可以看到其计算hash值的算法:
/* This is based on the hash algorithm from gdbm */unsigned int tdb_old_hash(TDB_DATA *key){ uint32_t value; /* Used to compute the hash value. */ uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) value = (value + (key->dptr[i] << (i*5 % 24))); return (1103515243 * value + 12345);}
查看运行返回的值已经是NULL了,随后返回失败的结果,指向creds的指针并没有初始化:
(gdb) n152 if (!value.dptr) {(gdb) p value$16 = {dptr = 0x0, dsize = <value optimized out>}
最后则是在释放指针的时候崩溃:
(gdb) n1224 TALLOC_FREE(creds);(gdb) cContinuing.Program received signal SIGSEGV, Segmentation fault.0x00007fa331e572f0 in talloc_parent_chunk (ptr=<value optimized out>) at ../lib/talloc/talloc.c:407407 while (tc->prev) tc=tc->prev;
3.2
接下去是使用验证过的计算机但将其凭证修改为其他值,这就需要先验证通过,http://www.freebuf.com/vuls/59898.html和https://technet.microsoft.com/zh-tw/exchange/cc237127中都表明需要使用netlogon服务都必须先通过NetrServerAuthenticate验证。代码如下所示:
但是经过多次尝试和改变,服务器端一直都是密码错误,不知为何:
所以第二种方法就暂时无法验证。
4.修复方法
知道了原因修复起来就简单多了,直接在creds声明的时候初始化为NULL,然后在释放前判断其是否为NULL即可。
- Samba远程崩溃或代码执行漏洞(CVE-2015-0240)简要分析
- Samba CVE-2015-0240 远程代码执行漏洞利用实践
- 漏洞预警+Samba远程代码执行漏洞(CVE-2017-7494)
- Tomcat 远程代码执行漏洞分析(CVE-2017-12615)
- Samba漏洞(CVE-2015-0240)poc分析
- ElasticSearch远程任意代码执行漏洞(CVE-2014-3120)分析
- Office远程代码执行漏洞POC样本分析(CVE-2017-11882)
- Tomcat远程代码执行漏洞(CVE-2017-12615)
- Supervisord远程命令执行漏洞分析(CVE-2017-11610)
- 技术文章 | CVE-2017-12615/CVE-2017-12616:Tomcat信息泄漏和远程代码执行漏洞分析报告
- Linux版SMB远程代码执行漏洞(CVE-2017-7494)-SambaCry 分析报告
- struts2远程代码执行漏洞简要回顾
- Struts 2 远程代码执行漏洞(CVE-2016-0785)解决方案
- MySQL远程代码执行(CVE-2016-6662)漏洞预警
- 测试Tomcat CVE-2017-12615 远程代码执行漏洞
- BlueBorne远程代码执行漏洞Poc实战(CVE-2017-0781)
- Office CVE-2017-8570远程代码执行漏洞复现
- Mysql本地提权及远程代码执行漏洞浅析(CVE-2016-6662)
- 观察者模式
- LeetCode Jump Game II
- (操作系统课程项目)系统调用
- Linux内和分析(一)计算机是如何工作的
- C#基础加强
- Samba远程崩溃或代码执行漏洞(CVE-2015-0240)简要分析
- Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
- perf arm交叉编译
- C++ Primer学习总结 第5章 语句
- MySQL 安装(RPM安装模式)及目录结构
- Python设计模式——抽象工厂
- 让s3c6410开发板支持WM-G-MR-09 Marvell8686 wifi 模块
- UVA 11404-Palindromic Subsequence(DP)
- shiro+springmvc 都使用缓存