sekureco 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: df8b1826ede11dcfaebae255e3e86b6a137beb8b
4
+ data.tar.gz: 26874f5e0fb27f88b638d623aaf6c490a20debfc
5
+ SHA512:
6
+ metadata.gz: 904a29783ba52f8b40c0b87b2231f428d87ca70a1877319c90060dd554f2a6e0a950c1193080c02ac0d819ae4a7ed0f46edf1bdba47ad056dbbdc71d122e6e36
7
+ data.tar.gz: 7be203e0b10b76f2dca7bac37c47b5017b8e83be03ef61c15b727a1b80ec2f3f44576e3e8aa95a035215d8a076d4cfa4c220a145c722eeb72d2cd921c0826d16
@@ -0,0 +1,65 @@
1
+ require 'nokogiri'
2
+ require 'uri'
3
+
4
+ module Sekureco
5
+
6
+ class HtmlPage
7
+ def initialize html_doc
8
+ @html_doc = Nokogiri::HTML(html_doc)
9
+ end
10
+
11
+ def content
12
+ @html_doc.to_html
13
+ end
14
+
15
+ def body
16
+ @html_doc.css("body").to_html
17
+ end
18
+
19
+ def parsed_body black_list = []
20
+ html = self.body.dup
21
+ black_list.each { |word| html.gsub! word, "" }
22
+ html.gsub(/(name=\"authenticity_token\" value=\".*\"|authenticity_token=[^;]*;|\?([^=]+=[^\&\"]+)+)/, '')
23
+ end
24
+
25
+ def links
26
+ @html_doc.css("a")
27
+ end
28
+
29
+ def scripts_with filter
30
+ @html_doc.css("script.#{filter}")
31
+ end
32
+
33
+ def forms
34
+ @html_doc.css("form")
35
+ end
36
+
37
+ def has_forms?
38
+ @html_doc.at_css("form")
39
+ end
40
+
41
+ def csrf_token
42
+ self.has_csrf_tokens? ? @html_doc.css('meta[name="csrf-token"]').first['content'] : ''
43
+ end
44
+
45
+ def has_csrf_tokens?
46
+ !@html_doc.css('meta[name="csrf-token"]').empty?
47
+ end
48
+
49
+ def to_s
50
+ self.parsed_body
51
+ end
52
+
53
+ def log
54
+ 2.times { puts }
55
+ if self.to_s.include? 'resizerElement'
56
+ puts "Error"
57
+ else
58
+ puts self
59
+ end
60
+ 2.times { puts }
61
+ puts "=" * 80
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,61 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Sekureco
5
+
6
+ class HttpClient
7
+
8
+ include Net
9
+
10
+ def initialize
11
+ @cookies = {}
12
+ end
13
+
14
+ def get uri
15
+ puts "GET #{uri.to_s}"
16
+ HTTP.start(uri.host, uri.port) do |http|
17
+ get_request = HTTP::Get.new uri
18
+ get_request['Cookie'] = cookies
19
+ @curr_response = http.request(get_request)
20
+ set_cookies
21
+ end
22
+ @curr_response
23
+ end
24
+
25
+ def post uri, params = {}
26
+ puts "POST #{uri.to_s}"
27
+ puts "params: #{params}"
28
+ HTTP.start(uri.host, uri.port) do |http|
29
+ post_request = HTTP::Post.new uri
30
+ post_request['Cookie'] = cookies
31
+ post_request.set_form_data(params)
32
+ @curr_response = http.request(post_request)
33
+ set_cookies
34
+ end
35
+ @curr_response
36
+ end
37
+
38
+ private
39
+
40
+ def set_cookies
41
+ unless @curr_response.nil?
42
+ new_cookies = @curr_response.get_fields('set-cookie')
43
+ unless new_cookies.nil?
44
+ new_cookies.each do |cookie|
45
+ key, value = cookie.split("; ").first.split("=")
46
+ @cookies[key] = value
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def cookies
53
+ cookies_field = []
54
+ @cookies.each do |k, v|
55
+ cookies_field << "#{k}=#{v}"
56
+ end
57
+ cookies_field.join("; ")
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,125 @@
1
+ require_relative 'html_page'
2
+ require_relative 'http_client'
3
+
4
+ module Sekureco
5
+
6
+ class WebCrawler
7
+
8
+ def initialize url, port, username = nil, password = nil, app_token = 'foo'
9
+ @uri = URI "#{url}:#{port}/"
10
+ @http_client = HttpClient.new
11
+ @source_page = HtmlPage.new @http_client.get(@uri).body
12
+ @visited = {}
13
+ @default_username = username
14
+ @default_password = password
15
+ @black_list = []
16
+ @app_token = app_token
17
+ end
18
+
19
+ def crawl
20
+ @queue = [@source_page]
21
+ mark_as_visited @source_page
22
+ @distance = { @source_page => 0 }
23
+ until @queue.empty?
24
+ @current_page = @queue.shift
25
+ @current_page.log
26
+ unless too_deep? @current_page
27
+ test_forms_of @current_page if @current_page.has_forms?
28
+ @current_page.links.each do |current_link|
29
+ next_link = URI.join(@uri.to_s, URI::encode(parse(current_link)))
30
+ next if next_link.path.include? 'logout'
31
+ response = if current_link["data-method"]
32
+ @http_client.post(next_link, { '_method' => current_link['data-method'],
33
+ 'authenticity_token' => @current_page.csrf_token })
34
+ else
35
+ @http_client.get(next_link)
36
+ end
37
+ next_page = HtmlPage.new(response.body)
38
+ unless already_visited?(next_page)
39
+ next_page.log
40
+ mark_as_visited next_page
41
+ update_distance next_page
42
+ @queue << next_page
43
+ end
44
+ end
45
+ end
46
+ @vulnerabilities = true if detect_embedded_scripts_in(@current_page)
47
+ puts "funcionou" if @vulnerabilities
48
+ end
49
+ end
50
+
51
+ def test_forms_of html_page
52
+ html_page.forms.each do |form|
53
+ params = {}
54
+ form.css("input, textarea").each do |input|
55
+ field_name = input['name']
56
+ next if field_name.nil?
57
+ if field_name.include? "password"
58
+ params[field_name] = @default_password || random_string
59
+ elsif possible_login_fields.any? { |s| field_name.include? s }
60
+ params[field_name] = @default_username || random_string
61
+ else
62
+ params[field_name] = input['value'] || input['content'] || xss_attack
63
+ end
64
+ end
65
+ response = @http_client.post(URI.join(@uri.to_s, form['action']), params)
66
+ next_page = HtmlPage.new(response.body)
67
+ unless already_visited?(next_page)
68
+ next_page.log
69
+ mark_as_visited next_page
70
+ update_distance next_page
71
+ @queue << next_page
72
+ end
73
+ end
74
+ end
75
+
76
+ def test_application
77
+ 2.times { self.crawl }
78
+ @vulnerabilities
79
+ end
80
+
81
+ private
82
+
83
+ def mark_as_visited page
84
+ @visited[page.parsed_body] = true
85
+ end
86
+
87
+ def already_visited? page
88
+ @visited[page.parsed_body]
89
+ end
90
+
91
+ def update_distance page
92
+ @distance[page] = @distance[@current_page] + 1
93
+ end
94
+
95
+ def too_deep? page
96
+ @distance[page] >= 2
97
+ end
98
+
99
+ def possible_login_fields
100
+ %w(username user name email login)
101
+ end
102
+
103
+ def random_string
104
+ @random_string ||= (0..(1 + rand(16))).map { ('a'..'z').to_a[rand(26)] }.join
105
+ end
106
+
107
+ def xss_attack
108
+ "<script class='#{@app_token}'>alert('It worked!');</script>"
109
+ end
110
+
111
+ def detect_embedded_scripts_in html_page
112
+ html_page.scripts_with(@app_token).any?
113
+ end
114
+
115
+ def parse link
116
+ uri = URI::parse(link["href"])
117
+ if uri.query
118
+ uri.path + "?" + uri.query
119
+ else
120
+ uri.path
121
+ end
122
+ end
123
+ end
124
+
125
+ end
data/lib/sekureco.rb ADDED
@@ -0,0 +1,9 @@
1
+ require_relative 'sekureco/web_crawler'
2
+
3
+ default_email = "joao-bonfim"
4
+ default_password = "test"
5
+ website = "http://localhost"
6
+ puts "Crawling #{website}"
7
+ 2.times { puts }
8
+ wc = Sekureco::WebCrawler.new(website, 3000, default_email, default_password)
9
+ puts wc.test_application
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sekureco
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pedro de Lyra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A tool to perform penetration tests on web applications
14
+ email: pedrodelyra@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/sekureco.rb
20
+ - lib/sekureco/html_page.rb
21
+ - lib/sekureco/http_client.rb
22
+ - lib/sekureco/web_crawler.rb
23
+ homepage: http://rubygems.org/gems/sekureco
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.6.11
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Pentest automation tool
47
+ test_files: []