githack 0.2.0 → 0.3.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 +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +56 -17
- data/bin/githack.rb +30 -6
- data/lib/githack.rb +38 -2
- data/lib/githack/leak.rb +11 -0
- data/lib/githack/repositories/cakephp.rb +23 -0
- data/lib/githack/repositories/laravel.rb +23 -0
- data/lib/githack/repositories/rails.rb +23 -0
- data/lib/githack/repositories/symfony.rb +49 -0
- data/lib/githack/repository.rb +50 -23
- data/lib/githack/version.rb +1 -1
- metadata +7 -3
- data/lib/githack/rails_repository.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a900b5b7270b5e428ca145df3ff430d2ba06d936
|
4
|
+
data.tar.gz: 7f63c2b10228956cc19120b2787bebcdfbb560bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 071452db5375ca0af30f609e9432b90b2b636cd494309be220375d519665476c59a548f3176785a0da81244643a423bcd6d1878e70aae55b50a7f0c485042e86
|
7
|
+
data.tar.gz: 6f92e2fdf1374fdd0171921a41ed44add19aa473ad7fdfa682852dd5ffbe277db4b27410a1833c1ac503d471156ed0b98cc05156e279f11a3264c7ed2cf24ac3
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,18 +2,16 @@
|
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/githack)
|
4
4
|
|
5
|
-
Crawl [Git][git]'s commits of a given repository to find forgotten credentials
|
5
|
+
Crawl [Git][git]'s commits of a given repository to find forgotten credentials according to given framework.
|
6
6
|
|
7
|
-
|
7
|
+
> [See documentation ](https://www.rubydoc.info/gems/githack/Githack/Repositories) to know which framework is currently supported
|
8
8
|
|
9
|
-
- [Ruby on Rails](https://rubyonrails.org)
|
10
|
-
|
11
|
-
- _config/secrets.yml_
|
12
|
-
- _config/database.yml_
|
13
9
|
|
14
10
|
## Dependencies
|
15
11
|
|
16
|
-
You need to install [Git][git].
|
12
|
+
You need to install [Git][git].
|
13
|
+
|
14
|
+
Exemple for Debian based distributions:
|
17
15
|
|
18
16
|
```bash
|
19
17
|
$ sudo apt install git
|
@@ -44,31 +42,44 @@ Simply use tis to clone the remote repository in your temporary folder
|
|
44
42
|
```ruby
|
45
43
|
require 'githack'
|
46
44
|
|
47
|
-
repository = Githack::
|
45
|
+
repository = Githack::Repositories::Rails::v4.new 'https://github.com/RaspberryCook/website'
|
48
46
|
```
|
49
47
|
|
50
|
-
And then you can search on repository
|
48
|
+
And then you can search on repository using `databases` or `secrets` who returns `Array<Githack::Leak>`. `Githack::Leak` contains `sha`, `file` and `content`:
|
51
49
|
|
52
50
|
```ruby
|
53
|
-
repository.
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
51
|
+
repository.databases.each do |leak|
|
52
|
+
# <Githack::Leak:Githack::Leak:0x00556db18af998 ... >,
|
53
|
+
puts leak.sha
|
54
|
+
# => 566fac779248c345192512423770f14cf4af1435
|
55
|
+
puts leak.file
|
56
|
+
# => /tmp/https___github_com_madeindjs_fooder/config/database.yml
|
57
|
+
puts leak.content
|
58
|
+
# "development:\n" +
|
59
|
+
# " adapter: mysql2\n" +
|
60
|
+
# " database: raspberry_cook\n" +
|
61
|
+
# " encoding: utf8\n" +
|
62
|
+
# " username: raspberry_cook\n" +
|
63
|
+
# " password: secret\n" +
|
64
|
+
# " host: localhost\n" +
|
65
|
+
end
|
66
|
+
|
67
|
+
repository.secrets.each do |leak|
|
68
|
+
# ....
|
69
|
+
end
|
58
70
|
```
|
59
71
|
|
60
72
|
Theses methods will:
|
61
73
|
|
62
74
|
1. Search all commit were file changed
|
63
75
|
2. Checkout on theses commit to get file content
|
64
|
-
3. Filter only usefull informations
|
65
76
|
|
66
77
|
### As command line tool
|
67
78
|
|
68
79
|
Simply use
|
69
80
|
|
70
81
|
```bash
|
71
|
-
$ githack.rb https://github.com/
|
82
|
+
$ githack.rb --framework=Rails::V4 https://github.com/madeindjs/fooder
|
72
83
|
```
|
73
84
|
|
74
85
|
## Development
|
@@ -79,7 +90,35 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
79
90
|
|
80
91
|
## Contributing
|
81
92
|
|
82
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
93
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/madeindjs/githack. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
94
|
+
|
95
|
+
### Add new framwork to support
|
96
|
+
|
97
|
+
Fork this repository & create a new file based on `Githack::Repositories::Rails`
|
98
|
+
|
99
|
+
```bash
|
100
|
+
$ cp lib/githack/repositories/rails.rb
|
101
|
+
```
|
102
|
+
|
103
|
+
Then simply overwride
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
# lib/githack/repositories/your_framework.rb
|
107
|
+
module Githack
|
108
|
+
module Repositories
|
109
|
+
# Module who hold all version of your framework
|
110
|
+
module YourFramework
|
111
|
+
# Represent a version of your framework
|
112
|
+
class V1 < Githack::Repository
|
113
|
+
# Represent the path to secrets files
|
114
|
+
DATABASE_PATHS = [File.join('config', 'database.php')].freeze
|
115
|
+
# Represent the path to database configuration files
|
116
|
+
SECRET_PATH = [File.join('config', 'secrets.yml')].freeze
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
```
|
83
122
|
|
84
123
|
## Code of Conduct
|
85
124
|
|
data/bin/githack.rb
CHANGED
@@ -8,14 +8,19 @@ url = nil
|
|
8
8
|
|
9
9
|
options = {
|
10
10
|
skip_config_secrets: false,
|
11
|
-
skip_config_database: false
|
11
|
+
skip_config_database: false,
|
12
|
+
framework: nil
|
12
13
|
}
|
13
14
|
|
14
|
-
OptionParser.new do |opts|
|
15
|
+
optparse = OptionParser.new do |opts|
|
15
16
|
opts.banner = 'Usage: githack.rb URL with URL as remote URL of a Git repository (currently works only for Rails project)'
|
16
17
|
|
17
18
|
url = ARGV.pop
|
18
19
|
|
20
|
+
opts.on '-f', '--framework FRAMEWORK', 'Specify repository framework to target to find leaked data', 'use without parameter to get the complete list' do |framework|
|
21
|
+
options[:framework] = framework
|
22
|
+
end
|
23
|
+
|
19
24
|
opts.on '--skip_config_secrets', 'Not search for config/secrets.yml' do |_o|
|
20
25
|
options[:skip_config_secrets] = true
|
21
26
|
end
|
@@ -24,22 +29,41 @@ OptionParser.new do |opts|
|
|
24
29
|
options[:skip_config_secrets] = true
|
25
30
|
end
|
26
31
|
|
32
|
+
opts.on('-h', '--help', 'Display this screen') do
|
33
|
+
puts opts
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
27
37
|
unless url
|
28
38
|
puts "You must provide a Git remote URL\r\n\r\n"
|
29
39
|
puts opts
|
30
40
|
exit
|
31
41
|
end
|
32
|
-
end
|
42
|
+
end
|
43
|
+
|
44
|
+
optparse.parse!
|
45
|
+
|
46
|
+
unless Githack::Repositories.get_availables_frameworks_versions_pretty.include?(options[:framework])
|
47
|
+
|
48
|
+
puts "You must specify framework\r\n\r\n"
|
49
|
+
Githack::Repositories.get_availables_frameworks_versions_pretty.each do |framework|
|
50
|
+
puts format(' - %s', framework)
|
51
|
+
end
|
52
|
+
|
53
|
+
exit
|
54
|
+
end
|
55
|
+
|
56
|
+
framework_class = Githack::Repositories.const_get(options[:framework])
|
33
57
|
|
34
58
|
spinner = TTY::Spinner.new '[:spinner] Cloning repository ...'
|
35
59
|
spinner.auto_spin
|
36
|
-
repository =
|
60
|
+
repository = framework_class.new url
|
37
61
|
spinner.stop('Done!')
|
38
62
|
|
39
63
|
unless options[:skip_config_database]
|
40
64
|
spinner = TTY::Spinner.new '[:spinner] Search in config/database.yml (Rails) ...'
|
41
65
|
spinner.auto_spin
|
42
|
-
result = repository.
|
66
|
+
result = repository.databases
|
43
67
|
spinner.stop('Done!')
|
44
68
|
pp result
|
45
69
|
end
|
@@ -47,7 +71,7 @@ end
|
|
47
71
|
unless options[:skip_config_secrets]
|
48
72
|
spinner = TTY::Spinner.new '[:spinner] Search in config/secrets.yml (Rails) ...'
|
49
73
|
spinner.auto_spin
|
50
|
-
result = repository.
|
74
|
+
result = repository.secrets
|
51
75
|
spinner.stop('Done!')
|
52
76
|
pp result
|
53
77
|
end
|
data/lib/githack.rb
CHANGED
@@ -1,6 +1,42 @@
|
|
1
1
|
require 'githack/version'
|
2
|
-
require 'githack/
|
2
|
+
require 'githack/repositories/cakephp'
|
3
|
+
require 'githack/repositories/laravel'
|
4
|
+
require 'githack/repositories/rails'
|
5
|
+
require 'githack/repositories/symfony'
|
6
|
+
require 'githack/leak'
|
3
7
|
|
4
8
|
module Githack
|
5
|
-
#
|
9
|
+
# Represent frameworks available to parse leaked data
|
10
|
+
module Repositories
|
11
|
+
# Get all class available as repository
|
12
|
+
#
|
13
|
+
# @return [Array<Class>]
|
14
|
+
def self.get_availables_frameworks_versions
|
15
|
+
available = []
|
16
|
+
|
17
|
+
frameworks = Githack::Repositories.constants.select do |c|
|
18
|
+
Githack::Repositories.const_get(c).is_a? Module
|
19
|
+
end
|
20
|
+
|
21
|
+
frameworks.each do |framework|
|
22
|
+
framework_module = Githack::Repositories.const_get(framework)
|
23
|
+
|
24
|
+
Githack::Repositories.const_get(framework).constants.each do |v|
|
25
|
+
v_class = framework_module.const_get(v)
|
26
|
+
available << v_class if v_class.is_a? Class
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
available
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get all class available as repository as pretty string
|
34
|
+
#
|
35
|
+
# @return [Array<String>]
|
36
|
+
def self.get_availables_frameworks_versions_pretty
|
37
|
+
Repositories.get_availables_frameworks_versions.map do |framework|
|
38
|
+
framework.to_s.gsub('Githack::Repositories::', '')
|
39
|
+
end.sort
|
40
|
+
end
|
41
|
+
end
|
6
42
|
end
|
data/lib/githack/leak.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'githack/repository'
|
2
|
+
|
3
|
+
module Githack
|
4
|
+
module Repositories
|
5
|
+
module CakePHP
|
6
|
+
class V3 < Githack::Repository
|
7
|
+
DATABASE_PATHS = [
|
8
|
+
File.join('config', 'app.php')
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
# SECRET_PATH = ['config', 'secrets.yml']
|
12
|
+
end
|
13
|
+
|
14
|
+
class V2 < Githack::Repository
|
15
|
+
DATABASE_PATHS = [
|
16
|
+
File.join('app', 'Config', 'database.php')
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
# SECRET_PATH = ['config', 'secrets.yml']
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'githack/repository'
|
2
|
+
|
3
|
+
module Githack
|
4
|
+
module Repositories
|
5
|
+
module Laravel
|
6
|
+
class V5 < Githack::Repository
|
7
|
+
DATABASE_PATHS = [
|
8
|
+
File.join('config', 'database.php')
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
# SECRET_PATH = ['config', 'secrets.yml']
|
12
|
+
end
|
13
|
+
|
14
|
+
class V4 < V5
|
15
|
+
DATABASE_PATHS = [
|
16
|
+
File.join('app', 'config', 'database.php')
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
# SECRET_PATH = ['config', 'secrets.yml']
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'githack/repository'
|
2
|
+
|
3
|
+
module Githack
|
4
|
+
module Repositories
|
5
|
+
module Rails
|
6
|
+
class V5 < Githack::Repository
|
7
|
+
SECRET_PATHS = [
|
8
|
+
File.join('config', 'secrets.yml')
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
DATABASE_PATHS = [
|
12
|
+
File.join('config', 'database.yml')
|
13
|
+
].freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
class V4 < V5
|
17
|
+
end
|
18
|
+
|
19
|
+
class V3 < V5
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'githack/repository'
|
2
|
+
|
3
|
+
module Githack
|
4
|
+
module Repositories
|
5
|
+
module Symfony
|
6
|
+
class V4 < Githack::Repository
|
7
|
+
SECRET_PATHS = ['.env'].freeze
|
8
|
+
|
9
|
+
# https://symfony.com/doc/4.1/doctrine.html
|
10
|
+
DATABASE_PATHS = [
|
11
|
+
File.join('config', 'packages', 'doctrine.yaml'),
|
12
|
+
File.join('config', 'packages', 'doctrine.xml'),
|
13
|
+
File.join('config', 'packages', 'doctrine.php')
|
14
|
+
].freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
class V3 < Githack::Repository
|
18
|
+
SECRET_PATHS = ['.env'].freeze
|
19
|
+
|
20
|
+
# https://symfony.com/doc/3.3/doctrine.html
|
21
|
+
DATABASE_PATHS = [
|
22
|
+
File.join('app', 'config', 'parameters.xml'),
|
23
|
+
File.join('app', 'config', 'parameters.yml'),
|
24
|
+
File.join('app', 'config', 'parameters.php')
|
25
|
+
].freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
class V2 < Githack::Repository
|
29
|
+
SECRET_PATHS = ['.env'].freeze
|
30
|
+
|
31
|
+
# https://symfony.com/doc/2.8/doctrine.html
|
32
|
+
DATABASE_PATHS = [
|
33
|
+
File.join('app', 'config', 'config.xml'),
|
34
|
+
File.join('app', 'config', 'config.yml'),
|
35
|
+
File.join('app', 'config', 'config.php')
|
36
|
+
].freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
class V1 < Githack::Repository
|
40
|
+
SECRET_PATHS = [].freeze
|
41
|
+
|
42
|
+
# https://symfony.com/legacy/doc/reference/1_4/en/07-Databases
|
43
|
+
DATABASE_PATHS = [
|
44
|
+
File.join('config', 'databases.yml')
|
45
|
+
].freeze
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/githack/repository.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'tmpdir'
|
2
2
|
require 'yaml'
|
3
3
|
require 'git'
|
4
|
+
require 'githack/leak'
|
4
5
|
|
5
6
|
module Githack
|
6
7
|
class Repository
|
7
8
|
attr_reader :git, :remote, :name, :path
|
8
9
|
|
10
|
+
# Represent the path to secrets files
|
11
|
+
SECRET_PATH = [].freeze
|
12
|
+
# Represent the path to database configuration files
|
13
|
+
DATABASE_PATH = [].freeze
|
14
|
+
|
9
15
|
def initialize(remote)
|
10
16
|
@remote = remote
|
11
17
|
@name = remote.gsub /[^0-9A-Z]/i, '_'
|
@@ -18,40 +24,61 @@ module Githack
|
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
21
|
-
|
27
|
+
# Get all changements for config/secrets.yml file (who contains some API keys)
|
28
|
+
#
|
29
|
+
# @return [Array<Githack::Leak>]
|
30
|
+
def secrets
|
31
|
+
leaks = []
|
32
|
+
files = self.class::SECRET_PATHS.map { |f| File.join(@path, f) }
|
22
33
|
|
23
|
-
|
34
|
+
get_leaks(*files).each do |leak|
|
35
|
+
leaks << leak
|
36
|
+
yield lead if block_given?
|
37
|
+
end
|
38
|
+
leaks
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get all changements for config/database.yml file (who contains database configuration for Ruby on Rails Framework)
|
24
42
|
#
|
25
|
-
# @
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# can't parse YAML file
|
34
|
-
end
|
43
|
+
# @return [Array<Githack::Leak>]
|
44
|
+
def databases
|
45
|
+
leaks = []
|
46
|
+
files = self.class::DATABASE_PATHS.map { |f| File.join(@path, f) }
|
47
|
+
|
48
|
+
get_leaks(*files).each do |leak|
|
49
|
+
leaks << leak
|
50
|
+
yield lead if block_given?
|
35
51
|
end
|
52
|
+
leaks
|
36
53
|
end
|
37
54
|
|
55
|
+
protected
|
56
|
+
|
38
57
|
# Checkout on all file changes
|
39
58
|
#
|
40
|
-
# @
|
41
|
-
|
42
|
-
|
59
|
+
# @yield [Githack::Leak]
|
60
|
+
def get_leaks(*files)
|
61
|
+
leaks = []
|
43
62
|
@git.checkout 'master'
|
44
|
-
begin
|
45
|
-
@git.log.object(file).each do |commit|
|
46
|
-
@git.checkout commit
|
47
|
-
next unless File.exist? file
|
48
63
|
|
49
|
-
|
64
|
+
files.each do |file|
|
65
|
+
begin
|
66
|
+
@git.log.object(file).each do |commit|
|
67
|
+
@git.checkout commit
|
68
|
+
next unless File.exist? file
|
69
|
+
|
70
|
+
leak = Githack::Leak.new(commit.sha, file)
|
71
|
+
leaks << leak
|
72
|
+
|
73
|
+
yield leak if block_given?
|
74
|
+
end
|
75
|
+
rescue StandardError
|
76
|
+
Psych::BadAlias
|
50
77
|
end
|
51
|
-
|
52
|
-
Psych::BadAlias
|
78
|
+
@git.checkout 'master'
|
53
79
|
end
|
54
|
-
|
80
|
+
|
81
|
+
leaks
|
55
82
|
end
|
56
83
|
end
|
57
84
|
end
|
data/lib/githack/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: githack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rousseau Alexandre
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -101,7 +101,11 @@ files:
|
|
101
101
|
- bin/setup
|
102
102
|
- githack.gemspec
|
103
103
|
- lib/githack.rb
|
104
|
-
- lib/githack/
|
104
|
+
- lib/githack/leak.rb
|
105
|
+
- lib/githack/repositories/cakephp.rb
|
106
|
+
- lib/githack/repositories/laravel.rb
|
107
|
+
- lib/githack/repositories/rails.rb
|
108
|
+
- lib/githack/repositories/symfony.rb
|
105
109
|
- lib/githack/repository.rb
|
106
110
|
- lib/githack/version.rb
|
107
111
|
homepage: https://github.com/madeindjs/githack
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'githack/repository'
|
2
|
-
|
3
|
-
module Githack
|
4
|
-
class RailsRepository < Repository
|
5
|
-
# Get all changements for config/secrets.yml file (who contains some API keys)
|
6
|
-
def search_rails_config_secrets
|
7
|
-
results = []
|
8
|
-
|
9
|
-
absolute_file_path = File.join @path, 'config', 'secrets.yml'
|
10
|
-
|
11
|
-
checkout_on_yaml_file_change(absolute_file_path) do |secrets|
|
12
|
-
results << secrets
|
13
|
-
end
|
14
|
-
|
15
|
-
results.uniq
|
16
|
-
end
|
17
|
-
|
18
|
-
# Get all changements for config/database.yml file (who contains database configuration for Ruby on Rails Framework)
|
19
|
-
def search_rails_config_database
|
20
|
-
results = []
|
21
|
-
|
22
|
-
absolute_file_path = File.join @path, 'config', 'database.yml'
|
23
|
-
|
24
|
-
checkout_on_yaml_file_change(absolute_file_path) do |configs|
|
25
|
-
configs.each do |config|
|
26
|
-
config_data = config[1]
|
27
|
-
next if config_data['adapter'] == 'sqlite3'
|
28
|
-
results << config_data
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
results.uniq
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|