Exploiting Exploiting Exchange PowerShell After ProxyNotShell: Part 3 – DLL Loading Chain for RCE

At [1], the code retrieves a listing of all files in the random temporary directory.

At [2], it iterates over those files, and at [3] it deletes them.

At [4], it deletes the entire directory. Please note that the second argument is equal to false. This means that the directory deletion operation is not recursive, and later on we are going to abuse that.

When I fully analyzed the DumpDataReader constructor, I realized that there are multiple obstacles in the way of using this as our file write primitive:

• We can only extract files ending with dmp, whereas we need to drop a file with the specific name FUSE.Paxos.dll, as hardcoded in the DLL loading gadget.
• Files will be removed right after the extraction.
• Files are extracted to a path containing a GUID, and we can’t predict that path name, whereas we would need to provide a full path to the DLL loading gadget.
• The attacker’s string (path) is verified with File.Exists. Later on, we will see how this is problematic.
• We may need to extract more than one file, and we will see below how this also presents a minor difficulty.

You can see that the list is quite long, so the gadget appears useless at this point. However, I realized that the expand call itself is vulnerable to Argument Injection. I started playing with expand by testing various arguments, and it turned out that this injection was enough to bypass all the above restrictions! Now let us see how.

1. DumpDataReader: Extracting files with extension other than DMP

The first restriction that we want to bypass is the one that prevents extraction of files unless the filename ends with dmp. This is due to the-F switch provided to the expand utility:

     expand -F:*dmp attacker-path C:\Windows\Temp\<random-guid>

Let’s consider a file f.cab that contains our malicious FUSE.Paxos.dll. We should not be able to extract it and preserve its name, due to the -F:*dmp argument. While playing around, I noticed that if either -r or -i is provided to expand, the -F argument is completely ignored! In the next screenshot, I have bypassed the extension-based protection by injecting the -i argument.

READ MORE HERE