Normal view

There are new articles available, click to refresh the page.
Before yesterdayHACKINGISCOOL

A case of DLL Side Loading from UNC via Windows environmental variable

5 July 2022 at 15:51

About a month ago I decided to take a look at JetBrains TeamCity, as I wanted to learn more about CVE-2022-25263 (an authenticated OS Command Injection in the Agent Push functionality).

Initially I just wanted to find the affected feature and test the mitigation put in place, eventually I ended up searching for other interesting behaviors that could be considered security issues- and came across something I believed was a vulnerability, however upon disclosure the vendor convinced me that the situation was considered normal in TeamCity's context and its thread model. Since the feature I was testing allowed me to set some of the environmental variables later passed to the given builder step process (in my case it was python.exe).

During that process I accidently discovered that Python on Windows can be used to side-load an arbitrary DLL named rsaenh.dll, placed in a directory named system32, located in a directory pointed by the SystemRoot environment variable passed to the process (it loads %SystemRoot%/system32/rsaenh.dll).

For the purpose of testing, I installed TeamCity on Windows 10 64-bit, with default settings, setting both the TeamCity Server and the TeamCity Build Agent to run as a regular user (which is the default setting).

I used the same system for both the TeamCity Server and the Build Agent.
First, as admin, I created a sample project with one build step of type Python.
I installed Python3 (python3.10 from the Microsoft App Store, checked the box to get it added to the PATH), so the agent would be compatible to run the build. I also created a hello world python build script:

From that point I switched to a regular user account, which was not allowed to define or edit build steps, but only to trigger them, with the ability to control custom build parameters (including some environmental variables).

I came across two separate instances of UNC path injection, allowing me to attack the Build Agent. In both cases I could make the system connect via SMB to the share of my choosing (allowing me to capture the NTLM hash, so I could try to crack it offline or SMB-relay it).

In case of build steps utilizing python, it also turned out possible to load an arbitrary DLL file from the share I set up with smbd hosted from the KALI box.


The local IP address of the Windows system was 192.168.99.4. I ran a KALI Linux box in the same network, under 192.168.99.5.

Injecting UNC to capture the hash / NTLM-relay

On the KALI box, I ran responder with default settings, like this:

Then, before running the build, I set the teamcity.build.checkoutDir parameter to \\192.168.99.5\pub:

I also ran Procmon and set up a filter to catch any events with the "Path" attribute containing "192.168.99.5".
I clicked "Run Build", which resulted in the UNC path being read by the service, as shown in the screenshot below:

Responder successfully caught the hash (multiple times):

I noticed that the teamcity.build.checkoutDir was validated and eventually it would not be used to attempt to load the build script (which was what I was trying to achieve in the first place by tampering with it), and the application fell back on the default value C:\TeamCity\buildAgent\work\2b35ac7e0452d98f when running the build. Still, before validation, the service interacted with the share, which I believe should not be the case.

Injecting UNC to load arbitrary DLL

I discovered I could attack the Build Agent by poisoning environmental variables the same way as I attacked the server, via build parameter customization.
Since my build step used python, I played with it a bit to see if I could influence the way it loads DLLs by changing environmental variables. It turned out I could.

Python on Windows can be used to side-load an arbitrary DLL named rsaenh.dll, placed in a directory named system32, located in a directory pointed by the SystemRoot environment variable passed to the process.

For example, by setting the SystemRoot environmental variable to "\\192.168.99.5\pub" (from the default "C:\WINDOWS" value):

In case of python3.10.exe, this resulted in the python executable trying to load \\192.168.99.5\pub\system32\rsaenh.dll:

With Responder running, just like in case of attacking the TeamCity Server, hashes were captured:

However, since python3.10 looked eager to load a DLL from a path that could be controlled with the SystemRoot variable, I decided to spin up an SMB share with public anonymous access and provide a copy of the original rsaenh.dll file into the pub\system32\ directory shared with SMB.
I used the following /etc/samba/smb.config:

[global]

workgroup = WORKGROUP
log file = /var/log/samba/log.%m
max log size = 1000
logging = file
panic action = /usr/share/samba/panic-action %d
server role = standalone server
map to guest = bad user
[pub]
comment = some useful files
read only = no
path = /home/pub
guest ok = yes
create mask = 0777
directory mask = 0777

I stopped Responder to free up the 445 port, I started smbd:

service smbd start

Then, I ran the build again, and had the python3.10 executable successfully load and execute the DLL from my share, demonstrating a vector of RCE on the Build Agent:

Not an issue from TeamCity perspective

About a week after reporting the issue to the vendor, I received a response, clarifying that any user having access to TeamCity is considered to have access to all build agent systems, therefore code execution on any build agent system, triggered from low-privileged user in TeamCity, does not violate any security boundaries. They also provided an example of an earlier, very similar submission, and the clarification that was given upon its closure https://youtrack.jetbrains.com/issue/TW-74408 (with a nice code injection vector via perl environmental variable).

python loading rsaenh.dll following the SystemRoot env variable

The fact that python used an environmental variable to load a DLL is an interesting occurrence on its own, as it could be used locally as an evasive technique alternative to rundll32.exe (https://attack.mitre.org/techniques/T1574/002/, https://attack.mitre.org/techniques/T1129/) - to inject malicious code into a process created from an original, signed python3.10.exe executable .

POC

The following code was used to build the DLL. It simply grabs the current username and current process command line, and appends them to a text file named poc.txt. Whenever DllMain is executed, for whatever reason, the poc.txt file will be appended with a line containing those details:

First, let's try to get it loaded without any signatures, locally:

Procmon output watching for any events with Path ending with "rsaenh.dll":

The poc.txt file was created in the current directory of  C:\Users\ewilded\HACKING\SHELLING\research\cmd.exe\python3_side_loading_via_SystemRoot while running python:

Similar cases

There must be more cases of popular software using environmental variables to locate some of the shared libraries they load.

To perform such a search dynamically, all executables in the scope directory could be iterated through and executed multiple times, each time testing arbitrary values set to individual common environmental variables like %SystemRoot% or %WINDIR%. This alone would be a good approach for starters, but it would definitely not provide an exhaustive coverage - most of the places in code those load attempts happen are not reachable without hitting proper command lines, specific to each executable.

A more exhaustive, and but also demanding approach, would be static analysis of all PE files in the scope that simply indicate the usage of both LoadLibrary and GetEnv functions (e..g LoadLibraryExW() and _wgetenv(), as python3.10.exe does) in their import tables.

Yesterday — 27 March 2024HACKINGISCOOL

Intel PowerGadget 3.6 Local Privilege Escalation

27 March 2024 at 05:09

Vulnerability summary: Local Privilege Escalation from regular user to SYSTEM, via conhost.exe hijacking triggered by MSI installer in repair mode
Affected Products: Intel PowerGadget
Affected Versions: tested on PowerGadget_3.6.msi (a3834b2559c18e6797ba945d685bf174), file signed on ‎Monday, ‎February ‎1, ‎2021 9:43:20 PM (this seems to be the latest version), earlier versions might be affected as well.
Affected Platforms: Windows
Common Vulnerability Scoring System (CVSS) Base Score (CVSSv3): 7.8 HIGH
Risk score (CVSSv3): 7.8 HIGH  AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H&version=3.1)

I have reported this issue to Intel, but since the product has been marked End of Life since October 2023, it is not going to receive a security update nor a security advisory. Intel said that they are OK with me making this finding public, under the condition that I would emphasize that the product is EOL.

Description and steps to replicate:
On systems where Intel PowerGadget is installed from an MSI package, a local interactive regular user is able to run the MSI installer file in the "repair" mode and hijack the conhost.exe process (which is created by an instance of sc.exe the installer calls during the process) by quickly left-clicking on the console window that pops up for a split second in the late stage of the process. Left-clicking on the conhost.exe console window area freezes the console (meaning it prevents the sc.exe process from exiting). That process is running as NT AUTHORITY/SYSTEM. From there, it is possible to run a web browser by clicking on one of the links in the small GUI window that can be called by right-clicking on the console window bar and entering "properties". Once a web browser is spawn, attacker can call up the "Open" dialog and in that way get a fully working escape to explorer. From there they can, for example, browse through C:\Windows\System32 and right-click on cmd.exe and run it, obtaining as SYSTEM shell.

Now - an important detail - on most recent builds of Windows neither Edge nor Internet Explorer will spawn as SYSTEM (this is a mitigation from Microsoft); thus for successful exploitation another browser has to already be present in the system. As you can see I pick Chrome and then spawn an instance of cmd.exe, which turns out to be running as SYSTEM. Also, when doing this, DO NOT check "always use this app" in that dialog, as if you pick the wrong one (e.g. Edge or IE), it will be saved as the default http/https handler for SYSTEM and from then further attacks like this won't work if you want to repeat the POC - unless you reverse that change somewhere in the registry.

This class of Local Privilege Escalations is described by Mandiant in this article: https://www.mandiant.com/resources/blog/privileges-third-party-windows-installers.

To run the installer in repair mode, one needs to identify the proper MSI file. After normal installation, it is by default present in C:\Windows\Installer directory, under a random name. The proper file can be identified by attributes like control sum, size or "author" information - just as presented in the screenshot below:

The exploitation process is illustrated in the screenshots below, reflecting the the steps taken to attain a SYSTEM shell (no exploit development is required, the issue can be exploited using GUI).

Just for the record, the versions of Chrome and Windows this was successfully performed on:

Recommendation:
Technically, as per the reference, it is recommended to change the way the sc.exe is called, using the WixQuietExec() method (see the second reference). In such case the conhost.exe window will not be visible to the user, thus making it impossible to perform any GUI interaction and an escape.
I am, however, aware that this product is no longer maintained since October 2023 (https://www.intel.com/content/www/us/en/developer/articles/tool/power-gadget.html) and that includes security updates. Still, I believe a security advisory and CVE should be released just to make users and administrators aware why they need to replace PowerGadget with Intel Performance Counter Monitor.
Another possible (short-term) mitigation is to disable MSI (https://learn.microsoft.com/en-us/windows/win32/msi/disablemsi).

References:
https://www.mandiant.com/resources/blog/privileges-third-party-windows-installers
https://wixtoolset.org/docs/v3/customactions/qtexec/
https://www.intel.com/content/www/us/en/developer/articles/tool/power-gadget.html)
https://learn.microsoft.com/en-us/windows/win32/msi/disablemsi

❌
❌