Normal view

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

CVE-2019-13142: Razer Surround 1.1.63.0 EoP

By: enigma0x3
5 July 2019 at 18:35

Version: Razer Surround 1.1.63.0
Operating System tested on: Windows 10 1803 (x64)
Vulnerability: Razer Surround Elevation of Privilege through Insecure folder/file permissions

Purpose
I hope that this post serves as a motivator for folks who see vulnerability research as an intimidating area to get started in. While this bug can be considered simple, the primary purpose of this post is to outline the methodology behind how to get started and what to look for. Additionally, I’d like it to serve as a reminder to not discount the low hanging fruit, no matter how large the organization.

Brief Description:
Razer Surround installs a service named “RzSurroundVADStreamingService” that runs as SYSTEM. This service runs “RzSurroundVADStreamingService.exe” out of “C:\ProgramData\Razer\Synapse\Devices\Razer Surround\Driver”. The permissions on  RzSurroundVADStreamingService.exe and “C:\ProgramData\Razer\Synapse\Devices\Razer Surround\Driver” allow for overwriting the service binary with a malicious one, resulting in elevation of privilege to SYSTEM.

Identification and Exploitation
When doing vulnerability research, picking a target to go after can be challenging. Hunting for bugs in large software platforms can be intimidating as there is an assumption that all vulnerabilities are complex and take a special skill set to identify. I’d like to use this vulnerability as an example as to why the act of hunting for vulnerabilities isn’t as hard as it sounds.

You may ask, why Razer? How do you identify a piece of software to begin hunting for vulnerabilities in? The answer is simple: Investigate what interests you. In this case, I own various Razer products. It is hard to ignore the urge to look when you use a product and the software associated with it every day.

When looking for vulnerabilities, there is often a common workflow that I follow once the software of interest is installed. This stage involves analyzing the potential attack surface that the target software has exposed. I typically start with the basics and then resort to dynamic/static analysis if needed. The things I typically look for initially are:

  1. Installed services (both the service permissions and the service executable/path permission)
  2. Named pipes (and their ACLs)
  3. Log file permissions in folders like C:\ProgramData
  4. Network sockets
  5. DCOM servers and hosted interfaces

As far as tooling goes, I mostly stick to Process Monitor and James Forshaw’s NTObjectManager project.

In the instance of Razer Surround, I began by checking what privileged processes the software uses by looking at the process list. This revealed that “RzSurroundVADStreamingService.exe” was running as “NT AUTHORITY\SYSTEM”. The next step was to figure out how that process was being started. Given the name of the process has “service” in it, that is a good starting point. To verify, it was easy enough to do “Get-Service *Rz*” in Powershell, which returned all of the services with “Rz” in the name. This led me to the “RzSurroundVadStreamingService” system service with the ImagePath set to the executable of interest. After dumping the ImagePath, the location of the service executable stood out as it was running out of “C:\ProgramData\Razer\Synapse\Devices\Razer Surround\Driver\”

Why is this interesting? By default, “BUILTIN\Users” have “GenericWrite” access to C:\ProgramData:

A very common error that software developers make is not properly locking down the permissions of any created subfolders in C:\ProgramData. If an installer simply creates a folder in C:\ProgramData, that folder and any subfolders will have inherited permissions of C:\ProgramData, which include the “GenericWrite” access right for “BUILTIN\Users”.

Improper file and folder permissions were the culprit in this case as “Everyone” was eventually granted “FullControl” over any files in “C:\ProgramData\Razer\Synapse\Devices\Razer Surround\Driver”

As previously noted, this path is where the “RzSurroundVADStreamingService” ImagePath for the service executable was pointing to. Given a low privileged user has “FullControl” over the folder and included files, it is possible to just replace the service executable for the “RzSurroundVADStreamingService” system service:

Once the payload is copied, rebooting the host will cause the service to start the new executable as SYSTEM. In this instance, the new service executable will start cmd.exe as SYSTEM:

Razer fixed this vulnerability by moving “RzSurroundVADStreamingService.exe” and the associated dependencies to a secured location in “C:\Program Files (x86)\Razer”.

Disclosure Timeline
As committed as SpecterOps is to transparency, we acknowledge the speed at which attackers adopt new offensive techniques once they are made public. This is why prior to publicization of a new bug or offensive technique, we regularly inform the respective vendor of the issue, supply ample time to mitigate the issue, and notify select, trusted vendors in order to ensure that detections can be delivered to their customers as quickly as possible.

  • March 20th, 2019 — Initial report sent to Razer
  • March 21st, 2019  — Report acknowledgement received from Razer
  • April 30th, 2019 —  30 days after initial report
  • May 2nd, 2019  —  Razer provided a fixed build to test
  • May 2nd, 2019 —  Fix was verified
  • May 20th, 2019 —  60 days after initial report
  • June 6th, 2019 —  Reached out to Razer for a timeframe regarding a public fix
  • June 6th, 2019 —  Razer informed me a fix should be live, but verification from the development team was needed
  • June 7th, 2019 —  Informed Razer that a fix wasn’t available on the site or via Surround’s update mechanism
  • June 10th, 2019 —  Razer informed me that there had been some internal confusion and that a fix was going live the end of June
  • June 11th, 2019 —  Informed Razer I would hold off on disclosure until the fix is live
  • June 20th, 2019 —  90 days after initial report, extension granted
  • July 1st, 2019 —  Razer informed me that a note is out to the development team regarding when the fix would be pushed live
  • July 5th, 2019 —  Fix published

-Matt N.

CVE-2019-13382: Local Privilege Escalation in SnagIt

By: enigma0x3
24 July 2019 at 17:15

Version: Snagit 2019.1.2 Build 3596
Operating System tested on: Windows 10 1803 (x64)
Vulnerability: SnagIt Relay Classic Recorder Local Privilege Escalation through insecure file move

This vulnerability was found in conjunction with Marcus Sailler, Rick Romo and Gary Muller of Capital Group’s Security Testing Team

Vulnerability Overview
Every 30-60 seconds, the TechSmith Uploader Service (UploaderService.exe) checks the folder “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations” for any presentation files in the “*.xml” format. If an invalid one is found, the service moves that file to “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations” as SYSTEM.

Since a low privileged user has full control over the QueuedPresentations and InvalidPresentations folders, it is possible to create an invalid presentation in the QueuedPresentations folder and then place a symbolic link for that file name in the InvalidPresentations folder that points to a privileged location.

When the service checks for presentations, it will move the file out of the QueuedPresentations folder and into the InvalidPresentations folder. When it does so, the service will hit the symbolic link and write the new file into a protected location with permissions that allow the low privileged user full control over the contents, resulting in Elevation of Privilege to NT AUTHORITY\SYSTEM.

Identification and Exploitation
When assessing software for privilege escalation vulnerabilities, finding a starting point can often be overwhelming as there are many different primitives and vulnerability classes that exist. My approach often includes starting with the basics and working my way up in complexity. This process typically involves running a tool such as PowerUp, which will identify various trivial (yet common) misconfigurations.

If nothing interesting is returned, the next step is often looking for logical vulnerabilities; specifically abusing symlink/mountpoint/hardlink primitives. In order to quickly identify potential vulnerabilities that could be exploited with the linking primitives, we need to identify locations on the OS where a privileged process (often SYSTEM) is interacting with a folder or file that a low privileged user has control over. This logic is true in most logical vulnerabilities in that interesting attack surface is linked to a privileged process utilizing a resource a low privileged user controls.

When hunting for such bugs, I often start with running Process Monitor with a filter on SYSTEM processes and commonly abused filesystem locations, such as C:\ProgramData, C:\Windows\Temp and C:\Users\<username>\AppData. Such a filter might look like so:

 

When applying the Process Monitor and watching the output for a few minutes, it became apparent that “UploaderService.exe” was querying the “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations” directory for any XML files:

Looking at the DACL on that folder, it also stood out that that “BUILTIN\Users” had write access:

This is particularly interesting in that a privileged SYSTEM process (UploaderService.exe) is looking for files in a directory that low privileged users have read/write access. With this information, the next step was to give “UploaderService.exe” an XML file to find and see what happens.

As expected, “UploaderService.exe” checks “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations” for any XML files and finds the one we created:

The next question was, what does “UploaderService.exe” do with our XML file? Does it read it in and ingest the contents? Does it place it someplace else?

Looking at the rest of the Process Monitor output answers that question for us. In this case, “UploaderService.exe” takes any XML files in “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations” and determines if the XML presentation file is valid. Since we simply echoed “1” into our XML file, the service executable determines that “1.xml” is an invalid presentation and moves it to “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml”:

Looking at the “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations” directory, “BUILTIN\Users” also have read/write access:

At this point, we have identified that a SYSTEM process (UploaderService.exe) is checking a user-controlled directory for any XML files. When found, the privileged process takes the attacker supplied XML file and moves it from the QueuedPresentations folder to the InvalidPresentations folder while retaining the original file name.

Why is this interesting? This presents the opportunity to use Symbolic Links during the move file operation to accomplish a privileged file write. How you might ask? The workflow would be like so:

  • Create a Symbolic Link on “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml” that points to “C:\Windows\System32\ualapi.dll”
    • It should be noted that “C:\Windows\System32\ualapi.dll” doesn’t exist. This is a DLL we are planting to get code-execution as SYSTEM
    • Since the process is privileged “SYSTEM”, it will have the correct permissions to write this file.
  • Write a dummy xml file to “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations\1.xml”
  • When “UploaderService.exe” checks “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations” for any XML files, it will find “1.xml” and move it to “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml”. While doing so, it will hit our Symbolic Link and instead move the file to “C:\Windows\System32\ualapi.dll” (while retaining the original DACL)

In theory, this should work. Let’s test it out! For the Symbolic Link, I used “CreateSymlink.exe” from James Forshaw’s Symbolic Link Testing Tools repo. All we need to do is place a symbolic link on “C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml” that points to “C:\Windows\System32\ualapi.dll” and then create “C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations\1.xml”:

With the symlink created and our dummy XML file created, we wait 60 seconds for “UploaderService.exe” to check the QueuedPresentations folder. When it does, it finds our “1.xml” file and tries to move it to “C:\ProgramData\TechSmith\TechSmith Recorder\InvalidPresentations\1.xml”. When it does so, it hits our symbolic link on “C:\ProgramData\TechSmith\TechSmith Recorder\InvalidPresentations\1.xml” and instead writes it to “C:\Windows\System32\ualapi.dll”:

We can then confirm the existence of “C:\Windows\System32\ualapi.dll”:

This is great and all, but shouldn’t the newly created “ualapi.dll” file simply inherit the permissions of the parent folder (C:\Windows\System32) and prevent a low privileged user from writing to it? That was my thought at first (before checking the DACL on the file), but “UploaderService.exe” uses MoveFileW(). According to the documentation, MoveFileW() retains the original DACL when moving the file on the same volume:

While not explicitly stated, it can be inferred that if the file is not moved across volumes, it is moved with the DACL intact. This means that when “UploaderService.exe” hits the symbolic link on “C:\ProgramData\TechSmith\TechSmith Recorder\InvalidPresentations\1.xml” and tries to move the original file to “C:\Windows\System32\ualapi.dll”, it keeps the original DACL for “1.xml”.  Since it was created by a low privileged user, it has a DACL that has the low privileged user as the Owner with “FullControl” rights:

At this point, we now have “C:\Windows\System32\ualapi.dll” that allows our low privileged user to write to it. This means we can simply copy over the newly created ualapi.dll file with a payload of our choosing. In this case, the payload starts cmd.exe when loaded.

We now have a payload sitting in C:\Windows\System32\ualapi.dll. This DLL gets loaded when the spooler service starts. For the PoC, all that is left is to reboot the host in order to get the spooler service to restart. Additionally, one could use the CollectorService to load the DLL without a reboot. Since this is a PoC, that is an exercise left up to the reader.

Once the host is rebooted, “spoolsv.exe” will load our payload from C:\Windows\System32\ualapi.dll as SYSTEM, resulting in privilege escalation:

A video of exploitation can be found here: https://www.youtube.com/watch?v=V90JRwlaHRY&feature=youtu.be

This vulnerability has been fixed in SnagIt versions 2019.1.3, 2018.2.4 and 13.1.7 with CVE-2019-13382. The fixed involved using _time64 when moving the file combined with a check for reparse points (FSCTL_GET_REPARSE_POINT). If a reparse point exists, it is removed.

 

Disclosure Timeline

As committed as SpecterOps is to transparency, we acknowledge the speed at which attackers adopt new offensive techniques once they are made public. This is why prior to publicization of a new bug or offensive technique, we regularly inform the respective vendor of the issue, supply ample time to mitigate the issue, and notify select, trusted vendors in order to ensure that detections can be delivered to their customers as quickly as possible.

  • June 19th, 2019: Vulnerability identified in conjunction with Capital Group’s Security Testing Team
  • June 20th, 2019: Joint disclosure with Capital Group began. Support case opened with a request for contact information for the security team at TechSmith
  • June 21st, 2019: Case assigned to a handler, new comment stated that the details can be uploaded to the current case and they will be forwarded to the security team
  • June 21st, 2019: Full write-up, PoC code and a demonstration video was uploaded to the open support case
  • June 25th, 2019: TechSmith confirmed the vulnerability and offered temporary remediation advice. TechSmith also requested notice before public disclosure.
  • June 25th, 2019: Informed TechSmith that public disclosure would be 90 days after the initial report with a note that an extension would be considered if needed.
  • July 2nd, 2019: TechSmith stated a fixed build is done and set to be deployed before the end of July with a note asking if we would verify the fix
  • July 2nd, 2019: Informed TechSmith that I would verify the fix
  • July 3rd, 2019: TechSmith provided a private fixed build
  • July 9th, 2019: Informed SnagIt that based on testing, the fix seemed sufficient 
  • July 23rd, 2019: Patch released, issue publicly disclosed

Avira Optimizer Local Privilege Escalation

By: enigma0x3
29 August 2019 at 18:41

Version: Avira Optimizer < 1.2.0.367
Operating System tested on: Windows 10 1803 (x64)
Vulnerability: Avira Optimizer Local Privilege Escalation through insecure named pipes

Vulnerability Overview
When users install the latest Avira antivirus, it comes shipped with a few different components along with it. One of these components is the Avira Optimizer. In short, “Avira.OptimizerHost.exe” runs as “NT AUTHORITY\SYSTEM” and takes commands issued over the “AviraOptimizerHost” named pipe (\\.\pipe\AviraOptimizerHost). The service does improper validation of the calling client along with invalid checks for started executables, which allows malicious code to issue process create calls to “Avira.OptimizerHost.exe” leading to local privilege escalation.

Identification and Exploitation
When assessing software for privilege escalation vulnerabilities, finding a starting point can often be overwhelming as there are many different primitives and vulnerability classes that exist. My approach often includes starting with the basics and working my way up in complexity. This process typically involves running a tool such as PowerUp, which will identify various trivial (yet common) misconfigurations.

If nothing interesting is returned, the next step is often looking for logical vulnerabilities. These vulnerabilities can be more difficult to automatically identify and require a little more manual poking. My workflow typically involves analyzing world-writable directories, writeable registry locations, exposed named pipes and RPC interfaces via NTObjectManager. When analyzing existing named pipes, it became apparent that some Avira process had created a named pipe with a NULL DACL. This effectively means that full access is granted to any user that requests it:

While interesting, it isn’t incredibly useful if the pipe isn’t being used by a privileged Avira process in some way. Checking the using process IDs of the pipe revealed that a SYSTEM Avira process is utilizing it:

The next step would be to figure out what “Avira.OptimizerHost.exe” is actually doing with the named pipe. This is a rabbit hole worth exploring since a privileged process is interacting with a resource that low privileged users have control over. Since “Avira.OptimizerHost.exe” has a handle to the pipe, it would make sense that the process is ingesting some sort of data being passed over it. In an effort to validate this, the next step was to pop open “Avira.OptimizerHost.exe” in IDA. After some poking, it became evident that the service was taking any client that connected to the “AviraOptimizerHost” named pipe and validating that it is a valid Avira file.

 In order to abuse this named pipe, we need to circumvent this check in order to successfully send data to the service via the named pipe. The service does the check by getting the connecting client via GetNamedPipeClientProcessID() and then pulls the full image path via QueryFullProcessImageNameW()

Once the path is obtained, the service pulls the calling client’s certificate and makes sure that it is signed by Avira and hasn’t been tampered with. The idea here was to make sure only valid Avira processes are able to issue commands to the service. In order to circumvent this, we can simply inject our code into a running Avira process (or probably just clone an existing certificate).

The next step is to figure out what we can issue to the service over the named pipe. In cases like this, I typically like to investigate any potential legitimate clients and see what they do during normal operation. Since this pipe is a part of Avira’s optimizer, I began to look through the installed Avira components. After some dead ends, Avira’s System Speedup application boiled to the top due to the fact that optimization and speedup are Synonymous. After looking in Avira’s “System Speedup” folder, I stumped upon the Avira System Speedup libraries. I then loaded all of the files in the System Speedup folder into DnSpy and began to search for named pipe references. This led me down to “Avira.SystemSpeedup.Core.Client.Services.dll”, specifically the “StartServiceHost()” method.

As suspected, this is code to connect to the “AviraOptimizerHost” named pipe. Underneath, this function goes on to call the “OptimizerHostCommandsClient.Connect()” in the Avira.Optimizer.Common.Tools.OptimizerHostClient class, which sounds really interesting. When looking at this function, it just calls WaitNamedPipe() to wait for the pipe to be ready. Once it is, CreateFile is used to get a handle to the named pipe.

Looking back at the “StartServiceHost” method, it instantiates an instance of the Avira.Optimizer.Common.Tools.OptimizerHostClient class, connects to the “AviraOptimizerHost” named pipe and then goes on to call an interesting method named “StartParentProcess()”. 

When looking at that instantiated class, there are many interesting methods. Such items include: StartProcess, StartParentProcess, StopProcess, AddTask and RemoveTask. These methods take various parameters and then go on to call “SendMessage” after converting the tasking to JSON:

The “SendMessage()” method takes the JSON of the command and sends it to the “AviraOptimizerHost” named pipe, where the SYSTEM process “Avira.OptimizerHost.exe” ingests it:

Looking at “Avira.OptimizerHost.exe”, we can see where the service reads in the JSON and parses out the arguments:

In this case, if we send the “StartProcess()” method to the named pipe, the service will pull out the “procid”, “exec” (executable path),“args” (arguments)/etc from the JSON blob sent over the named pipe. From there, it follows the same logic that was used to validate the named pipe in client, in which it takes the executable path from the “exec” parameter and checks the file’s certificate in order to ensure it belongs to Avira. The service relies on the subject and certificate serial number (both of which are attacker controlled), so it is possible to use a tool like SigPirate to clone the certificate off of a valid Avira executable and apply it to a custom payload.

In order to exploit this, we need to accomplish a few things:

  1. Prepare our payload. In this case, it is a .NET executable named Avira.SystemSpeedup.RealTime.Client.exe that starts cmd.exe
  2. Clone the certificate off of a valid Avira file and apply it to our payload
  3. Write code that injects into a valid Avira process, loads up Avira.Optimizer.Common.Tools.dll and instantiates an instance of the OptimizerHostClient class
  4. Use the exposed methods to connect to the “AviraOptimizerHost” named pipe and issue our commands to the service

For payload creation and certificate cloning, I will leave that as an exercise for the reader. In order to connect to the named pipe and send commands, we can reuse the existing Avira libraries by adding a reference to Avira.Optimizer.Common.Tools.dll and importing the Avira.Optimizer.Common.Tools.OptimizerHostClient namespace. Once done, we can just create an instance of the OptimizerHostCommandsClient class and call any of the interesting methods, such as “StartProcess”.

In order to achieve LPE, all we need to do is inject this assembly into an Avira process and invoke our entrypoint. Again, this is an exercise left up to the reader…but there are various projects that make this process easy (https://github.com/ChadSki/SharpNeedle). 

After injecting into an Avira process and executing the above C# code, cmd.exe will be started as SYSTEM after the assembly connects to the “AviraOptimizerHost” named pipe and sends the “StartProcess()” method with the “exec” argument set to the payload with a cloned Avira certificate (in this case, a payload named Avira.SystemSpeedup.RealTime.Client.exe).

This vulnerability has been fixed in Avira Optimizer version 1.2.0.367. After glancing at the fix, Avira now utilizes WinVerifyTrust() and an apparent path whitelist to ensure started processes aren’t influenced.

Disclosure Timeline

I’d like to take a second to give Avira and their development team props. The team remains in constant contact and fixes issues at a rapid pace. In the case of this report, a fix was developed and distributed to the public around 30 days after the initial report. It is refreshing to work with a vendor that takes vulnerability reports seriously and follows the community’s set expectations of 90 day fixes.

As committed as SpecterOps is to transparency, we acknowledge the speed at which attackers adopt new offensive techniques once they are made public. This is why prior to publication of a new bug or offensive technique, we regularly inform the respective vendor of the issue, supply ample time to mitigate the issue, and notify select, trusted vendors in order to ensure that detections can be delivered to their customers as quickly as possible.

  • July 23rd, 2019: Vulnerability sent to the Avira security team
  • July 24th,  2019: Avira acknowledged the report, noted some compile issues with the PoC
  • July 26th, 2019: Avira reproduced the vulnerability with the PoC provided
  • August 6th, 2019: Avira noted the developers fixed the issue, asked if I would like to test the fix
  • August 6th, 2019: Replied to Avira with a bypass for the patch, provided updated PoC and details
  • August 16th, 2019: Avira replied noting the developers implemented a new fix and asked if I’d like to test it
  • August 16th, 2019: Tested the new fix. Let Avira know that it seemed decent enough
  • August 27th, 2019: Fix pushed live
  • August 29th, 2019: Details published

CVE-2019-19248: Local Privilege Escalation in EA’s Origin Client

By: enigma0x3
10 December 2019 at 18:50

Version: Origin Client version 10.5.35.22222-0 (https://www.origin.com/usa/en-us/store/download)
Operating System tested on: Windows 10 1709 (x64)
Advisory: https://www.ea.com/security/news/easec-2019-001-elevation-of-privilege-vulnerability-in-origin-client
EA’s Blog: https://www.ea.com/security/news/origin-security-update-in-collaboration-with-external-security-researchers

Vulnerability: Origin Client Service DACL Overwrite Elevation of Privilege

Brief Description: When Origin is installed, it comes with a few different services, such as the “Origin Client Service”. This service can be stopped and started by low privileged users. When the Origin Client service starts, it checks for the existence of “C:\ProgramData\Origin\local.xml”. If this file doesn’t exist, it creates it and grants the “Everyone” group “FullControl” over the file. Since a low privileged user has rights to this file, it is possible to create a hardlink on “C:\ProgramData\Origin\local.xml” and point it to another file, resulting in the target file having “FullControl” rights granted to the “Everyone” group.

A low privileged user can use this to overwrite the DACL on privileged files, resulting in elevation of privilege to “NT AUTHORITY\SYSTEM”.

Vulnerability Explanation 
When Origin is installed, it comes with a few different services. One such service is the “Origin Client Service”. This service can be stopped and started by low privileged users:

When restarting the Origin Client Service, it checks to see if “C:\ProgramData\Origin\local.xml” exists. If it doesn’t, it will create it and then set the file’s security descriptor to grant Everyone GENERIC_ALL over the file:

Since a low privileged user has control of that file, its possible to delete it and replace it with a hardlink that points to a privileged file. In this case, we are creating a hardlink that points to “C:\Program Files (x86)\Origin\OriginWebHelperService.exe” (using James Forshaw’s Symbolic Link Testing Tools)

After creating the hardlink, restarting the “Origin Client Service” service will cause it to try and set the DACL on “C:\ProgramData\Origin\local.xml” to grant “FullControl” rights to the “AuthenticatedUsers” group. Since a hardlink is in place, it will follow it and end up setting the DACL on “C:\Program Files (x86)\Origin\OriginWebHelperService.exe” instead:

With the DACL on “C:\Program Files (x86)\Origin\OriginWebHelperService.exe” overwritten, all that needs done to elevate privileges is to stop the Origin Web Helper Service, replace “C:\Program Files (x86)\Origin\OriginWebHelperService.exe” and then start the service again:

The service will fail to start since “Payload.exe” is not a service executable, but the service will start it and cmd.exe will be running as “NT AUTHORITY\SYSTEM”, resulting in elevation of privilege.

This vulnerability has been fixed in 10.5.56.33908. The Origin team re-wrote the Origin client to include a “Restricted” mode that places restrictive ACLs on all of the Origin files.

DISCLOSURE TIMELINE

  • March 13th, 2019: Vulnerability sent to the EA security team
  • March 14th,  2019: EA acknowledged the vulnerability and assigned a case number
  • March 28th, 2019: Followed up with EA to see if there is anything they need
  • April 4th, 2019: EA classified the report as a high severity issue and notified me that they are working on a fix and have found other variants via additional hunting
  • May 2nd, 2019: Reached out to EA to inform them of the approaching 60 day window
  • May 23rd, 2019: EA responded with a note that they are still working on a fix and have ran into some issues with fixing the root cause
  • June 17th, 2019: Reached out to EA to inform them that the 90 day period has lapsed. Asked for an update and if additional time was needed
  • June 25th, 2019: EA informed me they are still having issues with implementing a fix that doesn’t break older game titles. Stated they have a way forward, but will need some time to dev it out. EA asked to schedule a phone call.
  • June 25th, 2019: Responded to EA’s request to schedule a phone call
  • July 8th, 2019: Had a phone call with EA’s security and engineering teams, agreed on periodical 30 day extensions due to the complexity of the issue being fixed
  • August 12th, 2019: Sent EA an additional variant of the issue
  • August 13th, 2019: EA informed me they have preliminary builds of the new Origin client in Alpha, stated they are tracking late September – early October for a fix
  • September 6th, 2019: Reached out to EA to get an estimated timeline on the fix
  • September 12th, 2019: EA responds with a note that they will have a beta build for me to test within the next week and are working on addressing the Mac client
  • September 25th, 2019: EA provides a link to the beta build to test with a well written explanation of the design decisions behind the fix and next steps (released to beta channel eventually). Also provided me an advisory to review.
  • September 26th, 2019: Replied to EA acknowledging receipt of the beta build and a thumbs up on the advisory draft
  • September 26th, 2019: Sent EA a few notes on the beta build, fix seemed sufficient
  • October 28th, 2019: Reached out to EA for a shipping ETA
  • October 28th, 2019: EA responded noting they have a request out to the Origin team for an update, and will provide an update when they can. Noted they are finishing up the Mac rewrite.
  • November 13th, 2019: Reached out to EA for a status update
  • November 13th, 2019: EA replied with dates the new builds will hit the public beta channels. Provided a newly updated Windows build for me to look at
  • November 14th, 2019: Replied to EA noting the beta looked good with restricted mode enabled
  • December 9th, 2019: EA informed me they are on track to publish the Origin update to the public and release the advisory on the 10th
  • December 10th, 2019: Advisory published, issue opened.

Avira VPN Local Privilege Escalation via Insecure Update Location

By: enigma0x3
15 January 2020 at 15:17

Product Version: Avira VPN
Operating System tested on: Windows 10 1709 (x64)
Vulnerability: Avira VPN Service Local Privilege Escalation

Brief Description: When the Phantom VPN Service (Avira.VPNService.exe) starts, it checks to see if there are any updates available. The service executes the update from C:\ProgramData\Avira\VPN\Update, which is writable by a low privileged user. Additionally, the service implements checks to prevent exploitation that can be circumvented. This allows an attacker to plant a valid Avira executable along with a malicious DLL in “C:\ProgramData\Avira\VPN\Update” and cause the service to execute the update file. A DLL hijack will occur, resulting in code-execution as SYSTEM.

Vulnerability Explanation:
When the Phantom VPN Service (Avira.VPNService.exe) starts, one of the first things it does is check for updates, which is done in C:\ProgramData (which is writable for low privileged users by default). The service does so by calling “VPNUpdater.UpdateProduct()”, which in turn calls “Updater.UpdateToNewPackageIfValid()”. This function handles all the logic for updating the VPN software:

Upon entering “Updater.UpdateToNewPackageifValid()”, the service first checks if there is an update that is downloaded via a call to “Updater.CheckForDownloadedUpdatePackage()”. In order to do this, it checks for the existence of “C:\ProgramData\Avira\VPN\Update\AviraVPNInstaller.exe” and if the update file has already been installed or not:

The service determines if the update is already present or not by comparing the “ProductVersion” property on the update executable with the “ProductVersion” property on the VPN service itself (Avira.VPNService.exe). If the update executable’s ProductVersion is greater than the ProductVersion of “Avira.VPNService.exe”, then the service continues down the path to install it:

After validating that “C:\ProgramData\Avira\VPN\Update\AviraVPNInstaller.exe” exists and hasn’t already been installed, the service makes a call to “Updater.IsUpdateFolderAccessRestricted()”. This function appears to make sure that “C:\ProgramData\Avira\VPN\Update” is locked down and cannot be written to by a low privileged user (in order to protect the update executable before it is executed). The service does this by first checking that the folder is owned by either NT AUTHORITY\SYSTEM, NT AUTHORITY\SERVICE or Administrators (values stored in “AcceptedSIDs”):

If the update folder is not owned by any of those SIDs, the function returns and a call is made to “Updater.RestoreUpdateFolder()”, which promptly deletes “C:\ProgramData\Avira\VPN\Update” and then re-creates it with a DACL that restricts access to the 3 accepted SIDs mentioned above. If the folder has an owner that is any of those accepted SIDs, the service then loops through each entry in the folder’s DACL to make sure that those 3 accepted SIDs are in the DACL as well (I assume to make sure that only those 3 privileged users/groups have the ability to control the folder’s contents).

The issue here is that it is possible to circumvent those checks and plant a malicious update in “C:\ProgramData\Avira\Update”. The first task is to pass the “Owner” check on the update folder. This can be accomplished by simply moving another folder on the filesystem that is owned by SYSTEM yet is writable by low privileged users to “C:\ProgramData\Avira\Update”. Since moving a file/folder on the same volume retains the permission set, the update folder will have an Owner of “SYSTEM”, which is what the service is checking for.

To abuse this, we can copy our version of “AviraVPNInstaller.exe” (and dependencies) to “C:\ProgramData\Avira\Launcher\LogFiles”, which is owned by SYSTEM yet writable by low privileged users:

Once done, we can move “C:\ProgramData\Avira\Launcher\Logfiles” to “C:\ProgramData\Avira\VPN\Update”:

At this point, we have a version of “C:\ProgramData\Avira\VPN\Update” that passes the “Owner” check. The next hurdle is to pass the DACL check that the service does to ensure the 3 accepted SIDs are present. This can simply be done by setting the DACL on the update folder to include “Administrators”, “SYSTEM” and “SERVICE”:

Once done, the update folder will only be accessible by the 3 accepted SIDs. After circumventing the Owner and DACL checks, the last hurdle is to circumvent the file integrity checks. Before executing the update file, the service checks to make sure it is signed by Avira and that the signature is valid (via a call to Updater.IsUpdatePackageAuthentic()). If “C:\ProgramData\Avira\VPN\Update\AviraVPNInstaller.exe” is not signed by Avira and does not contain a valid digital signature, the service will not execute it. In order to circumvent this, we need a file signed by Avira that has a ProductVersion greater than the currently installed version of Avira.VPNService.exe. After some hunting, I came across an Avira signed executable named “CefSharp.BrowserSubprocess.exe” that has a product version of “65.0.0.0”:

Since this executable is signed by Avira, has a valid digital certificate and has a product version greater than the present version of “Avira.VPNService.exe”, it will pass all of the checks that the service implements. This executable was renamed to “AviraVPNInstaller.exe” and used above in the file copy and folder move actions.

At this point, we have the following:

  1. A valid Avira signed executable that has a ProductVersion greater than the installed version of Avira.VPNService.exe
    1. When this executable starts, it looks for “VERSION.dll” in the current working directory
  2. The ability to plant this renamed executable, along with a malicious copy of VERSION.dll, in C:\ProgramData\Avira\VPN\Update via circumventing the folder Owner and DACL checks

Once the VPN service starts (via a reboot or manually), it will see that “C:\ProgramData\Avira\VPN\Update\AviraVPNInstaller.exe” is present. It will then see that the “Update” folder is owned by “SYSTEM” and that the folder DACL contains the “Administrators”, “SYSTEM”, and “SERVICE” SIDs. It will then check the file integrity of “AviraVPNInstaller.exe” and see that it is signed by Avira, that the digital signature is valid and that the ProductVersion is greater than the deployed VPN service. After passing all of those checks, the service will then execute the renamed version of “AviraVPNInstaller.exe” as SYSTEM and load our malicious “VERSION.dll”, resulting in local privilege escalation:

This issue has been fixed in the latest Avira VPN version.

CVE-2023-4632: Local Privilege Escalation in Lenovo System Updater

By: enigma0x3
26 October 2023 at 16:56

Version: Lenovo Updater Version <= 5.08.01.0009

Operating System Tested On: Windows 10 22H2 (x64)

Vulnerability: Lenovo System Updater Local Privilege Escalation via Arbitrary File Write

Advisory: https://support.lenovo.com/us/en/product_security/LEN-135367

Vulnerability Overview

The Lenovo System Update application is designed to allow non-administrators to check for and apply updates to their workstation. During the process of checking for updates, the privileged Lenovo Update application attempts to utilize C:\SSClientCommon\HelloLevel_9_58_00.xml, which doesn’t exist on the filesystem. Due to the ability for any low-privileged user to create a directory in the root of the C:\ drive, it’s possible to provide the privileged Lenovo System Update application a specially crafted HelloLevel_9_58_00.xml file, which is located in C:\SSClientCommon. This custom XML file contains a source and destination file path, which the Lenovo System Update application parses when the user checks for updates. Once parsed, the privileged Lenovo System Update application moves the source file to the destination location and allows for an arbitrary file write primitive, thus resulting in elevation of privilege to NT AUTHORITY\SYSTEM

Vulnerability Walkthrough

When a user checks for Lenovo updates via the Lenovo System Update application, Tvsukernel.exe is launched as the user Lenovo_tmp_<randomCharacters> in a privileged, High Integrity context. Upon execution, Tvsukernel.exe checks for HelloLevel_9_58_00.xml in C:\SSClientCommon, shown below in Figure 01.

Figure 01 – Missing Directory and XML File

By default, all versions of Windows allow for low-privileged users to create directories within the root of the C:\ drive. An attacker can manually create the directory C:\SSClientCommon\ and then place HelloLevel_9_58_00.xml within it, shown below in Figure 02.

Figure 02 — Directory and XML Creation in Root of C:\ Drive

After C:\SSClientCommon is created, an attacker can then create the required subdirectory C:\SSClientCommon\UTS, which will contain the attacker’s malicious binary. The directory structure for the attack looks similar to Figure 03 below:

Figure 03: Final Folder and File Structure

Since HelloLevel_9_58_00.xml resides in a location that an attacker can control, it is possible to craft a custom XML file that allows an attacker to move a file from one location to another. This is possible because the custom XML defines an “execute” action, providing a “Source” and “Destination” path. The “SourcePath” element defines a portable executable (PE) file located within C:\SSClientCommon\UTS–in this case, C:\SSClientCommon\UTS\poc2.exe.

The “DestinationPath” node defines the location in which the source file is to be copied to, shown below in Figure 04:

Figure 04 – Custom XML Source and Destination Paths

After the Lenovo System Update application launches and checks for updates, the privileged process (i.e., Tvsukernel.exe)checks to see whether C:\SSClientCommon\HelloLevel_9_58_00.xml exists. Since the path has been created and a custom XML file planted, Tvsukernel.exe will move the custom HelloLevel_9_58_00.xml file to C:\ProgramData\Lenovo\SystemUpdate\sessionSE\system\SSClientCommon\HelloLevel_9_58_00.xml, shown below in Figure 05:

Figure 05: Writing Custom XML to ProgramData

Once the XML file is moved, Tvsukernel.exe calls the ParseUDF() function within Client.dll in order to parse the XML file located in C:\ProgramData\Lenovo\SystemUpdate\sessionSE\system\SSClientCommon\HelloLevel_9_58_00.xml. When Tvsukernel.exe parses the XML, it prepends the DestinationPath contained in the XML with C:\ProgramData\Lenovo\SystemUpdate\sessionSE\, shown below in Figure 06:

Figure 06: XML Parsing in ParseUDF()

In the custom attacker-controlled XML file, it is possible to use directory traversal to break out of the replaced C:\ProgramData\Lenovo\SystemUpdate\sessionSE\ DestinationPath value. An attacker can leverage this to choose any location on the operating system, thus resulting in an arbitrary file write primitive. In this case, directory traversal was used to set the DestinationPath value to C:\Program Files (x86)\Lenovo\System Update\SUService.exe, shown below in Figure 07. This is due to the fact that the Lenovo Updater tries to launch this application as NT AUTHORITY\SYSTEM each time the Lenovo System Updater is launched.

Figure 07: Directory Traversal in Custom XML

With the custom XML created and placed in C:\SSClientCommon\HelloLevel_9_58_00.xml and a malicious binary placed in C:\SSClientCommon\UTS\poc2.exe, an attacker can simply open the Lenovo System Update application and check for updates. Upon execution, Tvsukernel.exe will move the malicious C:\SSClientCommon\HelloLevel_9_58_00.xml to C:\ProgramData\Lenovo\SystemUpdate\sessionSE\system\SSClientCommon\HelloLevel_9_58_00.xml, parse it, and then move C:\SSClientCommon\UTS\poc2.exe to C:\Program Files (x86)\Lenovo\System Update\SUService.exe; overwriting the SUService.exe binary, shown below in Figure 08:

Figure 08: Overwriting Lenovo SUService.exe Service Binary

With Lenovo’s SUService.exe binary overwritten with a custom application, an attacker can close and re-open the Lenovo System Update application, which will cause the attacker’s application to execute as NT AUTHORITY\SYSTEM. In this case, poc2.exe gets the username of the currently executing user and writes it out to C:\Windows\POCOutput.txt, shown below in Figure 09:

Figure 09: Code Execution as NT AUTHORITY\SYSTEM

This vulnerability has been fixed in the latest version of the Lenovo System Updater application.

Lenovo’s Advisory can be found here: https://support.lenovo.com/us/en/product_security/LEN-135367

❌
❌