Analyze response headers in Chrome driver

main
ElbertF 13 years ago
parent dd42af58c7
commit 7f50cc97cd

1
.gitignore vendored

@ -1 +0,0 @@
drivers/firefox/wappalyzer.xpi

@ -2,10 +2,9 @@
<html> <html>
<head> <head>
<script src="js/lib/jquery.min.js"></script>
<script src="js/wappalyzer.js"></script> <script src="js/wappalyzer.js"></script>
<script src="js/driver.js"></script>
<script src="js/apps.js"></script> <script src="js/apps.js"></script>
<script src="js/driver.js"></script>
</head> </head>
<body> <body>
<script> <script>

@ -1,85 +1,98 @@
(function() { (function() {
var self = { var c = {
debug: true,
element: false,
prevUrl: '',
init: function() { init: function() {
self.log('init'); c.log('init');
self.onPageLoad(); chrome.extension.sendRequest({ id: 'analyze', subject: { html: document.documentElement.innerHTML } });
},
log: function(message) { c.getEnvironmentVars();
if ( self.debug && message ) { c.getResponseHeaders();
console.log("Wappalyzer content.js: " + message);
}
}, },
onPageLoad: function(e) { log: function(message) {
self.log('onPageLoad'); chrome.extension.sendRequest({ id: 'log', message: '[ content.js ] ' + message });
if ( document.body ) {
self.getEnvironmentVars();
}
}, },
getEnvironmentVars: function() { getEnvironmentVars: function() {
self.log('getEnvironmentVars'); c.log('getEnvironmentVars');
if ( typeof document.documentElement.innerHTML === 'undefined' ) { if ( typeof document.documentElement.innerHTML === 'undefined' ) {
return; return;
} }
var environmentVars = '';
try { try {
var element = document.createElement('wappalyzerData'); var container = document.createElement('wappalyzerData');
element.setAttribute('id', 'wappalyzerData'); container.setAttribute('id', 'wappalyzerData');
element.setAttribute('style', 'display: none'); container.setAttribute('style', 'display: none');
var script = document.createElement('script'); var script = document.createElement('script');
script.setAttribute('id', 'wappalyzerEnvDetection'); script.setAttribute('id', 'wappalyzerEnvDetection');
script.setAttribute('id', 'text/javascript');
script.innerHTML = '(function() {' + script.innerHTML =
'(function() {' +
'try {' + 'try {' +
'var event = document.createEvent("Events");' + 'var i, environmentVars, event = document.createEvent("Events");' +
'event.initEvent("wappalyzerEvent", true, false);' + 'event.initEvent("wappalyzerEvent", true, false);' +
'var environmentVars = "";' + 'for ( i in window ) { environmentVars += i + " "; }' +
'for ( var i in window ) { environmentVars += i + " "; }' +
'document.getElementById("wappalyzerData").appendChild(document.createComment(environmentVars));' + 'document.getElementById("wappalyzerData").appendChild(document.createComment(environmentVars));' +
'document.getElementById("wappalyzerData").dispatchEvent(event);' + 'document.getElementById("wappalyzerData").dispatchEvent(event);' +
'}' + '}' +
'catch(e) { }' + 'catch(e) { }' +
'})();'; '})();';
element.addEventListener('wappalyzerEvent', (function(event) { container.addEventListener('wappalyzerEvent', (function(event) {
environmentVars = event.target.childNodes[0].nodeValue; var environmentVars = event.target.childNodes[0].nodeValue;
self.log('getEnvironmentVars: ' + environmentVars);
document.documentElement.removeChild(element); document.documentElement.removeChild(container);
document.documentElement.removeChild(script); document.documentElement.removeChild(script);
chrome.extension.sendRequest({ c.log('getEnvironmentVars: ' + environmentVars);
html: document.documentElement.innerHTML,
msg: 'analyze', environmentVars = environmentVars.split(' ');
env: environmentVars.split(' ')
}); chrome.extension.sendRequest({ id: 'analyze', subject: { env: environmentVars } });
}), true); }), true);
document.documentElement.appendChild(element); document.documentElement.appendChild(container);
document.documentElement.appendChild(script); document.documentElement.appendChild(script);
} catch(e) { } } catch(e) {
c.log('Error: ' + e);
}
},
getResponseHeaders: function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', window.location, true);
xhr.onreadystatechange = function() {
if ( xhr.readyState === 4 && xhr.status ) {
var headers = xhr.getAllResponseHeaders().split("\n");
if ( headers.length > 0 && headers[0] != '' ) {
c.log('responseHeaders: ' + xhr.getAllResponseHeaders());
var responseHeaders = {};
return environmentVars; headers.forEach(function(line) {
if ( line ) {
name = line.substring(0, line.indexOf(': '));
value = line.substring(line.indexOf(': ') + 2, line.length - 1);
responseHeaders[name] = value;
}
});
chrome.extension.sendRequest({ id: 'analyze', subject: { headers: responseHeaders } });
}
}
}
xhr.send();
} }
} }
self.init(); c.init();
return self;
})(); })();

@ -3,12 +3,11 @@
*/ */
(function() { (function() {
if ( wappalyzer == null ) return; if ( wappalyzer == null ) { return; }
var w = wappalyzer; var w = wappalyzer;
var var
debug = true,
tab, tab,
tabCache = {} tabCache = {}
; ;
@ -18,9 +17,7 @@
* Log messages to console * Log messages to console
*/ */
log: function(args) { log: function(args) {
if ( debug ) { console.log(args.message);
console.log(args.message);
}
}, },
/** /**
@ -32,21 +29,18 @@
chrome.browserAction.setBadgeBackgroundColor({ color: [255, 102, 0, 255] }); chrome.browserAction.setBadgeBackgroundColor({ color: [255, 102, 0, 255] });
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) { chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if ( typeof(request.msg != 'undefined' ) ) { if ( typeof request.id != 'undefined' ) {
w.log('request: ' + request.msg); w.log('request: ' + request.id);
switch ( request.id ) {
case 'log':
w.log(request.message);
switch ( request.msg ) { break;
case 'analyze': case 'analyze':
tab = sender.tab; tab = sender.tab;
chrome.browserAction.setBadgeText({ tabId: tab.id, text: '' }); w.analyze(tab.url, tab.url, request.subject);
tabCache[tab.id] = {
count: 0,
appsDetected: {}
};
w.analyze(tab.url, tab.url, { html: request.html, env: request.env });
break; break;
case 'get_apps': case 'get_apps':
@ -83,180 +77,11 @@
appsDetected: w.detected[tab.url] appsDetected: w.detected[tab.url]
}; };
chrome.browserAction.setBadgeText({ tabId: tab.id, text: count }); if ( count > 0 ) {
}, chrome.browserAction.setBadgeText({ tabId: tab.id, text: count });
};
w.init();
})();
/*
var wappalyzer = (function(){
self = {
debug: false,
tabCache: {},
log: function(message) {
if ( self.debug && message ) {
console.log(message);
} }
}, },
init: function() {
self.log('init');
chrome.browserAction.setBadgeBackgroundColor({ color: [255, 102, 0, 255] });
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if ( typeof(request.msg != 'undefined' ) ) {
self.log('request: ' + request.msg);
switch ( request.msg ) {
case 'analyze':
wappalyzer.analyze(sender.tab.id, sender.tab.url, request.html, request.env);
break;
case 'get_apps':
sendResponse({ tabCache: wappalyzer.tabCache[request.tab.id] });
break;
}
}
});
chrome.tabs.getAllInWindow(null, function(tabs) {
for ( i in tabs ) {
if ( tabs[i].url.match(/https?:\/\//) ) {
chrome.tabs.executeScript(tabs[i].id, { file: 'content.js' });
}
}
});
chrome.tabs.onRemoved.addListener(function(tabId) {
self.log('remove tab');
wappalyzer.tabCache[tabId] = null;
});
},
analyze: function(tabId, url, html, environmentVars) {
var app;
chrome.browserAction.setBadgeText({ tabId: tabId, text: '' });
wappalyzer.tabCache[tabId] = {
count: 0,
appsDetected: {}
};
if ( html && html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
for ( var appName in wappalyzer.apps ) {
app = wappalyzer.apps[appName];
// Scan html
if ( html ) {
if ( typeof(wappalyzer.tabCache[tabId].appsDetected[appName]) == 'undefined' ) {
if ( typeof(app.html) != 'undefined' ) {
var regex = app.html;
if ( regex.test(html) ) {
wappalyzer.register(tabId, appName);
}
}
}
}
// Scan script tags
if ( html && typeof app.script != 'undefined' ) {
var
regex = /<script[^>]+src=("|')([^"']+)\1/ig,
match = []
;
while ( match = regex.exec(html) ) {
if ( app.script.test(match[2]) ) {
wappalyzer.register(tabId, appName);
break;
}
}
}
// Scan meta tags
if ( html && typeof app.meta != 'undefined' ) {
var
regex = /<meta[^>]+>/ig,
match = []
;
while ( match = regex.exec(html) ) {
for ( meta in app.meta ) {
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
var content = match.toString().match(/content=("|')([^"']+)("|')/i);
if ( app.meta[meta].test(content[2]) ) {
wappalyzer.register(tabId, appName);
break;
}
}
}
}
}
// Scan url
if ( typeof(wappalyzer.tabCache[tabId].appsDetected[appName]) == 'undefined' ) {
if ( url && typeof(app.url) != 'undefined' ) {
var regex = app.url;
if ( regex.test(url) ) {
wappalyzer.register(tabId, appName);
}
}
}
// Scan environment variables
if ( typeof(wappalyzer.tabCache[tabId].appsDetected[appName]) == 'undefined' ) {
if ( environmentVars && typeof app.env != 'undefined' ) {
var regex = app.env;
for ( var i in environmentVars ) {
try {
if ( regex.test(environmentVars[i]) ) {
wappalyzer.register(tabId, appName);
}
}
catch(e) { }
}
}
}
}
html = null;
},
register: function(tabId, appName) {
wappalyzer.tabCache[tabId].appsDetected[appName] = {
cats: {},
name: appName
};
for ( cat in wappalyzer.apps[appName].cats ) {
wappalyzer.tabCache[tabId].appsDetected[appName].cats[cat] = wappalyzer.cats[wappalyzer.apps[appName].cats[cat]];
}
wappalyzer.tabCache[tabId].count = 0;
for ( i in wappalyzer.tabCache[tabId].appsDetected ) {
wappalyzer.tabCache[tabId].count ++;
}
chrome.browserAction.setBadgeText({ tabId: tabId, text: wappalyzer.tabCache[tabId].count.toString() });
}
}; };
return self; w.init();
})(); })();
*/

@ -0,0 +1,31 @@
categoryNames = {
1: 'CMS',
2: 'Message Board',
3: 'Database Manager',
4: 'Documentation Tool',
5: 'Widget',
6: 'Web Shop',
7: 'Photo Gallery',
8: 'Wiki',
9: 'Hosting Panel',
10: 'Analytics',
11: 'Blog',
12: 'Javascript Framework',
13: 'Issue Tracker',
14: 'Video Player',
15: 'Comment System',
16: 'Captcha',
17: 'Font Script',
18: 'Web Framework',
19: 'Miscellaneous',
20: 'Editor',
21: 'LMS',
22: 'Web Server',
23: 'Cache Tool',
24: 'Rich Text Editor',
25: 'Javascript Graphics',
26: 'Mobile Framework',
27: 'Programming Language',
28: 'Operating System',
29: 'Search Engine'
};

@ -4,7 +4,7 @@
"32": "images/icon_32.png", "32": "images/icon_32.png",
"128": "images/icon_128.png" "128": "images/icon_128.png"
}, },
"version": "0.6", "version": "0.8",
"description": "Identifies software on the web", "description": "Identifies software on the web",
"browser_action": { "browser_action": {
"default_icon": "images/icon_32.png", "default_icon": "images/icon_32.png",

@ -6,66 +6,30 @@
<script> <script>
var wappalyzer = {}; var wappalyzer = {};
categoryNames = {
1: 'CMS',
2: 'Message Boards',
3: 'Database Managers',
4: 'Documentation Tools',
5: 'Widgets',
6: 'Web Shops',
7: 'Photo Galleries',
8: 'Wikis',
9: 'Hosting Panels',
10: 'Analytics',
11: 'Blogs',
12: 'Javascript Frameworks',
13: 'Issue Trackers',
14: 'Video Players',
15: 'Comment Systems',
16: 'Captchas',
17: 'Font Scripts',
18: 'Web Frameworks',
19: 'Miscellaneous',
20: 'Editors',
21: 'LMS',
22: 'Web Servers',
23: 'Cache Tools',
24: 'Rich Text Editors',
25: 'Javascript Graphics',
26: 'Mobile Frameworks',
27: 'Programming Languages',
28: 'Operating Systems',
29: 'Search Engines'
};
</script> </script>
<script src="js/lib/jquery.min.js"></script>
<script src="js/apps.js"></script> <script src="js/apps.js"></script>
<script src="js/locale.js"></script>
</head> </head>
<body> <body>
<div id="detected-apps"></div> <div id="detected-apps"></div>
<script> <script>
console.log('popup.html'); $('#detected-apps').html('<div class="empty">No applications detected.</div>');
var detectedApps = document.getElementById('detected-apps');
detectedApps.innerHTML = '<div class="empty">No applications detected.</div>';
chrome.tabs.getSelected(null, function(tab) { chrome.tabs.getSelected(null, function(tab) {
chrome.extension.sendRequest({ msg: 'get_apps', tab: tab }, function(response) { chrome.extension.sendRequest({ id: 'get_apps', tab: tab }, function(response) {
if ( response.tabCache.count ) { if ( response.tabCache.count > 0 ) {
while ( detectedApps.childNodes.length > 0 ) { $('#detected-apps').html('');
detectedApps.removeChild(detectedApps.childNodes.item(0));
}
response.tabCache.appsDetected.map(function(appName) { response.tabCache.appsDetected.map(function(appName) {
html = html =
'<a target="_blank" href="http://wappalyzer.com/applications/' + encodeURIComponent(appName) + '">' + '<div class="detected-app">' +
'<img src="images/icons/' + appName + '.png"/>' + '<a target="_blank" href="http://wappalyzer.com/applications/' + encodeURIComponent(appName) + '">' +
'<span class="label">' + appName + '</span>' + '<img src="images/icons/' + appName + '.png"/>' +
'</a>' '<span class="label">' + appName + '</span>' +
; '</a>';
wappalyzer.apps[appName].cats.map(function(cat) { wappalyzer.apps[appName].cats.map(function(cat) {
html += html +=
@ -74,15 +38,11 @@
'</a>'; '</a>';
}); });
html += '</a>'; html +=
'</a>' +
var e = document.createElement('div'); '</div>';
e.setAttribute('class', 'detected-app');
e.innerHTML = html;
detectedApps.appendChild(e); $('#detected-apps').append(html);
}); });
} }
}); });

@ -0,0 +1 @@
wappalyzer.xpi