Jul 102017

In this blog post I want to discuss a code injection vulnerability in VMware Horizon‘s macOS Client Version 4.4.0 (5164329) that can be abused to gain local root privileges. The good news is, that it has already been fixed in the latest available version. I found it after learning about the “Open VMware View Client Services” SUID binary on my Mac.

I think it is used internally by Horizon’s remote USB services and is only exploitable after they have been started once by entering administrative credentials.

To investigate the binary further, I used the newly released Fireeye application Monitor.app. It basically is Process Monitor (procmon) for macOS.

Based on the activities as captured by Monitor.app it was clear that “Open VMware View Client Services” was basically a wrapper around “services.sh”. This makes sense as the SUID bit is ignored for script files.

After taking a closer look at this script, I identified the highlighted line in the following screenshot as a starting point for a possible code injection vulnerability. Although I had no idea about the inner workings of “./vmware-usbarbitrator” this binary was immediately my focus for further investigations. The reason for this is that I – as a non-admin user – am able to set the content of the environment variable VMWARE_VIEW_USBARBITRATOR_LOG_OPTIONS – that is used in an SUID executed script. 

After taking a closer look at the possible command line options I was pretty sure I could abuse this setup to load a custom kernel extension by abusing the –kext flag. 

However, there are two further problems:

  1. Kernel Extensions are only loaded if they are owned by root : wheel
  2. Additionally, KEXTs the have to be signed by Apple.

In the course of this LPE I will ignore issue #2. Hence, I disabled SIP.

So let’s focus on issue #1. To successfully load a kernel extension the binary has to be owned by root : wheel. However, for a normal user it is impossible to set this file system permissions on a any local file. Luckily, I had already invested plenty of time to learn about the In’s and Out’s of file systems at Tools On Air. So I knew, the only thing I had to do was to abuse NFS. This is possible because NFS allows the server to specify the file system permissions, even if mounted by a user. Any other local or remote file system I know of, ignores files owned by root in some way. So my next step was to simply export a remote folder (on my Kali Linux I always carry around with me) using NFS…

… and mount it using Finder’s “Connect to Server”.

After creating a simple KEXT …

and updating the Info.plist file to meet the requirements (simply add a dictionary “IOKitPersonalities”) we are ready! 

After copying this KEXT to the NFS server and adapting its permissions to meet the “root:wheel” requirement, we are finally able to start the real exploitation.

To do so simply set the “VMWARE_VIEW_USBARBITRATOR_LOG_OPTIONS” environment variable to our previously create KEXT and run “Open VMware View Client Services”. This is enough to load it!

Hence, we gained code execution from a normal user’s account within the kernel context!

Suggested Solution


Disclosure Timeline

21-04-2017: The issues has been documented and reported
24-04-2017: VMware started investigating
06-06-2017: Fix ready
08-06-2017: Updated Horizon version 4.5 alongside security advisory VMSA-2017-0011 released

Oct 172016

As many of you may know I’m an OS X guy. I have been using it since many years and I’m pretty happy with it! However this also makes this vulnerability something special: It’s the first time I’m disclosing a vulnerability affecting an OS X application! Here it goes…

A few weeks ago I thought about using WineBottler (in the current then version 1.8-rc4) – a graphical Wine front-end for OS X – to build myself a KeePass OS X application. However, after LittleSnitch informed me that WineBottler tried to connect to winetricks.org using unsecured HTTP, I got a little skeptical: What is WineBottler downloading from there?

Screen Shot 2016-06-02 at 13.48.22

So I launched Burp and started to analyse the HTTP network traffic. Thereby I discovered the following request to http://winetricks.org/winetricks.

3 vulnerable request detail

Further investigation showed that after a redirect, a Terminal script is served over HTTPS from there. However as the first request is initiated using unencrypted HTTP we can intercept and modify all further requests.

An attacker can thereby modify the unsecured HTTP connection using a man-in-the-middle attack. This can be carried out by using for example ARP spoofing or by providing a malicious “free” Wifi hotspot.

Anyhow, by replying to the initial request with a valid Terminal script, remote commands can be injected.

5 modified response

As the script is also immediately executed this is a reliable way to overtake a system as shown below.

6 rce

As I had a little time spare, I automated the attack using mitmproxy and the following custom script named “drunken_winebottler.py”.

from mitmproxy.models import decoded

NEWLINE = '\r\n'

def response(context, flow):
    if flow.request.url == "http://winetricks.org/winetricks" and flow.response.status_code == 301 and flow.request.method=="GET":
        flow.response.status_code=200 # overwrite 301 status code to 200
        with decoded(flow.response):  # automatically decode gzipped responses.
            flow.response.content =  "" # replace original script to launch Calculator.app
            flow.response.content += '#!/bin/sh'+NEWLINE
            flow.response.content += '/usr/bin/open /Applications/Calculator.app'

Simply launch mitmproxy using the following command and redirect all HTTP traffic to it (either by using ARP spoofing or by simply setting a manual proxy for testing).

./mitmproxy -s drunken_winebottler.py

Tada, after launching WineBottler the script is downloaded and executed. Calculator.app is executed to proof that remote code execution has been gained.

Screen Shot 2016-06-02 at 14.27.30

What about the Bundles itself?

The next logical step was to verify the bundles that have been created using WineBottler. “Bundles” are basically Windows applications wrapped by WineBottler so that you can use them as if they were OS X applications. I verified that they are also affected by this issue. However I think they only download and run winetricks on their first launch. This in turn greatly limits the attack surface.


To demonstrate the attack here’s a video showing the above mitmproxy script in action.

Suggested solution

All request should be carried out over encrypted communication channels like HTTPS. The author already mentioned that he is planing to do so in the future. Maybe this issue speeds up this process.

Screen Shot 2016-06-02 at 14.33.06


As blocking the request to winetricks.org stalls WineBottler I can think of no reliable way to work around this issue. If you have any ideas I would love to hear them.


  • 29.5.2016: The issue has been discovered
  • 30.5.2016: Tried to establish initial contact with the developer using Facebook
  • 31.5.2016: Requested CVE number; Retried to contact developer using Facebook
  • 1.6.2016: MITRE declined CVE: The product is not covered.
  • 2.6.2016: Created this documentation; Sent to developer using mail
  • 18.6.2016: Developer responded on Facebook
  • 20.6.2016: Developer promised that Winetricks update will be switched to HTTPS. Agreed on the 29.7. for the public disclosure
  • 25.7.2016: Tried to contact developer as no new version has been released – no success
  • 29.7.2016: Initially agreed public disclosure date – rescheduled
  • 31.7.2016: Tried again to contact developer – again no success.
  • 13.8.2016: Tried a last time to get in touch with the developer – again no success
  • 17.10.2016: Public disclosure altough unfixed: Developer unresponsive
Aug 182015

1439896694_internet_earthIn the need for a simple and easy to use OS X based Always On VPN solution? If so, I may have something for you.

We are using a straight forward L2TP over IPSec VPN connection for connecting into our Pentesting lab. Beside giving me access to many of my most needed tools it also allows me to surf the web without any proxy or firewall limitation. As I encountered several VPN disconnects over my work day I decided to solve it once an forever by automatically reconnecting the VPN after a dropout.

To do so I wrote the following Apple Script based on this Apple Support Communities discussion.

global PING_HOST
global VPN_NAME

set PING_HOST to "vpn.example.com" # A host on the web to ensure the current connection is working at all
set VPN_NAME to "Your VPN" # The name of the VPN connection to dial (works with PPTP, L2TP over IPSec and Cisco IPSec)

on idle

		# as the ping causes an exception if no response is received we only try to connect to the server if it's really reachable and thereby surpress error messages
		do shell script "ping -c 1 -W 500 " & PING_HOST

		tell application "System Events"
			tell current location of network preferences
				set myConnection to the service VPN_NAME
				if myConnection is not null then
					if current configuration of myConnection is not connected then
						connect myConnection
					end if
				end if
			end tell
		end tell

	end try

	return 2 # schedule to run again in two seconds
end idle

Simply save it as an application and check the box “Stay open after run handler”:
Screen Shot 2015-08-18 at 20.17.12
As long as the App it is running, your VPN connection will be redialed automatically. This small helper gained a permanent spot in my Dock!

PS: To give the App a nicer appearance you may want to change it’s icon to this free one. Here is a tutorial on how to do that.

Edit: Updated the code to use the “on idle” handler

Feb 022015

BonjourOverWan2For me and many of my customers it would be a great feature to have Bonjour working over VPN connections. Apple’s Bonjour (also called mDNS or multicast DNS) is the service responsible for discovering other machines and the services provided by these machines in your network. The most important feature for me is the fileserver integration in Finder as shown on the right. Thereby all detected fileservers are integrated into the left Finder sidebar and you can simply connect by clicking them. Unfortunately this does not work over VPN connections as multicast traffic is generally not routed.

To simulate this fileserver discovery over a VPN connection I wrote a small wrapper script for dns-sd. It checks if a given server is available by pinging it’s IP and if so it adds it to the sidebar by using dns-sd’s proxy feature. You can check out the script at my Google Code snippet repository. The following diagram shows the inner workings.


To install it just download serverProxy.sh, rename it to myServerProxy.sh to allow multiple proxies, make it executable, adapt the settings at the top and create a launchd configuration. I recommend to use Lingon to create a “My Agent” launchd job that gets loaded at startup and that keeps the script alive. In theory it should not crash but who knows. You can use as many proxies as you like. Finally reboot and check if the configured server is now shown after you connected to your VPN.

Jan 142015

frankensteinCurrently there are several articles like the one on Arstechnica that complain about the DNS resolver in OS X 10.10. Amongst others they report issues with name resolution per se and Bonjour machine names that get changed. Many of this posts then suggest to replace the new discoveryd with the legacy mDNSResponder service.

This post acts as a warning: Never ever replace core system components!

By following the instructions to replace discoveryd you are completely on your own. By replacing such a vital system component you can introduce all kinds of bugs. Many of those may not even look related to name resolution but are triggered by some strange side effect. Furthermore I’m pretty sure Apple does not test their updates with this Frankenstein-like system configuration. Last but not least you may even introduce security problems.

Even if there are bugs, which is inevitable, please report them to the developers and wait for a system update to fix them. You simply don’t know what problems you cause by doing otherwise.

Dec 312014

This year’s last post is all about time. In fact, it’s about how to get NTP working within an isolated network. The Network Time Protocol is a network protocol used to synchronise computer clocks across networks. It is necessary as computers measure time using oscillating crystals. However each computer has a slightly different oscillating interval that causes the local clocks of different systems to drift apart. This can cause problems in distributed systems.

One such problem occurs within redundant playout systems with multiple servers. All systems need to have exactly the same time reference (and to do so they often use the local system time) to play the same video frame all the time. Otherwise there is a visible service disruption during fallback.


As this example shows it’s more about a coherent time source / reference than it is about a correct one. What that means is that it is more important that all systems have exactly the same time, however it does not really matter if it’s 0,5 seconds ahead the correct one.

To do so I always use one Linux system within the isolated broadcast network as NTP server using ntp. This server gets queried by all other systems and shares his local time.

Timesync Server

There is only a small problem with this setup. As the time source for the Linux NTP Server is only his oscillating crystal and not a precise system like an atomic clock the other systems don’t trust his information. His strata is simply too high. There are two solutions to solve this issue:

Whichever you use, you will get a coherent time reference on all nodes within the network. However be aware that it’s just a relative time.

Guten Rutsch ins neue Jahr 2015

Dec 152014

A few weeks ago I learned about LinEnum. It’s original author owen described it as follows:

It’s a very basic shell script that performs over 65 checks, getting anything from kernel information to locating possible escalation points such as potentially useful SUID/GUID files and Sudo/rhost mis-configurations and more.

The first thing that came to my mind was if this script will work on OS X. I cloned the GitHub repository to my Mac and was immediately greeted with multiple error messages. As I had some spare minutes I forked the repository and fixed the most major bugs.


As I had to disable some tests I hope to find some more time to fix and reenable them. My goal is to maintain the Linux compatibility and only extend the script to fully work on OS X. I think this could become be a handy quick-check tool.

Dec 052014

Today’s blog post is a summary of several useful formulas for dimensioning video storage systems. Before you start reading it, it is very important to understand the connection between the Kilo, Mega, Giga and Tera prefix, the difference between Bit and Byte and difference between an indication of size (like MB) and an indication of speed (like MBps respectively MB/s). I created all the equation using the great Online LaTeX Equation Editor.

This post uses the following terminology:

  • A capital B stands for Byte
    Example: MB means Megabyte
  • A lower case b stands for Bit
    Example: Mb means Megabit
  • To indicate a transmission speed the “per second” postfix is appended
    Example: MBps means Megabytes per second

Now let’s start…

How much Space of my Volume should I use?

You should never use all the available space as this forces the filesystem to split new files into many small junks. These small junks lead to increased seek times and thereby slower transfer rates.

Tipp: Use quotas to limit the user visible size.

How much Storage do I need?

As described above you have to add a little extra space to avoid high seek times.

CodeCogsEqn (7)

How much Hours of Video can I Store on my Volume?

This is often used to find out if there is already enough storage capacity to handle a new project or if you have to add more.

CodeCogsEqn (8)

What Performance do I need?

The first formula calculates the Theoretical Minimum Performance Requirement in MBps. To be honest, it’s a pretty useless calculation as you need a lot more raw storage performance than this formula indicates. For examples it doesn’t take disk seek times or CPU limitations into account.

CodeCogsEqn (4)

For a more realistic estimate use the following one. However this is still just an estimate to get a rough overview. It is very hard to size a video storage correctly and I haven’t found the correct formula yet.

CodeCogsEqn (9)

Can I go with 1Gb Ethernet or do I need 10Gb Ethernet?

Many people think that they have to use 10Gb Ethernet if they want to edit videos using AFP, SMB or NFS. However in reality they often don’t need that much performance and can better spend the money on more storage capacity or better networking infrastructure.

CodeCogsEqn (6)

It’s fine to go with 1Gb Ethernet if the Theoretical Minimum Connection Speed is 850Mbps or less. Go with 10Gb Ethernet as long as you need less than 3000 Mbps otherwise please talk to the system manufacturer.

What Network Protocol should I use?

That’s an easy one: Always use SMB on Linux, OS X and Windows!

(Except if you use OS X in combination with FCPX libraries stored on your NAS than go with NFS)

Nov 102014

Over the last few years I encountered the following QuickTime 7 error message several times while trying to play a file:

The movie could not be opened. The resource map is incorrect

The cause of this message is a broken Resource Fork which is stored within the file’s extended attributes. This error often occurs if the file is or was stored on a network drive or an external disc. It also affect all applications that build upon QuickTime 7’s API. To verify if a file is unplayable because of it’s Resource Fork just try to play it with VLC. It should work fine. If so, it can be fixed.

To make it easy to repair such files I wrote QT7 EA FIX. Just launch the script and drop the broken file. The rest will be handled automatically and you should be able to play the file afterwards.

Screen Shot 2014-10-22 at 14.19.48 Click here to download QT7 EA FIX.command.

Nov 022014

SharedEAStoreExtended attributes on OS X allow applications to store additional metadata along data files. Filesystems like JHFS+ that natively support this feature store this metadata completely hidden from the user. On filesystems that don’t support extended attributes OS X writes this data into Dot Underscore (._) sidecar files. Many people including me have been bugged by this fallback and have searched for ways to remove those files. I described one possible way in my post Win & Mac: Clean Dot Underscore Files. However this post is about a very interesting problem that occurs only if you try to use a Linux server as a fileserver that exposes the same folder for OS X clients using SMB and AFP with extended attribute sharing.

The goal is that whatever network protocol you use you should always see the same data (including it’s metadata). To do that I disabled netatalk’s native EA support (ea = none in afpd.conf). Thereby SMB and AFP use the Dot Underscore fallback. In theory now all OS X clients independently of the network protocol they use should have a consistent view. However that’s only the theory.

If you write extended attributes using SMB and read the data over AFP it get’s scrambled. Here’s an example executed on a mounted SMB sharepoint:

$ xattr -w sh.bogner.test.entry 1234567890abcdef testfile #write EA
$ xattr -l testfile #read EA
	sh.bogner.test.entry: 1234567890abcdef

Up to this point, everything is as expected: We could access the metadata and it was exactly what we put in. However, if you try to read the same metadata over an AFP-mounted sharepoint it’s a completely different picture: The metadata is completely unusable.

4The problem I described here is an issue by itself, however some applications depend on working extended attributes. These applications either don’t work at all or have issues on such storages. Possible solution are to either go with separate EA stores for SMB and AFP, to delete all Dot Underscore files in close-to-realtime or to only use one protocol.