parent
14c537fbc0
commit
9e9555ecdc
@ -1,19 +1,9 @@
|
|||||||
.vagrant
|
.vagrant
|
||||||
|
|
||||||
build/*
|
build/*
|
||||||
|
|
||||||
drivers/npm/node_modules
|
|
||||||
drivers/npm/npm-debug.log
|
|
||||||
|
|
||||||
src/icons/converted/*
|
src/icons/converted/*
|
||||||
|
|
||||||
package.json
|
node_modules
|
||||||
node_modules/
|
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
|
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
apps.json
|
|
||||||
images/icons/*.png
|
|
||||||
images/icons/*.svg
|
|
||||||
js/wappalyzer.js
|
|
Before Width: | Height: | Size: 9.5 KiB |
@ -1,30 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Wappalyzer</title>
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="images/icon.png"/>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="js/wappalyzer.js"></script>
|
|
||||||
<script type="text/javascript" src="js/driver.js"></script>
|
|
||||||
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
font-family: Verdana, Arial, sans-serif;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#apps {
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#apps img {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="apps"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,67 +0,0 @@
|
|||||||
(function() {
|
|
||||||
if ( wappalyzer == null ) { return };
|
|
||||||
|
|
||||||
var w = wappalyzer;
|
|
||||||
|
|
||||||
w.driver = {
|
|
||||||
/**
|
|
||||||
* Log messages to console
|
|
||||||
*/
|
|
||||||
log: function(args) {
|
|
||||||
if ( console != null ) { console[args.type](args.message) };
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize
|
|
||||||
*/
|
|
||||||
init: function() {
|
|
||||||
// Load apps.json
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhr.open('GET', 'apps.json', true);
|
|
||||||
|
|
||||||
xhr.overrideMimeType('application/json');
|
|
||||||
|
|
||||||
xhr.onload = function() {
|
|
||||||
var json = JSON.parse(xhr.responseText);
|
|
||||||
|
|
||||||
w.categories = json.categories;
|
|
||||||
w.apps = json.apps;
|
|
||||||
|
|
||||||
window.document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
w.analyze('google.com', 'http://google.com', {
|
|
||||||
html: '<script src="jquery.js"><meta name="generator" content="WordPress"/>',
|
|
||||||
headers: { 'Server': 'Apache' },
|
|
||||||
env: [ 'Mootools' ]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.send(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display apps
|
|
||||||
*/
|
|
||||||
displayApps: function() {
|
|
||||||
var
|
|
||||||
app,
|
|
||||||
url = Object.keys(w.detected)[0];
|
|
||||||
|
|
||||||
document.getElementById('apps').innerHTML = '';
|
|
||||||
|
|
||||||
for ( app in w.detected[url] ) {
|
|
||||||
document.getElementById('apps').innerHTML += '<img src="images/icons/' + w.apps[app].icon + '" width="16" height="16"/> ' + app + '<br/>';
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go to URL
|
|
||||||
*/
|
|
||||||
goToURL: function(args) {
|
|
||||||
window.open(args.url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
w.init();
|
|
||||||
})();
|
|
@ -1,14 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = tab
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.{js,py}]
|
|
||||||
charset = utf-8
|
|
||||||
|
|
||||||
[*.py]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
@ -1,3 +0,0 @@
|
|||||||
wappalyzer.js
|
|
||||||
apps.json
|
|
||||||
node_modules/
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"node" : true,
|
|
||||||
"browser" : "false",
|
|
||||||
"predef": []
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
# Wappalyzer
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Install wappalyzer from NPM with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install wappalyzer
|
|
||||||
```
|
|
||||||
## Quickstart
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// load in the lib
|
|
||||||
var wappalyzer = require("wappalyzer");
|
|
||||||
|
|
||||||
// set our options
|
|
||||||
var options={
|
|
||||||
|
|
||||||
url : "http://codelanka.github.io/Presentation-Engines",
|
|
||||||
hostname:"codelanka.github.io",
|
|
||||||
debug:false
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// detect from the url directly, library will make a request
|
|
||||||
wappalyzer.detectFromUrl(options,function (err,apps,appInfo) {
|
|
||||||
|
|
||||||
// output for the test
|
|
||||||
console.dir(apps);
|
|
||||||
console.dir(appInfo);
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
// sample data
|
|
||||||
var data = {
|
|
||||||
|
|
||||||
url: options.url,
|
|
||||||
headers: {
|
|
||||||
|
|
||||||
test: 1
|
|
||||||
|
|
||||||
},
|
|
||||||
html: '<p>HTML CONTENT OF PAGE HERE</p>'
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// detect from content you have already
|
|
||||||
wappalyzer.detectFromHTML(options,function (err,apps,appInfo) {
|
|
||||||
|
|
||||||
// output for the test
|
|
||||||
console.dir(apps);
|
|
||||||
console.log(appInfo);
|
|
||||||
|
|
||||||
})
|
|
||||||
```
|
|
||||||
### Output from QuickStart
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
|
|
||||||
// Apps
|
|
||||||
[
|
|
||||||
'CloudFlare',
|
|
||||||
'Font Awesome',
|
|
||||||
'Google Maps',
|
|
||||||
'Modernizr',
|
|
||||||
'Nginx',
|
|
||||||
'RequireJS',
|
|
||||||
'jQuery'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Detailed info on links
|
|
||||||
{
|
|
||||||
CloudFlare: {
|
|
||||||
app: 'CloudFlare',
|
|
||||||
confidence: { 'headers Server /cloudflare/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '',
|
|
||||||
versions: []
|
|
||||||
},
|
|
||||||
'Font Awesome': {
|
|
||||||
app: 'Font Awesome',
|
|
||||||
confidence: { 'html /<link[^>]* href=[^>]+font-awesome(?:\.min)?\.css/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '',
|
|
||||||
versions: []
|
|
||||||
},
|
|
||||||
'Google Maps': {
|
|
||||||
app: 'Google Maps',
|
|
||||||
confidence: { 'script ///maps.googleapis.com/maps/api/js/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '',
|
|
||||||
versions: []
|
|
||||||
},
|
|
||||||
'Modernizr': {
|
|
||||||
app: 'Modernizr',
|
|
||||||
confidence: { 'script /modernizr(?:-([\d.]*[\d]))?.*\.js/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '2.6.2',
|
|
||||||
versions: [ '2.6.2' ]
|
|
||||||
},
|
|
||||||
'Nginx': {
|
|
||||||
app: 'Nginx',
|
|
||||||
confidence: { 'headers Server /nginx(?:/([\d.]+))?/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '',
|
|
||||||
versions: []
|
|
||||||
},
|
|
||||||
'RequireJS': {
|
|
||||||
app: 'RequireJS',
|
|
||||||
confidence: { 'script /require.*\.js/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '',
|
|
||||||
versions: []
|
|
||||||
},
|
|
||||||
'jQuery': {
|
|
||||||
app: 'jQuery',
|
|
||||||
confidence:
|
|
||||||
{ 'script //([\d.]+)/jquery(\.min)?\.js/i': 100,
|
|
||||||
'script /jquery.*\.js/i': 100 },
|
|
||||||
confidenceTotal: 100,
|
|
||||||
detected: true,
|
|
||||||
excludes: [],
|
|
||||||
version: '1.10.1',
|
|
||||||
versions: [ '1.10.1' ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
## Credits
|
|
||||||
|
|
||||||
### Wappalyzer Author - Elbert Alias
|
|
||||||
|
|
||||||
[Wappalyzer](https://wappalyzer.com/) is a
|
|
||||||
[cross-platform](https://github.com/AliasIO/Wappalyzer/wiki/Drivers) utility that uncovers the
|
|
||||||
technologies used on websites. It detects
|
|
||||||
[content management systems](https://wappalyzer.com/categories/cms),
|
|
||||||
[eCommerce platforms](https://wappalyzer.com/categories/ecommerce),
|
|
||||||
[web servers](https://wappalyzer.com/categories/web-servers),
|
|
||||||
[JavaScript frameworks](https://wappalyzer.com/categories/javascript-frameworks),
|
|
||||||
[analytics tools](https://wappalyzer.com/categories/analytics) and
|
|
||||||
[many more](https://wappalyzer.com/applications).
|
|
||||||
|
|
||||||
Refer to the [wiki](https://github.com/AliasIO/Wappalyzer/wiki) for
|
|
||||||
[screenshots](https://github.com/AliasIO/Wappalyzer/wiki/Screenshots), information on how to
|
|
||||||
[contribute](https://github.com/AliasIO/Wappalyzer/wiki/Contributing) and
|
|
||||||
[more](https://github.com/AliasIO/Wappalyzer/wiki/_pages).
|
|
||||||
|
|
||||||
### NPM Module
|
|
||||||
|
|
||||||
* [Pasindu De Silva](https://github.com/pasindud) - Initial version with tests
|
|
||||||
* [Johann du Toit](http://johanndutoit.net) from [Passmarked](http://passmarked.com) - Updated to support just passing data and helped publish to NPMJS
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
*Licensed under the [GPL](https://github.com/AliasIO/Wappalyzer/blob/master/LICENSE).*
|
|
||||||
|
|
||||||
## Donations
|
|
||||||
|
|
||||||
Donate Bitcoin: 16gb4uGDAjaeRJwKVmKr2EXa8x2fmvT8EQ - *Thanks!*
|
|
||||||
|
|
||||||
![QR Code](https://wappalyzer.com/sites/default/themes/wappalyzer/images/bitcoinqrcode.png)
|
|
@ -1,11 +0,0 @@
|
|||||||
var wappalyzer = require("./index");
|
|
||||||
|
|
||||||
var options={
|
|
||||||
url : "http://codelanka.github.io/Presentation-Engines",
|
|
||||||
hostname:"codelanka.github.io",
|
|
||||||
debug:false
|
|
||||||
}
|
|
||||||
|
|
||||||
wappalyzer.detectFromUrl(options,function (err,apps,appInfo) {
|
|
||||||
console.log(err,apps,appInfo);
|
|
||||||
})
|
|
@ -1,151 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var request = require('request');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the actual detection with information passed
|
|
||||||
**/
|
|
||||||
exports.detect = function(options, data, cb) {
|
|
||||||
|
|
||||||
// run the wrapper function that will
|
|
||||||
// trigger the actual library to run
|
|
||||||
runWrappalyer(options, data, cb);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wraps the detect method, just kept to reuse old method names
|
|
||||||
* and not break anything. Although this was just stubbed out.
|
|
||||||
**/
|
|
||||||
exports.detectFromHTML = function(options, data, cb) {
|
|
||||||
|
|
||||||
// run the detect method
|
|
||||||
exports.detect(options, data, cb);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do a actual request for the body & headers, then
|
|
||||||
* run through detection
|
|
||||||
**/
|
|
||||||
exports.detectFromUrl = function(options, cb) {
|
|
||||||
|
|
||||||
// ensure options and url were
|
|
||||||
if(!options || !options.url) {
|
|
||||||
|
|
||||||
// send back a error ...
|
|
||||||
cb(new Error("\"url\" is a required option to run"
|
|
||||||
+ " wappalyzer and get the page content"))
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// local variables to
|
|
||||||
var url = options.url;
|
|
||||||
|
|
||||||
// get the body content from the url
|
|
||||||
getHTMLFromUrl(url, function(err, data) {
|
|
||||||
|
|
||||||
// check for error or if we got no data back
|
|
||||||
if (err || data === null) {
|
|
||||||
|
|
||||||
// handle the error and don't do anything else ..
|
|
||||||
cb(err, null);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// run actual detection
|
|
||||||
exports.detect(options, data, cb);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getHTMLFromUrl(url, cb) {
|
|
||||||
request(url, function(error, response, body) {
|
|
||||||
if (!error && response.statusCode == 200) {
|
|
||||||
var data = {
|
|
||||||
html: body,
|
|
||||||
url: url,
|
|
||||||
headers: response.headers
|
|
||||||
};
|
|
||||||
cb(null, data);
|
|
||||||
} else {
|
|
||||||
cb(error, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAppsJson(cb) {
|
|
||||||
|
|
||||||
// depending on evironment select a direction to the path
|
|
||||||
var appsFileStr = path.resolve(__dirname, './apps.json');
|
|
||||||
|
|
||||||
// handle the environment variable if it's there
|
|
||||||
if(process.env.NODE_ENV == 'testing') {
|
|
||||||
|
|
||||||
// set the apps.json to testing stage
|
|
||||||
appsFileStr = path.resolve(__dirname, '../../apps.json');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// read in the file
|
|
||||||
fs.readFile(appsFileStr, 'utf8', function(err, data) {
|
|
||||||
if (err) throw err;
|
|
||||||
return cb(null, JSON.parse(data));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runWrappalyer(options, data, cb) {
|
|
||||||
var debug = options.debug || false;
|
|
||||||
|
|
||||||
// according to environment check it
|
|
||||||
var wappalyzer = null;
|
|
||||||
|
|
||||||
// change depending on the environment
|
|
||||||
if( process.env.NODE_ENV == 'testing' ) {
|
|
||||||
|
|
||||||
wappalyzer = require('../../wappalyzer').wappalyzer;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
wappalyzer = require('./wappalyzer').wappalyzer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getAppsJson(function(err, apps) {
|
|
||||||
var w = wappalyzer;
|
|
||||||
w.driver = {
|
|
||||||
log: function(args) {
|
|
||||||
if (debug) {
|
|
||||||
console.log(args.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
w.categories = apps.categories;
|
|
||||||
w.apps = apps.apps;
|
|
||||||
},
|
|
||||||
displayApps: function() {
|
|
||||||
var app, url = Object.keys(w.detected)[0];
|
|
||||||
var detectedApps = [];
|
|
||||||
|
|
||||||
for (app in w.detected[url]) {
|
|
||||||
detectedApps.push(app);
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
console.log(app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cb(null, detectedApps, w.detected[url]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
w.init();
|
|
||||||
w.detected = [];
|
|
||||||
w.analyze(options.hostname, options.url, data);
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "wappalyzer",
|
|
||||||
"version": "2.0.3",
|
|
||||||
"description": "NPM Module that uncovers the technologies used on websites",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "NODE_ENV=testing mocha -t 15000"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/AliasIO/Wappalyzer"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"wappalyzer",
|
|
||||||
"detect",
|
|
||||||
"stack",
|
|
||||||
"technologies"
|
|
||||||
],
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Pasindu De Silva"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Johann du Toit"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"author": "Elbert Alias",
|
|
||||||
"license": "GPLv3",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/AliasIO/Wappalyzer/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/AliasIO/Wappalyzer",
|
|
||||||
"directories": {
|
|
||||||
"test": "test"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"request": "^2.51.0"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"Date":"Fri, 17 Jul 2015 11:05:08 GMT",
|
|
||||||
"Content-Encoding":"gzip",
|
|
||||||
"Age":"0",
|
|
||||||
"X-Cache":"MISS",
|
|
||||||
"Connection":"keep-alive",
|
|
||||||
"Content-Length":"1940",
|
|
||||||
"Via":"1.1 varnish",
|
|
||||||
"X-Served-By":"cache-lcy1122-LCY",
|
|
||||||
"Last-Modified":"Thu, 16 Apr 2015 14:24:18 GMT",
|
|
||||||
"Server":"GitHub.com",
|
|
||||||
"X-Timer":"S1437131108.300792,VS0,VE84",
|
|
||||||
"Vary":"Accept-Encoding",
|
|
||||||
"Content-Type":"text/html; charset=utf-8",
|
|
||||||
"Access-Control-Allow-Origin":"*",
|
|
||||||
"Expires":"Fri, 17 Jul 2015 11:10:54 GMT",
|
|
||||||
"Cache-Control":"max-age=600",
|
|
||||||
"Accept-Ranges":"bytes",
|
|
||||||
"X-Cache-Hits":"0"
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" ng-app="presen" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>Preso Engines | CodeLanka</title>
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
|
||||||
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
|
|
||||||
<script src="//code.jquery.com/jquery.js"></script>
|
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
|
|
||||||
<link href='//fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'>
|
|
||||||
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(function () {
|
|
||||||
"use strict";
|
|
||||||
var $bgobj = $(".ha-bg-parallax"); // assigning the object
|
|
||||||
$(window).on("scroll", function () {
|
|
||||||
var yPos = -($(window).scrollTop() / $bgobj.data('speed'));
|
|
||||||
// Put together our final background position
|
|
||||||
var coords = '100% ' + yPos + 'px';
|
|
||||||
// Move the background
|
|
||||||
$bgobj.css({ backgroundPosition: coords });
|
|
||||||
});
|
|
||||||
$('div.product-chooser').not('.disabled').find('div.product-chooser-item').on('click', function(){
|
|
||||||
$(this).parent().parent().find('div.product-chooser-item').removeClass('selected');
|
|
||||||
$(this).addClass('selected');
|
|
||||||
$(this).find('input[type="radio"]').prop("checked", true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div>
|
|
||||||
<div class="ha-bg-parallax text-center block-marginb-none" data-type="background" data-speed="20">
|
|
||||||
<div class="ha-parallax-body">
|
|
||||||
<div class="ha-content ha-content-whitecolor">
|
|
||||||
<h1 id="headernav">Preso Engines</h1>
|
|
||||||
"Presentation Engines"
|
|
||||||
</div>
|
|
||||||
<div class="ha-parallax-divider-wrapper">
|
|
||||||
<span class="ha-diamond-divider-md img-responsive"></span>
|
|
||||||
</div>
|
|
||||||
<div class="ha-heading-parallax">By | CodeLanka</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container" ng-controller="presentationController">
|
|
||||||
<h2></h2>
|
|
||||||
<div class="row form-group product-chooser">
|
|
||||||
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4"
|
|
||||||
ng-repeat="presentation in presentations">
|
|
||||||
<div class="product-chooser-item">
|
|
||||||
<div class="col-xs-8 col-sm-8 col-md-12 col-lg-12">
|
|
||||||
<hr/>
|
|
||||||
<span class="title">
|
|
||||||
{{presentation.name}}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="website">
|
|
||||||
<a href="{{presentation.website}}">{{presentation.website}}</a>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="description">
|
|
||||||
{{presentation.description}}</span>
|
|
||||||
<input type="radio" name="product" value="mobile_desktop"
|
|
||||||
checked="checked">
|
|
||||||
<hr/>
|
|
||||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
|
||||||
<i class="fa fa-star"></i>
|
|
||||||
<h2>{{presentation.stargazers_count}}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
|
||||||
<i class="fa fa-users"></i>
|
|
||||||
<h2>{{presentation.watchers_count}}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
|
||||||
<i class="fa fa-bug"></i>
|
|
||||||
<h2>{{presentation.open_issues_count}}</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="clear"></div>
|
|
||||||
<hr>
|
|
||||||
<p>Github -
|
|
||||||
<a href="http://github.com/{{presentation.github}}">{{presentation.github}}</a>
|
|
||||||
</p>
|
|
||||||
<p>Demo -
|
|
||||||
<a href="{{presentation.demo}}">{{presentation.demo}}</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>License - {{presentation.license}} </p>
|
|
||||||
|
|
||||||
<p>Language - {{presentation.language}} </p>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- jQuery -->
|
|
||||||
<!-- Bootstrap JavaScript -->
|
|
||||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var phonecatApp = angular.module('presen', []);
|
|
||||||
phonecatApp.controller('presentationController', function ($scope,$http) {
|
|
||||||
|
|
||||||
var github = "https://api.github.com/repos/";
|
|
||||||
|
|
||||||
$http.get('data.json').
|
|
||||||
success(function(data, status, headers, config) {
|
|
||||||
$scope.presentations=data.engines;
|
|
||||||
|
|
||||||
for (var i = data.engines.length - 1; i >= 0; i--) {
|
|
||||||
$scope.presentations[i].stargazers_count=0;
|
|
||||||
$scope.presentations[i].watchers_count=0;
|
|
||||||
$scope.presentations[i].open_issues_count=0;
|
|
||||||
|
|
||||||
(function(no){
|
|
||||||
var githuburl = github+data.engines[no].github;
|
|
||||||
|
|
||||||
$http.get(githuburl)
|
|
||||||
.success(function(data, status, headers, config) {
|
|
||||||
$scope.presentations[no].stargazers_count=data.stargazers_count;
|
|
||||||
$scope.presentations[no].watchers_count=data.watchers_count;
|
|
||||||
$scope.presentations[no].open_issues_count=data.open_issues_count;
|
|
||||||
|
|
||||||
})
|
|
||||||
.error(function(data, status, headers, config) {});
|
|
||||||
}(i));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}).
|
|
||||||
error(function(data, status, headers, config) {});
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,65 +0,0 @@
|
|||||||
var assert = require("assert")
|
|
||||||
var fs = require('fs')
|
|
||||||
|
|
||||||
describe('wappalyzer', function(){
|
|
||||||
describe('detectFromUrl', function(){
|
|
||||||
it('should have the expected apps detected', function(done){
|
|
||||||
|
|
||||||
var wappalyzer = require("../index");
|
|
||||||
|
|
||||||
var expect = ['AngularJS','Font Awesome','Google Font API','Twitter Bootstrap','jQuery'];
|
|
||||||
|
|
||||||
var options={
|
|
||||||
url : "http://codelanka.github.io/Presentation-Engines",
|
|
||||||
hostname:"codelanka.github.io",
|
|
||||||
debug:false
|
|
||||||
}
|
|
||||||
|
|
||||||
wappalyzer.detectFromUrl(options,function (err,apps) {
|
|
||||||
assert.equal(expect[0], apps[0]);
|
|
||||||
assert.equal(expect[1], apps[1]);
|
|
||||||
assert.equal(expect[2], apps[2]);
|
|
||||||
assert.equal(expect[3], apps[3]);
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('detectFromHTML', function(){
|
|
||||||
it('should have the expected apps detected when passed raw info', function(done){
|
|
||||||
|
|
||||||
var wappalyzer = require("../index");
|
|
||||||
|
|
||||||
var expect = ['AngularJS','Font Awesome','Google Font API','Twitter Bootstrap','jQuery'];
|
|
||||||
|
|
||||||
var options={
|
|
||||||
url : "http://codelanka.github.io/Presentation-Engines",
|
|
||||||
hostname:"codelanka.github.io",
|
|
||||||
debug:false
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
|
|
||||||
url: options.url,
|
|
||||||
headers: require('./sample.headers.json'),
|
|
||||||
html: fs.readFileSync('./test/sample.html').toString(),
|
|
||||||
headers: {
|
|
||||||
|
|
||||||
headers: {}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
wappalyzer.detectFromHTML(options, data, function (err,apps) {
|
|
||||||
|
|
||||||
assert.equal(expect[0], apps[0]);
|
|
||||||
assert.equal(expect[1], apps[1]);
|
|
||||||
assert.equal(expect[2], apps[2]);
|
|
||||||
assert.equal(expect[3], apps[3]);
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,30 +1,31 @@
|
|||||||
FROM phusion/baseimage
|
FROM ubuntu:latest
|
||||||
|
|
||||||
MAINTAINER Elbert Alias <elbert@alias.io>
|
MAINTAINER Elbert Alias <elbert@alias.io>
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN sed -i 's/archive\.ubuntu\.com/au.archive.ubuntu.com/g' /etc/apt/sources.list
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && apt-get install -y \
|
apt-get update && apt-get install -y \
|
||||||
bzip2 \
|
|
||||||
libfreetype6 \
|
libfreetype6 \
|
||||||
libfontconfig \
|
libfontconfig \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
WORKDIR /usr/local
|
RUN ln -s $(which nodejs) /usr/bin/node
|
||||||
|
|
||||||
# PhantomJS
|
RUN mkdir /usr/local/wappalyzer
|
||||||
RUN \
|
|
||||||
mkdir phantomjs && \
|
|
||||||
curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2 | tar xvjC phantomjs --strip 1
|
|
||||||
|
|
||||||
# Wappalyzer
|
WORKDIR /usr/local/wappalyzer
|
||||||
RUN \
|
|
||||||
mkdir wappalyzer && \
|
|
||||||
curl -sSL https://github.com/AliasIO/Wappalyzer/archive/master.tar.gz | tar xzC wappalyzer --strip 1
|
|
||||||
|
|
||||||
RUN wappalyzer/bin/wappalyzer-links wappalyzer
|
ADD apps.json .
|
||||||
|
ADD driver.js .
|
||||||
|
ADD index.js .
|
||||||
|
ADD package.json .
|
||||||
|
ADD wappalyzer.js .
|
||||||
|
|
||||||
WORKDIR wappalyzer/src/drivers/phantomjs
|
RUN npm i
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/phantomjs/bin/phantomjs", "--load-images=false", "--ignore-ssl-errors=yes", "--ssl-protocol=any", "driver.js"]
|
ENTRYPOINT ["node", "index.js"]
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
# Wappalyzer
|
||||||
|
|
||||||
|
[Wappalyzer](https://wappalyzer.com/) is a
|
||||||
|
[cross-platform](https://github.com/AliasIO/Wappalyzer/wiki/Drivers) utility that uncovers the
|
||||||
|
technologies used on websites. It detects
|
||||||
|
[content management systems](https://wappalyzer.com/categories/cms),
|
||||||
|
[eCommerce platforms](https://wappalyzer.com/categories/ecommerce),
|
||||||
|
[web servers](https://wappalyzer.com/categories/web-servers),
|
||||||
|
[JavaScript frameworks](https://wappalyzer.com/categories/javascript-frameworks),
|
||||||
|
[analytics tools](https://wappalyzer.com/categories/analytics) and
|
||||||
|
[many more](https://wappalyzer.com/applications).
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ npm i wappalyzer
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Run from the command line
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ node index.js https://wappalyzer.com --quiet
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Run from a script
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const wappalyzer = require('@wappalyzer/wappalyzer');
|
||||||
|
|
||||||
|
wappalyzer.run(['https://wappalyzer.com', '--quiet'], function(stdout, stderr) {
|
||||||
|
if ( stdout ) {
|
||||||
|
process.stdout.write(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stderr ) {
|
||||||
|
process.stderr.write(stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Arguments
|
||||||
|
|
||||||
|
**-v, --verbose**
|
||||||
|
|
||||||
|
Display debug output.
|
||||||
|
|
||||||
|
**-q, --quiet**
|
||||||
|
|
||||||
|
Suppress errors.
|
||||||
|
|
||||||
|
**--resource-timeout=ms**
|
||||||
|
|
||||||
|
Abort the connection after 'ms' milliseconds.
|
@ -0,0 +1,32 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const
|
||||||
|
path = require('path'),
|
||||||
|
spawn = require('child_process').spawn,
|
||||||
|
phantomjs = require('phantomjs-prebuilt');
|
||||||
|
|
||||||
|
exports.run = function(args, callback) {
|
||||||
|
args.push.apply(['--web-security=no', '--load-images=false', '--ignore-ssl-errors=yes', '--ssl-protocol=any']);
|
||||||
|
|
||||||
|
var driver = phantomjs.exec('driver.js', args);
|
||||||
|
|
||||||
|
driver.stdout.on('data', (data) => {
|
||||||
|
callback(`${data}`, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
driver.stderr.on('data', (data) => {
|
||||||
|
callback(null, `${data}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !module.parent ) {
|
||||||
|
exports.run(process.argv.slice(2), function(stdout, stderr) {
|
||||||
|
if ( stdout ) {
|
||||||
|
process.stdout.write(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stderr ) {
|
||||||
|
process.stderr.write(stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "wappalyzer",
|
||||||
|
"description": "Uncovers the technologies used on websites",
|
||||||
|
"homepage": "https://github.com/AliasIO/Wappalyzer",
|
||||||
|
"version": "3.0.3",
|
||||||
|
"author": "Elbert Alias",
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/AliasIO/Wappalyzer"
|
||||||
|
},
|
||||||
|
"main": "index.js",
|
||||||
|
"files": [
|
||||||
|
"apps.json",
|
||||||
|
"driver.js",
|
||||||
|
"wappalyzer.js"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"phantomjs-prebuilt": "*"
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
js/wappalyzer.js
|
|
||||||
apps.json
|
|
@ -1,193 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Wappalyzer
|
|
||||||
{
|
|
||||||
public
|
|
||||||
$debug = false,
|
|
||||||
$curlUserAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1',
|
|
||||||
$curlFollowLocation = true,
|
|
||||||
$curlTimeout = 5,
|
|
||||||
$curlMaxRedirects = 3
|
|
||||||
;
|
|
||||||
|
|
||||||
protected
|
|
||||||
$v8,
|
|
||||||
$apps,
|
|
||||||
$categories
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
public function __construct($url)
|
|
||||||
{
|
|
||||||
chdir(dirname(__FILE__));
|
|
||||||
|
|
||||||
$this->v8 = new V8Js();
|
|
||||||
|
|
||||||
$this->url = $url;
|
|
||||||
|
|
||||||
$json = json_decode(file_get_contents('apps.json'));
|
|
||||||
|
|
||||||
$this->apps = $json->apps;
|
|
||||||
$this->categories = $json->categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyze a website
|
|
||||||
* @param string $url
|
|
||||||
*/
|
|
||||||
public function analyze()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$this->load(array('wappalyzer.js', 'driver.js'));
|
|
||||||
|
|
||||||
$result = $this->curl($this->url);
|
|
||||||
|
|
||||||
//$env = $this->executeScripts($result);
|
|
||||||
|
|
||||||
$json = json_encode(array(
|
|
||||||
'host' => $result->host,
|
|
||||||
'url' => $result->url,
|
|
||||||
'html' => $result->html,
|
|
||||||
'headers' => $result->headers,
|
|
||||||
//'env' => $env
|
|
||||||
));
|
|
||||||
|
|
||||||
$result = $this->v8->executeString('
|
|
||||||
w.apps = ' . json_encode($this->apps) . ';
|
|
||||||
w.categories = ' . json_encode($this->categories) . ';
|
|
||||||
w.driver.debug = ' . ( $this->debug ? 'true' : 'false' ) . ';
|
|
||||||
w.driver.data = ' . $json . ';
|
|
||||||
|
|
||||||
w.driver.init();
|
|
||||||
');
|
|
||||||
|
|
||||||
return json_decode($result);
|
|
||||||
} catch ( V8JsException $e ) {
|
|
||||||
throw new WappalyzerException('JavaScript error: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load and execute one or more JavaScript files
|
|
||||||
* @param mixed $files
|
|
||||||
*/
|
|
||||||
protected function load($files)
|
|
||||||
{
|
|
||||||
if ( !is_array($files) ) {
|
|
||||||
$files = array($files);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ( $files as $file ) {
|
|
||||||
$this->v8->executeString(file_get_contents('js/' . $file), $file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a cURL request
|
|
||||||
* @param string $url
|
|
||||||
*/
|
|
||||||
protected function curl($url)
|
|
||||||
{
|
|
||||||
if ( $this->debug ) {
|
|
||||||
echo 'cURL request: ' . $url . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$ch = curl_init($url);
|
|
||||||
|
|
||||||
curl_setopt_array($ch, array(
|
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
|
||||||
CURLOPT_HEADER => true,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_FOLLOWLOCATION => $this->curlFollowLocation,
|
|
||||||
CURLOPT_MAXREDIRS => $this->curlMaxRedirects,
|
|
||||||
CURLOPT_TIMEOUT => $this->curlTimeout,
|
|
||||||
CURLOPT_USERAGENT => $this->curlUserAgent
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
|
|
||||||
if ( curl_errno($ch) !== 0 ) {
|
|
||||||
throw new WappalyzerException('cURL error: ' . curl_error($ch));
|
|
||||||
}
|
|
||||||
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
if ( $httpCode != 200 ) {
|
|
||||||
throw new WappalyzerException('cURL request returned HTTP code ' . $httpCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = new stdClass();
|
|
||||||
|
|
||||||
$result->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
|
||||||
|
|
||||||
$result->host = parse_url($result->url, PHP_URL_HOST);
|
|
||||||
|
|
||||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
|
||||||
|
|
||||||
$result->html = substr($response, $headerSize);
|
|
||||||
|
|
||||||
$result->html = mb_check_encoding($result->html, 'UTF-8') ? $result->html : utf8_encode($result->html);
|
|
||||||
|
|
||||||
$headers = trim(substr($response, 0, $headerSize));
|
|
||||||
$headers = preg_split('/^\s*$/m', $headers);
|
|
||||||
$headers = end($headers);
|
|
||||||
$lines = array_slice(explode("\n", $headers), 1);
|
|
||||||
|
|
||||||
foreach ( $lines as $line ) {
|
|
||||||
if ( strpos(trim($line), ': ') !== false ) {
|
|
||||||
list($key, $value) = explode(': ', trim($line, "\r"));
|
|
||||||
|
|
||||||
$result->headers[strtolower($key)] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function executeScripts($page)
|
|
||||||
{
|
|
||||||
preg_match_all('/<script[^>]+src=("|\')(.+?)\1/i', $page->html, $matches);
|
|
||||||
|
|
||||||
if ( $urls = $matches[2] ) {
|
|
||||||
foreach ( $urls as $url ) {
|
|
||||||
if ( !preg_match('/^https?:\/\//', $url) ) {
|
|
||||||
$url = $page->url . '/' . $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $this->curl($url);
|
|
||||||
} catch ( WappalyzerException $e ) {
|
|
||||||
if ( $this->debug ) echo $e->getMessage() . "\n";
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$v8 = new V8Js();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$v8->executeString('
|
|
||||||
var
|
|
||||||
document = {},
|
|
||||||
window = { document: document }
|
|
||||||
;
|
|
||||||
');
|
|
||||||
|
|
||||||
$v8->executeString($result->html, $url);
|
|
||||||
|
|
||||||
$result = $v8->executeString('Object.keys(window);');
|
|
||||||
|
|
||||||
var_dump($result);
|
|
||||||
} catch ( V8JsException $e ) {
|
|
||||||
if ( $this->debug ) echo "\n", print_r($e->getJsTrace()), "\n\n";
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class WappalyzerException extends Exception
|
|
||||||
{ }
|
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require('WappalyzerException.php');
|
|
||||||
require('Wappalyzer.php');
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ( php_sapi_name() !== 'cli' ) {
|
|
||||||
exit('Run me from the command line');
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = !empty($argv[1]) ? $argv[1] : '';
|
|
||||||
|
|
||||||
if ( !$url ) {
|
|
||||||
echo "Usage: php {$argv[0]} <url>\n";
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
$wappalyzer = new Wappalyzer($url);
|
|
||||||
|
|
||||||
$detectedApps = $wappalyzer->analyze();
|
|
||||||
|
|
||||||
if ( $detectedApps ) {
|
|
||||||
foreach ( $detectedApps as $detectedApp => $data ) {
|
|
||||||
echo $detectedApp . ', ' . $data->version . ', ', $data->confidence . '%, ', implode(', ', $data->categories) . "\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo "No applications detected\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
} catch ( Exception $e ) {
|
|
||||||
echo $e->getMessage() . "\n";
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
var w = wappalyzer;
|
|
||||||
|
|
||||||
w.driver = {
|
|
||||||
debug: false,
|
|
||||||
data: {},
|
|
||||||
timeout: 5000,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log messages to console
|
|
||||||
*/
|
|
||||||
log: function(args) {
|
|
||||||
if ( w.driver.debug ) { print(args.type + ': ' + args.message + "\n"); }
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize
|
|
||||||
*/
|
|
||||||
init: function() {
|
|
||||||
var app, apps = {};
|
|
||||||
|
|
||||||
w.analyze(w.driver.data.host, w.driver.data.url, {
|
|
||||||
html: w.driver.data.html,
|
|
||||||
headers: w.driver.data.headers
|
|
||||||
});
|
|
||||||
|
|
||||||
for ( app in w.detected[w.driver.data.url] ) {
|
|
||||||
apps[app] = {
|
|
||||||
categories: [],
|
|
||||||
confidence: w.detected[w.driver.data.url][app].confidenceTotal,
|
|
||||||
version: w.detected[w.driver.data.url][app].version
|
|
||||||
};
|
|
||||||
|
|
||||||
w.apps[app].cats.forEach(function(cat) {
|
|
||||||
apps[app].categories.push(w.categories[cat]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return JSON.stringify(apps);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dummy
|
|
||||||
*/
|
|
||||||
displayApps: function() {
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,2 +0,0 @@
|
|||||||
js/wappalyzer.js
|
|
||||||
apps.json
|
|
@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import PyV8
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
|
||||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
||||||
|
|
||||||
from urlparse import urlparse
|
|
||||||
|
|
||||||
try:
|
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
|
|
||||||
class Wappalyzer(object):
|
|
||||||
|
|
||||||
def __init__(self, url):
|
|
||||||
self.file_dir = os.path.dirname(__file__)
|
|
||||||
|
|
||||||
f = open(os.path.join(self.file_dir, 'apps.json'))
|
|
||||||
data = json.loads(f.read())
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
self.categories = data['categories']
|
|
||||||
self.apps = data['apps']
|
|
||||||
self.url = url
|
|
||||||
|
|
||||||
def analyze(self):
|
|
||||||
ctxt = PyV8.JSContext()
|
|
||||||
ctxt.enter()
|
|
||||||
|
|
||||||
f1 = open(os.path.join(self.file_dir, 'js/wappalyzer.js'))
|
|
||||||
f2 = open(os.path.join(self.file_dir, '../php/js/driver.js'))
|
|
||||||
ctxt.eval(f1.read())
|
|
||||||
ctxt.eval(f2.read())
|
|
||||||
f1.close()
|
|
||||||
f2.close()
|
|
||||||
|
|
||||||
host = urlparse(self.url).hostname
|
|
||||||
response = requests.get(self.url, verify=False)
|
|
||||||
html = response.text
|
|
||||||
headers = dict(response.headers)
|
|
||||||
|
|
||||||
data = {'host': host, 'url': self.url, 'html': html, 'headers': headers}
|
|
||||||
apps = json.dumps(self.apps)
|
|
||||||
categories = json.dumps(self.categories)
|
|
||||||
return ctxt.eval("w.apps = %s; w.categories = %s; w.driver.data = %s; w.driver.init();" % (apps, categories, json.dumps(data)))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
w = Wappalyzer(sys.argv[1])
|
|
||||||
print w.analyze()
|
|
||||||
except IndexError:
|
|
||||||
print ('Usage: python %s <url>' % sys.argv[0])
|
|
@ -1,2 +0,0 @@
|
|||||||
js/wappalyzer.js
|
|
||||||
apps.json
|
|
@ -1,46 +0,0 @@
|
|||||||
var w = wappalyzer;
|
|
||||||
|
|
||||||
w.driver = {
|
|
||||||
debug: false,
|
|
||||||
data: {},
|
|
||||||
timeout: 5000,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log messages to console
|
|
||||||
*/
|
|
||||||
log: function(args) {
|
|
||||||
if ( w.driver.debug ) { print(args.type + ': ' + args.message + "\n"); }
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize
|
|
||||||
*/
|
|
||||||
init: function() {
|
|
||||||
var app, apps = {};
|
|
||||||
|
|
||||||
w.analyze(w.driver.data.host, w.driver.data.url, {
|
|
||||||
html: w.driver.data.html,
|
|
||||||
headers: w.driver.data.headers
|
|
||||||
});
|
|
||||||
|
|
||||||
for ( app in w.detected[w.driver.data.url] ) {
|
|
||||||
apps[app] = {
|
|
||||||
categories: [],
|
|
||||||
confidence: w.detected[w.driver.data.url][app].confidenceTotal,
|
|
||||||
version: w.detected[w.driver.data.url][app].version
|
|
||||||
};
|
|
||||||
|
|
||||||
w.apps[app].cats.forEach(function(cat) {
|
|
||||||
apps[app].categories.push(w.categories[cat]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return JSON.stringify(apps);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dummy
|
|
||||||
*/
|
|
||||||
displayApps: function() {
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,43 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
require 'net/http'
|
|
||||||
require 'v8'
|
|
||||||
require 'json'
|
|
||||||
require 'openssl'
|
|
||||||
|
|
||||||
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
|
||||||
Encoding.default_external = Encoding::UTF_8
|
|
||||||
|
|
||||||
class Wappalyzer
|
|
||||||
def initialize
|
|
||||||
@realdir = File.dirname(File.realpath(__FILE__))
|
|
||||||
file = File.join(@realdir, 'apps.json')
|
|
||||||
@json = JSON.parse(IO.read(file))
|
|
||||||
@categories, @apps = @json['categories'], @json['apps']
|
|
||||||
end
|
|
||||||
|
|
||||||
def analyze(url)
|
|
||||||
uri, body, headers = URI(url), nil, {}
|
|
||||||
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', :open_timeout => 5) do |http|
|
|
||||||
resp = http.get(uri.request_uri)
|
|
||||||
resp.each_header{|k,v| headers[k.downcase] = v}
|
|
||||||
body = resp.body.encode('UTF-8', :invalid => :replace, :undef => :replace)
|
|
||||||
end
|
|
||||||
|
|
||||||
cxt = V8::Context.new
|
|
||||||
cxt.load File.join(@realdir, 'js', 'wappalyzer.js')
|
|
||||||
cxt.load File.join(@realdir, 'js', 'driver.js')
|
|
||||||
data = {'host' => uri.hostname, 'url' => url, 'html' => body, 'headers' => headers}
|
|
||||||
output = cxt.eval("w.apps = #{@apps.to_json}; w.categories = #{@categories.to_json}; w.driver.data = #{data.to_json}; w.driver.init();")
|
|
||||||
JSON.load(output)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if $0 == __FILE__
|
|
||||||
url = ARGV[0]
|
|
||||||
if url
|
|
||||||
puts JSON.pretty_generate(Wappalyzer.new.analyze(ARGV[0]))
|
|
||||||
else
|
|
||||||
puts "Usage: #{__FILE__} http://example.com"
|
|
||||||
end
|
|
||||||
end
|
|
Reference in new issue