wappalyzer_rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in wappalyzer_rb.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ # Capybara request specs
17
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
19
+
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ wappalyzer-ruby
2
+ ===============
3
+
4
+ Analyzes a provided url and returns any services it can detect.
5
+
6
+ Usage:
7
+
8
+ url = 'http://some.url.com'
9
+ WappalyzerRb.new(url).analysis #=> ['Ruby', 'nginx', ...]
10
+
11
+ It is a fork of https://github.com/ElbertF/Wappalyzer (commit 7431c5e1e1).
12
+
13
+ TODO
14
+ ----
15
+
16
+ * Break off wappalyzer.rb config into some other file
17
+ * Write a script to automatically translate apps.js to a ruby config file
18
+ * Turn this into a gem
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,349 @@
1
+ module WappalyzerRb
2
+ CATEGORIES = [
3
+ nil,
4
+ 'cms',
5
+ 'message-boards',
6
+ 'database-managers',
7
+ 'documentation-tools',
8
+ 'widgets',
9
+ 'web-shops',
10
+ 'photo-galleries',
11
+ 'wikis',
12
+ 'hosting-panels',
13
+ 'analytics',
14
+ 'blogs',
15
+ 'javascript-frameworks',
16
+ 'issue-trackers',
17
+ 'video-players',
18
+ 'comment-systems',
19
+ 'captchas',
20
+ 'font-scripts',
21
+ 'web-frameworks',
22
+ 'miscellaneous',
23
+ 'editors',
24
+ 'lms',
25
+ 'web-servers',
26
+ 'cache-tools',
27
+ 'rich-text editors',
28
+ 'javascript-graphics',
29
+ 'mobile-frameworks',
30
+ 'programming-languages',
31
+ 'operating-systems',
32
+ 'search-engines'
33
+ ]
34
+
35
+ APPS = {
36
+ '1und1' => { cats: [ 6 ], url: /\/shop\/catalog\/browse\?sessid\=/ },
37
+ '1C-Bitrix' => { cats: [ 1 ], html: /<link[^>]+components\/bitrix/i, script: /1c\-bitrix/i },
38
+ '2z Project' => { cats: [ 1 ], meta: { 'generator' => /2z project/i } },
39
+ 'AddThis' => { cats: [ 5 ], script: /addthis\.com\/js/, env: /^addthis$/ },
40
+ 'Adobe GoLive' => { cats: [ 20 ], meta: { 'generator' => /Adobe GoLive/i } },
41
+ 'Advanced Web Stats' => { cats: [ 10 ], html: /aws.src = [^<]+caphyon\-analytics/i },
42
+ 'Ametys' => { cats: [ 1 ], meta: { 'generator' => /(Ametys|Anyware Technologies)/i }, script: /STools.js/ },
43
+ 'Amiro.CMS' => { cats: [ 1 ], meta: { 'generator' => /Amiro/i } },
44
+ 'AOLserver' => { cats: [ 22 ], headers: { 'Server' => /AOLserver/i } },
45
+ 'Apache' => { cats: [ 22 ], headers: { 'Server' => /(Apache($|[^-])|HTTPD)/i } },
46
+ 'Apache Tomcat' => { cats: [ 22 ], headers: { 'Server' => /Apache-Coyote/i } },
47
+ 'Apache Traffic Server' => { cats: [ 22 ], headers: { 'Server' => /YTS/i } },
48
+ 'Arc Forum' => { cats: [ 2 ], html: /ping\.src = node\.href;/ },
49
+ 'ATG Web Commerce' => { cats: [ 6 ], headers: { 'X-ATG-Version' => /ATG/i }, html: /<[^>]+_DARGS/ },
50
+ 'Atlassian Confluence' => { cats: [ 8 ], html: /Powered by <a href=.http:\/\/www\.atlassian\.com\/software\/confluence/i },
51
+ 'Atlassian Jira' => { cats: [ 13 ], env: /^jira$/i, html: /Powered by <a href=.http:\/\/www\.atlassian\.com\/software\/jira/i, implies: [ 'Java' ] },
52
+ 'Alloy' => { cats: [ 12 ], env: /^AUI$/ },
53
+ 'AWStats' => { cats: [ 10 ], meta: { 'generator' => /AWStats/i } },
54
+ 'Banshee' => { cats: [ 1, 18 ], html: /Built upon the <a href=("|')[^>]+banshee-php\.org/i },
55
+ 'Backbone.js' => { cats: [ 12 ], script: /backbone.*\.js/, env: /^Backbone$/ },
56
+ 'BIGACE' => { cats: [ 1 ], meta: { 'generator' => /BIGACE/ }, html: /Powered by <a href=("|')[^>]+BIGACE|<!--\s+Site is running BIGACE/i },
57
+ 'BigDump' => { cats: [ 3 ], html: /<!-- <h1>BigDump: Staggered MySQL Dump Importer/ },
58
+ 'Bigware' => { cats: [ 6 ], html: /bigware/i },
59
+ 'blip.tv' => { cats: [ 14 ], html: /<(param|embed)[^>]+blip\.tv\/play/i },
60
+ 'Blogger' => { cats: [ 11 ], meta: { 'generator' => /blogger/i }, url: /^(www.)?.+\.blogspot\.com/i },
61
+ 'Bugzilla' => { cats: [ 13 ], html: /<[^>]+(id|title|name)=("|')bugzilla/i },
62
+ 'Burning Board' => { cats: [ 2 ], html: /<a href=('|")[^>]+woltlab\.com.+Burning Board/i },
63
+ 'Business Catalyst' => { cats: [ 1 ], script: /CatalystScripts/, html: /<!-- BC_OBNW -->/ },
64
+ 'CakePHP' => { cats: [ 18 ], headers: { 'set-cookie' => /cakephp=/ }, meta: { 'application-name' => /CakePHP/ } },
65
+ 'Cargo' => { cats: [ 1 ], script: /\/cargo\./i, html: /<link [^>]+Cargo feed/ },
66
+ 'CentOS' => { cats: [ 28 ], headers: { 'Server' => /CentOS/i, 'X-Powered-By' => /CentOS/i } },
67
+ 'Chameleon' => { cats: [ 1 ], meta: { 'generator' => /chameleon\-cms/i } },
68
+ 'chartbeat' => { cats: [ 10 ], html: /function loadChartbeat\(\) {/i },
69
+ 'Chamilo' => { cats: [ 21 ], meta: { 'generator' => /Chamilo/i }, headers: { 'X-Powered-By' => /Chamilo/ } },
70
+ 'Cherokee' => { cats: [ 22 ], headers: { 'Server' => /Cherokee/i } },
71
+ 'CKEditor' => { cats: [ 24 ], env: /^CKEDITOR$/ },
72
+ 'ClickHeat' => { cats: [ 10 ], script: /clickheat.*\.js/i, env: /^clickHeatBrowser$/ },
73
+ 'ClickTale' => { cats: [ 10 ], html: /if\(typeof ClickTale(Tag)*==("|')function("|')\)/, env: /^ClickTale/i },
74
+ 'Clicky' => { cats: [ 10 ], script: /static\.getclicky\.com/, env: /^clicky$/ },
75
+ 'CMS Made Simple' => { cats: [ 1 ], meta: { 'generator' => /CMS Made Simple/i } },
76
+ 'CO2Stats' => { cats: [ 10 ], html: /src=("|')http:\/\/www\.co2stats\.com\/propres\.php/ },
77
+ 'CodeIgniter' => { cats: [ 18 ], headers: { 'Set-Cookie' => /(exp_last_activity|exp_tracker|ci_session)/ }, implies: [ 'PHP' ] },
78
+ 'Commerce Server' => { cats: [ 6 ], headers: { 'COMMERCE-SERVER-SOFTWARE' => /.+/ } },
79
+ 'comScore' => { cats: [ 10 ], html: /<i{1}frame[^>]* (id=("|')comscore("|')|scr=[^>]+comscore)/, env: /^_?COMSCORE$/i },
80
+ 'Concrete5' => { cats: [ 1 ], meta: { 'generator' => /concrete5/i } },
81
+ 'Contao' => { cats: [ 1, 6 ], html: /(<!--\s+This website is powered by (TYPOlight|Contao)|<link[^>]+(typolight|contao).css)/i, implies: [ 'PHP' ] },
82
+ 'Contens' => { cats: [ 1 ], meta: { 'generator' => /contens/i } },
83
+ 'ConversionLab' => { cats: [ 10 ], script: /conversionlab\.trackset\.com\/track\/tsend\.js/ },
84
+ 'Coppermine' => { cats: [ 7 ], html: /<!--Coppermine Photo Gallery/i, implies: [ 'PHP' ] },
85
+ 'Cosmoshop' => { cats: [ 6 ], script: /cosmoshop_functions\.js/ },
86
+ 'Cotonti' => { cats: [ 1 ], meta: { 'generator' => /Cotonti/i } },
87
+ 'CouchDB' => { cats: [ 22 ], headers: { 'Server' => /CouchDB/i } },
88
+ 'cPanel' => { cats: [ 9 ], html: /<!-- cPanel/i },
89
+ 'Crazy Egg' => { cats: [ 10 ], script: /cetrk\.com\/pages\/scripts\/[0-9]+\/[0-9]+\.js/ },
90
+ 'CS Cart' => { cats: [ 6 ], html: /&nbsp;Powered by (<a href=.http:\/\/www\.cs\-cart\.com|CS\-Cart)/i },
91
+ 'CubeCart' => { cats: [ 6 ], html: /(Powered by <a href=.http:\/\/www\.cubecart\.com|<p[^>]+>Powered by CubeCart)/i },
92
+ 'cufon' => { cats: [ 17 ], script: /cufon\-yui\.js/, env: /^Cufon$/ },
93
+ 'd3' => { cats: [ 25 ], script: /d3(\.min)?\.js/ },
94
+ 'Dancer' => { cats: [ 18 ], headers: { 'X-Powered-By' => /Perl Dancer/, 'Server' => /Perl Dancer/ }, implies: [ 'Perl' ] },
95
+ 'Danneo CMS' => { cats: [ 1 ], meta: { 'generator' => /Danneo/i } },
96
+ 'DataLife Engine' => { cats: [ 1 ], meta: { 'generator' => /DataLife Engine/i } },
97
+ 'David Webbox' => { cats: [ 22 ], headers: { 'Server' => /David-WebBox/i } },
98
+ 'Debian' => { cats: [ 28 ], headers: { 'Server' => /Debian/i, 'X-Powered-By' => /(Debian|dotdeb|etch|lenny|squeeze|wheezy)/i } },
99
+ 'DedeCMS' => { cats: [ 1 ], env: /^Dede/, script: /dedeajax/ },
100
+ 'Demandware' => { cats: [ 6 ], html: /<[^>]+demandware.edgesuite/, env: /^dwAnalytics/ },
101
+ 'DHTMLX' => { cats: [ 12 ], script: /dhtmlxcommon\.js/ },
102
+ 'DirectAdmin' => { cats: [ 9 ], html: /<a[^>]+>DirectAdmin<\/a> Web Control Panel/i },
103
+ 'Disqus' => { cats: [ 15 ], script: /disqus_url/, html: /<div[^>]+id=("|')disqus_thread("|')/, env: /^DISQUS/i },
104
+ 'Django' => { cats: [ 18 ] },
105
+ 'Django CMS' => { cats: [ 1 ], script: /media\/cms\/js\/csrf\.js/, headers: { 'Set-Cookie' => /django/ }, implies: [ 'Django' ] },
106
+ 'dojo' => { cats: [ 12 ], script: /dojo(\.xd)?\.js/, env: /^dojo$/ },
107
+ 'Dokeos' => { cats: [ 21 ], meta: { 'generator' => /Dokeos/i }, html: /Portal <a[^>]+>Dokeos|@import "[^"]+dokeos_blue/i, headers: { 'X-Powered-By' => /Dokeos/ } },
108
+ 'DokuWiki' => { cats: [ 8 ], meta: { 'generator' => /DokuWiki/i } },
109
+ 'DotNetNuke' => { cats: [ 1 ], meta: { 'generator' => /DotNetNuke/i }, html: /(<!\-\- by DotNetNuke Corporation|<link[^>]+\/portals\/_default\/[^>]+\.css)/i, env: /^(DDN|DotNetNuke)/i },
110
+ 'DreamWeaver' => { cats: [ 20 ], html: /(<!\-\-[^>]*(InstanceBeginEditable|Dreamweaver[^>]+target|DWLayoutDefaultTable)|function MM_preloadImages\(\) {)/ },
111
+ 'Drupal' => { cats: [ 1 ], script: /drupal\.js/, html: /(jQuery\.extend\(Drupal\.settings, \{|Drupal\.extend\(\{ settings: \{|<link[^>]+sites\/(default|all)\/themes\/|<style[^>]+sites\/(default|all)\/(themes|modules)\/)/i, headers: { 'X-Drupal-Cache' => /.*/, 'X-Generator' => /Drupal/, 'Expires' => /19 Nov 1978/ }, env: /^Drupal$/, implies: [ 'PHP' ] },
112
+ 'Drupal Commerce' => { cats: [ 6 ], html: /id="block[_-]commerce[_-]cart[_-]cart|class="commerce[_-]product[_-]field/i, implies: [ 'PHP' ] },
113
+ 'Dynamicweb' => { cats: [ 1 ], meta: { 'generator' => /Dynamicweb/i } },
114
+ 'e107' => { cats: [ 1 ], script: /e107\.js/ },
115
+ 'Ecodoo' => { cats: [ 6 ], script: /addons\/lytebox\/lytebox\.js/ },
116
+ 'Exhibit' => { cats: [ 25 ], script: /exhibit.*\.js/, env: /^Exhibit$/ },
117
+ 'ExtJS' => { cats: [ 12 ], script: /ext\-base\.js/, env: /^Ext$/ },
118
+ 'ExpressionEngine' => { cats: [ 1 ], headers: { 'Set-Cookie' => /(exp_last_activity|exp_tracker)/ } },
119
+ 'eZ Publish' => { cats: [ 1 ], meta: { 'generator' => /eZ Publish/i } },
120
+ 'FAST Search for SharePoint' => { cats: [ 29 ], url: /Pages\/SearchResults\.aspx\?k\=/, implies: [ 'Microsoft ASP.NET' ] },
121
+ 'FAST ESP' => { cats: [ 29 ], html: /fastsearch|searchProfile\=|searchCategory\=/i, url: /esppublished|searchProfile\=|searchCategory\=/i },
122
+ 'Fact Finder' => { cats: [ 29 ], html: /\/images\/fact-finder\.gif|ViewParametricSearch|factfinder|Suggest\.ff/i, url: /ViewParametricSearch|factfinder|ffsuggest/i },
123
+ 'FlexCMP' => { cats: [ 1 ], meta: { 'generator' => /FlexCMP/ }, headers: { 'X-Powered-By' => /FlexCMP/ } },
124
+ 'FluxBB' => { cats: [ 2 ], html: /Powered by (<strong>)?<a href=("|')[^>]+fluxbb/i },
125
+ 'Flyspray' => { cats: [ 13 ], html: /(<a[^>]+>Powered by Flyspray|<map id=("|')projectsearchform)/ },
126
+ 'FreeBSD' => { cats: [ 28 ], headers: { 'Server' => /FreeBSD/i } },
127
+ 'FWP' => { cats: [ 6 ], meta: {'generator' => /FWP Shop/ } },
128
+ 'FrontPage' => { cats: [ 20 ], meta: { 'generator' => /Microsoft FrontPage/ }, html: /<html[^>]+urn:schemas\-microsoft\-com:office:office/i },
129
+ 'Gallery' => { cats: [ 7 ], env: /galleryAuthToken/, html: /<div id="gsNavBar" class="gcBorder1">/ },
130
+ 'Gambio' => { cats: [ 6 ], html: /brought to you by XT-Commerce|[Gg]ambio|content\.php\?coID=\d/},
131
+ 'Gauges' => { cats: [ 10 ], html: /t\.src = '\/\/secure\.gaug\.es\/track\.js/, env: /^_gauges$/ },
132
+ 'Gentoo' => { cats: [ 28 ], headers: { 'X-Powered-By' => /-?gentoo/} },
133
+ 'Get Satisfaction' => { cats: [ 13 ], html: /var feedback_widget = new GSFN\.feedback_widget\(feedback_widget_options\)/ },
134
+ 'Google Analytics' => { cats: [ 10 ], script: /(\.google\-analytics\.com\/ga\.js|google-analytics\.com\/urchin\.js)/, env: /^gaGlobal$/ },
135
+ 'Google App Engine' => { cats: [ 22 ], headers: { 'Server' => /Google Frontend/i } },
136
+ 'Google Font API' => { cats: [ 17 ], script: /googleapis.com\/.+webfont/, html: /<link[^>]* href=("|')http:\/\/fonts\.googleapis\.com/, env: /^WebFont/ },
137
+ 'Google Friend Connect' => { cats: [ 5 ], script: /google.com\/friendconnect/ },
138
+ 'Google Maps' => { cats: [ 5 ], script: /(maps\.google\.com\/maps\?file=api|maps\.google\.com\/maps\/api\/staticmap)/ },
139
+ 'Google Sites' => { cats: [ 1 ], url: /sites.google.com/ },
140
+ 'GoStats' => { cats: [ 10 ], env: /^_go(stats|_track)/i },
141
+ 'Graffiti CMS' => { cats: [ 1 ], meta: { 'generator' => /Graffiti CMS/i } },
142
+ 'Gravatar' => { cats: [ 19 ], env: /^Gravatar$/ },
143
+ 'Gravity Insights' => { cats: [ 10 ], html: /gravityInsightsParams\.site_guid = '/, env: /^GravityInsights$/ },
144
+ 'Handlebars' => { cats: [ 12 ], env: /^Handlebars$/ },
145
+ 'Hiawatha' => { cats: [ 22 ], headers: { 'Server' => /Hiawatha/i } },
146
+ 'Highcharts' => { cats: [ 25 ], script: /highcharts.*\.js/, env: /^Highcharts$/ },
147
+ 'Hotaru CMS' => { cats: [ 1 ], meta: { 'generator' => /Hotaru CMS/i } },
148
+ 'Hybris' => { cats: [ 6 ], html: /\/sys_master\/|\/hybr\//, header: { 'Set-Cookie' => /_hybris/ }, implies: [ 'Java' ] },
149
+ 'IIS' => { cats: [ 22 ], headers: { 'Server' => /IIS/i }, implies: [ 'Windows Server' ] },
150
+ 'Indexhibit' => { cats: [ 1 ], html: /<link [^>]+ndxz-studio/i },
151
+ 'InstantCMS' => { cats: [ 1 ], meta: { 'generator' => /InstantCMS/i } },
152
+ 'Intershop' => { cats: [ 6 ], url: /is-bin|INTERSHOP/i, script: /is-bin|INTERSHOP/i },
153
+ 'IPB' => { cats: [ 2 ], script: /jscripts\/ips_/, env: /^IPBoard/, html: /<link[^>]+ipb_[^>]+\.css/ },
154
+ 'iWeb' => { cats: [ 20 ], meta: { 'generator' => /iWeb/i } },
155
+ 'Jalios' => { cats: [ 1 ], meta: { 'generator' => /Jalios/i } },
156
+ 'Java' => { cats: [ 27 ] },
157
+ 'Javascript Infovis Toolkit' => { cats: [ 25 ], script: /jit.*\.js/, env: /^\$jit$/ },
158
+ 'Jo' => { cats: [ 26, 12 ], env: /^jo(Cache|DOM|Event)$/ },
159
+ 'JobberBase' => { cats: [ 19 ], meta: { 'generator' => /Jobberbase/i }, env: /^Jobber$/ },
160
+ 'Joomla' => { cats: [ 1 ], meta: { 'generator' => /Joomla/i }, html: /(<!\-\- JoomlaWorks "K2"|<[^>]+(feed|components)\/com_)/i, headers: { 'X-Content-Encoded-By' => /Joomla/ }, env: /^(jcomments)$/i },
161
+ 'jqPlot' => { cats: [ 25 ], script: /jqplot.*\.js/, env: /^jQuery.jqplot$/ },
162
+ 'jQTouch' => { cats: [ 26 ], script: /jqtouch.*\.js/i, env:/^jQT$/ },
163
+ 'jQuery UI' => { cats: [ 12 ], script: /jquery\-ui.*\.js/, implies: [ 'jQuery' ] },
164
+ 'jQuery' => { cats: [ 12 ], script: /jquery.*.js/, env: /^jQuery$/ },
165
+ 'jQuery Mobile' => { cats: [ 26 ], script: /jquery\.mobile.*\.js/i },
166
+ 'jQuery Sparklines' => { cats: [ 25 ], script: /jquery\.sparkline.*\.js/i },
167
+ 'JS Charts' => { cats: [ 25 ], script: /jscharts.*\.js/i, env: /^JSChart$/ },
168
+ 'JTL Shop' => { cats: [ 6 ], html: /(<input[^>]+name=('|")JTLSHOP|<a href=('|")jtl\.php)/i },
169
+ 'K2' => { cats: [ 19 ], html: /<!\-\- JoomlaWorks "K2"/, env: /^K2RatingURL$/, implies: [ 'Joomla' ] },
170
+ 'Kampyle' => { cats: [ 10 ], script: /cf\.kampyle\.com\/k_button\.js/ },
171
+ 'Kentico CMS' => { cats: [ 1 ], meta: { 'generator' => /Kentico CMS/i } },
172
+ 'Koego' => { cats: [ 10 ], script: /tracking\.koego\.com\/end\/ego\.js/ },
173
+ 'Kohana' => { cats: [ 18 ], headers: { 'Set-Cookie' => /kohanasession/i, 'X-Powered-By' => /Kohana/ }, implies: [ 'PHP' ] },
174
+ 'Kolibri CMS' => { cats: [ 1 ], meta: { 'generator' => /Kolibri/i } },
175
+ 'Koobi' => { cats: [ 1 ], meta: { 'generator' => /Koobi/i } },
176
+ 'lighttpd' => { cats: [ 22 ], headers: { 'Server' => /lighttpd/i } },
177
+ 'LiveJournal' => { cats: [ 11 ], url: /^(www.)?.+\.livejournal\.com/i },
178
+ 'Liferay' => { cats: [ 1 ], env: /^Liferay$/, headers: { 'Liferay-Portal' => /.*/i } },
179
+ 'Lotus Domino' => { cats: [ 22 ], headers: { 'Server' => /Lotus\-Domino/i } },
180
+ 'Magento' => { cats: [ 6 ], script: /\/(js\/mage|skin\/frontend\/(default|enterprise))\//, env: /^(Mage|VarienForm)$/, implies: [ 'PHP '] },
181
+ 'Mambo' => { cats: [ 1 ], meta: { 'generator' => /Mambo/i } },
182
+ 'MantisBT' => { cats: [ 13 ], html: /<img[^>]+ alt=("|')Powered by Mantis Bugtracker/i },
183
+ 'MaxSite CMS' => { cats: [ 1 ], meta: { 'generator' => /MaxSite CMS/i } },
184
+ 'MediaWiki' => { cats: [ 8 ], meta: { 'generator' => /MediaWiki/i }, html: /(<a[^>]+>Powered by MediaWiki<\/a>|<[^>]+id=("|')t\-specialpages)/i },
185
+ 'Meebo' => { cats: [ 5 ], html: /(<iframe id=("|')meebo\-iframe("|')|Meebo\('domReady'\))/ },
186
+ 'Microsoft ASP.NET' => { cats: [ 18 ], html: /<input[^>]+name=("|')__VIEWSTATE/, headers: { 'X-Powered-By' => /ASP\.NET/, 'X-AspNet-Version' => /.+/ }, implies: [ 'Windows Server' ] },
187
+ 'Microsoft SharePoint' => { cats: [ 1 ], meta: { 'generator' => /Microsoft SharePoint/i }, headers: { 'MicrosoftSharePointTeamServices' => /.*/, 'X-SharePointHealthScore' => /.*/, 'SPRequestGuid' => /.*/, 'SharePointHealthScore' => /.*/ } },
188
+ 'MiniBB' => { cats: [ 2 ], html: /<a href=("|')[^>]+minibb.+\s+<!--End of copyright link/i },
189
+ 'Mint' => { cats: [ 10 ], script: /mint\/\?js/, env: /^Mint$/ },
190
+ 'Mixpanel' => { cats: [ 10 ], script: /api\.mixpanel\.com\/track/ },
191
+ 'MochiKit' => { cats: [ 12 ], script: /MochiKit\.js/, env: /^MochiKit$/ },
192
+ 'Modernizr' => { cats: [ 12 ], script: /modernizr.*\.js/, env: /^Modernizr$/ },
193
+ 'MODx' => { cats: [ 1 ], html: /(<a[^>]+>Powered by MODx<\/a>|var el= \$\('modxhost'\);|<script type=("|')text\/javascript("|')>var MODX_MEDIA_PATH = "media";)|<(link|script)[^>]+assets\/snippets\//i },
194
+ 'Mojolicious' => { cats: [ 18 ], headers: { 'x-powered-by' => /mojolicious/ }, implies: [ 'PERL' ] },
195
+ 'Mollom' => { cats: [ 16 ], script: /mollom\.js/, html: /<img[^>]+\/.mollom\/.com/i },
196
+ 'Mondo Media' => { cats: [ 6 ], meta: { 'generator' => /Mondo Shop/ } },
197
+ 'Mongrel' => { cats: [ 22 ], headers: { 'Server' => /Mongrel/ }, implies: [ 'Ruby' ] },
198
+ 'Moodle' => { cats: [ 21 ], html: /(var moodleConfigFn = function\(me\)|<img[^>]+moodlelogo)/i, implies: [ 'PHP' ] },
199
+ 'Moogo' => { cats: [ 1 ], script: /kotisivukone.js/ },
200
+ 'MooTools' => { cats: [ 12 ], script: /mootools.*\.js/, env: /^MooTools$/ },
201
+ 'Movable Type' => { cats: [ 1 ], meta: { 'generator' => /Movable Type/i } },
202
+ 'Mustache' => { cats: [ 12 ], env: /^Mustache$/ },
203
+ 'Hiawatha' => { cats: [ 22 ], headers: { 'Server' => /Hiawatha/i } },
204
+ 'MyBB' => { cats: [ 2 ], html: /(<script [^>]+\s+<!--\s+lang\.no_new_posts|<a[^>]* title=("|')Powered By MyBB)/i, env: /^MyBB/ },
205
+ 'MyBlogLog' => { cats: [ 5 ], script: /pub\.mybloglog\.com/i },
206
+ 'Mynetcap' => { cats: [ 1 ], meta: { 'generator' => /Mynetcap/i } },
207
+ 'Nedstat' => { cats: [ 10 ], html: /sitestat\(("|')http:\/\/nl\.sitestat\.com/ },
208
+ 'Netmonitor' => { cats: [ 10 ], script: /netmonitor\.fi\/nmtracker\.js/, env: /^netmonitor/ },
209
+ 'Nginx' => { cats: [ 22 ], headers: { 'Server' => /nginx/i } },
210
+ 'NOIX' => { cats: [ 19 ], html: /<[^>]+(src|href)=[^>]*(\/media\/noix)|<!\-\- NOIX/i },
211
+ 'nopCommerce' => { cats: [ 6 ], html: /(<!\-\-Powered by nopCommerce|Powered by: <a[^>]+nopcommerce)/i },
212
+ 'OneStat' => { cats: [ 10 ], html: /var p=("|')http("|')\+\(d\.URL\.indexOf\('https:'\)==0\?'s':''\)\+("|'):\/\/stat\.onestat\.com\/stat\.aspx\?tagver/i },
213
+ 'OpenCart' => { cats: [ 6 ], html: /(Powered By <a href=("|')[^>]+OpenCart|route = getURLVar\(("|')route)/i },
214
+ 'openEngine' => { cats: [ 1 ], html: /<meta[^>]+openEngine/i },
215
+ 'OpenGSE' => { cats: [ 22 ], headers: { 'Server' => /GSE/i } },
216
+ 'OpenLayers' => { cats: [ 5 ], script: /openlayers/, env:/^OpenLayers$/ },
217
+ 'OpenNemas' => { cats: [ 1 ], headers: { 'X-Powered-By' => /OpenNemas/ } },
218
+ 'Open Web Analytics' => { cats: [ 10 ], html: /<!-- (Start|End) Open Web Analytics Tracker -->/, env: /^_?owa_/i },
219
+ 'Optimizely' => { cats: [ 10 ], env: /^optimizely/ },
220
+ 'Oracle Recommendations On Demand' => { cats: [ 10 ], script: /atgsvcs.+atgsvcs\.js/ },
221
+ 'osCommerce' => { cats: [ 6 ], html: /<a[^>]*osCsid/i },
222
+ 'osCSS' => { cats: [ 6 ], html: /<body onload=("|')window\.defaultStatus='oscss templates';("|')/i },
223
+ 'OXID eShop' => { cats: [ 6 ], html: /<!--.*OXID eShop/, env: /^ox(TopMenu|ModalPopup|LoginBox|InputValidator)/ },
224
+ 'PANSITE' => { cats: [ 1 ], meta: { 'generator' => /PANSITE/i } },
225
+ 'papaya CMS' => { cats: [ 1 ], html: /<link[^>]*\/papaya-themes\//i },
226
+ 'Parse.ly' => { cats: [ 10 ], env: /^PARSELY$/ },
227
+ 'Perl' => { cats: [ 27 ] },
228
+ 'PHP' => { cats: [ 27 ], headers: { 'Server' => /php/i, 'X-Powered-By' => /php/i, 'Set-Cookie' => /PHPSESSID/ }, url: /\.php$/ },
229
+ 'Phpcms' => { cats: [ 1 ], env: /^phpcms/ },
230
+ 'PHP-Fusion' => { cats: [ 1 ], html: /Powered by <a href=("|')[^>]+php-fusion/i },
231
+ 'PHP-Nuke' => { cats: [ 2 ], meta: { 'generator' => /PHP-Nuke/i }, html: /<[^>]+Powered by PHP\-Nuke/i },
232
+ 'phpBB' => { cats: [ 2 ], meta: { 'copyright' => /phpBB Group/ }, html: /(Powered by <a[^>]+phpbb|<a[^>]+phpbb[^>]+class=.copyright|\tphpBB style name|<[^>]+styles\/(sub|pro)silver\/theme|<img[^>]+i_icon_mini|<table class="forumline)/i, env: /^(style_cookie_settings|phpbb_)/, headers: { 'Set-Cookie' => /^phpbb/ }, implies: [ 'PHP' ] },
233
+ 'phpDocumentor' => { cats: [ 4 ], html: /<!-- Generated by phpDocumentor/, implies: [ 'PHP' ] },
234
+ 'phpMyAdmin' => { cats: [ 3 ], html: /(var pma_absolute_uri = '|PMA_sendHeaderLocation\(|<title>phpMyAdmin<\/title>)/i, implies: [ 'PHP' ] },
235
+ 'phpPgAdmin' => { cats: [ 3 ], html: /(<title>phpPgAdmin<\/title>|<span class=("|')appname("|')>phpPgAdmin)/i },
236
+ 'Piwik' => { cats: [ 10 ], html: /var piwikTracker = Piwik\.getTracker\(/i, env: /^Piwik$/ },
237
+ 'Plentymarkets' => { cats: [ 6 ], meta: { 'generator' => /www\.plentyMarkets\./i } },
238
+ 'Plesk' => { cats: [ 9 ], script: /common\.js\?plesk/i },
239
+ 'Plone' => { cats: [ 1 ], meta: { 'generator' => /Plone/i }, implies: [ 'Python' ] },
240
+ 'Plura' => { cats: [ 19 ], html: /<iframe src="http:\/\/pluraserver\.com/ },
241
+ 'posterous' => { cats: [ 1, 11 ], html: /<div class=("|')posterous/i, env: /^Posterous/i },
242
+ 'Powergap' => { cats: [ 6 ], html: /(s\d\d)\.php\?shopid=\1/ },
243
+ 'Prestashop' => { cats: [ 6 ], meta: { 'generator' => /PrestaShop/i }, html: /Powered by <a href=("|')[^>]+PrestaShop/i },
244
+ 'Prototype' => { cats: [ 12 ], script: /(prototype|protoaculous)\.js/, env: /^Prototype$/ },
245
+ 'Protovis' => { cats: [ 25 ], script: /protovis.*\.js/, env: /^protovis$/ },
246
+ 'punBB' => { cats: [ 2 ], html: /Powered by <a href=("|')[^>]+punbb/i },
247
+ 'Python' => { cats: [ 27 ] },
248
+ 'Quantcast' => { cats: [ 10 ], script: /edge\.quantserve\.com\/quant\.js/, env: /^quantserve$/ },
249
+ 'Quick.Cart' => { cats: [ 6 ], html: /<a href="[^>]+opensolution\.org\/">Powered by/i },
250
+ 'ReallyCMS' => { cats: [ 1 ], meta: { 'generator' => /ReallyCMS/ } },
251
+ 'Red Hat' => { cats: [ 28 ], headers: { 'Server' => /Red Hat/i, 'X-Powered-By' => /Red Hat/i } },
252
+ 'Raphael' => { cats: [ 25 ], script: /raphael.*\.js/, env: /^Raphael$/ },
253
+ 'reCAPTCHA' => { cats: [ 16 ], script: /(api\-secure\.recaptcha\.net|recaptcha_ajax\.js)/, html: /<div[^>]+id=("|')recaptcha_image/, env: /^Recaptcha$/ },
254
+ 'Reddit' => { cats: [ 2 ], html: /(<script[^>]+>var reddit = {|<a[^>]+Powered by Reddit|powered by <a[^>]+>reddit<)/i, url: /^(www\.)?reddit\.com/, env: /^reddit$/, implies: [ 'Python' ] },
255
+ 'Redmine' => { cats: [ 13 ], meta: { 'description' => /Redmine/i }, html: /Powered by <a href=("|')[^>]+Redmine/i, implies: [ 'Ruby' ] },
256
+ 'Reinvigorate' => { cats: [ 10 ], html: /reinvigorate\.track\("/ },
257
+ 'RequireJS' => { cats: [ 12 ], script: /require.*\.js/ , env: /^requirejs$/},
258
+ 'Ruby' => { cats: [ 27 ], headers: { 'Server' => /(Mongrel|WEBrick|Ruby|mod_rails|mod_rack|Phusion.Passenger)/i, 'X-Powered-By' => /(mod_rails|mod_rack|Phusion.Passenger)/i } },
259
+ 'S.Builder' => { cats: [ 1 ], meta: { 'generator' => /S\.Builder/i } },
260
+ 's9y' => { cats: [ 1 ], meta: { 'generator' => /Serendipity/i, 'Powered-By' => /Serendipity/i } },
261
+ 'script.aculo.us' => { cats: [ 12 ], script: /(scriptaculous|protoaculous)\.js/, env: /^Scriptaculous$/ },
262
+ 'Sencha Touch' => { cats: [ 26, 12 ], script: /sencha\-touch.*\.js/ },
263
+ 'Seoshop' => { cats: [ 6 ], html: /http:\/\/www\.getseoshop\.com/ },
264
+ 'ShareThis' => { cats: [ 5 ], script: /w\.sharethis\.com\//, env: /^SHARETHIS$/ },
265
+ 'Shopify' => { cats: [ 6 ], html: /<link[^>]+=cdn\.shopify\.com/, env: /^Shopify$/ },
266
+ 'sIFR' => { cats: [ 17 ], script: /sifr\.js/ },
267
+ 'Site Meter' => { cats: [ 10 ], script: /sitemeter.com\/js\/counter\.js\?site=/ },
268
+ 'SiteCatalyst' => { cats: [ 10 ], html: /var s_code=s\.t\(\);if\(s_code\)document\.write\(s_code\)/i, env: /^s_account$/ },
269
+ 'SiteEdit' => { cats: [ 1 ], meta: { 'generator' => /SiteEdit/i } },
270
+ 'Smartstore' => { cats: [ 6 ], script: /smjslib\.js/ },
271
+ 'SMF' => { cats: [ 2 ], html: /<script [^>]+\s+var smf_/i, env: /^smf_/ },
272
+ 'sNews' => { cats: [ 1 ], meta: { 'generator' => /sNews/ } },
273
+ 'Snoobi' => { cats: [ 10 ], script: /snoobi\.com\/snoop\.php/ },
274
+ 'SOBI 2' => { cats: [ 19 ], html: /(<!\-\- start of Sigsiu Online Business Index|<div[^>]* class=("|')sobi2)/i },
275
+ 'SoundManager' => { cats: [ 12 ], env: /^(SoundManager|BaconPlayer)$/ },
276
+ 'SPIP' => { cats: [ 1 ], meta: { 'generator' => /SPIP/i }, headers: { 'X-Spip-Cache' => /.*/ } },
277
+ 'SQL Buddy' => { cats: [ 3 ], html: /(<title>SQL Buddy<\/title>|<[^>]+onclick=("|')sideMainClick\(("|')home\.php)/i },
278
+ 'Squarespace' => { cats: [ 1 ], html: /Squarespace\.Constants\.CURRENT_MODULE_ID/i },
279
+ 'Squiz Matrix' => { cats: [ 1 ], meta: { 'generator' => /Squiz Matrix/ }, html: / Running (MySource|Squiz) Matrix/i, 'X-Powered-By' => /Squiz Matrix/ },
280
+ 'StatCounter' => { cats: [ 10 ], script: /statcounter\.com\/counter\/counter/ },
281
+ 'Store Systems' => { cats: [ 6 ], html: /Shopsystem von <a href="http:\/\/www\.store-systems\.de"|\.mws_boxTop/ },
282
+ 'SWFObject' => { cats: [ 19 ], script: /swfobject.*\.js/i, env: /^SWFObject$/ },
283
+ 'swift.engine' => { cats: [ 1 ], headers: { 'X-Powered-By' => /swift\.engine/ } },
284
+ 'Swiftlet' => { cats: [ 18 ], meta: { 'generator' => /Swiftlet/i }, html: /Powered by <a href=("|')[^>]+Swiftlet/i, headers: { 'X-Swiftlet-Cache' => /.*/, 'X-Powered-By' => /Swiftlet/, 'X-Generator' => /Swiftlet/ }, implies: [ 'PHP' ] },
285
+ 'Textpattern CMS' => { cats: [ 1 ], meta: { 'generator' => /Textpattern/i } },
286
+ 'Tiki Wiki CMS Groupware' => { cats: [ 1, 2, 8, 11, 13 ], script: /(\/|_)tiki/, meta: { 'generator' => /^Tiki/i } },
287
+ 'Timeplot' => { cats: [ 25 ], script: /timeplot.*\.js/, env: /^Timeplot$/ },
288
+ 'TinyMCE' => { cats: [ 24 ], env: /^tinyMCE$/ },
289
+ 'TomatoCart' => { cats: [ 6 ], meta: { 'generator' => /TomatoCart/i } },
290
+ 'Trac' => { cats: [ 13 ], html: /(<a id=("|')tracpowered)/i, implies: [ 'Python' ] },
291
+ 'Tumblr' => { cats: [ 11 ], html: /<iframe src=("|')http:\/\/www\.tumblr\.com/i, url: /^(www.)?.+\.tumblr\.com/i, headers: { 'X-Tumblr-Usec' => /.*/ } },
292
+ 'Twilight CMS' => { cats: [ 1 ], headers: { 'X-Powered-CMS' => /Twilight CMS/ } },
293
+ 'Twitter Bootstrap' => { cats: [ 18 ], script: /twitter\.github\.com\/bootstrap/, html: /<link[^>]+bootstrap[^>]+css/, env: /^Twipsy$/ },
294
+ 'Typekit' => { cats: [ 17 ], script: /use.typekit.com/, env: /^Typekit$/ },
295
+ 'TypePad' => { cats: [ 11 ], meta: { 'generator' => /typepad/i }, url: /^(www.)?.+\.typepad\.com/i },
296
+ 'TYPO3' => { cats: [ 1 ], headers: { 'Set-Cookie' => /fe_typo_user/ }, meta: { 'generator' => /TYPO3/i }, html: /(<(script[^>]* src|link[^>]* href)=[^>]*fileadmin|<!--TYPO3SEARCH)/i, url: /\/typo3/i },
297
+ 'Ubercart' => { cats: [ 6 ], script: /uc_cart\/uc_cart_block\.js/ },
298
+ 'Ubuntu' => { cats: [ 28 ], headers: { 'Server' => /Ubuntu/i, 'X-Powered-By' => /Ubuntu/i } },
299
+ 'Umbraco' => { cats: [ 1 ], meta: { 'generator' => /umbraco/i }, headers: { 'X-Umbraco-Version' => /.+/ }, html: /powered by <a href=[^>]+umbraco/i, implies: [ 'Microsoft ASP.NET' ] },
300
+ 'Underscore.js' => { cats: [ 12 ], script: /underscore.*\.js/ },
301
+ 'UNIX' => { cats: [ 28 ], headers: { 'Server' => /Unix/i } },
302
+ 'UserRules' => { cats: [ 13 ], html: /var _usrp =/ , env: /^\_usrp$/ },
303
+ 'UserVoice' => { cats: [ 13 ], env: /^UserVoice$/ },
304
+ 'Vanilla' => { cats: [ 2 ], html: /<body id=("|')(DiscussionsPage|vanilla)/i, headers: { 'X-Powered-By' => /Vanilla/ } },
305
+ 'Varnish' => { cats: [ 22 ], headers: { 'X-Varnish' => /.+/, 'X-Varnish-Age' => /.+/, 'X-Varnish-Cache' => /.+/, 'X-Varnish-Action' => /.+/, 'X-Varnish-Hostname' => /.+/, 'Via' => /Varnish/i } },
306
+ 'vBulletin' => { cats: [ 2 ], meta: { 'generator' => /vBulletin/i }, env: /^(vBulletin|vB_)/ },
307
+ 'viennaCMS' => { cats: [ 1 ], html: /powered by <a href=("|')[^>]+viennacms/i },
308
+ 'Vignette' => { cats: [ 1 ], html: /<[^>]+?=("|')(vgn\-ext|vgnext)/i },
309
+ 'Vimeo' => { cats: [ 14 ], html: /<(param|embed)[^>]+vimeo\.com\/moogaloop/i },
310
+ 'VirtueMart' => { cats: [ 6 ], html: /<div id=("|')vmMainPage/, headers: { 'Set-Cookie' => /^virtuemart\=/ } },
311
+ 'VisualPath' => { cats: [ 10 ], script: /visualpath[^\/]*\.trackset\.it\/[^\/]+\/track\/include\.js/ },
312
+ 'VIVVO' => { cats: [ 1 ], headers: { 'Set-Cookie' => /VivvoSessionId/, env: /^vivvo/i } },
313
+ 'Vox' => { cats: [ 11 ], url: /^(www.)?.+\.vox\.com/i },
314
+ 'VP-ASP' => { cats: [ 6 ], script: /vs350\.js/, html: /<a[^>]+>Powered By VP\-ASP Shopping Cart<\/a>/, implies: [ 'Microsoft ASP.NET' ] },
315
+ 'W3Counter' => { cats: [ 10 ], script: /w3counter\.com\/tracker\.js/ },
316
+ 'Web Optimizer' => { cats: [ 10 ], html: /<title [^>]*lang=("|')wo("|')>/ },
317
+ 'Websale' => { cats: [ 6 ], url: /\/websale7\// },
318
+ 'webEdition' => { cats: [ 1 ], meta: { 'generator' => /webEdition/i, 'DC.title' => /webEdition/i } },
319
+ 'WebGUI' => { cats: [ 1 ], meta: { 'generator' => /WebGUI/i } },
320
+ 'WebPublisher' => { cats: [ 1 ], meta: { 'generator' => /WEB\|Publisher/i } },
321
+ 'WebsiteBaker' => { cats: [ 1 ], meta: { 'generator' => /WebsiteBaker/i } },
322
+ 'Webtrekk' => { cats: [ 10 ], html: /var webtrekk = new Object/ },
323
+ 'Webtrends' => { cats: [ 10 ], html: /<img[^>]+id=("|')DCSIMG("|')[^>]+webtrends/i, env: /^(WTOptimize|WebTrends)/i },
324
+ 'Weebly' => { cats: [ 1 ], html: /<[^>]+class=("|')weebly/i },
325
+ 'WikkaWiki' => { cats: [ 8 ], meta: { 'generator' => /WikkaWiki/ }, html: /Powered by <a href=("|')[^>]+WikkaWiki/i },
326
+ 'Windows Server' => { cats: [ 28 ] },
327
+ 'wink' => { cats: [ 26, 12 ], script: /(\_base\/js\/base|wink).*\.js/i, env: /^wink$/ },
328
+ 'Wolf CMS' => { cats: [ 1 ], html: /<a href=("|')[^>]+wolfcms.org.+Wolf CMS.+inside/i },
329
+ 'Woopra' => { cats: [ 10 ], script: /static\.woopra\.com/ },
330
+ 'WordPress' => { cats: [ 1, 11 ], meta: { 'generator' => /WordPress/i }, html: /<link rel=("|')stylesheet("|') [^>]+wp-content/i, env: /^wp_username$/, implies: [ 'PHP' ] },
331
+ 'xajax' => { cats: [ 12 ], script: /xajax_core.*\.js/i },
332
+ 'Xanario' => { cats: [ 6 ], meta: { 'generator' => /xanario shopsoftware/i } },
333
+ 'XenForo' => { cats: [ 2 ], html: /(jQuery\.extend\(true, XenForo|Forum software by XenForo&trade;|<!\-\-XF:branding)/ },
334
+ 'XiTi' => { cats: [ 10 ], html: /<[^>]+src=("|')[^>]+xiti.com\/hit.xiti/i, env: /^Xt_/ },
335
+ 'XMB' => { cats: [ 2 ], html: /<!-- Powered by XMB/i },
336
+ 'xui' => { cats: [ 26, 12 ], script: /[^a-zA-Z]xui.*\.js/i, env: /^xui$/ },
337
+ 'XOOPS' => { cats: [ 1 ], meta: { 'generator' => /XOOPS/i } },
338
+ 'xtCommerce' => { cats: [ 6 ], meta: { 'generator' => /xt:Commerce/ }, html: /<div class=("|')copyright("|')>.+<a[^>]+>xt:Commerce/i },
339
+ 'YaBB' => { cats: [ 2 ], html: /Powered by <a href=("|')[^>]+yabbforum/i },
340
+ 'Yahoo! Web Analytics' => { cats: [ 10 ], script: /d\.yimg\.com\/mi\/ywa\.js/ },
341
+ 'Yandex.Metrika' => { cats: [ 10 ], script: /mc\.yandex\.ru\/metrika\/watch\.js/ },
342
+ 'YouTube' => { cats: [ 14 ], html: /<(param|embed|iframe)[^>]+youtube(-nocookie)?\.com\/(v|embed)/i },
343
+ 'YUI Doc' => { cats: [ 4 ], html: /<html[^>]* yuilibrary\.com\/rdf\/[0-9.]+\/yui\.rdf/i },
344
+ 'YUI' => { cats: [ 12 ], script: /\/yui\/|yui\.yahooapis\.com/, env: /^YAHOO$/ },
345
+ 'Zen Cart' => { cats: [ 6 ], meta: { 'generator' => /Zen Cart/i } },
346
+ 'Zend' => { cats: [ 22 ], headers: { 'X-Powered-By' => /Zend/ } },
347
+ 'Zepto' => { cats: [ 12 ], script: /zepto.*.js/, env: /^Zepto$/ }
348
+ }
349
+ end
@@ -0,0 +1,3 @@
1
+ module WappalyzerRb
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,97 @@
1
+ require "wappalyzer_rb/version"
2
+ require "wappalyzer_rb/apps"
3
+
4
+ module WappalyzerRb
5
+ class Some
6
+ attr_reader :analysis
7
+
8
+ def initialize(url)
9
+ @url = url
10
+ analyze!
11
+ end
12
+
13
+ private
14
+
15
+ def hostname
16
+ @hostname ||= URI.parse(@url).host
17
+ end
18
+
19
+ def data
20
+ response.body
21
+ end
22
+
23
+ def url
24
+ @url
25
+ end
26
+
27
+ def scripts
28
+ @scripts ||= begin
29
+ data.scan(/<script[^>]+src=("|')([^"']+)\1/i).transpose[1] || []
30
+ end
31
+ end
32
+
33
+ def metas
34
+ @metas ||= begin
35
+ data.scan(/<meta[^>]+>/i).flatten.reduce(Hash.new) do |hash, line|
36
+ name = line[/name=("|')([^"']+)\1/, 2]
37
+ content = line[/content=("|')([^"']+)\1/, 2]
38
+
39
+ hash[name] = content
40
+ hash
41
+ end
42
+ end
43
+ end
44
+
45
+ def headers
46
+ response
47
+ end
48
+
49
+ def response
50
+ @response ||= begin
51
+ uri = URI.parse(@url)
52
+ http = Net::HTTP.new(uri.host, uri.port)
53
+ request = Net::HTTP::Get.new(uri.request_uri)
54
+ http.request(request)
55
+ end
56
+ end
57
+
58
+ def analyze!
59
+ @analysis ||= begin
60
+ matched_apps = []
61
+
62
+ APPS.each do |app, tells|
63
+ tells.each do |type, matcher|
64
+ next if type == :cats
65
+
66
+ case type
67
+ when :url
68
+ matched_apps << app if url =~ matcher
69
+ when :html
70
+ matched_apps << app if data =~ matcher
71
+ when :script
72
+ if scripts.any?{|script| script =~ matcher}
73
+ matched_apps << app
74
+ end
75
+ when :meta
76
+ matcher.each do |name, content_rx|
77
+ if metas[name] =~ content_rx
78
+ matched_apps << app
79
+ end
80
+ end
81
+ when :headers
82
+ matcher.each do |type, content_rx|
83
+ if headers[type.downcase] =~ content_rx
84
+ matched_apps << app
85
+ end
86
+ end
87
+ when :env
88
+ # Not way to peer into the page's DOM yet
89
+ end
90
+ end
91
+ end
92
+
93
+ matched_apps.uniq
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe WappalyzerRb::Some do
4
+ let(:mock_response) do
5
+ mock(:response, body: "nobody", :[] => nil)
6
+ end
7
+
8
+ it "should initialize" do
9
+ WappalyzerRb::Some.any_instance.stub(:response).and_return(mock_response)
10
+ WappalyzerRb::Some.new('http://someurl.com')
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'wappalyzer_rb'
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "wappalyzer_rb/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "wappalyzer_rb"
7
+ s.version = WappalyzerRb::VERSION
8
+ s.authors = ["Kostas Karachalios"]
9
+ s.email = ["kostas.karachalios@me.com"]
10
+ s.homepage = "https://github.com/vrinek/wappalyzer-ruby"
11
+ s.summary = %q{Analyzes a provided url and returns any services it can detect}
12
+ s.description = %q{This is merely a port of the javascript parts of Wappalyzer extension for Firefox and Chrome}
13
+
14
+ s.rubyforge_project = "wappalyzer_rb"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec"
23
+ s.add_development_dependency "guard"
24
+ s.add_development_dependency "guard-rspec"
25
+ # s.add_runtime_dependency "rest-client"
26
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wappalyzer_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kostas Karachalios
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: guard
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: This is merely a port of the javascript parts of Wappalyzer extension
63
+ for Firefox and Chrome
64
+ email:
65
+ - kostas.karachalios@me.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - Guardfile
74
+ - README.md
75
+ - Rakefile
76
+ - lib/wappalyzer_rb.rb
77
+ - lib/wappalyzer_rb/apps.rb
78
+ - lib/wappalyzer_rb/version.rb
79
+ - spec/lib/wappalyzer_rb_spec.rb
80
+ - spec/spec_helper.rb
81
+ - wappalyzer_rb.gemspec
82
+ homepage: https://github.com/vrinek/wappalyzer-ruby
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project: wappalyzer_rb
102
+ rubygems_version: 1.8.24
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Analyzes a provided url and returns any services it can detect
106
+ test_files: []
107
+ has_rdoc: