wordstress 0.15.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 559b014cd3100530e2a30f54da9bbebcd37530c4
4
- data.tar.gz: 0398ef2797138d181fba62c84609456e5a1e4d76
3
+ metadata.gz: b75716cca39e58a1207a5d4901dbc878ca553fcd
4
+ data.tar.gz: d63b16b6134ba9640c627d45a535714f36fb968c
5
5
  SHA512:
6
- metadata.gz: a1c1a877d30ef0557957ac1bc2f56bedc33653e78cb16b0c014ba667a38fb5ef3b8572cfe93e09ba06f97e0980de749270f815034d914cf159bae93371d50ab9
7
- data.tar.gz: 0b9cc780b6a570919b72aa637b6f86c00c63ac6a91fc3eac59c5f547113cc7232d70e42f2d9af01aca9da9444d388989f1ee0f356f2257babf30b23ceb03eaa0
6
+ metadata.gz: 968b67f94189455ee2f9c88efd70153283bd3dd74a00570cf0173c06f7dc0e80e4e707e533de464a68630a11df0df375f96e1d73d5ca6dc54c2b6308b15775f4
7
+ data.tar.gz: 20c5b07abad346fd080ede674850d9e0d0b9a0c5680b46a1423ae24469ad148cc8100cf365a2c7c4e3d32f9ce53af1b0a169188bc3cda59eba8f666d9e9fd91f
data/README.md CHANGED
@@ -27,11 +27,16 @@ During those years I was very upset as pentester with false positives about
27
27
  themes and plugins and their version. Since an authenticated check is necessary
28
28
  to match scan results with installed plugin (or theme) version, I tought it was
29
29
  a better idea to start authenticated from the beginning.
30
+ ** UPDATE ** - this can be very tricky to accomplish
30
31
 
31
32
  Of course, wordstress will perform blackbox testing, trying to guess the
32
33
  installed wordpress version and listing vulnerabilities taken from
33
34
  [wpvulndb](https://wpvulndb.com).
34
35
 
36
+ ## Online resource
37
+
38
+ [Attacking Wordpress](http://hackertarget.com/attacking-wordpress/)
39
+
35
40
  ## Killing features
36
41
 
37
42
  * A great knowledge base powered by [wpvulndb API](https://wpvulndb.com)
data/Rakefile CHANGED
@@ -1,5 +1,17 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ namespace :update do
4
+ desc 'Update themes'
5
+ task :themes, :name do |t,args|
6
+
7
+ end
8
+
9
+ desc 'Update plugins'
10
+ task :plugins, :name do |t, args|
11
+
12
+ end
13
+
14
+ end
3
15
  namespace :import do
4
16
  desc 'Import themes'
5
17
  task :themes, :name do |t,args|
data/bin/wordstress CHANGED
@@ -19,12 +19,16 @@ APPNAME = File.basename($0)
19
19
  $logger = Codesake::Commons::Logging.instance
20
20
  @output_root = File.join(Dir.home, '/wordstress')
21
21
  scanning_mode = :gentleman
22
+ interactive = {:url=>"", :pwd=>""}
22
23
 
23
24
  opts = GetoptLong.new(
24
- [ '--gentleman','-G', GetoptLong::NO_ARGUMENT],
25
- [ '--csv', '-C', GetoptLong::NO_ARGUMENT],
26
- [ '--version', '-v', GetoptLong::NO_ARGUMENT],
27
- [ '--help', '-h', GetoptLong::NO_ARGUMENT]
25
+ [ '--gentleman', '-G', GetoptLong::NO_ARGUMENT],
26
+ [ '--interactive','-I', GetoptLong::NO_ARGUMENT],
27
+ [ '--interactive-url', '-u', GetoptLong::REQUIRED_ARGUMENT],
28
+ [ '--interactive-pwd', '-p', GetoptLong::REQUIRED_ARGUMENT],
29
+ [ '--csv', '-C', GetoptLong::NO_ARGUMENT],
30
+ [ '--version', '-v', GetoptLong::NO_ARGUMENT],
31
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT]
28
32
  )
29
33
 
30
34
  opts.quiet=true
@@ -32,6 +36,12 @@ opts.quiet=true
32
36
  begin
33
37
  opts.each do |opt, val|
34
38
  case opt
39
+ when '--interactive'
40
+ scanning_mode = :interactive
41
+ when '--interactive-url'
42
+ interactive[:url] = val
43
+ when '--interactive-pwd'
44
+ interactive[:pwd] = val
35
45
  when '--version'
36
46
  puts "#{Wordstress::VERSION}"
37
47
  Kernel.exit(0)
@@ -63,7 +73,7 @@ trap("INT") { $logger.die('[INTERRUPTED]') }
63
73
  $logger.die("missing target") if target.nil?
64
74
 
65
75
  $logger.log "scanning #{target}"
66
- site = Wordstress::Site.new({:target=>target, :scanning_mode=>scanning_mode})
76
+ site = Wordstress::Site.new({:target=>target, :scanning_mode=>scanning_mode, :interactive=>interactive})
67
77
 
68
78
  if site.version[:version] == "0.0.0"
69
79
  $logger.err "can't detect wordpress version running on #{target}. Giving up!"
@@ -5,7 +5,7 @@ module Wordstress
5
5
 
6
6
  attr_reader :version, :scanning_mode, :wp_vuln_json, :plugins, :themes, :themes_vuln_json
7
7
 
8
- def initialize(options={:target=>"http://localhost", :scanning_mode=>:gentleman})
8
+ def initialize(options={:target=>"http://localhost", :scanning_mode=>:gentleman, :interactive=>{}})
9
9
  begin
10
10
  @uri = URI(options[:target])
11
11
  @raw_name = options[:target]
@@ -24,6 +24,8 @@ module Wordstress
24
24
  @wp_vuln_json = get_wp_vulnerabilities unless @version[:version] == "0.0.0"
25
25
  @wp_vuln_json = Hash.new.to_json if @version[:version] == "0.0.0"
26
26
 
27
+ @wordstress_page = post_and_get(options[:interactive][:url], options[:interactive][:pwd]) if options[:scanning_mode] == :interactive && !options[:interactive][:pwd].empty?
28
+ @wordstress_page = get(options[:interactive][:url]) if options[:scanning_mode] == :interactive && options[:interactive][:pwd].empty?
27
29
  @plugins = find_plugins
28
30
  @themes = find_themes
29
31
  # @themes_vuln_json = get_themes_vulnerabilities
@@ -99,9 +101,13 @@ module Wordstress
99
101
 
100
102
  v_rss = ""
101
103
  rss_doc = Nokogiri::HTML(@homepage.body)
102
- rss = Nokogiri::HTML(get(rss_doc.css('link[type="application/rss+xml"]').first.attr('href')).body)
104
+ begin
105
+ rss = Nokogiri::HTML(get(rss_doc.css('link[type="application/rss+xml"]').first.attr('href')).body) unless l.nil?
106
+ v_rss= rss.css('generator').text.split('=')[1]
107
+ rescue => e
108
+ v_rss = "0.0.0"
109
+ end
103
110
 
104
- v_rss= rss.css('generator').text.split('=')[1]
105
111
 
106
112
  return {:version => v_meta, :accuracy => 1.0} if v_meta == v_readme && v_meta == v_rss
107
113
  return {:version => v_meta, :accuracy => 0.8} if v_meta == v_readme || v_meta == v_rss
@@ -123,11 +129,13 @@ module Wordstress
123
129
  end
124
130
 
125
131
  def find_themes
126
- return find_themes_gentleman if @scanning_mode == :gentleman
132
+ return find_themes_gentleman if @scanning_mode == :gentleman
133
+ return find_themes_interactive if @scanning_mode == :interactive
127
134
  return []
128
135
  end
129
136
  def find_plugins
130
137
  return find_plugins_gentleman if @scanning_mode == :gentleman
138
+ return find_plugins_interactive if @scanning_mode == :interactive
131
139
 
132
140
  # bruteforce check must start with error page discovery.
133
141
  # the idea is to send 2 random plugin names (e.g. 2 sha256 of time seed)
@@ -136,14 +144,42 @@ module Wordstress
136
144
  return []
137
145
  end
138
146
 
147
+ def post_and_get(url, pass)
148
+ uri = URI(url)
149
+ res = Net::HTTP.post_form(uri, {'post_password' => pass, 'Submit'=>'Submit'})
150
+ get(url)
151
+ res.body
152
+ end
153
+
139
154
  private
155
+ def find_plugins_interactive
156
+ ret = []
157
+ doc = Nokogiri::HTML(@wordstress_page.body)
158
+ doc.css('#all_plugin').each do |link|
159
+ l=link.text.split(',')
160
+ ret << {:name=>l[2], :version=>l[1], :status=>l[3]}
161
+ end
162
+ $logger.debug ret
163
+ ret
164
+ end
165
+ def find_themes_interactive
166
+ ret = []
167
+ doc = Nokogiri::HTML(@wordstress_page.body)
168
+ doc.css('#all_theme').each do |link|
169
+ l=link.text.split(',')
170
+ ret << {:name=>l[2], :version=>l[1]}
171
+ end
172
+ $logger.debug ret
173
+ ret
174
+ end
175
+
140
176
  def find_themes_gentleman
141
177
  ret = []
142
178
  doc = Nokogiri::HTML(@homepage.body)
143
179
  doc.css('link').each do |link|
144
180
  if link.attr('href').include?("wp-content/themes")
145
181
  theme = theme_name(link.attr('href'))
146
- ret << theme if ret.index(theme).nil?
182
+ ret << {:name=>theme, :version=>""} if ret.index(theme).nil?
147
183
  end
148
184
  end
149
185
  ret
@@ -163,7 +199,7 @@ module Wordstress
163
199
  if ! link.attr('src').nil?
164
200
  if link.attr('src').include?("wp-content/plugins")
165
201
  plugin = plugin_name(link.attr('src'))
166
- ret << plugin if ret.index(plugin).nil?
202
+ ret << {:name=>plugin, :version=>"", :status=>"active"} if ret.index(plugin).nil?
167
203
  end
168
204
  end
169
205
  end
@@ -1,3 +1,3 @@
1
1
  module Wordstress
2
- VERSION = "0.15.0"
2
+ VERSION = "0.20.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wordstress
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paolo Perego
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-26 00:00:00.000000000 Z
11
+ date: 2015-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler