adassault 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b131722d9575f757c8cdf53cac4e4419d9968d5eeb11a66dabb4ef542fe85a5c
4
+ data.tar.gz: bf1de9fd4ddc2dd772980bc93945fd23309e5c7634e79bcb1171530e5b48db9c
5
+ SHA512:
6
+ metadata.gz: bf803a032eb88ccc4444eebbf32c8edf94dc724ceec842e82855e6e75943e75e84e01514633f33f09565017dae052698d23ae7973b895863298f9318131eddbe
7
+ data.tar.gz: 31826ce2fed8ac57816ecbcfcd3063ea985f94f5dbdc908fcb0f51af5ae89d518866a20daad76e73f78ed1b2b0ecfeaf1ea823b2517591d2c29e8d566fbbba89
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Alexandre ZANNI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/bin/ada ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Ruby internal
5
+ # Project internal
6
+ require 'adassault'
7
+ require 'adassault/cli'
8
+ # External
9
+
10
+ ADAssault::CLI.run(ARGV)
data/bin/adassault ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Ruby internal
5
+ # Project internal
6
+ require 'adassault'
7
+ require 'adassault/cli'
8
+ # External
9
+
10
+ ADAssault::CLI.run(ARGV)
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'adassault/dns'
4
+ require 'gli'
5
+
6
+ module ADAssault
7
+ class CLI
8
+ extend GLI::App
9
+
10
+ desc 'DNS related commands'
11
+ # since 0.0.1
12
+ command :dns do |dns|
13
+ dns.desc 'Spot all domain controllers in a Microsoft Active Directory environment'
14
+ # since 0.0.1
15
+ dns.command :find_dcs do |find_dcs|
16
+ find_dcs.flag %i[d domain], desc: 'Active Directory domain.', type: String, required: false
17
+ find_dcs.flag %i[s nameserver name-server],
18
+ desc: 'The IP address of the domain DNS server. If not provided uses your system DNS.',
19
+ type: String
20
+ find_dcs.action do |_global_options, options, _args|
21
+ dns_opts = options[:nameserver].nil? ? nil : { nameserver: [options[:nameserver]] }
22
+ dcd = ADAssault::DNS::FindDCs.new(options[:domain], dns_opts)
23
+ dcd.display
24
+ end
25
+ end
26
+
27
+ dns.desc 'TODO'
28
+ dns.command :entry_add do |entry_add|
29
+ entry_add.action do |_global_options, _options, _args|
30
+ puts 'entry_add'
31
+ end
32
+ end
33
+
34
+ dns.desc 'TODO'
35
+ dns.command :entry_delete do |entry_delete|
36
+ entry_delete.action do |_global_options, _options, _args|
37
+ puts 'entry_delete'
38
+ end
39
+ end
40
+
41
+ dns.desc 'TODO'
42
+ dns.command :entry_update do |entry_update|
43
+ entry_update.action do |_global_options, _options, _args|
44
+ puts 'entry_update'
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'adassault/version'
4
+ require 'adassault/cli/dns'
5
+
6
+ require 'gli'
7
+ require 'paint'
8
+
9
+ module ADAssault
10
+ # Class containing all commands and sub-commands for the CLI,
11
+ # mapping CLI commands with library classes.
12
+ # @since 0.0.1
13
+ class CLI
14
+ extend GLI::App
15
+
16
+ program_desc 'ADAsault desc'
17
+ subcommand_option_handling :normal
18
+ sort_help :alpha # :manually
19
+ version ADAssault::VERSION
20
+
21
+ switch [:color], desc: 'Switch colorized output', default_value: true
22
+ switch [:debug], desc: 'Display options', default_value: false
23
+ pre do |global_options, command, options, args|
24
+ Paint.mode = 0 unless global_options[:color]
25
+ if global_options[:debug]
26
+ puts 'Global options:'
27
+ p global_options
28
+ puts "\nCommand:"
29
+ p command
30
+ puts "\nLocal options:"
31
+ p options
32
+ puts "\nArguments:"
33
+ p args
34
+ end
35
+ true # https://github.com/davetron5000/gli/issues/321
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'resolv'
4
+ require 'paint'
5
+
6
+ module ADAssault
7
+ # @since 0.0.1
8
+ module DNS
9
+ # Spot all domain controllers in a Microsoft Active Directory environment
10
+ # @since 0.0.1
11
+ class FindDCs
12
+ # Hash containing all DCs.
13
+ # Cached result of {fetch_dcs}.
14
+ # @return [Hash] hash containing all DCs
15
+ # @since 0.0.1
16
+ attr_reader :dcs
17
+
18
+ # Create the FindDCs object.
19
+ # @param ad_domain [String] the Active Directory domain to work on.
20
+ # @param dns_opts [Hash] options for the DNS resolver. See [Resolv::DNS.new](https://ruby-doc.org/3.3.0/stdlibs/resolv/Resolv/DNS.html#method-c-new).
21
+ # @option dns_opts [Array|String] :nameserver the DNS server to contact
22
+ # @example
23
+ # dcd = ADAssault::DNS::FindDCs.new('THM.local', nameserver: ['10.10.25.54'])
24
+ # dcd = ADAssault::DNS::FindDCs.new('spookysec.local', nameserver: ['10.10.197.59'])
25
+ # dcd = ADAssault::DNS::FindDCs.new('za.tryhackme.com', nameserver: ['10.200.28.101'])
26
+ def initialize(ad_domain, dns_opts = nil)
27
+ @ad_domain = ad_domain
28
+ @dns_opts = dns_opts
29
+ @dcs = fetch_dcs
30
+ end
31
+
32
+ # Get DC(s) FQDN directly from the DNS server.
33
+ # Not cached in `@dcs`.
34
+ # @return [Array] the list of FQDN of all DCs
35
+ # @example
36
+ # dcd.dc_fqdn
37
+ # # => ["THMDC.za.tryhackme.com"]
38
+ # @see https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/how-domain-controllers-are-located
39
+ # @since 0.0.1
40
+ def dc_fqdn
41
+ Resolv::DNS.open(@dns_opts) do |dns|
42
+ # _kerberos._tcp, _kpasswd._tcp, _ldap._tcp works too but are not MS only
43
+ # _kerberos._tcp.dc._msdcs
44
+ # _ldap._tcp.pdc._msdcs, _gc._tcp
45
+ # _udp variants
46
+ ress = dns.getresources "_ldap._tcp.dc._msdcs.#{@ad_domain}", Resolv::DNS::Resource::IN::ANY
47
+ ress.map { |x| x.target.to_s }
48
+ end
49
+ end
50
+
51
+ # Get DC(s) computer name directly from the DNS server.
52
+ # Not cached in `@dcs`.
53
+ # Call {dc_fqdn} and extract the name from it (substract the domain).
54
+ # @return [Array] the list of computer name of all DCs
55
+ # @example
56
+ # dcd.dc_name
57
+ # # => ["THMDC"]
58
+ # @since 0.0.1
59
+ def dc_name
60
+ dc_fqdn.map { |x| x[...-@ad_domain.size - 1] }
61
+ end
62
+
63
+ # Get DC(s) IP address name directly from the DNS server.
64
+ # Not cached in `@dcs`.
65
+ # @return [Array] the list of IP address of all DCs
66
+ # @example
67
+ # dcd.dc_ip
68
+ # # => ["10.10.10.101", "10.200.28.101"]
69
+ # @since 0.0.1
70
+ def dc_ip
71
+ Resolv::DNS.open(@dns_opts) do |dns|
72
+ ress = dns.getresources "gc._msdcs.#{@ad_domain}", Resolv::DNS::Resource::IN::A
73
+ ress.map { |x| x.address.to_s }
74
+ end
75
+ end
76
+
77
+ # rubocop:disable Metrics/MethodLength
78
+
79
+ # Generates a hash containing all DCs.
80
+ # The key is the short name, the value is a hash with two keys: the FQDN and the IPs addresses.
81
+ # This method is called while instantiating the class and teh result stored in `@dcs` attribute.
82
+ # @return [Hash] hash containing all DCs
83
+ # @since 0.0.1
84
+ def fetch_dcs
85
+ h = {}
86
+ dc_fqdn.each do |fqdn|
87
+ Resolv::DNS.open(@dns_opts) do |dns|
88
+ ress = dns.getresources fqdn, Resolv::DNS::Resource::IN::A
89
+ short_name = fqdn[...-@ad_domain.size - 1].upcase
90
+ h[short_name] = {
91
+ fqdn: fqdn,
92
+ ips: ress.map { |x| x.address.to_s }
93
+ }
94
+ end
95
+ end
96
+ h
97
+ end
98
+ # rubocop:enable Metrics/MethodLength
99
+
100
+ # Display a CLI-friendly output listing all DCs with their short name, FQDN and IP addresses.
101
+ # @return [nil]
102
+ # @since 0.0.1
103
+ def display
104
+ dcs.each do |short_name, dc|
105
+ puts "#{Paint[short_name, :bold,
106
+ 'dark turquoise']} (#{Paint[dc[:fqdn], 'cyan']}) - #{Paint[dc[:ips].join(', '), 'aquamarine']}"
107
+ end
108
+ end
109
+
110
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
111
+
112
+ # @deprecated Use {display} instead.
113
+ def display_old
114
+ puts Paint['DC(s) name', :underline, :bold, 'dark turquoise']
115
+ dc_name.each do |name|
116
+ puts Paint["🔍 #{name}"]
117
+ end
118
+ puts Paint["\nDC(s) FQDN", :underline, :bold, 'cyan']
119
+ dc_fqdn.each do |fqdn|
120
+ puts Paint["🔍 #{fqdn}"]
121
+ end
122
+ puts Paint["\nDC(s) IP address", :underline, :bold, 'aquamarine']
123
+ dc_ip.each do |ip|
124
+ puts Paint["🔍 #{ip}"]
125
+ end
126
+ end
127
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'adassault/dns/find_dcs'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ADAssault
4
+ # Version of ADAssault library and app
5
+ VERSION = '0.0.1'
6
+ end
data/lib/adassault.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'adassault/version'
4
+
5
+ require 'adassault/dns'
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adassault
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexandre ZANNI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-06-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.21'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.21'
27
+ - !ruby/object:Gem::Dependency
28
+ name: paint
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
41
+ description: An Active Directory environments pentest tool complementary to existing
42
+ ones like NetExec
43
+ email: alexandre.zanni@europe.com
44
+ executables:
45
+ - ada
46
+ - adassault
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE
51
+ - bin/ada
52
+ - bin/adassault
53
+ - lib/adassault.rb
54
+ - lib/adassault/cli.rb
55
+ - lib/adassault/cli/dns.rb
56
+ - lib/adassault/dns.rb
57
+ - lib/adassault/dns/find_dcs.rb
58
+ - lib/adassault/version.rb
59
+ homepage: https://noraj.github.io/adassault/
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ yard.run: yard
64
+ bug_tracker_uri: https://github.com/noraj/ADAssault/issues
65
+ changelog_uri: https://noraj.github.io/ADAssault/yard/file.CHANGELOG.html
66
+ documentation_uri: https://noraj.github.io/ADAssault/yard/file.Usage.html
67
+ homepage_uri: https://noraj.github.io/ADAssault/yard/
68
+ source_code_uri: https://github.com/noraj/ADAssault/
69
+ funding_uri: https://github.com/sponsors/noraj
70
+ rubygems_mfa_required: 'true'
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 3.0.0
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.5.3
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Dominate the Active Directory game
93
+ test_files: []