gengiscan 0.50.0 → 0.60.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fed93cc7ea720d55a5cf3f95b58cabf8d9206f32
4
+ data.tar.gz: fb1dbccd09d5862509583aeab1bc407ff9a5da65
5
+ SHA512:
6
+ metadata.gz: d8b653a0e99b229cf294dcd011e41d8179125c435b928b7bdf9316557107e275061fabfe1d26b3314a8a5be1f67b51d079b7781dda637a497ee035ede37bc4b9
7
+ data.tar.gz: 4d405fad03b5a25ddd8ea2cea099b4ceae66e5c7cfc3af28a4c45bd49c66d649f933e9988acd012e33f3bcc8a9ebdd9564a1a59f290e9c4f18ea7614d3aab4f3
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gengiscan'
3
+ require 'codesake-commons'
3
4
 
5
+ $logger = Codesake::Commons::Logging.instance
4
6
 
7
+ $logger.helo("gengiscan v#{Gengiscan::VERSION} is starting up")
5
8
  puts Gengiscan::Engine.new.detect(ARGV[0])
6
9
 
@@ -16,6 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Gengiscan::VERSION
17
17
 
18
18
  gem.add_dependency('nokogiri')
19
+ gem.add_dependency('mechanize')
20
+ gem.add_dependency('codesake-commons')
19
21
  gem.add_development_dependency('rake')
20
22
  gem.add_development_dependency('rspec')
21
23
  gem.add_development_dependency('webmock')
@@ -1,59 +1,200 @@
1
- require 'net/http'
2
1
  require 'nokogiri'
2
+ require 'mechanize'
3
+ require 'digest/md5'
3
4
 
4
5
  module Gengiscan
5
6
  class Engine
6
7
 
7
-
8
8
  attr_reader :res
9
9
  attr_reader :body
10
10
 
11
-
12
-
13
11
  def initialize
12
+
14
13
  end
15
14
 
16
-
15
+
17
16
  def detect(url)
18
17
  uri = URI(url)
19
- begin
20
- res = Net::HTTP.get_response(uri)
21
- body = check_for_phpinfo(uri)
22
- {:status=>:OK, :message=> nil, :code=>res.code, :server=>res['Server'], :powered=>res['X-Powered-By'], :generator=>get_generator_signature(res), :php_info=>! body.empty?}
18
+ agent = Mechanize.new
19
+ page = agent.get(url)
20
+
21
+ begin
22
+ phpbb = {:cookies=>{:version=>"", :detected=>false}, :body=>{:version=>"", :detected=>false}, :changelog=>{:version=>"", :detected=>false}, :style=>{:version=>"", :detected=>false}}
23
+ phpbb[:cookies] = phpbb_cookie_detect(agent.cookies)
24
+ phpbb[:body] = phpbb_body_detect(page)
25
+ phpbb[:changelog] = nil
26
+
27
+ changelog_html = agent.get(url+'/docs/CHANGELOG.html')
28
+ phpbb[:changelog] = phpbb_changelog_checksum(changelog_html.body)
29
+ phpbb[:style] = phpbb_theme_cfg_detect(page, url, agent)
30
+
31
+ {:status=>:OK, :code=>page.code, :server=>page.header['server'], :powered=>page.header['X-Powered-By'], :generator=>get_generator_signature(page.body), :message=>""} unless is_phpbb?(phpbb)
32
+ {:status=>:OK, :code=>page.code, :server=>page.header['server'], :powered=>page.header['X-Powered-By'], :generator=>get_generator_signature(page.body), :message=>"", :cms=>"phpbb", :version=>get_phpbb_version(phpbb)} if is_phpbb?(phpbb)
23
33
  rescue => e
24
- {:status=>:KO, :message=>e.message, :code=>nil, :server=>nil, :powered=>nil, :generator=>nil, :php_info=>nil}
34
+
35
+ $logger.err("detect(): #{e.message}")
36
+ {:status=>:OK, :code=>page.code, :server=>page.header['server'], :powered=>page.header['X-Powered-By'], :generator=>get_generator_signature(page.body), :message=>e.message}
37
+
25
38
  end
26
39
  end
27
40
 
28
41
  private
29
42
 
30
- def get_generator_signature(res)
31
- generator = ""
32
- doc=Nokogiri::HTML(res.body)
33
- doc.xpath("//meta[@name='generator']/@content").each do |value|
34
- generator = value.value
43
+ def is_phpbb?(p)
44
+ return true if p[:style][:detected] || p[:changelog][:detected] || p[:cookies][:detected] || p[:body][:detected]
45
+ false
46
+ end
47
+
48
+ def get_phpbb_version(p)
49
+ return p[:style][:version] if p[:style][:detected]
50
+ return p[:changelog][:version] if p[:changelog][:detected]
51
+ return p[:cookies][:version] if p[:cookies][:detected]
52
+
53
+ "unknown"
54
+
55
+ end
56
+
57
+ def phpbb_changelog_checksum(content="")
58
+ changelog_hashes = [
59
+ { :md5=>'3a3a98deb01ca9a41d60d0cd30f61e22', :version=>'2.0.4' },
60
+ { :md5=>'d469f1cee34e4fb55f265bec0f0c14a8', :version=>'2.0.5' },
61
+ { :md5=>'5905fc107b1a68762ac0d06c0fecc7b9', :version=>'2.0.6' },
62
+ { :md5=>'7e9a7f6fb9aa3fc3debbdc09ca1941de', :version=>'2.0.7' },
63
+ { :md5=>'d0406ed8e5cf4bd82192f3c88bb7fcd2', :version=>'2.0.8' },
64
+ { :md5=>'734f0ecaeb1dc40ce64c1af60d082dcc', :version=>'2.0.8a' },
65
+ { :md5=>'603328ab56f740a8eba90d435132da9f', :version=>'2.0.9' },
66
+ { :md5=>'6dca72f720e5fd098e33e06ff7617bc2', :version=>'2.0.10' },
67
+ { :md5=>'1e11b01aac9fe84682596d2fa38c9265', :version=>'2.0.11' },
68
+ { :md5=>'7262663177c2cb9440a3250989de1847', :version=>'2.0.12' },
69
+ { :md5=>'11771948789983e496646c12eb2709e6', :version=>'2.0.13' },
70
+ { :md5=>'bd9d2285839fb7e15a556f0ba2f7ae2c', :version=>'2.0.14' },
71
+ { :md5=>'d636b63d299cbfb2948450e80d5be7d6', :version=>'2.0.15' },
72
+ { :md5=>'d4d2f1e38096a4b32e22dff57773c62d', :version=>'2.0.16' },
73
+ { :md5=>'bb29b25a9734d10328f970001f0295b3', :version=>'2.0.17' },
74
+ { :md5=>'3058647f25b2d3d4804cd8e3e69a938f', :version=>'2.0.18' },
75
+ { :md5=>'4880b1bc3a16771e934b7f69b4d87f2e', :version=>'2.0.19' },
76
+ { :md5=>'b90c8f20ebfb920cc9ac332b60960cef', :version=>'2.0.20' },
77
+ { :md5=>'90520361b651f583853fc7058fe10256', :version=>'2.0.21' },
78
+ { :md5=>'4f1e462f7da7df826a07d1cf0faae4ae', :version=>'2.0.22' },
79
+ { :md5=>'3eba9db5133b98df8a54abc55be34307', :version=>'2.0.23' },
80
+ { :md5=>'e60f14eba6d00d56956c16f8a94ca140', :version=>'3.0-B5' },
81
+ { :md5=>'e60f14eba6d00d56956c16f8a94ca140', :version=>'3.0-RC1' },
82
+ { :md5=>'565c3b1933cda61295e54c1f141ef8b7', :version=>'3.0-RC2' },
83
+ { :md5=>'f3f30e22403564e99e64d09f7f731dea', :version=>'3.0-RC3' },
84
+ { :md5=>'63b9c4065b2aabda328a1c9b0677f986', :version=>'3.0-RC4' },
85
+ { :md5=>'3d7aed030411838411a91ae4fcd213e4', :version=>'3.0-RC5' },
86
+ { :md5=>'074417fdfca31a8d7349c88e8081d8cd', :version=>'3.0-RC6' },
87
+ { :md5=>'2e139da54418cd096405d58e049bffd9', :version=>'3.0-RC7' },
88
+ { :md5=>'e7de4c40a4fbf920aa0ef8d935564ed2', :version=>'3.0-RC8' },
89
+ { :md5=>'dc1866d542cfcfface533b024ac3da77', :version=>'3.0.0' },
90
+ { :md5=>'cfa612fc182916fd76467cce11c2e708', :version=>'3.0.1' },
91
+ { :md5=>'fe1e7b8f3fc448ebfb7b2c1c5ec1e2d7', :version=>'3.0.1-RC1' },
92
+ { :md5=>'59d04c38f084936b68551a0acccd3ea2', :version=>'3.0.2' },
93
+ { :md5=>'f8b7389f4d5e61d0041430b5986378e2', :version=>'3.0.2-RC1' },
94
+ { :md5=>'59d04c38f084936b68551a0acccd3ea2', :version=>'3.0.2-RC2' },
95
+ { :md5=>'f4a6893faa9918962db5858f8b96c600', :version=>'3.0.3' },
96
+ { :md5=>'f4a6893faa9918962db5858f8b96c600', :version=>'3.0.3-RC1' },
97
+ { :md5=>'d638931f610f6a7073cf7bb43bf6370f', :version=>'3.0.4' },
98
+ { :md5=>'d638931f610f6a7073cf7bb43bf6370f', :version=>'3.0.4-RC1' },
99
+ { :md5=>'931e4dd982451b9baf4dbfa3a6d6da4e', :version=>'3.0.5' },
100
+ { :md5=>'0fdcbb67c9773f490d3f0691a6dd4db9', :version=>'3.0.5-RC1' },
101
+ { :md5=>'aedf28d7599038cf0b07e9404c69ffca', :version=>'3.0.6' },
102
+ { :md5=>'5c40c50b6ca823ced16edac6aa8b2a1e', :version=>'3.0.6-RC1' },
103
+ { :md5=>'38e7d25631ab2238a149c4880b69e42f', :version=>'3.0.6-RC2' },
104
+ { :md5=>'4ac3967261c38fe4e934fe89f55f4a7a', :version=>'3.0.6-RC3' },
105
+ { :md5=>'e1854e1d6c7058eb10aee1d0a2acd01b', :version=>'3.0.6-RC4' },
106
+ { :md5=>'fc9c79e09cd265c44b025f08bd6bce30', :version=>'3.0.7' },
107
+ { :md5=>'9354df71b5f83de36b0e51b833b2917b', :version=>'3.0.7-RC1' },
108
+ { :md5=>'a2a05cfceecb678f843060ca9980dd5a', :version=>'3.0.7-RC2' },
109
+ { :md5=>'ff4e8980be0af81ed2702dc9ef4c5e6c', :version=>'3.0.7-PL1' },
110
+ { :md5=>'30f539c93140b2933765800b81e05707', :version=>'3.0.8' },
111
+ { :md5=>'a544ff00e1242e21210ccc1466c02bac', :version=>'3.0.8-RC1' },
112
+ { :md5=>'3f5c6ba11ff90cff9ced65833bdcfe8a', :version=>'3.0.9' },
113
+ { :md5=>'eca607ffc079c0236bdc281d92c3db86', :version=>'3.0.9-RC1' },
114
+ { :md5=>'94f5af08e7962466d50fcda1c1dc25a0', :version=>'3.0.9-RC2' },
115
+ { :md5=>'ed7033cfc20fdf2b58bdebfb078cf8ae', :version=>'3.0.9-RC3' },
116
+ { :md5=>'3f5c6ba11ff90cff9ced65833bdcfe8a', :version=>'3.0.9-RC4' },
117
+ { :md5=>'4a57a4ad14dc5726fa76aea354c4a7b9', :version=>'3.0.10' },
118
+ { :md5=>'ea02497f03a5a713c89a3a08da7e9818', :version=>'3.0.10-RC1' },
119
+ { :md5=>'a69edd44fff3366c037d543a22d07ac3', :version=>'3.0.10-RC2' },
120
+ { :md5=>'4a57a4ad14dc5726fa76aea354c4a7b9', :version=>'3.0.10-RC3' },
121
+ { :md5=>'38c91a4e7015bd99ea0189be77d131a8', :version=>'3.0.11' } ,
122
+ { :md5=>'69f1aad5d8eb2402f3290828232baced', :version=>'3.0.11-RC1' },
123
+ { :md5=>'38c91a4e7015bd99ea0189be77d131a8', :version=>'3.0.11-RC2' },
124
+ { :md5=>'fbe3fde19e59d20a1c400164e56fe972', :version=>'3.0.12-RC1' },
125
+ { :md5=>'14fefb5e6fc8948aa3ef0aa50ee75571', :version=>'3.0.12-RC2' },
126
+ { :md5=>'a52d4327967adf6b86cd5d18ebd49996', :version=>'3.0.12-RC3' }
127
+ ]
128
+
129
+ chksum = Digest::MD5.hexdigest(content)
130
+ changelog_hashes.each do |hash|
131
+ return {:version=>hash[:version], :detected=>true} if hash[:md5] == chksum
35
132
  end
36
133
 
37
- generator
134
+ {:version=>"", :detected=>false}
38
135
  end
39
136
 
40
- def check_for_phpinfo(uri)
41
- body = ""
42
- r = Net::HTTP.get_response(URI("#{uri.scheme}://#{uri.host}:#{uri.port}/phpinfo.php"))
43
- filename = "#{uri.host}_phpinfo.html"
44
- body = r.body if r.code == "200"
45
- r = Net::HTTP.get_response(URI("#{uri.scheme}://#{uri.host}:#{uri.port}/info.php")) if body.nil?
46
- filename = "#{uri.host}_info.html" if body.nil?
47
- body = r.body if r.code == "200"
137
+ def phpbb_body_detect(page)
138
+ # 1. detect if we have phpbb_logo.gif
139
+ page.images.each do |img|
140
+ return {:version=>"unknown", :detected=>true} if ! (img.src =~ /logo_phpBB.gif/).nil?
141
+ end
142
+
143
+ # 2. check for copyright notice
144
+ return {:version=>"unknown", :detected=>true} if !(page.body =~ /We request you retain the full copyright notice below including the link to www.phpbb.com./).nil?
145
+
146
+ # 3. check for "Powered by" link
147
+ page.links.each do |link|
148
+ return {:version=>"unknown", :detected=>true} if link.href == "http://www.phpbb.com" && link.text.downcase.match("powered by")
149
+ end
150
+ {:version=>"", :detected=>false}
151
+ end
48
152
 
49
- f= File.new(filename, "w")
50
- f.puts(body)
51
- f.close
153
+ def phpbb_theme_cfg_detect(page, url, agent)
52
154
 
155
+ page.links.each do |link|
156
+ theme_name = link.href.match(/styles\/(\w*)\//) unless link.href.nil?
157
+ unless theme_name.nil?
53
158
 
54
- body
159
+ link = url + "/styles/#{theme_name}/style.cfg"
160
+
161
+ $logger.log("trying to fetch #{link}")
162
+ cfg = agent.get(link)
163
+ if cfg.code == "200"
164
+ $logger.ok("style.cfg found!")
165
+ version = cfg.body.match(/version(\s+)=(\s+)(\w.*)/)
166
+ return {:version=>version, :detected=>true}
167
+ end
168
+ end
169
+ end
170
+ {:version=>"", :detected=>false}
55
171
  end
56
172
 
173
+ def phpbb_cookie_detect(cookies=[])
174
+
175
+ first = nil
176
+ second = false
177
+ third = false
178
+
179
+ cookies.each do |c|
180
+ return {:version=>"2", :detected=>true} if c.name =~ /phpbb([\d])mysql_data/
181
+ first = c.name.scan(/([^ ]+)_u/).flatten.first if first.nil?
182
+ second = (c.name == "#{first}_k") if ! second
183
+ third = (c.name == "#{first}_sid") if ! third
184
+ end
185
+ return {:version=>"3", :detected=>true} if ! first.nil? && second && third
186
+ {:version=>"", :detected=>false}
187
+ end
188
+
189
+ def get_generator_signature(body)
190
+ generator = ""
191
+ doc=Nokogiri::HTML(body)
192
+ doc.xpath("//meta[@name='generator']/@content").each do |value|
193
+ generator = value.value
194
+ end
195
+
196
+ generator
197
+ end
57
198
 
58
199
  end
59
200
  end
@@ -1,3 +1,3 @@
1
1
  module Gengiscan
2
- VERSION = "0.50.0"
2
+ VERSION = "0.60.1"
3
3
  end
metadata CHANGED
@@ -1,78 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gengiscan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.50.0
5
- prerelease:
4
+ version: 0.60.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Paolo Perego
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
11
+ date: 2013-09-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: nokogiri
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mechanize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codesake-commons
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
28
53
  - !ruby/object:Gem::Version
29
54
  version: '0'
30
55
  - !ruby/object:Gem::Dependency
31
56
  name: rake
32
57
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
58
  requirements:
35
- - - ! '>='
59
+ - - '>='
36
60
  - !ruby/object:Gem::Version
37
61
  version: '0'
38
62
  type: :development
39
63
  prerelease: false
40
64
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
65
  requirements:
43
- - - ! '>='
66
+ - - '>='
44
67
  - !ruby/object:Gem::Version
45
68
  version: '0'
46
69
  - !ruby/object:Gem::Dependency
47
70
  name: rspec
48
71
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
72
  requirements:
51
- - - ! '>='
73
+ - - '>='
52
74
  - !ruby/object:Gem::Version
53
75
  version: '0'
54
76
  type: :development
55
77
  prerelease: false
56
78
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
79
  requirements:
59
- - - ! '>='
80
+ - - '>='
60
81
  - !ruby/object:Gem::Version
61
82
  version: '0'
62
83
  - !ruby/object:Gem::Dependency
63
84
  name: webmock
64
85
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
86
  requirements:
67
- - - ! '>='
87
+ - - '>='
68
88
  - !ruby/object:Gem::Version
69
89
  version: '0'
70
90
  type: :development
71
91
  prerelease: false
72
92
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
93
  requirements:
75
- - - ! '>='
94
+ - - '>='
76
95
  - !ruby/object:Gem::Version
77
96
  version: '0'
78
97
  description: gengiscan is a CMS fingerprinting tool using Generator meta tag and Server
@@ -99,33 +118,26 @@ files:
99
118
  - spec/spec_helper.rb
100
119
  homepage: ''
101
120
  licenses: []
121
+ metadata: {}
102
122
  post_install_message:
103
123
  rdoc_options: []
104
124
  require_paths:
105
125
  - lib
106
126
  required_ruby_version: !ruby/object:Gem::Requirement
107
- none: false
108
127
  requirements:
109
- - - ! '>='
128
+ - - '>='
110
129
  - !ruby/object:Gem::Version
111
130
  version: '0'
112
- segments:
113
- - 0
114
- hash: 742138534975512519
115
131
  required_rubygems_version: !ruby/object:Gem::Requirement
116
- none: false
117
132
  requirements:
118
- - - ! '>='
133
+ - - '>='
119
134
  - !ruby/object:Gem::Version
120
135
  version: '0'
121
- segments:
122
- - 0
123
- hash: 742138534975512519
124
136
  requirements: []
125
137
  rubyforge_project:
126
- rubygems_version: 1.8.24
138
+ rubygems_version: 2.0.4
127
139
  signing_key:
128
- specification_version: 3
140
+ specification_version: 4
129
141
  summary: gengiscan is a CMS fingerprinting tool using Generator meta tag and Server
130
142
  HTTP response header to fingerpring a CMS used by a website
131
143
  test_files: