ronin 2.0.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -3
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +5 -1
  5. data/.ruby-version +1 -1
  6. data/ChangeLog.md +62 -1
  7. data/Gemfile +66 -29
  8. data/README.md +165 -20
  9. data/Rakefile +9 -0
  10. data/data/completions/ronin +655 -0
  11. data/data/templates/dns_proxy.rb.erb +35 -0
  12. data/gemspec.yml +29 -15
  13. data/lib/ronin/cli/binary_template.rb +124 -0
  14. data/lib/ronin/cli/commands/archive.rb +104 -0
  15. data/lib/ronin/cli/commands/banner_grab.rb +2 -0
  16. data/lib/ronin/cli/commands/bitflip.rb +1 -1
  17. data/lib/ronin/cli/commands/bitsquat.rb +119 -0
  18. data/lib/ronin/cli/commands/cert_dump.rb +20 -4
  19. data/lib/ronin/cli/commands/cert_gen.rb +9 -19
  20. data/lib/ronin/cli/commands/cert_grab.rb +4 -3
  21. data/lib/ronin/cli/commands/completion.rb +115 -0
  22. data/lib/ronin/cli/commands/dns_proxy.rb +239 -0
  23. data/lib/ronin/cli/commands/http.rb +80 -8
  24. data/lib/ronin/cli/commands/ip.rb +101 -0
  25. data/lib/ronin/cli/commands/iprange.rb +25 -8
  26. data/lib/ronin/cli/commands/netcat.rb +2 -0
  27. data/lib/ronin/cli/commands/new/dns_listener.rb +37 -0
  28. data/lib/ronin/cli/commands/new/dns_proxy.rb +99 -0
  29. data/lib/ronin/cli/commands/new/exploit.rb +34 -0
  30. data/lib/ronin/cli/commands/new/http_listener.rb +37 -0
  31. data/lib/ronin/cli/commands/new/nokogiri.rb +33 -0
  32. data/lib/ronin/cli/commands/new/payload.rb +34 -0
  33. data/lib/ronin/cli/commands/new/project.rb +1 -1
  34. data/lib/ronin/cli/commands/new/script.rb +1 -1
  35. data/lib/ronin/cli/commands/new/web_app.rb +37 -0
  36. data/lib/ronin/cli/commands/new/web_server.rb +37 -0
  37. data/lib/ronin/cli/commands/new/web_spider.rb +37 -0
  38. data/lib/ronin/cli/commands/new.rb +3 -1
  39. data/lib/ronin/cli/commands/pack.rb +339 -0
  40. data/lib/ronin/cli/commands/public_suffix_list.rb +2 -0
  41. data/lib/ronin/cli/commands/tld_list.rb +2 -0
  42. data/lib/ronin/cli/commands/unarchive.rb +128 -0
  43. data/lib/ronin/cli/commands/unhexdump.rb +3 -1
  44. data/lib/ronin/cli/commands/unpack.rb +195 -0
  45. data/lib/ronin/cli/commands/url.rb +2 -0
  46. data/lib/ronin/cli/http_shell.rb +25 -0
  47. data/lib/ronin/cli.rb +10 -0
  48. data/lib/ronin/version.rb +1 -1
  49. data/man/ronin-archive.1.md +49 -0
  50. data/man/ronin-asn.1 +60 -77
  51. data/man/ronin-asn.1.md +25 -21
  52. data/man/ronin-banner-grab.1 +10 -21
  53. data/man/ronin-banner-grab.1.md +9 -5
  54. data/man/ronin-bitflip.1 +35 -61
  55. data/man/ronin-bitflip.1.md +30 -26
  56. data/man/ronin-bitsquat.1 +40 -0
  57. data/man/ronin-bitsquat.1.md +43 -0
  58. data/man/ronin-cert-dump.1 +44 -54
  59. data/man/ronin-cert-dump.1.md +18 -14
  60. data/man/ronin-cert-gen.1 +73 -94
  61. data/man/ronin-cert-gen.1.md +38 -34
  62. data/man/ronin-cert-grab.1 +29 -37
  63. data/man/ronin-cert-grab.1.md +12 -8
  64. data/man/ronin-completion.1 +78 -0
  65. data/man/ronin-completion.1.md +80 -0
  66. data/man/ronin-decode.1 +32 -63
  67. data/man/ronin-decode.1.md +29 -25
  68. data/man/ronin-decrypt.1 +42 -57
  69. data/man/ronin-decrypt.1.md +20 -16
  70. data/man/ronin-dns-proxy.1 +100 -0
  71. data/man/ronin-dns-proxy.1.md +70 -0
  72. data/man/ronin-dns.1 +10 -21
  73. data/man/ronin-dns.1.md +9 -5
  74. data/man/ronin-email-addr.1 +27 -40
  75. data/man/ronin-email-addr.1.md +15 -11
  76. data/man/ronin-encode.1 +93 -63
  77. data/man/ronin-encode.1.md +64 -26
  78. data/man/ronin-encrypt.1 +42 -57
  79. data/man/ronin-encrypt.1.md +20 -16
  80. data/man/ronin-entropy.1 +11 -21
  81. data/man/ronin-entropy.1.md +8 -4
  82. data/man/ronin-escape.1 +22 -46
  83. data/man/ronin-escape.1.md +22 -18
  84. data/man/ronin-extract.1 +74 -149
  85. data/man/ronin-extract.1.md +73 -69
  86. data/man/ronin-grep.1 +77 -155
  87. data/man/ronin-grep.1.md +76 -72
  88. data/man/ronin-help.1 +3 -14
  89. data/man/ronin-help.1.md +2 -2
  90. data/man/ronin-hexdump.1 +249 -265
  91. data/man/ronin-hexdump.1.md +93 -89
  92. data/man/ronin-highlight.1 +8 -18
  93. data/man/ronin-highlight.1.md +8 -4
  94. data/man/ronin-hmac.1 +17 -30
  95. data/man/ronin-hmac.1.md +14 -10
  96. data/man/ronin-homoglyph.1 +11 -22
  97. data/man/ronin-homoglyph.1.md +10 -6
  98. data/man/ronin-host.1 +23 -47
  99. data/man/ronin-host.1.md +22 -18
  100. data/man/ronin-http.1 +40 -69
  101. data/man/ronin-http.1.md +40 -30
  102. data/man/ronin-ip.1 +70 -80
  103. data/man/ronin-ip.1.md +44 -28
  104. data/man/ronin-iprange.1 +14 -22
  105. data/man/ronin-iprange.1.md +12 -5
  106. data/man/ronin-irb.1 +9 -17
  107. data/man/ronin-irb.1.md +7 -3
  108. data/man/ronin-md5.1 +13 -24
  109. data/man/ronin-md5.1.md +11 -7
  110. data/man/ronin-netcat.1 +25 -51
  111. data/man/ronin-netcat.1.md +25 -21
  112. data/man/ronin-new-dns-proxy.1 +45 -0
  113. data/man/ronin-new-dns-proxy.1.md +44 -0
  114. data/man/ronin-new-project.1 +32 -45
  115. data/man/ronin-new-project.1.md +11 -11
  116. data/man/ronin-new-script.1 +10 -22
  117. data/man/ronin-new-script.1.md +4 -4
  118. data/man/ronin-new.1 +56 -31
  119. data/man/ronin-new.1.md +48 -8
  120. data/man/ronin-pack.1 +979 -0
  121. data/man/ronin-pack.1.md +929 -0
  122. data/man/ronin-proxy.1 +37 -63
  123. data/man/ronin-proxy.1.md +29 -25
  124. data/man/ronin-public-suffix-list.1 +16 -32
  125. data/man/ronin-public-suffix-list.1.md +13 -9
  126. data/man/ronin-quote.1 +17 -36
  127. data/man/ronin-quote.1.md +17 -13
  128. data/man/ronin-rot.1 +26 -39
  129. data/man/ronin-rot.1.md +15 -11
  130. data/man/ronin-sha1.1 +13 -24
  131. data/man/ronin-sha1.1.md +11 -7
  132. data/man/ronin-sha256.1 +13 -24
  133. data/man/ronin-sha256.1.md +11 -7
  134. data/man/ronin-sha512.1 +13 -24
  135. data/man/ronin-sha512.1.md +11 -7
  136. data/man/ronin-strings.1 +30 -55
  137. data/man/ronin-strings.1.md +27 -23
  138. data/man/ronin-tips.1 +8 -16
  139. data/man/ronin-tips.1.md +7 -3
  140. data/man/ronin-tld-list.1 +16 -32
  141. data/man/ronin-tld-list.1.md +13 -9
  142. data/man/ronin-typo.1 +14 -28
  143. data/man/ronin-typo.1.md +13 -9
  144. data/man/ronin-typosquat.1 +15 -32
  145. data/man/ronin-typosquat.1.md +15 -11
  146. data/man/ronin-unarchive.1.md +41 -0
  147. data/man/ronin-unescape.1 +22 -46
  148. data/man/ronin-unescape.1.md +22 -18
  149. data/man/ronin-unhexdump.1 +81 -91
  150. data/man/ronin-unhexdump.1.md +16 -12
  151. data/man/ronin-unpack.1 +980 -0
  152. data/man/ronin-unpack.1.md +920 -0
  153. data/man/ronin-unquote.1 +17 -36
  154. data/man/ronin-unquote.1.md +17 -13
  155. data/man/ronin-url.1 +19 -40
  156. data/man/ronin-url.1.md +19 -15
  157. data/man/ronin-xor.1 +14 -28
  158. data/man/ronin-xor.1.md +13 -9
  159. data/man/ronin.1 +208 -29
  160. data/man/ronin.1.md +156 -11
  161. data/scripts/setup +58 -0
  162. metadata +157 -67
  163. data/lib/ronin/config.rb +0 -95
  164. /data/data/{new → templates}/project/.gitignore +0 -0
  165. /data/data/{new → templates}/project/.ruby-version.erb +0 -0
  166. /data/data/{new → templates}/project/Dockerfile.erb +0 -0
  167. /data/data/{new → templates}/project/Gemfile.erb +0 -0
  168. /data/data/{new → templates}/project/Rakefile +0 -0
  169. /data/data/{new → templates}/project/project.rb.erb +0 -0
  170. /data/data/{new → templates}/script.rb.erb +0 -0
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # Ronin is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Ronin is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Ronin. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/core/cli/completion_command'
20
+ require 'ronin/repos/cli/commands/completion'
21
+ require 'ronin/wordlists/cli/commands/completion'
22
+ require 'ronin/db/cli/commands/completion'
23
+ require 'ronin/fuzzer/cli/commands/completion'
24
+ require 'ronin/web/cli/commands/completion'
25
+ require 'ronin/vulns/cli/commands/completion'
26
+ require 'ronin/payloads/cli/commands/completion'
27
+ require 'ronin/exploits/cli/commands/completion'
28
+ require 'ronin/listener/cli/commands/completion'
29
+ require 'ronin/nmap/cli/commands/completion'
30
+ require 'ronin/masscan/cli/commands/completion'
31
+ require 'ronin/recon/cli/commands/completion'
32
+ require 'ronin/root'
33
+
34
+ module Ronin
35
+ class CLI
36
+ module Commands
37
+ #
38
+ # Manages the shell completion rule for `ronin` and all other `ronin-*`
39
+ # commands.
40
+ #
41
+ # ## Usage
42
+ #
43
+ # ronin completion [options]
44
+ #
45
+ # ## Options
46
+ #
47
+ # --print Prints the shell completion file
48
+ # --install Installs the shell completion file
49
+ # --uninstall Uninstalls the shell completion file
50
+ # -h, --help Print help information
51
+ #
52
+ # ## Examples
53
+ #
54
+ # ronin completion --print
55
+ # ronin completion --install
56
+ # ronin completion --uninstall
57
+ #
58
+ # @since 2.1.0
59
+ #
60
+ class Completion < Core::CLI::CompletionCommand
61
+
62
+ man_dir File.join(ROOT,'man')
63
+ man_page 'ronin-completion.1'
64
+
65
+ description 'Manages the shell completion rules for ronin and all other ronin-* commands'
66
+
67
+ # All shell completion files for `ronin` and the other `ronin-*`
68
+ # commands.
69
+ COMPLETION_FILES = [
70
+ File.join(ROOT,'data','completions','ronin'),
71
+
72
+ Repos::CLI::Commands::Completion.completion_file,
73
+ Wordlists::CLI::Commands::Completion.completion_file,
74
+ DB::CLI::Commands::Completion.completion_file,
75
+ Fuzzer::CLI::Commands::Completion.completion_file,
76
+ Web::CLI::Commands::Completion.completion_file,
77
+ Vulns::CLI::Commands::Completion.completion_file,
78
+ Payloads::CLI::Commands::Completion.completion_file,
79
+ Exploits::CLI::Commands::Completion.completion_file,
80
+ Listener::CLI::Commands::Completion.completion_file,
81
+ Nmap::CLI::Commands::Completion.completion_file,
82
+ Masscan::CLI::Commands::Completion.completion_file,
83
+ Recon::CLI::Commands::Completion.completion_file
84
+ ]
85
+
86
+ #
87
+ # Prints all completion files.
88
+ #
89
+ def print_completion_file
90
+ COMPLETION_FILES.each do |completion_file|
91
+ super(completion_file)
92
+ end
93
+ end
94
+
95
+ #
96
+ # Installs all completion files.
97
+ #
98
+ def install_completion_file
99
+ COMPLETION_FILES.each do |completion_file|
100
+ super(completion_file)
101
+ end
102
+ end
103
+
104
+ #
105
+ # Uninstall all completion files.
106
+ #
107
+ def uninstall_completion_file
108
+ COMPLETION_FILES.each do |completion_file|
109
+ super(completion_file)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # Ronin is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Ronin is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Ronin. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/cli/command'
20
+ require 'ronin/core/cli/logging'
21
+ require 'ronin/dns/proxy'
22
+
23
+ module Ronin
24
+ class CLI
25
+ module Commands
26
+ #
27
+ # Starts a DNS proxy.
28
+ #
29
+ # ## Usage
30
+ #
31
+ # ronin dns-proxy [options] [HOST] PORT
32
+ #
33
+ # ## Options
34
+ #
35
+ # -n, --nameserver IP The upstream nameserver IP to use
36
+ # -r RECORD_TYPE:NAME:RESULT|RECORD_TYPE:/REGEXP/:RESULT,
37
+ # --rule Adds a rule to the DNS proxy
38
+ # -h, --help Print help information
39
+ #
40
+ # ## Arguments
41
+ #
42
+ # [HOST] The host name to listen on.
43
+ # PORT The port number to listen on.
44
+ #
45
+ # @since 2.1.0
46
+ #
47
+ class DnsProxy < Command
48
+
49
+ include Core::CLI::Logging
50
+
51
+ usage '[options] [HOST] PORT'
52
+
53
+ option :nameserver, short: '-n',
54
+ value: {
55
+ type: String,
56
+ usage: 'IP'
57
+ },
58
+ desc: 'The upstream nameserver IP to use' do |ip|
59
+ @nameservers << ip
60
+ end
61
+
62
+ option :rule, short: '-r',
63
+ value: {
64
+ type: %r{\A[^:]+:(?:[^:]+|/[^/:]+/):.+\z},
65
+ usage: 'RECORD_TYPE:NAME:RESULT|RECORD_TYPE:/REGEXP/:RESULT'
66
+ },
67
+ desc: 'Adds a rule to the DNS proxy' do |rule|
68
+ @rules << parse_rule(rule)
69
+ end
70
+
71
+ argument :host, required: false,
72
+ desc: 'The host to listen on'
73
+
74
+ argument :port, required: true,
75
+ desc: 'The port number to listen on'
76
+
77
+ description 'Starts a DNS proxy'
78
+
79
+ man_page 'ronin-dns-proxy.1'
80
+
81
+ # The upstream nameserver IP addresses to forward DNS queries to.
82
+ #
83
+ # @return [Array<String>]
84
+ attr_reader :nameservers
85
+
86
+ # The rules for the DNS proxy server.
87
+ #
88
+ # @return [Array<(Symbol, String, String), (Symbol, Regexp, String)>]
89
+ attr_reader :rules
90
+
91
+ #
92
+ # Initializes the `ronin dns-proxy` command.
93
+ #
94
+ # @param [Hash{Symbol => Object}] kwargs
95
+ # Additional keyword arguments for the command.
96
+ #
97
+ def initialize(**kwargs)
98
+ super(**kwargs)
99
+
100
+ @nameservers = []
101
+ @rules = []
102
+ end
103
+
104
+ #
105
+ # Runs the `ronin dns-proxy` command.
106
+ #
107
+ def run(host='127.0.0.1',port)
108
+ port = port.to_i
109
+
110
+ log_info "Listening on #{host}:#{port} ..."
111
+ DNS::Proxy.run(host,port,**proxy_kwargs)
112
+ end
113
+
114
+ #
115
+ # The keyword arguments for `Ronin::DNS::Proxy.run`.
116
+ #
117
+ # @return [Hash{Symbol => Object}]
118
+ #
119
+ def proxy_kwargs
120
+ kwargs = {rules: @rules}
121
+
122
+ unless @nameservers.empty?
123
+ kwargs[:nameservers] = @nameservers
124
+ end
125
+
126
+ return kwargs
127
+ end
128
+
129
+ # Record types.
130
+ RECORD_TYPES = {
131
+ 'A' => :A,
132
+ 'AAAA' => :AAAA,
133
+ 'ANY' => :ANY,
134
+ 'CNAME' => :CNAME,
135
+ 'HINFO' => :HINFO,
136
+ 'LOC' => :LOC,
137
+ 'MINFO' => :MINFO,
138
+ 'MX' => :MX,
139
+ 'NS' => :NS,
140
+ 'PTR' => :PTR,
141
+ 'SOA' => :SOA,
142
+ 'SRV' => :SRV,
143
+ 'TXT' => :TXT,
144
+ 'WKS' => :WKS
145
+ }
146
+
147
+ #
148
+ # Parses a record type name.
149
+ #
150
+ # @param [String] record_type
151
+ # The record type to parse.
152
+ #
153
+ # @return [:A, :AAAA, :ANY, :CNAME, :HINFO, :LOC, :MINFO, :MX, :NS, :PTR, :SOA, :SRV, :TXT, :WKS]
154
+ # The parsed record type.
155
+ #
156
+ # @raise [OptionParser::InvalidArgument]
157
+ # The record type was unknown.
158
+ #
159
+ def parse_record_type(record_type)
160
+ RECORD_TYPES.fetch(record_type) do
161
+ raise(OptionParser::InvalidArgument,"invalid record type: #{record_type.inspect}")
162
+ end
163
+ end
164
+
165
+ #
166
+ # Parses the name field of a record.
167
+ #
168
+ # @param [String] name
169
+ # The name field to parse.
170
+ #
171
+ # @return [String, Regex]
172
+ # The parsed name. If the name field starts with a `/` and ends with a
173
+ # `/`, then a Regexp will be returned.
174
+ #
175
+ # @raise [OptionParser::InvalidArgument]
176
+ # The name field regex could not be parsed.
177
+ #
178
+ def parse_record_name(name)
179
+ if name.start_with?('/') && name.end_with?('/')
180
+ begin
181
+ Regexp.new(name[1..-2])
182
+ rescue RegexpError => error
183
+ raise(OptionParser::InvalidArgument,"invalid Regexp: #{error.message}")
184
+ end
185
+ else
186
+ name
187
+ end
188
+ end
189
+
190
+ # Error names.
191
+ ERROR_CODES = {
192
+ 'NoError' => :NoError,
193
+ 'FormErr' => :FormErr,
194
+ 'ServFail' => :ServFail,
195
+ 'NXDomain' => :NXDomain,
196
+ 'NotImp' => :NotImp,
197
+ 'Refused' => :Refused,
198
+ 'NotAuth' => :NotAuth
199
+ }
200
+
201
+ #
202
+ # Parses a result value.
203
+ #
204
+ # @param [String] result
205
+ # A result value to parse.
206
+ #
207
+ # @return [String, :NoError, :FormErr, :ServFail, :NXDomain, :NotImp, :Refused, :NotAuth]
208
+ # The parsed result value or a DNS error code.
209
+ #
210
+ def parse_rule_result(result)
211
+ ERROR_CODES.fetch(result,result)
212
+ end
213
+
214
+ #
215
+ # Parses a rule string.
216
+ #
217
+ # @param [String] rule
218
+ # The string to parse.
219
+ #
220
+ # @return [(Symbol, String, String), (Symbol, Regexp, String)]
221
+ # The parsed rule.
222
+ #
223
+ # @raise [OptionParser::InvalidArgument]
224
+ # The rule string could not be parsed.
225
+ #
226
+ def parse_rule(rule)
227
+ record_type, name, result = rule.split(':',3)
228
+
229
+ [
230
+ parse_record_type(record_type),
231
+ parse_record_name(name),
232
+ parse_rule_result(result)
233
+ ]
234
+ end
235
+
236
+ end
237
+ end
238
+ end
239
+ end
@@ -20,6 +20,7 @@ require 'ronin/cli/value_processor_command'
20
20
  require 'ronin/cli/printing/http'
21
21
  require 'ronin/cli/http_shell'
22
22
  require 'ronin/support/network/http'
23
+ require 'ronin/support/network/http/cookie'
23
24
 
24
25
  require 'command_kit/options/verbose'
25
26
  require 'addressable/uri'
@@ -57,9 +58,11 @@ module Ronin
57
58
  # --shell URL Open an interactive HTTP shell
58
59
  # -P, --proxy URL The proxy to use
59
60
  # -U, --user-agent-string STRING The User-Agent string to use
60
- # -u chrome-linux|chrome-macos|chrome-windows|chrome-iphone|chrome-ipad|chrome-android|firefox-linux|firefox-macos|firefox-windows|firefox-iphone|firefox-ipad|firefox-android|safari-macos|safari-iphone|safari-ipad|edge,
61
- # --user-agent The User-Agent to use
61
+ # -u random|chrome|firefox|safari|linux|macos|windows|iphone|ipad|android|chrome_linux|chrome_macos|chrome_windows|chrome_iphone|chrome_ipad|chrome_android|firefox_linux|firefox_macos|firefox_windows|firefox_iphone|firefox_ipad|firefox_android|safari_macos|safari_iphone|safari_ipad|edge,
62
+ # --user-agent The User-Agent alias to use
62
63
  # -H, --header "NAME: VALUE" Adds a header to the request
64
+ # -C, --cookie COOKIE Sets the Cookie header
65
+ # -c, --cookie-param NAME=VALUE Sets an additional cookie param
63
66
  # -B, --body STRING The request body
64
67
  # -F, --body-file FILE Sends the file as the request body
65
68
  # -f, --form-data NAME=VALUE Adds a value to the form data
@@ -76,7 +79,7 @@ module Ronin
76
79
  include Printing::HTTP
77
80
 
78
81
  # `http://` and `https://` URL validation regex.
79
- URL_REGEX = URI::DEFAULT_PARSER.make_regexp(%w[http https])
82
+ URL_REGEX = /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/
80
83
 
81
84
  usage '[options] {URL [...] | --shell URL}'
82
85
 
@@ -178,13 +181,46 @@ module Ronin
178
181
  @user_agent = ua
179
182
  end
180
183
 
184
+ # Mapping of user-agent aliases.
185
+ USER_AGENT_ALIASES = {
186
+ 'random' => :random,
187
+ 'chrome' => :chrome,
188
+ 'firefox' => :firefox,
189
+ 'safari' => :safari,
190
+ 'linux' => :linux,
191
+ 'macos' => :macos,
192
+ 'windows' => :windows,
193
+ 'iphone' => :iphone,
194
+ 'ipad' => :ipad,
195
+ 'android' => :android,
196
+
197
+ 'chrome_linux' => :chrome_linux,
198
+ 'chrome_macos' => :chrome_macos,
199
+ 'chrome_windows' => :chrome_windows,
200
+ 'chrome_iphone' => :chrome_iphone,
201
+ 'chrome_ipad' => :chrome_ipad,
202
+ 'chrome_android' => :chrome_android,
203
+
204
+ 'firefox_linux' => :firefox_linux,
205
+ 'firefox_macos' => :firefox_macos,
206
+ 'firefox_windows' => :firefox_windows,
207
+ 'firefox_iphone' => :firefox_iphone,
208
+ 'firefox_ipad' => :firefox_ipad,
209
+
210
+ 'firefox_android' => :firefox_android,
211
+
212
+ 'safari_macos' => :safari_macos,
213
+ 'safari_iphone' => :safari_iphone,
214
+ 'safari_ipad' => :safari_ipad,
215
+
216
+ 'edge' => :edge
217
+ }
218
+
181
219
  option :user_agent, short: '-u',
182
220
  value: {
183
- type: Support::Network::HTTP::UserAgents::ALIASES.transform_keys { |key|
184
- key.to_s.tr('_','-')
185
- }
221
+ type: USER_AGENT_ALIASES
186
222
  },
187
- desc: 'The User-Agent to use' do |name|
223
+ desc: 'The User-Agent alias to use' do |name|
188
224
  @user_agent = name
189
225
  end
190
226
 
@@ -199,6 +235,35 @@ module Ronin
199
235
  @headers[name] = value
200
236
  end
201
237
 
238
+ option :cookie, short: '-C',
239
+ value: {
240
+ type: String,
241
+ usage: 'COOKIE'
242
+ },
243
+ desc: 'Sets the Cookie header' do |cookie|
244
+ cookie = Support::Network::HTTP::Cookie.parse(cookie)
245
+
246
+ if @cookie
247
+ @cookie.merge!(cookie)
248
+ else
249
+ @cookie = cookie
250
+ end
251
+ end
252
+
253
+ option :cookie_param, short: '-c',
254
+ value: {
255
+ type: /[^\s=]+=\w+/,
256
+ usage: 'NAME=VALUE'
257
+ },
258
+ desc: 'Sets an additional cookie param' do |param|
259
+ name, value = param.split('=',2)
260
+
261
+ # lazy initialize the cookie
262
+ @cookie ||= Support::Network::HTTP::Cookie.new
263
+
264
+ @cookie[name] = value
265
+ end
266
+
202
267
  option :body, short: '-B',
203
268
  value: {
204
269
  type: String,
@@ -262,9 +327,14 @@ module Ronin
262
327
  # @return [Hash{String => String}]
263
328
  attr_reader :headers
264
329
 
330
+ # The optional `Cookie` header to send.
331
+ #
332
+ # @return [Ronin::Support::Network::HTTP::Cookie, nil]
333
+ attr_reader :cookie
334
+
265
335
  # Optional `User-agent` string to use.
266
336
  #
267
- # @return [String, nil]
337
+ # @return [String, Symbol, nil]
268
338
  attr_reader :user_agent
269
339
 
270
340
  # Additional URL query params.
@@ -294,6 +364,7 @@ module Ronin
294
364
  @proxy = nil
295
365
  @http_method = :get
296
366
  @headers = {}
367
+ @cookie = nil
297
368
  @user_agent = nil
298
369
  @query_params = {}
299
370
  @form_data = {}
@@ -347,6 +418,7 @@ module Ronin
347
418
  begin
348
419
  Support::Network::HTTP.request(
349
420
  @http_method, uri, proxy: @proxy,
421
+ cookie: @cookie,
350
422
  user_agent: @user_agent,
351
423
  query_params: @query_params,
352
424
  headers: @headers,
@@ -19,6 +19,7 @@
19
19
  require 'ronin/cli/value_processor_command'
20
20
  require 'ronin/support/network/ip'
21
21
  require 'uri'
22
+ require 'ipaddr'
22
23
 
23
24
  module Ronin
24
25
  class CLI
@@ -40,6 +41,10 @@ module Ronin
40
41
  # -D, --decimal Converts the IP address to decimal format
41
42
  # -O, --octal Converts the IP address to octal format
42
43
  # -B, --binary Converts the IP address to binary format
44
+ # --hex-octet Converts the IP address to hexadecimal format by octet
45
+ # --octal-octet Converts the IP address to octal format by octet
46
+ # --ipv6-compat Converts the IPv4 address to an IPv6 compatible address
47
+ # --ipv6-expanded Expands a shortened or compressed IPv6 address
43
48
  # -C, --cidr NETMASK Converts the IP address into a CIDR range
44
49
  # -H, --host Converts the IP address to a host name
45
50
  # -p, --port PORT Appends the port number to each IP
@@ -89,6 +94,16 @@ module Ronin
89
94
  option :binary, short: '-B',
90
95
  desc: 'Converts the IP address to binary format'
91
96
 
97
+ option :hex_octet,
98
+ desc: 'Converts the IP address to hexadecimal format by octet'
99
+
100
+ option :octal_octet,
101
+ desc: 'Converts the IP address to octal format by octet'
102
+
103
+ option :ipv6_compat, desc: 'Converts the IPv4 address to an IPv6 compatible address'
104
+
105
+ option :ipv6_expanded, desc: 'Expands a shortened or compressed IPv6 address'
106
+
92
107
  option :cidr, short: '-C',
93
108
  value: {
94
109
  type: String,
@@ -225,19 +240,105 @@ module Ronin
225
240
  # The formatted IP address.
226
241
  #
227
242
  def format_ip(ip)
243
+ if ip.ipv4?
244
+ format_ipv4(ip)
245
+ else
246
+ format_ipv6(ip)
247
+ end
248
+ end
249
+
250
+ private
251
+
252
+ #
253
+ # Formats an IPv4 address.
254
+ #
255
+ # @param [Ronin::Support::Network::IP] ip
256
+ # The IP address to format.
257
+ #
258
+ # @return [String]
259
+ # The formatted IP address.
260
+ #
261
+ def format_ipv4(ip)
228
262
  if options[:hex]
229
263
  "0x%x" % ip.to_i
264
+ elsif options[:hex_octet]
265
+ ipv4_hex_octet(ip)
230
266
  elsif options[:decimal]
231
267
  "%u" % ip.to_i
232
268
  elsif options[:octal]
233
269
  "0%o" % ip.to_i
270
+ elsif options[:octal_octet]
271
+ ip.to_s.split(".").map { |octet| "0%o" % octet.to_i }.join(".")
272
+ elsif options[:binary]
273
+ "%b" % ip.to_i
274
+ elsif options[:ipv6_compat]
275
+ ip.ipv4_mapped.to_s
276
+ elsif options[:ipv6_expanded]
277
+ print_error "called with --ipv6-expanded for #{ip}"
278
+ exit(1)
279
+ else
280
+ ip.to_s
281
+ end
282
+ end
283
+
284
+ #
285
+ # Formats an IPv6 address.
286
+ #
287
+ # @param [Ronin::Support::Network::IP] ip
288
+ # The IP address to format.
289
+ #
290
+ # @return [String]
291
+ # The formatted IP address.
292
+ #
293
+ def format_ipv6(ip)
294
+ if options[:decimal]
295
+ "%u" % ip.to_i
296
+ elsif options[:hex]
297
+ "0x%x" % ip.to_i
298
+ elsif options[:octal]
299
+ "0%o" % ip.to_i
300
+ elsif options[:octal_octet]
301
+ print_error "called with --octal-octet for #{ip}"
302
+ exit(1)
303
+ elsif options[:hex_octet]
304
+ if ip.ipv4_mapped?
305
+ "::ffff:#{ipv4_hex_octet(ip.ipv4)}"
306
+ else
307
+ print_error "called with --hex-octet for #{ip}"
308
+ exit(1)
309
+ end
234
310
  elsif options[:binary]
235
311
  "%b" % ip.to_i
312
+ elsif options[:ipv6_expanded]
313
+ ip.canonical
314
+ elsif options[:ipv6_compat]
315
+ print_error "called with --ipv6-compat for #{ip}"
316
+ exit(1)
236
317
  else
237
318
  ip.to_s
238
319
  end
239
320
  end
240
321
 
322
+ #
323
+ # Converts the octets of an IP address to hex
324
+ #
325
+ # @param [Ronin::Support::Network::IP] ip
326
+ # The IP address to convert.
327
+ #
328
+ # @return [String]
329
+ # The formatted IP address.
330
+ #
331
+ def ipv4_hex_octet(ip)
332
+ ip_uint = ip.to_i
333
+
334
+ format(
335
+ "%<octet1>x.%<octet2>x.%<octet3>x.%<octet4>x",
336
+ octet1: (ip_uint & 0xff000000) >> 24,
337
+ octet2: (ip_uint & 0xff0000) >> 16,
338
+ octet3: (ip_uint & 0xff00) >> 8,
339
+ octet4: (ip_uint & 0xff)
340
+ )
341
+ end
241
342
  end
242
343
  end
243
344
  end