Lateral Movement
It’s finally time to perform lateral movement and compromise file01.
Since our attack has exploited constrained delegation to obtain
a service ticket, we must perform lateral movement as pass-the-ticket,
and not pass-the-hash.
Since the TGS is often cleared from memory, our ability to use it can be
diminished, especially when we access it through our reverse Meterpreter shell.
This means using a different Metasploit module
for lateral movement will often fail.
Additionally, using a module like PsExec
from Metasploit will trigger Windows Defender.
Because of these complications, we’ll take a different route and modify the
service binary for an unused service on file01 to point to a custom application.
We’ll then start our custom “service” and obtain a meterpreter shell.
In a previous module, we demonstrated how to do this without touching the disk
through an inmemory PowerShell shellcode runner.
This is a complex approach and AMSI would make it even more complex.
We’ll try a more basic approach instead and use our access to the c$ share on
file01 to copy our custom executable from web01.
Before we can begin this attack, there is a complication we must address.
A Windows service expects a service executable, which is coded in a
particular way and must provide some callbacks to the service manager,
otherwise the service manager will time out and the executable will terminate.
We can generate a service executable with msfvenom but Windows Defender will flag it
To solve this issue, we can either attempt to modify the service generated
by msfvenom, code our own implementation,
or perform process injection from our normal custom application.
We’ll take the latter approach.
If our executable performs process injection into a different SYSTEM process
that is notprotected by PPL, our shell will not die
when the service manager terminates the associated process.
On Windows Server 2019 and newer editions of Windows 10, a fair number of SYSTEM
processes execute with PPL enabled by default,
meaning there are not many viable targets.
One service process that is not protected and we can inject into is spoolsv.
To recap, our lateral movement technique will perform three actions.
First, the properties of SensorService are modified and the service is started.
This will trigger a copy operation of the shellcode into the spoolsv process.
Finally, the shellcode executes inside spoolsv.
Our C# application is called Inject and performs process injection into spoolsv.
We’ll combine the AV bypass technique that leveraged non-emulated APIs and a
Caesar cipher with the process injection technique we developed previously.
Next, we’ll compile it,
upload it to web01,
and subsequently use our CIFS access to copy it to file01.
Before we continue, let’s start our listener again.
With the file in place, we can now move to the second application we used
in a previous module with this attack.
The code in this application modifies the SensorService,
in order to start inject.exe when the service is started.
The target computer must also be specified.
The compiled file must now be uploaded to web01.
Now we’ll invoke lat.exe on web01 from the SYSTEM shell.
This will leverage the requested TGS we obtained through constrained delegation
and perform a pass-the-ticket attack to access the service control manager.
The 1053 error code indicates that the service manager timed out,
which is expected since we did not supply a valid service executable.
When we switch to our new meterpreter session,
we find that it did not complete correctly.
If a Meterpreter session initiates and then hangs, the process running the
shellcode was terminated early.
This is most often either due to incorrect shellcode architecture
or because antivirus software caught it.
In this type of situation, it’s best to figure out what, exactly, is happening.
We know that our lateral movement attempt performs three actions.
First, the properties of SensorService are modified and the service is started.
Next, inject.exe executes and copies the shellcode into the spoolsv process.
Finally, the shellcode executes inside spoolsv.
A new session was started, which indicates that both the service
modifications and the code injection went undetected.
However, the execution of the Meterpreter shellcode inside spoolsv was stopped.
Using signatures from network packets, Windows Defender and other AV products
sometimes detect network traffic
associated with setting up a staged Meterpreter session.
The shellcode evades detection on disk, but not while executed inside spoolsv.
This issue cannot be solved through encryption or emulation detection in C#.
However, we could attempt to use different payloads
until we discover one that bypasses antivirus.
This type of brute force is tedious
and could lead to a problem with our lateral movement technique.
When Windows Defender detects the Meterpreter executing inside spoolsv,
it terminates the process.
Since it’s a service, it will restart automatically up to two times;
after that, it will remain disabled.
Additionally, Windows Defender will trigger an alert
based on the SensorService repeatedly interacting with spoolsv.
If this happens multiple times, Windows Defender will disable SensorService
and mark it for deletion.
This approach seems doomed to failure.
We could take a different approach and target Windows Defender itself.
The real-time protection provided by Windows Defender runs in the
MsMpEng SYSTEM process,
which executes with PPL enabled.
Even with SYSTEM level access, we cannot terminate that process.
This approach is also problematic.
There is however, a different approach that could work in this situation.
Windows Defender includes the command-line MpCmdRun tool
that we can use to initiate scans and perform signature updates.
The documentation reveals that we can also use it to remove signature
definitions with RemoveDefinitions All,
which was designed to prevent issues with failed updates
We can abuse this by first setting the service executable of SensorService to
“MpCmdRun” with the options to remove all signatures and start it.
Once it times out, we update it again to “Inject”.
This time, Windows Defender is stripped of all signatures
and will not flag our network traffic.
Now we'll upload the new version of lat.exe to web01,
and ensure that inject.exe is still present on file01.
Once everything is in order, we’ll launch lat.exe.
The output shows that we have received a new
SYSTEM-context reverse Meterpreter shell
We have performed lateral movement from web01 to file01
and obtained a SYSTEM-context Meterpreter.
In the process, we evaded antivirus detection by removing its signatures.
Very Nice!
From here, we can perform more post-exploitation,
which will hopefully lead us to additional compromises in the domain.