enigma0x3.net Open in urlscan Pro
192.0.78.24  Public Scan

Submitted URL: http://enigma0x3.net/
Effective URL: https://enigma0x3.net/
Submission: On January 10 via api from US — Scanned from DE

Form analysis 3 forms found in the DOM

GET https://enigma0x3.net/

<form role="search" method="get" class="search-form" action="https://enigma0x3.net/">
  <label>
    <span class="screen-reader-text">Search for:</span>
    <input type="search" class="search-field" placeholder="Search …" value="" name="s">
  </label>
  <input type="submit" class="search-submit" value="Search">
</form>

POST https://subscribe.wordpress.com

<form method="post" action="https://subscribe.wordpress.com" accept-charset="utf-8" style="display: none;">
  <div class="actnbr-follow-count">Join 182 other subscribers</div>
  <div>
    <input type="email" name="email" placeholder="Enter your email address" class="actnbr-email-field" aria-label="Enter your email address">
  </div>
  <input type="hidden" name="action" value="subscribe">
  <input type="hidden" name="blog_id" value="62662083">
  <input type="hidden" name="source" value="https://enigma0x3.net/">
  <input type="hidden" name="sub-type" value="actionbar-follow">
  <input type="hidden" id="_wpnonce" name="_wpnonce" value="64eb32f5d6">
  <div class="actnbr-button-wrap">
    <button type="submit" value="Sign me up"> Sign me up </button>
  </div>
</form>

<form id="jp-carousel-comment-form">
  <label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Write a Comment...</label>
  <textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a Comment..."></textarea>
  <div id="jp-carousel-comment-form-submit-and-info-wrapper">
    <div id="jp-carousel-comment-form-commenting-as">
      <fieldset>
        <label for="jp-carousel-comment-form-email-field">Email (Required)</label>
        <input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-author-field">Name (Required)</label>
        <input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-url-field">Website</label>
        <input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field">
      </fieldset>
    </div>
    <input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Post Comment">
  </div>
</form>

Text Content

Red Teamer and Security Addict


ENIGMA0X3


CVE-2023-4632: LOCAL PRIVILEGE ESCALATION IN LENOVO SYSTEM UPDATER

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

October 26, 2023 by enigma0x3 Leave a comment


AVIRA VPN LOCAL PRIVILEGE ESCALATION VIA INSECURE UPDATE LOCATION

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.

January 15, 2020 by enigma0x3 Leave a comment


CVE-2019-19248: LOCAL PRIVILEGE ESCALATION IN EA’S ORIGIN CLIENT

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.

December 10, 2019 by enigma0x3 Leave a comment


AVIRA OPTIMIZER LOCAL PRIVILEGE ESCALATION

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

August 29, 2019 by enigma0x3 Leave a comment


CVE-2019-13382: LOCAL PRIVILEGE ESCALATION IN SNAGIT

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

July 24, 2019 by enigma0x3 3 Comments


CVE-2019-13142: RAZER SURROUND 1.1.63.0 EOP

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.

July 5, 2019 by enigma0x3 Leave a comment


AVIRA VPN (2.15.2.28160) ELEVATION OF PRIVILEGE THROUGH INSECURE UPDATE LOCATION

Product Version: Avira Phantom VPN
Downloaded from:
https://package.avira.com/package/oeavira/win/int/avira_en_vpn__ws.exe
Operating System tested on: Windows 10 1709 (x64)
Vulnerability: Avira VPN Elevation of Privilege

Brief Description: The Avira Phantom VPN Service performs a handful of checks
when it checks for an update (this happens when the service starts, so on boot
or via manual start/stopping). When updating, the VPN service downloads the
update to “C:\Windows\Temp\” as AviraVPNInstaller.exe (which any user can write
to). It then checks if the file is signed, and if the version is less than the
installed product version. If these requirements are met, the service will run
the update binary as SYSTEM.  It is possible to overwrite
“AviraVPNInstaller.exe” with a signed, valid Avira executable (with a version
greater than the installed version) that looks for various DLLs in the current
directory. Due to the search order, it is possible to plant a DLL in
“C:\Windows\Temp” and elevate to NT AUTHORITY\SYSTEM.

Vulnerability Explanation
When the Avira VPN service (Avira.VPNService.exe, version 2.15.2.28160) starts,
it checks to see if there is an update available:



After some poking, it was determined that the VPN service updates from
“C:\Windows\Temp”



As you may know already, any authenticated user can write (but not read) to
C:\Windows\Temp. Once the update is there (as
C:\Windows\Temp\AviraVPNInstaller.exe), the VPN service checks the “FileVersion”
property of the executable in order to determine if the “update” is already
installed on the system:



If the version of the file shows it hasn’t been installed, the service will
check the file to make sure it is valid and signed by Avira:



If the file is indeed valid and signed by Avira, the VPN service will start the
“update” package. Since all of this happens in a place a low privilege user can
write to, it is possible to hijack the update package and perform DLL
sideloading.

In order to hijack “AviraVPNInstaller.exe”, three of the following conditions
have to be met:

 1. “AviraVPNInstaller.exe” has to be signed by Avira
 2. The signature on “AviraVPNInstaller.exe” has to be valid (any modification
    of that file would invalidate the signature
 3. The version number of “AviraVPNInstaller.exe” proves the update hasn’t been
    installed on the system.

This means we need to abuse an Avira signed file that has a version greater than
what is deployed.

After some hunting, “ToastNotifier.exe” fit the bill as it satisfies all three
requirements:



(If you are curious of where ToastNotifier.exe came from, it is from the Avira
Antivirus product suite that was abused in a similar manner in a bug reported on
the Antivirus platform).

To exploit this, all we need to do is copy “ToastNotifier.exe” to
“C:\Windows\Temp\AviraVPNInstaller.exe”. Since the requirements are met, the VPN
service will run it as SYSTEM when the service restarts. This can be
accomplished via a reboot, or by running powershell as an Administrator and then
doing “Get-Service AviraPhantomVPN | Stop-Service” followed by “Get-Service
AviraPhantomVPN | Start-Service”. Once executed, “ToastNotifier.exe” (which is
now C:\Windows\Temp\AviraVPNInstaller.exe) will try to load a handful of DLLs
out of C:\Windows\temp:



 To elevate our privileges to SYSTEM, all we need to do is provide one of those
DLLs. In this case, we will hijack “cryptnet.dll”. This will result in the VPN
service starting our “AviraVPNInstaller.exe” binary as SYSTEM, which will then
load “cryptnet.dll” as SYSTEM, which is our malicious code. This results in
elevation from a low privileged user to SYSTEM:

 

Disclosure Timeline:

 1. Submitted to Avira on September 28, 2018
 2. October 1, 2018: Issue reproduced by Avira
 3. December 13, 2018: Issue fixed by Avira

 

 

 

 

 

 

 

 

 

March 20, 2019 by enigma0x3 Leave a comment


AVIRA VPN 2.15.2.28160 ELEVATION OF PRIVILEGE

Product Version: Avira Phantom VPN version 2.15.2.28160

Downloaded from:
https://package.avira.com/package/oeavira/win/int/avira_en_vpn__ws.exe

Operating System tested on: Windows 10 1803 (x64)

Vulnerability: Avira VPN Elevation of Privilege

Brief Description: The Avira Phantom VPN service changes the DACL on
“C:\ProgramData\Avira\VPN\VpnSharedSettings.backup” and
“C:\ProgramData\Avira\VPN\VpnSharedSettings.config” when a configuration change
is made in the VPN settings menu. By setting a hardlink on
“C:\ProgramData\Avira\VPN\VpnSharedSettings.backup”, it is possible to overwrite
the DACL on an arbitrary file, leading to elevation from a low privileged user
to SYSTEM.

Vulnerability Explanation

When making a configuration change via the VPN GUI, the VPN service
(Avira.VPNService.exe) calls the function “AdjustSecurity()” that resides in
“Avira.VPN.Core.dll” to change the DACL to allow any authenticated user to write
to “C:\ProgramData\Avira\VPN\VpnSharedSettings.backup” or
“C:\ProgramData\Avira\VPN\VpnSharedSettings.config”. When a configuration change
is made (which can be done as a low privileged user), the service makes sure the
“Shared” VPN profile setting file
(C:\ProgramData\Avira\VPN\VpnSharedSettings.backup and
C:\ProgramData\Avira\VPN\VpnSharedSettings.config) exist by calling
“EnsureFileExists()”:



If the configuration file doesn’t exist, the service will create it and
continue. If it does, it simply continues to  the
“StorageSecurity.AdjustSecurity()” function. In the case of the shared vs
private configuration profiles, the “StorageType” being passed is either
“AllUserAccess” or “Secure”. The “private” VPN profile is assigned the “Secure”
storage type while the shared profile is assigned “AllUserAccess”.



When the “AdjustSecurity()” function is called (passing the storage type of the
configuration file), it adjusts the DACL on the file itself appropriately. This
is where the bug lies. For the “shared” profile (with the StorageType of
“AlluserAccess”), the VPN service calls “AdjustSecurity()” and grants the
everyone full control over the file:



This is dangerous because the “SetAccessControll()” call changes the DACL on a
file in which a low privileged user can control. So, how do we exploit this?

First, an attacker needs to create a hardlink on
“C:\ProgramData\Avira\VPN\VpnSharedSettings.backup” and point it at a file. In
this case, we will point it at  “C:\Program Files
(x86)\Avira\VPN\OpenVPN\phantomvpn.exe”. Doing so will overwrite the DACL on
“C:\Program Files (x86)\Avira\VPN\OpenVPN\phantomvpn.exe”.



After doing so, open the VPN and click the “Settings” tab:



After doing so, uncheck the “Send Diagnostic Data” box. This will trigger a
config change and kick the code-path off:



At this point, the DACL on “C:\Program Files
(x86)\Avira\VPN\OpenVPN\phantomvpn.exe” has been overwritten to allow any user
to write to it. The attacker now just needs to copy a malicious binary to
replace it:



Once done, execution of the malicious binary can be accomplished by simply
trying to connect to the VPN. This can be done by clicking “Secure my
Connection” in the VPN GUI:



After clicking “Secure my connection”, you should see a few cmd.exe processes
running as SYSTEM:



Disclosure Timeline:

 1. Reported to Avira on September 28, 2018
 2. October 1, 2018: Avira acknowledged the report
 3. October 4, 2018: Avira was able to reproduce
 4. December 13, 2018: Issue resolved

March 20, 2019 by enigma0x3 Leave a comment


RAZER SYNAPSE 3 ELEVATION OF PRIVILEGE

Product Version: Razer Synapse 3 (3.3.1128.112711) Windows Client
Downloaded from: https://www.razer.com/downloads
Operating System tested on: Windows 10 1803 (x64)
Vulnerability: Razer Synapse Windows Service EoP

Brief Description: The Razer Synapse software has a service (Razer Synapse
Service) that runs as “NT AUTHORITY\SYSTEM” and loads multiple .NET assemblies
from “C:\ProgramData\Razer\*”. The folder “C:\ProgramData\Razer\*” and recursive
directories/files have weak permissions that grant any authenticated user
FullControl over the contents. It is possible to circumvent signing checks and
elevate to SYSTEM using assembly sideloading.

Vulnerability Explanation:
When the Razer Synapse service starts, it will load .NET assemblies out of
various directories within “C:\ProgramData\Razer\*”, such as
“C:\ProgramData\Razer\Synapse3\Service\bin”.



When looking at the DACL on the folder
“C:\ProgramData\Razer\Synapse3\Service\bin”, you will notice that “Everyone” has
“FullControl” rights over the folder (including any files within the folder):



In theory, an attacker could simply replace an existing .NET assembly with a
malicious one, reboot the system and let the Razer Synapse Service load it when
it starts. This approach came with some complications, such as a race condition
to replace an assembly before the service loads it. Additionally, the service
implements some checks that must be passed before the assembly can be loaded.
For efficient exploitation, it is important to fully understand the conditions
in which an assembly can be loaded successfully.

The first issue to tackle is getting a malicious assembly planted in such a way
that the service will try to load it. Hijacking an existing assembly can be
challenging as low privileged users do not have rights to stop or start the
Razer Synapse service. This means that to trigger the assembly loading code
path, the box needs to be rebooted. This makes winning the race condition for
swapping out a legitimate assembly with a malicious one challenging. Looking at
the service, this problem is solved pretty easily as it recursively enumerates
all DLLs in “C:\ProgramData\Razer\*”.



This means that we can simply drop an assembly in one of the folders
(C:\ProgramData\Razer\Synapse3\Service\bin, for example) and it will be treated
the same as an existing, valid assembly.

After recursively enumerating all DLLs in “C:\ProgramData\Razer\*”, the service
attempts to ensure those identified assemblies are signed by Razer. This is done
by grabbing certificate information from “Razer.cer”, calling
X509Certificate.CreateFromSignedFile() on each assembly and then comparing the
certificate chain from Razer.cer with the assembly being loaded.



If the certificate chain on the assembly doesn’t match that of Razer.cer, the
service will not load it. While the thought behind checking the trust of .NET
assemblies before loading them is good, the implementation wasn’t robust, as
X509Certificate.CreateFromSignedFile() only extracts the certificate chain and
in no way attests the validity of the signature of the file being checked
(https://twitter.com/tiraniddo/status/1072475737142239233). This means that it
is possible to use a tool such as SigPirate to clone the certificate from a
valid Razer assembly onto a malicious one, due to the fact that the signature of
said assembly is never actually verified.

Once the assembly passes the certificate check, the service will then load it
into the current app domain via  Assembly.LoadFile(). No malicious code will
execute during the Assembly.LoadFile() call, however. After doing so, the
service will check to make sure there is an IPackage interface implemented.



This interface is specific to the SimpleInjector project, which is well
documented. The only requirement to pass this check is to implement the IPackage
interface in our malicious assembly. Once the service validates the certificate
chain of the assembly and verifies the presence of IPackage, it adds the
assembly to a running list. Once this is done for all the assemblies found in
“C:\ProgramData\Razer\*”, the list is then passed to SimpleInjector’s
“RegisterPackages()” function.



RegisterPackages() will take the list of “verified” assemblies and call the
“RegisterServices()” function within the IPackage interface of each assembly.



This is the point in which we, as an attacker, can execute malicious code. All
that needs done is to add malicious logic in the “RegisterServices()” method
within the IPackage interface of our malicious assembly.

At this point, we have found ways to abuse all of the requirements to get
elevated code-execution.

 1. Write a custom assembly that implements the IPackage interface from the
    SimpleInjector project
 2. Add malicious logic in the “RegisterServices()” method inside the IPackage
    interface
 3. Compile the assembly and use a tool such as SigPirate to clone the
    certificate chain from a valid Razer assembly
 4. Drop the final malicious assembly into
    “C:\ProgramData\Razer\Synapse3\Service\bin”
 5. Restart the service or reboot the host

Exploitation:
After understanding the requirements to get arbitrary code-execution in an
elevated context, we can now exploit it. First, we need to create our malicious
assembly that implements the required IPackage interface. To do so, a reference
to the “SimpleInjector” and “SimpleInjector.Packaging” assemblies need to be
added from the SimpleInjector project. Once the reference is added, we just need
to implement the interface and add malicious logic. A PoC assembly would look
something like this:



Since the Razer service is 32-bit, we compile the assembly as x86. Once
compiled, we need to pass the certificate chain check. Since the service is
using X509Certificate.CreateFromSignedFile() without any signature validation,
we can simply clone the certificate from a signed Razer assembly using
SigPirate:



Using “Get-AuthenticodeSignature” in PowerShell, we can verify that the
certificate was applied to our “lol.dll” assembly that was created from
SigPirate:



At this point, we have a malicious assembly with a “backdoored” IPackage
interface that has a cloned certificate chain from a valid Razer assembly. The
last step is to drop “lol.dll” in “C:\ProgramData\Razer\Synapse3\Service\bin”
and reboot the host. Once the host restarts, you will see that “Razer Synapse
Service.exe” (running as SYSTEM) will have loaded “lol.dll” out of
“C:\ProgramData\Razer\Synapse3\Service\bin”, causing the “RegisterServices()”
method in the implemented IPackage interface to execute cmd.exe.



When the service loads “lol.dll”, it sees it as valid due to the cloned
certificate, and EoP occurs due to the “malicious” logic in the IPackage
implementation.

Razer fixed this by implementing a new namespace called “Security.WinTrust”,
which contains functionality for integrity checking. The service will now call
“WinTrust.VerifyEmbeddedSignature() right after pulling all the “*.dll” files
from the Razer directory.



When looking at “WinTrust.VerifyEmbeddedSignature()”, the function utilizes
“WinTrust.WinVerifyTrust()” to validate that the file being checked has a valid
signature (through WinVerifyTrust()).



If the file has a valid signature AND the signer is by Razer, then the service
will continue the original code path of checking for a valid IPackage interface
before loading the assembly. By validating the integrity of the file, an
attacker can no longer clone the certificate off of a signed Razer file as the
signature of the newly cloned file will not be valid.

For additional reading on trust validation, I encourage you to read the
whitepaper “Subverting Trust in Windows” by Matt Graeber.

Disclosure Timeline:

06/05/2018: Submitted vulnerability report to Razer’s HackerOne program
06/08/2018: Response posted on the H1 thread acknowledging the report
06/08/2018: H1 staff asked for specific version number of the Synapse 3
installer
06/08/2018: Synapse 3 installer version number provided to Razer
07/05/2018: Asked for an update
08/06/2018: Report marked as triaged
08/27/2018: Asked for an update, no response
09/14/2018: Asked for update, along with a direct email address to speed up
communication. No response
12/14/2018: Asked for a security contact for Razer via Twitter
12/14/2018: H1 program manager reached out to investigate the H1 report
12/15/2018: Razer CEO Min-Liang Tan reached out directly asking for a direct
email to pass to the security team
12/16/2018: The Information Security Manager and SVP of Software reached out
directly via email. I was provided context that a fix would be pushed out to the
public in a couple of weeks
12/19/2018: Pulled down the latest Synapse 3 build and investigated vulnerable
code path. Submitted additional information to Razer’s H1 program, along with
notice to Razer’s Manager of Information Security
12/25/2018: I was contacted by someone at Razer with a link to an internal build
for remediation verification
12/27/2018: Per their request, provided feedback on the implemented mitigation
via the H1 report
01/09/2019: Asked for a timeline update for the fixed build to be provided to
the public (via H1)
01/10/2019: Informed that the build is now available to the public
01/10/2019: Report closed
01/10/2019: Requested permission for public disclosure
01/10/2019: Permission for public disclosure granted by Razer
01/21/2019: Report published

*Note: While the disclosure timeline was lengthy, I have to assume it was due to
a disconnect between the folks at Razer managing the H1 program and the folks at
Razer working on the fix. Once I was provided an internal contact, the timeline
and experience improved drastically.

 

-Matt N.

January 21, 2019 by enigma0x3 Leave a comment


CVE-2018–8414: A CASE STUDY IN RESPONSIBLE DISCLOSURE

The process of vulnerability disclosure can be riddled with frustrations,
concerns about ethics, and communication failure. I have had tons of bugs go
well. I have had tons of bugs go poorly.

I submit a lot of bugs, through both bounty programs (Bugcrowd/HackerOne) and
direct reporting lines (Microsoft). I’m not here to discuss ethics. I’m not here
to provide a solution to the great “vulnerability disclosure” debate. I am
simply here to share one experience that really stood out to me, and I hope it
causes some reflection on the reporting processes for all vendors going forward.

First, I’d like to give a little background on myself and my relationship with
vulnerability research.

I’m not an experienced reverse engineer. I’m not a full-time developer. Do I
know C/C++ well? No. I’m relatively new to the industry (3 years in). I give up
my free time to do research and close my knowledge gaps. I don’t find crazy
kernel memory leaks, rather, I find often overlooked user-mode logic bugs (DACL
overwrite bugs, anyone?).

Most importantly, I do vulnerability research (VR) as a hobby in order to learn
technical concepts I’m interested in that don’t necessarily apply directly to my
day job. While limited, my experience in VR comes with the same pains that
everyone else has.

When I report bugs, the process typically goes like this:

 1. Find bug->Disclose bug->Vendor’s eyes open widely at bug->Bug is fixed and
    CVE possibly issued (with relevant acknowledgement)->case closed
 2. Find bug->Disclose bug->Vendor fails to see the impact, issues a won’t
    fix->case closed

When looking at these two situations, there are various factors that can
determine if your report lands on #1 or #2. Such factors can include:

 1. Internal vendor politics/reorg
 2. Case handler experience/work ethic/communication (!!!!)
 3. Report quality (did you explain the bug well, and outline the impact the bug
    has on a product?)

Factors that you can’t control can start to cause frustration when they occur
repeatedly. This is where the vendor needs to be open to feedback regarding
their processes, and where researchers need to be open to feedback regarding
their reports.

So, let us look at a case study in a vulnerability report gone wrong (and then
subsequently rectified):

On Feb 16, 2018 at 2:37 PM, I sent an email to secure@microsoft.com with a
write-up and PoC for RCE in the .SettingContent-ms file format on Windows 10.
Here is the original email:



This situation is a good example where researchers need to be open to feedback.
Looking back on my original submission, I framed the bug mostly around Office
2016’s OLE block list and a bypass of the Attack Surface Reduction Rules in
Windows Defender. I did, however, mention in the email that “The PoC zip
contains the weaponized .settingcontent-ms file (which enables code-execution
from the internet with no security warnings for the user)”. This is a very
important line, but it was overshadowed by the rest of the email.

On Feb 16, 2018 at 4:34 PM, I received a canned response from Microsoft stating
that a case number was assigned. My understanding is that this email is fairly
automated when a case handler takes (or is assigned) your case:



Great. At this point, it is simply a waiting game while they triage the report.
After a little bit of waiting, I received an email on March 2nd, 2018 at 12:27pm
stating that they successfully reproduced the issue:



Awesome! This means that they were able to take my write-up with PoC and confirm
its validity. At this very point, a lot of researchers see frustration. You take
the time to find a bug, you take the time to report it, you get almost immediate
responses from the vendor, and once they reproduce it, things go quiet. This is
understandable since they are likely working on doing root cause analysis on the
issue. This is the critical point in which it will be determined if the bug is
worth fixing or not.

I will admit, I generally adhere to the 90 day policy that Google Project Zero
uses. I do not work for GPZ, and I don’t get paid to find bugs (or manage
multiple reports). I tend to be lenient if the communication is there. If a
vendor doesn’t communicate with me, I drop a blog post the day after the 90 days
window closes.

Vendors, PLEASE COMMUNICATE TO YOUR RESEARCHERS!

In this case, I did as many researchers would do once more than a month goes by
without any word…I asked for an update:



At this point, it has almost been a month and a half since I have heard
anything. After asking for an update, this email comes in:



Interesting…I all of the sudden have someone else handling my case? I can
understand this as Microsoft is a huge organization with various people handling
the massive load of reports they get each day. Maybe my case handler got
swamped?

Let’s pause and evaluate things thus far: I reported a bug. This bug was
assigned a case number. I was told they reproduced the issue, then I hear
nothing for a month and a half. After reaching out, I find out the case was
re-assigned. Why?

Vendors, this is what causes frustration. Researchers feel like they are being
dragged along and kept in the dark. Communication is key if you don’t want 0days
to end up on Twitter. In reality, a lot of us sacrifice personal time to find
bugs in your products. If people feel like they don’t matter or are placed on
the backburner, they are less likely to report bugs to you and more likely to
sell them or drop them online.

Ok, so my case was re-assigned on April 25th, 2018 at 12:42 pm. I say “Thanks!!”
a few days later and let the case sit while they work the bug.



Then, a little over a month goes by with no word. At this point, it has been
over 90 days since I submitted the original report. In response, I sent another
follow up on June 1st, 2018 at 1:29pm:



After a few days, I get a response on June 4th, 2018 at 10:29am:



Okay. So, let’s take this from the top. On Feb 16, 2018, I reported a bug. After
the typical process of opening a case and verifying the issue, I randomly get
re-assigned a case handler after not hearing back for a while. Then, after
waiting some time, I still don’t hear anything. So, I follow up and get a “won’t
fix” response a full 111 days after the initial report.

I’ll be the first to admit that I don’t mind blogging about something once a
case is closed. After all, if the vendor doesn’t care to fix it, then the world
should know about it, in my opinion.

Given that response, I went ahead and blogged about it on July 11, 2018. After I
dropped the post, I was contacted pretty quickly by another researcher on
Twitter letting me know that my blog post resulted in 0days in Chrome and
Firefox due to Mark-of-the-Web (MOTW) implications on the .SettingContent-ms
file format. Given this new information, I sent a fresh email to MSRC on June
14, 2018 at 9:44am:



At this point, I saw two exploits impacting Google Chrome and Mozilla FireFox
that utilized the .SettingContent-ms file format. After resending details, I got
an email on June 14, 2018 at 11:05am, in which MSRC informed me the case would
be updated:



On June 26, 2018 at 12:17pm, I sent another email to MSRC letting them know that
Mozilla issued CVE-2018-12368 due to the bug:



That same day, MSRC informed me that the additional details would be passed
along to the team:



This is where things really took a turn. I received another email on July 3,
2018 at 9:52pm stating that my case had been reassigned once again, and that
they are re-evaluating the case based on various other MSRC cases, the Firefox
CVE, and the pending fixes to Google Chrome:



This is where sympathy can come into play. We are all just people doing jobs.
While the process I went through sucked, I’m not bitter or angry about it. So,
my response went like this:



After some time, I became aware that some crimeware groups were utilizing the
technique in some really bad ways
(https://www.proofpoint.com/us/threat-insight/post/ta505-abusing-settingcontent-ms-within-pdf-files-distribute-flawedammyy-rat).
After seeing it being used in the wild, I let MSRC know:



MSRC quickly let me know that they are going to ship a fix as quickly as
possible…which is a complete 180 compared to the original report assessment:



Additionally, there was mention of “another email on a different MSRC case
thread”. That definitely piqued my interest. A few days later, I got a strange
email with a different case number than the one originally assigned:



At this point, my jaw was on the floor. After sending some additional
information to a closed MSRC case, the bug went from a “won’t fix” to “we are
going to ship a fix as quickly as possible, and award you a bounty, too”. After
some minor logistic exchanges with the Microsoft Bounty team, I saw that
CVE-2018-8414 landed a spot on cve.mitre.org. This was incredibly interesting
given less than a month ago, the issue was sitting as a “won’t fix”. So, I asked
MSRC about it:



This is when I quickly found out that CVE-2018-8414 was being issued for the
.SettingContent-ms RCE bug:



This is where the process gets cool. Previously, I disclosed a bug. That bug was
given a “won’t fix” status. So, I blogged about it
(https://posts.specterops.io/the-tale-of-settingcontent-ms-files-f1ea253e4d39).
I then found out it had been used to exploit 2 browsers, and it was being used
in the wild. Instead of letting things sit, I was proactive with MSRC and let
them know about all of this. Once the August patch Tuesday came around, I
received this email:



Yay!!! So Microsoft took a “Won’t Fix” bug and reassessed it based on new
information I had provided once the technique was public. After a few more days
and some logistical emails with Microsoft, I received this:



I have to give it to Microsoft for making things right. This bug report went
from “won’t fix” to a CVE, public acknowledgement and a $15,000 bounty pretty
quickly.

As someone who likes to critique myself, I can’t help but acknowledge that the
original report was mostly focused on Office 2016 OLE and Windows Defender ASR,
neither of which are serviceable bugs (though, RCE was mentioned). How could I
have done better, and what did I learn?

If you have a bug, demonstrate the most damage it can do. I can’t place all the
fault on myself, though. While I may have communicated the *context* of the bug
incorrectly, MSRC’s triage and product teams should have caught the implications
in the original report, especially since I mentioned “which enables
code-execution from the internet with no security warnings for the user”.

This brings me to my next point. We are all human beings. I made a mistake in
not clearly communicating the impact/context of my bug. MSRC made a mistake in
the assessment of the bug. It happens.

Here are some key points I learned during this process:

 1. Vendors are people. Try to do right by them, and hopefully they try to do
    right by you. MSRC gave me a CVE, an acknowledgement and a $15,000 bounty
    for a bug which ended up being actively exploited before being fixed
 2. Vendors: PLEASE COMMUNICATE TO YOUR RESEARCHERS. This is the largest issue I
    have with vulnerability disclosure. This doesn’t just apply to Microsoft,
    this applies to every vendor. If you leave a researcher in the dark, without
    any sort of proactive response (or an actual response), your bugs will end
    up in the last place you want them.
 3. If you think your bug was misdiagnosed, see it through by following up and
    stating your case. Can any additional information be provided that might be
    useful? If you get a bug that is issued a “won’t fix”, and then you see it
    being exploited left and right, let the vendor know. This information could
    change the game for both you and their customers.

Vulnerability disclosure is, and will continue to be, a hard problem. Why?
Because there are vendors out there that will not do right by their researchers.
I am sitting on 0days in products due to a hostile relationship with “VendorX”
(not Microsoft, to be clear). I also send literally anything I think might
remotely resemble a bug to other vendors, because they do right by me.

At the end of the day, treat people the way you would like to be treated. This
applied to both the vendors and the researchers. We are all in this to make
things better. Stop adding roadblocks.

Timeline:

Feb 16, 2018 at 2:37 PM EDT: Report submitted to secure@microsoft.com
Feb 16, 2018 at 4:34 PM EDT: MSRC acknowledged the report and opened a case
March 2, 2018 at 12:27 PM EDT: MSRC responded noting they could reproduce the
issue
April 24, 2018 at 4:06 PM EDT: Requested an update on the case
April 25, 2018 at 12:42 PM EDT: Case was reassigned to another case handler.
June 1, 2018 at 1:29 PM EDT: Asked new case handler for a case update
June 4, 2018 at 10:29 AM EDT: Informed the issue was below the bar for
servicing; case closed.
July 11, 2018: Issue is publicly disclosed via a blog post
June 14, 2018 at 9:44 AM EDT: Sent MSRC a follow up after hearing of 2 browser
bugs using the bug
June 14, 2018 at 11:05 AM EDT: Case was updated with new information
June 26, 2018 at 12:17 PM EDT: informed MSRC of mozilla CVE (CVE-2018-12368)
June 26, 2018 at 1:15 PM EDT: MSRC passed the mozilla CVE to the product team
July 3, 2018 at 9:52 PM EDT: Case was reassigned to another case handler
Jul 23, 2018 at 4:49 PM EDT: Let MSRC know .settingcontent-ms was being abused
in the wild.
Jul 27, 2018 at 7:47 PM EDT: MSRC informed me they are shipping a fix ASAP
Jul 27, 2018 at 7:55 PM EDT: MSRC informed me of bounty qualification
Aug 6, 2018 at 3:39 PM EDT: Asked MSRC if CVE-2018-8414 was related to the case
Aug 6, 2018 at 4:23 PM EDT: MSRC confirmed CVE-2018-8414 was assigned to the
case
Aug 14, 2018: Patch pushed out to the public
Sept 28, 2018 at 4:36 PM EDT: $15,000 bounty awarded

Before publishing this blog post, I asked MSRC to review it and offer any
comments they may have. They asked that I include on official response statement
from them, which you can find below:



Cheers,
Matt N.

October 23, 2018 by enigma0x3 Leave a comment


POST NAVIGATION

← Older posts
Older posts
Search for:


RECENT POSTS

 * CVE-2023-4632: Local Privilege Escalation in Lenovo System Updater
 * Avira VPN Local Privilege Escalation via Insecure Update Location
 * CVE-2019-19248: Local Privilege Escalation in EA’s Origin Client
 * Avira Optimizer Local Privilege Escalation
 * CVE-2019-13382: Local Privilege Escalation in SnagIt


RECENT COMMENTS

Ron on CVE-2019-13382: Local Privileg…enigma0x3 on CVE-2019-13382: Local
Privileg…Ron on CVE-2019-13382: Local Privileg…Soc on Defeating Device Guard: A
look…“Fileless… on “Fileless” UAC Byp…


ARCHIVES

 * October 2023
 * January 2020
 * December 2019
 * August 2019
 * July 2019
 * March 2019
 * January 2019
 * October 2018
 * June 2018
 * January 2018
 * November 2017
 * October 2017
 * September 2017
 * August 2017
 * July 2017
 * April 2017
 * March 2017
 * January 2017
 * November 2016
 * August 2016
 * July 2016
 * May 2016
 * March 2016
 * February 2016
 * January 2016
 * October 2015
 * August 2015
 * April 2015
 * March 2015
 * January 2015
 * October 2014
 * July 2014
 * June 2014
 * March 2014
 * January 2014


CATEGORIES

 * Uncategorized


META

 * Register
 * Log in
 * Entries feed
 * Comments feed
 * WordPress.com

Blog at WordPress.com.

 * Subscribe Subscribed
    * enigma0x3
      
      Join 182 other subscribers
      
      Sign me up
    * Already have a WordPress.com account? Log in now.

 * Privacy
 *  * enigma0x3
    * Customize
    * Subscribe Subscribed
    * Sign up
    * Log in
    * Report this content
    * View site in Reader
    * Manage subscriptions
    * Collapse this bar

 

Loading Comments...

 

Write a Comment...
Email (Required) Name (Required) Website