wordstress 0.0.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9301fb80995974a668a7245491db622a632666ca
4
- data.tar.gz: 7c5d509f3ccbc31daf5ce31530dc8c2c52fffe9d
3
+ metadata.gz: 95999506c82f7c592ba1519d3135c0e374bb7d7d
4
+ data.tar.gz: d98e8756e937c3ff926036ea34ab8111be6b030d
5
5
  SHA512:
6
- metadata.gz: 3db58fd8f50d296511f44936ca1094f591914b100da227aba099ff3b904227ee4621a8b828c6b4e115efd6e71332d79f2263e0bda482464b59778bc47f898313
7
- data.tar.gz: c09c73dec2c66493bde8b7a1499f2a52f2af34c45704e4c15f619555aadadcdc3055dbdf3197a8a7ed2a37b7ed94be88a04c6b6d688ad83429cbd83f9c6c9dbf
6
+ metadata.gz: d0e4d4519077f8a3beb10db5733d4ac98e68cc74a0eae589c4ae69fad7767233013f573d9ffdefeed2bd0b46b8a45d683aed1c5dc4b834ac6403702908e80d13
7
+ data.tar.gz: 189f863ab0ced45cef88ca6c87eed227d59d376db85a57d158cc88e2f428a774a7dc9040536169e687d1e64c622a8c787d69ef5069643911cb462b39f22c88c4
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.sw?
2
+ .rvmrc
2
3
  .DS_Store
3
4
  /.bundle/
4
5
  /.yardoc
data/README.md CHANGED
@@ -30,6 +30,7 @@ I want a security tool that follows 'the ruby way'.
30
30
  * SQL and CSV output. Suitable for script integration
31
31
  * Massive websites scan from text file
32
32
  * SSL server rating using [Qualys SSL Labs rating guide](https://www.ssllabs.com/projects/rating-guide/)
33
+ * Whitebox testing using existing wordpress user
33
34
 
34
35
 
35
36
  ## Installation
data/bin/wordstress ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'getoptlong'
4
+ require 'json'
5
+ require 'codesake-commons'
6
+
7
+ require 'wordstress'
8
+
9
+ APPNAME = File.basename($0)
10
+
11
+ $logger = Codesake::Commons::Logging.instance
12
+
13
+ opts = GetoptLong.new(
14
+ [ '--version', '-v', GetoptLong::NO_ARGUMENT],
15
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT]
16
+ )
17
+
18
+ opts.quiet=true
19
+
20
+ begin
21
+ opts.each do |opt, val|
22
+ case opt
23
+ when '--version'
24
+ puts "#{Wordstress::VERSION}"
25
+ Kernel.exit(0)
26
+ when '--help'
27
+ Kernel.exit(0)
28
+ end
29
+ end
30
+ rescue GetoptLong::InvalidOption => e
31
+ $logger.helo APPNAME, Wordstress::VERSION
32
+ $logger.err e.message
33
+ Kernel.exit(-1)
34
+ end
35
+
36
+ target=ARGV.shift
37
+ $logger.helo APPNAME, Wordstress::VERSION
38
+ $logger.toggle_syslog
39
+
40
+ trap("INT") { $logger.die('[INTERRUPTED]') }
41
+ $logger.die("missing target") if target.nil?
42
+
43
+ $logger.log "scanning #{target}"
44
+ site = Wordstress::Site.new(target)
45
+ $logger.ok "wordpress version #{site.version[:version]} detected"
46
+ wp_vuln_hash = JSON.parse(site.wp_vuln_json)
47
+ $logger.ok "#{wp_vuln_hash["wordpress"]["vulnerabilities"].size} vulnerabilities found due wordpress version"
48
+ wp_vuln_hash["wordpress"]["vulnerabilities"].each do |v|
49
+ $logger.log "#{v["id"]} - #{v["title"]}"
50
+
51
+ end
@@ -0,0 +1,91 @@
1
+ require 'net/http'
2
+
3
+ module Wordstress
4
+ class Site
5
+
6
+ attr_reader :version, :wp_vuln_json
7
+ def initialize(name="")
8
+ begin
9
+ @uri = URI(name)
10
+ @raw_name = name
11
+ @valid = true
12
+ rescue
13
+ @valid = false
14
+ end
15
+
16
+ @robots_txt = get(@raw_name + "/robots.txt")
17
+ @readme_html = get(@raw_name + "/readme.html")
18
+ @homepage = get(@raw_name)
19
+ @version = detect_version
20
+
21
+ @wp_vuln_json = get_wp_vulnerabilities
22
+
23
+ end
24
+
25
+ def get_wp_vulnerabilities
26
+ get_https("https://wpvulndb.com/api/v1/wordpresses/#{version_pad(@version[:version])}").body
27
+ end
28
+
29
+ def version_pad(version)
30
+ # 3.2.1 => 321
31
+ # 4.0 => 400
32
+ return version.gsub('.', '') if version.split('.').count == 3
33
+ return version.gsub('.', '')+'0' if version.split('.').count == 2
34
+ end
35
+
36
+ def detect_version
37
+
38
+ #
39
+ # 1. trying to detect wordpress version from homepage body meta generator
40
+ # tag
41
+
42
+ v_meta = ""
43
+ doc = Nokogiri::HTML(@homepage.body)
44
+ doc.xpath("//meta[@name='generator']/@content").each do |attr|
45
+ v_meta = attr.value.split(' ')[1]
46
+ end
47
+
48
+ #
49
+ # 2. trying to detect wordpress version from readme.html in the root
50
+ # directory
51
+
52
+ v_readme = ""
53
+ doc = Nokogiri::HTML(@readme_html.body)
54
+ v_readme = doc.at_css('h1').children.last.text.chop.lstrip.split(' ')[1]
55
+
56
+ v_rss = ""
57
+ rss_doc = Nokogiri::HTML(@homepage.body)
58
+ rss = Nokogiri::HTML(get(rss_doc.css('link[type="application/rss+xml"]').first.attr('href')).body)
59
+
60
+ v_rss= rss.css('generator').text.split('=')[1]
61
+
62
+ return {:version => v_meta, :accuracy => 1.0} if v_meta == v_readme && v_meta == v_rss
63
+ return {:version => v_meta, :accuracy => 0.8} if v_meta == v_readme || v_meta == v_rss
64
+ end
65
+
66
+ def get(page)
67
+ return get_http(page) if @uri.scheme == "http"
68
+ return get_https(page) if @uri.scheme == "https"
69
+ end
70
+
71
+ def is_valid?
72
+ return @valid
73
+ end
74
+
75
+ private
76
+ def get_http(page)
77
+ uri = URI.parse(page)
78
+ http = Net::HTTP.new(uri.host, uri.port)
79
+ request = Net::HTTP::Get.new(uri.request_uri)
80
+ return http.request(request)
81
+ end
82
+ def get_https(page)
83
+ uri = URI.parse(page)
84
+ http = Net::HTTP.new(uri.host, uri.port)
85
+ http.use_ssl = true
86
+ request = Net::HTTP::Get.new(uri.request_uri)
87
+ return http.request(request)
88
+
89
+ end
90
+ end
91
+ end
@@ -1,3 +1,3 @@
1
1
  module Wordstress
2
- VERSION = "0.0.1"
2
+ VERSION = "0.10.0"
3
3
  end
data/lib/wordstress.rb CHANGED
@@ -1,5 +1,2 @@
1
+ require "wordstress/site"
1
2
  require "wordstress/version"
2
-
3
- module Wordstress
4
- # Your code goes here...
5
- end
data/wordstress.gemspec CHANGED
@@ -20,4 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.add_dependency 'codesake-commons'
25
+ spec.add_dependency 'json'
23
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wordstress
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paolo Perego
@@ -38,10 +38,39 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.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
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  description: wordstress is a security scanner for wordpress powered websites
42
70
  email:
43
71
  - thesp0nge@gmail.com
44
- executables: []
72
+ executables:
73
+ - wordstress
45
74
  extensions: []
46
75
  extra_rdoc_files: []
47
76
  files:
@@ -50,7 +79,9 @@ files:
50
79
  - LICENSE.txt
51
80
  - README.md
52
81
  - Rakefile
82
+ - bin/wordstress
53
83
  - lib/wordstress.rb
84
+ - lib/wordstress/site.rb
54
85
  - lib/wordstress/version.rb
55
86
  - wordstress.gemspec
56
87
  homepage: https://github.com/thesp0nge/wordstress