gitrob 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +47 -0
  7. data/Rakefile +2 -0
  8. data/bin/gitrob +258 -0
  9. data/gitrob.gemspec +36 -0
  10. data/lib/gitrob.rb +116 -0
  11. data/lib/gitrob/github/blob.rb +41 -0
  12. data/lib/gitrob/github/http_client.rb +127 -0
  13. data/lib/gitrob/github/organization.rb +93 -0
  14. data/lib/gitrob/github/repository.rb +72 -0
  15. data/lib/gitrob/github/user.rb +78 -0
  16. data/lib/gitrob/observers/sensitive_files.rb +82 -0
  17. data/lib/gitrob/progressbar.rb +52 -0
  18. data/lib/gitrob/util.rb +11 -0
  19. data/lib/gitrob/version.rb +3 -0
  20. data/lib/gitrob/webapp.rb +76 -0
  21. data/models/blob.rb +35 -0
  22. data/models/finding.rb +14 -0
  23. data/models/organization.rb +32 -0
  24. data/models/repo.rb +22 -0
  25. data/models/user.rb +28 -0
  26. data/patterns.json +303 -0
  27. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  28. data/public/fonts/glyphicons-halflings-regular.svg +229 -0
  29. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  30. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  31. data/public/javascripts/bootstrap.min.js +7 -0
  32. data/public/javascripts/gitrob.js +75 -0
  33. data/public/javascripts/jquery-2.1.1.min.js +4 -0
  34. data/public/javascripts/lang-apollo.js +2 -0
  35. data/public/javascripts/lang-basic.js +3 -0
  36. data/public/javascripts/lang-clj.js +18 -0
  37. data/public/javascripts/lang-css.js +2 -0
  38. data/public/javascripts/lang-dart.js +3 -0
  39. data/public/javascripts/lang-erlang.js +2 -0
  40. data/public/javascripts/lang-go.js +1 -0
  41. data/public/javascripts/lang-hs.js +2 -0
  42. data/public/javascripts/lang-lisp.js +3 -0
  43. data/public/javascripts/lang-llvm.js +1 -0
  44. data/public/javascripts/lang-lua.js +2 -0
  45. data/public/javascripts/lang-matlab.js +6 -0
  46. data/public/javascripts/lang-ml.js +2 -0
  47. data/public/javascripts/lang-mumps.js +2 -0
  48. data/public/javascripts/lang-n.js +4 -0
  49. data/public/javascripts/lang-pascal.js +3 -0
  50. data/public/javascripts/lang-proto.js +1 -0
  51. data/public/javascripts/lang-r.js +2 -0
  52. data/public/javascripts/lang-rd.js +1 -0
  53. data/public/javascripts/lang-scala.js +2 -0
  54. data/public/javascripts/lang-sql.js +2 -0
  55. data/public/javascripts/lang-tcl.js +3 -0
  56. data/public/javascripts/lang-tex.js +1 -0
  57. data/public/javascripts/lang-vb.js +2 -0
  58. data/public/javascripts/lang-vhdl.js +3 -0
  59. data/public/javascripts/lang-wiki.js +2 -0
  60. data/public/javascripts/lang-xq.js +3 -0
  61. data/public/javascripts/lang-yaml.js +2 -0
  62. data/public/javascripts/prettify.js +30 -0
  63. data/public/javascripts/run_prettify.js +34 -0
  64. data/public/stylesheets/bootstrap.min.css +7 -0
  65. data/public/stylesheets/bootstrap.min.css.vanilla +5 -0
  66. data/public/stylesheets/gitrob.css +88 -0
  67. data/public/stylesheets/prettify.css +51 -0
  68. data/spec/lib/gitrob/observers/sensitive_files_spec.rb +558 -0
  69. data/spec/spec_helper.rb +127 -0
  70. data/views/blob.erb +22 -0
  71. data/views/index.erb +32 -0
  72. data/views/layout.erb +30 -0
  73. data/views/organization.erb +126 -0
  74. data/views/repository.erb +51 -0
  75. data/views/user.erb +51 -0
  76. metadata +317 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2644a28d02e265e64b4217080b1b3dece92f499d
4
+ data.tar.gz: e6540cad01070d9bc0c7329c90e70ce0f498b53b
5
+ SHA512:
6
+ metadata.gz: df03cc1140011bfacab7d828b31af4c2ed62acd3d86ffbdaf1ab33c40a5ba580b1aaac24b2cef43ba400926c9d2f108a6439474a311fe6554db49fc0cce6437e
7
+ data.tar.gz: 772f06c99dd5b3c3012e676629fad0cdfc0478f3dfa0e066647828adb910a32b13b0be1314143389a7520295a29223624a1698da5fe6c07450462026df29f682
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.swp
15
+ mkmf.log
16
+ .ruby-version
17
+ .ruby-gemset
18
+ agreement
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gitrob.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michael Henriksen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Gitrob
2
+
3
+ Developers generally like to share their code, and many of them do so by open sourcing it on GitHub, a social code hosting and collaboration service. Many companies also use GitHub as a convenient place to host both private and public code repositories by creating GitHub organizations where employees can be joined.
4
+
5
+ Sometimes employees might publish things that should not be publicly available, things that contain sensitive information or things that could even lead to direct compromise of a system. This can happen by accident or because the employee does not know the sensitivity of the information.
6
+
7
+ Gitrob is a command line tool that can help organizations and security professionals find such sensitive information. The tool will iterate over all public organization and member repositories and match filenames against a range of patterns for files, that typically contain sensitive or dangerous information.
8
+
9
+ Read the [blog post](http://michenriksen.com/blog/gitrob-putting-the-open-source-in-osint/) for more information and screenshots.
10
+
11
+ ## How it works
12
+
13
+ Looking for sensitive information in GitHub repositories is not a new thing, it has been [known for a while](http://blog.conviso.com.br/2013/06/github-hacking-for-fun-and-sensitive.html) that things such as private keys and credentials can be found with GitHub's search functionality, however Gitrob makes it easier to focus the effort on a specific organization.
14
+
15
+ The first thing the tool does is to collect all public repositories of the organization itself. It then goes on to collect all the organization members and their public repositories, in order to compile a list of repositories that might be related or have relevance to the organization.
16
+
17
+ When the list of repositories has been compiled, it proceeds to gather all the filenames in each repository and runs them through a series of observers that will flag the files, if they match any patterns of known sensitive files. This step might take a while if the organization is big or if the members have a lot of public repositories.
18
+
19
+ All of the members, repositories and files will be saved to a PostgreSQL database. When everything has been sifted through, it will start a Sinatra web server locally on the machine, which will serve a simple web application to present the collected data for analysis.
20
+
21
+ ## Installation
22
+
23
+ Gitrob is written in Ruby and requires at least version 1.9.3 or above. If you are on an older version, it is very easy to install newer versions with [RVM](http://rvm.io/). If you are installing Gitrob on [Kali](http://www.kali.org/), you are almost good to go, you just need to update Bundler with `gem install bundler` and install a PostgreSQL dependency with `apt-get install libpq-dev` in a terminal.
24
+
25
+ Gitrob is a Ruby gem, so installation is a simple `gem install gitrob` in a terminal. This will automatically install all the code dependencies as well.
26
+
27
+ A [PostgreSQL](http://www.postgresql.org/) database is also needed for Gitrob to store its data. Installing PostgreSQL is pretty straight forward; here is an installation guide for [Mac OS X](http://www.gotealeaf.com/blog/how-to-install-postgresql-on-a-mac) and one for [Ubuntu/Debian](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-14-04) based Linux. If you're installing Gitrob on Kali, you already have PostgreSQL installed, however you need to start the server with `service postgresql start` in a terminal.
28
+
29
+ The last thing we need is a GitHub access token in order to be able to talk to their API. The easiest way is to create a [personal access token](https://github.com/settings/applications). If you plan on using Gitrob extensively or on a very big organization, it might be necessary to have multiple access tokens to prevent running into rate limiting, but they need to be from different user accounts.
30
+
31
+ When everything is ready, simply run `gitrob --configure` and you will be presented with a configuration wizard that asks you for database connection details and GitHub access tokens. All of this configuration can be changed by running the same command again. The configuration will be saved in `~/.gitrobrc` - and yes, Gitrob is looking for this file too so watch out.
32
+
33
+ When everything is set up, you can start analyzing organizations by running `gitrob -o <orgname>` in a terminal. To see options, use `gitrob --help`.
34
+
35
+ ## Contributing
36
+
37
+ Gitrob should be considered Beta and there is probably a good amount of bugs. Bug reports and suggestions for improvements are welcome!
38
+
39
+ Another way to help out is to contribute new patterns for sensitive files. If you know of any sensitive files that are not already identified, please submit them in a pull request. I am especially interested in sensitive web framework files and configuration files. Have a look at the [patterns.json](https://github.com/michenriksen/gitrob/blob/master/patterns.json) file to see what is already looked for.
40
+
41
+ ### How to make a pull request:
42
+
43
+ 1. Fork it ( https://github.com/michenriksen/gitrob/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/gitrob ADDED
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'gitrob'
5
+
6
+ class App
7
+ include Methadone::Main
8
+
9
+ leak_exceptions true
10
+
11
+ main do
12
+ Thread.abort_on_exception = true
13
+ Paint.mode = 0 if options.include?('no-color')
14
+
15
+ puts Paint[Gitrob::banner, :bright, :blue] unless options.include?('no-banner')
16
+ Gitrob::status("Starting Gitrob version #{Gitrob::VERSION} at #{Time.now.strftime("%Y-%m-%d %I:%S %Z")}")
17
+
18
+ if !Gitrob::agreement_accepted?
19
+ puts Gitrob::agreement
20
+ print Paint["\n\nDo you agree to the terms of use? [y/n]: ", :bright, :green]
21
+ choice = $stdin.gets.chomp
22
+ if %w{y yes}.include?(choice)
23
+ Gitrob::agreement_accepted
24
+ else
25
+ Gitrob::fatal("Exiting Gitrob.")
26
+ end
27
+ end
28
+
29
+ if !Gitrob::configured? || options.include?('configure')
30
+ Gitrob::status("Starting Gitrob configuration wizard\n\n")
31
+
32
+ hostname = ask("#{Paint[" Enter PostgreSQL hostname:", :bright, :white]} ") { |q| q.default = "localhost" }
33
+ port = ask("#{Paint[" Enter PostgreSQL port:", :bright, :white]} ", Integer) { |q| q.default = 5432; q.in = 1..65535 }
34
+ username = ask("#{Paint[" Enter PostgreSQL username:", :bright, :white]} ")
35
+ password = ask("#{Paint[" Enter PostgreSQL password for #{username} (masked):", :bright, :white]} ") { |q| q.echo = 'x' }
36
+ database = ask("#{Paint[" Enter PostgreSQL database name:", :bright, :white]} ") { |q| q.default = 'gitrob' }
37
+
38
+ access_tokens = Array.new
39
+ while access_tokens.uniq.empty?
40
+ access_tokens = ask(Paint[" Enter GitHub access tokens (blank line to stop):", :bright, :white],
41
+ lambda { |ans| ans =~ /[a-f0-9]{40}/ ? ans : nil } ) do |q|
42
+ q.gather = ""
43
+ end
44
+ end
45
+
46
+ config = {
47
+ 'sql_connection_uri' => "postgres://#{username}:#{password}@#{hostname}:#{port}/#{database}",
48
+ 'github_access_tokens' => access_tokens.uniq
49
+ }
50
+
51
+ Gitrob::task("Saving configuration to file...") do
52
+ Gitrob::save_configuration!(config)
53
+ end
54
+
55
+ exit unless options['organization']
56
+ end
57
+
58
+ Gitrob::task("Loading configuration...") do
59
+ Gitrob::load_configuration!
60
+ end
61
+
62
+ Gitrob::task("Preparing SQL database...") do
63
+ Gitrob::prepare_database!
64
+ end
65
+
66
+ if options['reset-db']
67
+ Gitrob::task("Resetting database tables...") do
68
+ DataMapper::auto_migrate!
69
+ end
70
+ exit
71
+ end
72
+
73
+ if options['delete']
74
+ Gitrob::delete_organization(options['delete'])
75
+ exit
76
+ end
77
+
78
+ if options['start-server']
79
+ Gitrob::status("Starting web application on http://#{options['bind-address']}:#{options['port']}/...")
80
+ puts "\n\n"
81
+ Gitrob::WebApp.run!(:port => options['port'].to_i, :bind => options['bind-address'])
82
+ exit
83
+ end
84
+
85
+ org_name = options['organization']
86
+ repo_count = 0
87
+ members = Array.new
88
+ http_client = Gitrob::Github::HttpClient.new({:access_tokens => Gitrob::configuration['github_access_tokens']})
89
+ observers = Gitrob::Observers.constants.collect { |c| Gitrob::Observers::const_get(c) }
90
+
91
+ Gitrob::task("Loading file patterns...") do
92
+ Gitrob::Observers::SensitiveFiles::load_patterns!
93
+ end
94
+
95
+ begin
96
+ org = Gitrob::Github::Organization.new(org_name, http_client)
97
+
98
+ Gitrob::delete_organization(org.login)
99
+
100
+ Gitrob::task("Collecting organization repositories...") do
101
+ repo_count = org.repositories.count
102
+ end
103
+ rescue Gitrob::Github::HttpClient::ClientError => e
104
+ if e.status == 404
105
+ Gitrob::fatal("Cannot find GitHub organization with that name; exiting.")
106
+ else
107
+ raise e
108
+ end
109
+ end
110
+
111
+ Gitrob::task("Collecting organization members...") do
112
+ members = org.members
113
+ end
114
+
115
+ progress = Gitrob::ProgressBar.new("Collecting member repositories...",
116
+ :total => members.count
117
+ )
118
+ thread_pool = Thread.pool(options['threads'].to_i)
119
+
120
+ members.each do |member|
121
+ thread_pool.process do
122
+ if member.repositories.count > 0
123
+ repo_count += member.repositories.count
124
+ progress.log("Collected #{Gitrob::Util::pluralize(member.repositories.count, 'repository', 'repositories')} from #{Paint[member.username, :bright, :white]}")
125
+ end
126
+ progress.increment
127
+ end
128
+ end
129
+
130
+ thread_pool.shutdown
131
+
132
+ if repo_count.zero?
133
+ Gitrob::fatal("Organization has no repositories to check; exiting.")
134
+ end
135
+
136
+ progress = Gitrob::ProgressBar.new("Processing repositories...",
137
+ :total => repo_count
138
+ )
139
+
140
+ db_org = org.save_to_database!
141
+ thread_pool = Thread.pool(options['threads'].to_i)
142
+
143
+ org.repositories.each do |repo|
144
+ thread_pool.process do
145
+ begin
146
+ if repo.contents.count > 0
147
+ db_repo = repo.save_to_database!(db_org)
148
+ findings = 0
149
+
150
+ repo.contents.each do |blob|
151
+ db_blob = blob.to_model(db_org, db_repo)
152
+
153
+ observers.each do |observer|
154
+ observer.observe(db_blob)
155
+ end
156
+
157
+ db_blob.findings.each do |f|
158
+ db_blob.findings_count += 1
159
+ findings += 1
160
+ f.organization = db_org
161
+ f.repo = db_repo
162
+ end
163
+
164
+ db_blob.save
165
+ end
166
+ progress.log("Processed #{Gitrob::Util::pluralize(repo.contents.count, 'file', 'files')} from #{Paint[repo.full_name, :bright, :white]} with #{findings.zero? ? 'no findings' : Paint[Gitrob::Util.pluralize(findings, 'finding', 'findings'), :yellow]}")
167
+ end
168
+ progress.increment
169
+ rescue Exception => e
170
+ progress.log_error("Encountered error when processing #{Paint[repo.full_name, :bright, :white]} (#{e.class.name})")
171
+ progress.increment
172
+ end
173
+ end
174
+ end
175
+
176
+ org.members.each do |member|
177
+ thread_pool.process do
178
+ begin
179
+ db_user = member.save_to_database!(db_org)
180
+
181
+ member.repositories.each do |repo|
182
+ if repo.contents.count > 0
183
+ db_repo = repo.save_to_database!(db_org, db_user)
184
+ findings = 0
185
+
186
+ repo.contents.each do |blob|
187
+ db_blob = blob.to_model(db_org, db_repo)
188
+
189
+ observers.each do |observer|
190
+ observer.observe(db_blob)
191
+ end
192
+
193
+ db_blob.findings.each do |f|
194
+ db_blob.findings_count += 1
195
+ findings += 1
196
+ f.organization = db_org
197
+ f.repo = db_repo
198
+ f.user = db_user
199
+ end
200
+
201
+ db_blob.save
202
+ end
203
+ progress.log("Processed #{Gitrob::Util::pluralize(repo.contents.count, 'file', 'files')} from #{Paint[repo.full_name, :bright, :white]} with #{findings.zero? ? 'no findings' : Paint[Gitrob::Util.pluralize(findings, 'finding', 'findings'), :yellow]}")
204
+ end
205
+ progress.increment
206
+ end
207
+ rescue Exception => e
208
+ progress.log_error("Encountered error when processing #{Paint[repo.full_name, :bright, :white]} (#{e.class.name})")
209
+ progress.increment
210
+ end
211
+ end
212
+ end
213
+
214
+ thread_pool.shutdown
215
+
216
+ if !options.include?('no-server')
217
+ Gitrob::status("Starting web application on port #{options['port']}...")
218
+ Gitrob::status("Browse to http://#{options['bind-address']}:#{options['port']}/ to see results!")
219
+ puts "\n\n"
220
+ Gitrob::WebApp.run!(:port => options[:port].to_i, :bind => options['bind-address'])
221
+ exit
222
+ end
223
+ end
224
+
225
+ version Gitrob::VERSION
226
+ description "Reconnaissance tool for GitHub organizations."
227
+
228
+ options['bind-address'] = '127.0.0.1'
229
+ options['port'] = 9393
230
+ options['threads'] = 3
231
+
232
+ on('-o', '--organization NAME', "Name of GitHub organization")
233
+ on('-s', '--start-server', "Start web server, don't run any checks")
234
+ on('-p', '--port PORT', "Port to bind web server to")
235
+ on('-b', '--bind-address ADDRESS', "Address to bind web server to")
236
+ on('-t', '--threads THREADS', "Number of threads to use")
237
+ on('--delete NAME', "Delete an organization in the database")
238
+ on('--reset-db', "Resets the database")
239
+ on('--configure', "Start configuration wizard")
240
+ on('--no-server', "Don't start the server when finished")
241
+ on('--no-color', "Don't colorize output")
242
+ on('--no-banner', "Don't print Gitrob banner")
243
+
244
+ begin
245
+ go!
246
+ rescue Gitrob::Github::HttpClient::MissingAccessTokensError
247
+ Gitrob::fatal("Configuration file does not contain any GitHub access tokens. Run Gitrob with --configure flag to set it up.")
248
+ rescue Gitrob::Github::HttpClient::AccessTokensDepletedError
249
+ Gitrob::fatal("All GitHub access tokens under rate limiting. Go have a cup of coffee and try again.")
250
+ rescue Gitrob::Github::HttpClient::RequestError => e
251
+ Gitrob::fatal("A request to the GitHub API failed: #{e.message}")
252
+ rescue Interrupt
253
+ print "\b\b\n"; # Remove ^C from screen
254
+ Gitrob::fatal("Caught interrupt; exiting.")
255
+ rescue => e
256
+ Gitrob::fatal("An error occurred: #{e.class.name}: #{e.message}")
257
+ end
258
+ end
data/gitrob.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gitrob/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gitrob"
8
+ spec.version = Gitrob::VERSION
9
+ spec.authors = ["Michael Henriksen"]
10
+ spec.email = ["michenriksen@neomailbox.ch"]
11
+ spec.summary = %q{Reconnaissance tool for GitHub organizations.}
12
+ spec.description = %q{Reconnaissance tool for GitHub organizations.}
13
+ spec.homepage = "https://github.com/michenriksen/gitrob"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "httparty", "~> 0.13"
22
+ spec.add_dependency "methadone", "~> 1.7"
23
+ spec.add_dependency "highline", "~> 1.6"
24
+ spec.add_dependency "paint", "~> 0.8"
25
+ spec.add_dependency "ruby-progressbar", "~> 1.6"
26
+ spec.add_dependency "thread", "~> 0.1"
27
+ spec.add_dependency "sinatra", "~> 1.4"
28
+ spec.add_dependency "thin", "~> 1.6"
29
+ spec.add_dependency "datamapper", "~> 1.2"
30
+ spec.add_dependency "dm-postgres-adapter"
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.7"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "rspec", "~> 3.1"
35
+ spec.add_development_dependency "webmock", "~> 1.20"
36
+ end
data/lib/gitrob.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'json'
2
+ require 'cgi'
3
+
4
+ require 'methadone'
5
+ require 'highline/import'
6
+ require 'thread/pool'
7
+ require 'httparty'
8
+ require 'ruby-progressbar'
9
+ require 'paint'
10
+ require 'sinatra/base'
11
+ require 'data_mapper'
12
+
13
+ require 'gitrob/version'
14
+ require 'gitrob/util'
15
+ require 'gitrob/progressbar'
16
+ require 'gitrob/github/http_client'
17
+ require 'gitrob/github/repository'
18
+ require 'gitrob/github/blob'
19
+ require 'gitrob/github/organization'
20
+ require 'gitrob/github/user'
21
+ require 'gitrob/observers/sensitive_files'
22
+ require 'gitrob/webapp'
23
+
24
+ require "#{File.dirname(__FILE__)}/../models/organization"
25
+ require "#{File.dirname(__FILE__)}/../models/repo"
26
+ require "#{File.dirname(__FILE__)}/../models/user"
27
+ require "#{File.dirname(__FILE__)}/../models/blob"
28
+ require "#{File.dirname(__FILE__)}/../models/finding"
29
+
30
+ module Gitrob
31
+ def self.task(message)
32
+ print " #{Paint['[*]', :bright, :blue]} #{Paint[message, :bright, :white]}"
33
+ yield
34
+ puts Paint[" done", :bright, :green]
35
+ rescue => e
36
+ puts Paint[" failed", :bright, :red]
37
+ puts "#{Paint[' [!]', :bright, :red]} #{Paint[e.class, :bright, :white]}: #{e.message}"
38
+ exit!
39
+ end
40
+
41
+ def self.status(message)
42
+ puts " #{Paint['[*]', :bright, :blue]} #{Paint[message, :bright, :white]}"
43
+ end
44
+
45
+ def self.fatal(message)
46
+ puts " #{Paint['[!]', :bright, :red]} #{Paint[message, :bright, :white]}"
47
+ exit!
48
+ end
49
+
50
+ def self.prepare_database!
51
+ DataMapper::Model.raise_on_save_failure = true
52
+ DataMapper::Property.auto_validation(false)
53
+ DataMapper.setup(:default, configuration['sql_connection_uri'])
54
+ DataMapper.finalize
55
+ DataMapper.auto_upgrade!
56
+ end
57
+
58
+ def self.delete_organization(org)
59
+ orgs = Gitrob::Organization.all(:login => org)
60
+ if orgs.count > 0
61
+ task("Deleting existing #{org} organization...") do
62
+ orgs.destroy
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.agreement_accepted?
68
+ File.exists?("#{File.dirname(__FILE__)}/../agreement")
69
+ end
70
+
71
+ def self.agreement
72
+ "\n#{self.license}\n\n" +
73
+
74
+ Paint["Gitrob is designed for security professionals. If you use any information\n" +
75
+ "found through this tool for malicious purposes that are not authorized by\n" +
76
+ "the organization, you are violating the terms of use and license of this\n" +
77
+ "tool. By typing y/yes, you agree to the terms of use and that you will use\n" +
78
+ "this tool for lawful purposes only.",
79
+ :bright, :red]
80
+ end
81
+
82
+ def self.agreement_accepted
83
+ File.open("#{File.dirname(__FILE__)}/../agreement", 'w') { |file| file.write("user accepted") }
84
+ end
85
+
86
+ def self.license
87
+ File.read("#{File.dirname(__FILE__)}/../LICENSE.txt")
88
+ end
89
+
90
+ def self.configured?
91
+ File.exists?("#{Dir.home}/.gitrobrc")
92
+ end
93
+
94
+ def self.configuration
95
+ @config ||= load_configuration!
96
+ end
97
+
98
+ def self.load_configuration!
99
+ YAML.load_file("#{Dir.home}/.gitrobrc")
100
+ end
101
+
102
+ def self.save_configuration!(config)
103
+ @config = config
104
+ File.open("#{Dir.home}/.gitrobrc", 'w') { |f| f.write YAML.dump(config) }
105
+ end
106
+
107
+ def self.banner
108
+ <<-BANNER
109
+ _ _ _
110
+ ___|_| |_ ___ ___| |_
111
+ | . | | _| _| . | . |
112
+ |_ |_|_| |_| |___|___|
113
+ |___| #{Paint["By @michenriksen", :bright, :white]}
114
+ BANNER
115
+ end
116
+ end