ronin 2.0.5 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) 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/ChangeLog.md +56 -1
  6. data/Gemfile +66 -29
  7. data/README.md +162 -17
  8. data/Rakefile +9 -0
  9. data/data/completions/ronin +655 -0
  10. data/data/templates/dns_proxy.rb.erb +35 -0
  11. data/gemspec.yml +27 -13
  12. data/lib/ronin/cli/binary_template.rb +124 -0
  13. data/lib/ronin/cli/commands/archive.rb +104 -0
  14. data/lib/ronin/cli/commands/banner_grab.rb +2 -0
  15. data/lib/ronin/cli/commands/bitflip.rb +1 -1
  16. data/lib/ronin/cli/commands/bitsquat.rb +119 -0
  17. data/lib/ronin/cli/commands/cert_dump.rb +20 -4
  18. data/lib/ronin/cli/commands/cert_gen.rb +9 -19
  19. data/lib/ronin/cli/commands/cert_grab.rb +4 -3
  20. data/lib/ronin/cli/commands/completion.rb +115 -0
  21. data/lib/ronin/cli/commands/dns_proxy.rb +235 -0
  22. data/lib/ronin/cli/commands/http.rb +80 -8
  23. data/lib/ronin/cli/commands/ip.rb +101 -0
  24. data/lib/ronin/cli/commands/iprange.rb +25 -8
  25. data/lib/ronin/cli/commands/netcat.rb +2 -0
  26. data/lib/ronin/cli/commands/new/dns_listener.rb +37 -0
  27. data/lib/ronin/cli/commands/new/dns_proxy.rb +99 -0
  28. data/lib/ronin/cli/commands/new/exploit.rb +34 -0
  29. data/lib/ronin/cli/commands/new/http_listener.rb +37 -0
  30. data/lib/ronin/cli/commands/new/nokogiri.rb +33 -0
  31. data/lib/ronin/cli/commands/new/payload.rb +34 -0
  32. data/lib/ronin/cli/commands/new/project.rb +1 -1
  33. data/lib/ronin/cli/commands/new/script.rb +1 -1
  34. data/lib/ronin/cli/commands/new/web_app.rb +37 -0
  35. data/lib/ronin/cli/commands/new/web_server.rb +37 -0
  36. data/lib/ronin/cli/commands/new/web_spider.rb +37 -0
  37. data/lib/ronin/cli/commands/new.rb +3 -1
  38. data/lib/ronin/cli/commands/pack.rb +339 -0
  39. data/lib/ronin/cli/commands/public_suffix_list.rb +2 -0
  40. data/lib/ronin/cli/commands/tld_list.rb +2 -0
  41. data/lib/ronin/cli/commands/unarchive.rb +128 -0
  42. data/lib/ronin/cli/commands/unhexdump.rb +3 -1
  43. data/lib/ronin/cli/commands/unpack.rb +195 -0
  44. data/lib/ronin/cli/commands/url.rb +2 -0
  45. data/lib/ronin/cli/http_shell.rb +25 -0
  46. data/lib/ronin/cli.rb +10 -0
  47. data/lib/ronin/version.rb +1 -1
  48. data/man/ronin-archive.1.md +49 -0
  49. data/man/ronin-asn.1 +60 -77
  50. data/man/ronin-asn.1.md +25 -21
  51. data/man/ronin-banner-grab.1 +10 -21
  52. data/man/ronin-banner-grab.1.md +9 -5
  53. data/man/ronin-bitflip.1 +35 -61
  54. data/man/ronin-bitflip.1.md +30 -26
  55. data/man/ronin-bitsquat.1 +40 -0
  56. data/man/ronin-bitsquat.1.md +43 -0
  57. data/man/ronin-cert-dump.1 +44 -54
  58. data/man/ronin-cert-dump.1.md +18 -14
  59. data/man/ronin-cert-gen.1 +73 -94
  60. data/man/ronin-cert-gen.1.md +38 -34
  61. data/man/ronin-cert-grab.1 +29 -37
  62. data/man/ronin-cert-grab.1.md +12 -8
  63. data/man/ronin-completion.1 +78 -0
  64. data/man/ronin-completion.1.md +80 -0
  65. data/man/ronin-decode.1 +32 -63
  66. data/man/ronin-decode.1.md +29 -25
  67. data/man/ronin-decrypt.1 +42 -57
  68. data/man/ronin-decrypt.1.md +20 -16
  69. data/man/ronin-dns-proxy.1 +100 -0
  70. data/man/ronin-dns-proxy.1.md +70 -0
  71. data/man/ronin-dns.1 +10 -21
  72. data/man/ronin-dns.1.md +9 -5
  73. data/man/ronin-email-addr.1 +27 -40
  74. data/man/ronin-email-addr.1.md +15 -11
  75. data/man/ronin-encode.1 +93 -63
  76. data/man/ronin-encode.1.md +64 -26
  77. data/man/ronin-encrypt.1 +42 -57
  78. data/man/ronin-encrypt.1.md +20 -16
  79. data/man/ronin-entropy.1 +11 -21
  80. data/man/ronin-entropy.1.md +8 -4
  81. data/man/ronin-escape.1 +22 -46
  82. data/man/ronin-escape.1.md +22 -18
  83. data/man/ronin-extract.1 +74 -149
  84. data/man/ronin-extract.1.md +73 -69
  85. data/man/ronin-grep.1 +77 -155
  86. data/man/ronin-grep.1.md +76 -72
  87. data/man/ronin-help.1 +3 -14
  88. data/man/ronin-help.1.md +2 -2
  89. data/man/ronin-hexdump.1 +249 -265
  90. data/man/ronin-hexdump.1.md +93 -89
  91. data/man/ronin-highlight.1 +8 -18
  92. data/man/ronin-highlight.1.md +8 -4
  93. data/man/ronin-hmac.1 +17 -30
  94. data/man/ronin-hmac.1.md +14 -10
  95. data/man/ronin-homoglyph.1 +11 -22
  96. data/man/ronin-homoglyph.1.md +10 -6
  97. data/man/ronin-host.1 +23 -47
  98. data/man/ronin-host.1.md +22 -18
  99. data/man/ronin-http.1 +40 -69
  100. data/man/ronin-http.1.md +40 -30
  101. data/man/ronin-ip.1 +70 -80
  102. data/man/ronin-ip.1.md +44 -28
  103. data/man/ronin-iprange.1 +14 -22
  104. data/man/ronin-iprange.1.md +12 -5
  105. data/man/ronin-irb.1 +9 -17
  106. data/man/ronin-irb.1.md +7 -3
  107. data/man/ronin-md5.1 +13 -24
  108. data/man/ronin-md5.1.md +11 -7
  109. data/man/ronin-netcat.1 +25 -51
  110. data/man/ronin-netcat.1.md +25 -21
  111. data/man/ronin-new-dns-proxy.1 +45 -0
  112. data/man/ronin-new-dns-proxy.1.md +44 -0
  113. data/man/ronin-new-project.1 +32 -45
  114. data/man/ronin-new-project.1.md +11 -11
  115. data/man/ronin-new-script.1 +10 -22
  116. data/man/ronin-new-script.1.md +4 -4
  117. data/man/ronin-new.1 +56 -31
  118. data/man/ronin-new.1.md +48 -8
  119. data/man/ronin-pack.1 +977 -0
  120. data/man/ronin-pack.1.md +929 -0
  121. data/man/ronin-proxy.1 +37 -63
  122. data/man/ronin-proxy.1.md +29 -25
  123. data/man/ronin-public-suffix-list.1 +16 -32
  124. data/man/ronin-public-suffix-list.1.md +13 -9
  125. data/man/ronin-quote.1 +17 -36
  126. data/man/ronin-quote.1.md +17 -13
  127. data/man/ronin-rot.1 +26 -39
  128. data/man/ronin-rot.1.md +15 -11
  129. data/man/ronin-sha1.1 +13 -24
  130. data/man/ronin-sha1.1.md +11 -7
  131. data/man/ronin-sha256.1 +13 -24
  132. data/man/ronin-sha256.1.md +11 -7
  133. data/man/ronin-sha512.1 +13 -24
  134. data/man/ronin-sha512.1.md +11 -7
  135. data/man/ronin-strings.1 +30 -55
  136. data/man/ronin-strings.1.md +27 -23
  137. data/man/ronin-tips.1 +8 -16
  138. data/man/ronin-tips.1.md +7 -3
  139. data/man/ronin-tld-list.1 +16 -32
  140. data/man/ronin-tld-list.1.md +13 -9
  141. data/man/ronin-typo.1 +14 -28
  142. data/man/ronin-typo.1.md +13 -9
  143. data/man/ronin-typosquat.1 +15 -32
  144. data/man/ronin-typosquat.1.md +15 -11
  145. data/man/ronin-unarchive.1.md +41 -0
  146. data/man/ronin-unescape.1 +22 -46
  147. data/man/ronin-unescape.1.md +22 -18
  148. data/man/ronin-unhexdump.1 +81 -91
  149. data/man/ronin-unhexdump.1.md +16 -12
  150. data/man/ronin-unpack.1 +978 -0
  151. data/man/ronin-unpack.1.md +920 -0
  152. data/man/ronin-unquote.1 +17 -36
  153. data/man/ronin-unquote.1.md +17 -13
  154. data/man/ronin-url.1 +19 -40
  155. data/man/ronin-url.1.md +19 -15
  156. data/man/ronin-xor.1 +14 -28
  157. data/man/ronin-xor.1.md +13 -9
  158. data/man/ronin.1 +208 -29
  159. data/man/ronin.1.md +156 -11
  160. data/scripts/setup +58 -0
  161. metadata +162 -73
  162. data/lib/ronin/config.rb +0 -95
  163. /data/data/{new → templates}/project/.gitignore +0 -0
  164. /data/data/{new → templates}/project/.ruby-version.erb +0 -0
  165. /data/data/{new → templates}/project/Dockerfile.erb +0 -0
  166. /data/data/{new → templates}/project/Gemfile.erb +0 -0
  167. /data/data/{new → templates}/project/Rakefile +0 -0
  168. /data/data/{new → templates}/project/project.rb.erb +0 -0
  169. /data/data/{new → templates}/script.rb.erb +0 -0
@@ -0,0 +1,339 @@
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/cli/binary_template'
21
+
22
+ module Ronin
23
+ class CLI
24
+ module Commands
25
+ #
26
+ # Packs values into binary data.
27
+ #
28
+ # ## Usage
29
+ #
30
+ # ronin pack [options] TYPE:VALUE [...]
31
+ #
32
+ # ## Options
33
+ #
34
+ # -E, --endian little|big|net Sets the endianness
35
+ # -A x86|x86_64|ppc|ppc64|mips|mips_le|mips_be|mips64|mips64_le|mips64_be|arm|arm_le|arm_be|arm64|arm64_le|arm64_be,
36
+ # --arch Sets the architecture
37
+ # -O linux|macos|windows|android|apple_ios|bsd|freebsd|openbsd|netbsd,
38
+ # --os Sets the OS
39
+ # -x, --hexdump Hexdumps the packed data, instead of writing it out
40
+ # --output PATH Optional output file to write to
41
+ # -h, --help Print help information
42
+ #
43
+ # ## Arguments
44
+ #
45
+ # TYPE:VALUE A value and it's type.
46
+ #
47
+ # ### Types
48
+ #
49
+ # Native Little-endian Big-endian Network-endian
50
+ # ------ ------------- ---------- --------------
51
+ #
52
+ # char
53
+ # uchar
54
+ # byte
55
+ # string
56
+ # int int_le int_be int_net
57
+ # int8
58
+ # int16 int16_le int16_be int16_net
59
+ # int32 int32_le int32_be int32_net
60
+ # int64 int64_le int64_be int64_net
61
+ # short short_le short_be short_net
62
+ # long long_le long_be long_net
63
+ # long_long long_long_le long_long_be long_long_net
64
+ # uint uint_le uint_be uint_net
65
+ # uint8
66
+ # uint1616 uint16_le uint16_be uint16_net
67
+ # uint3232 uint32_le uint32_be uint32_net
68
+ # uint6464 uint64_le uint64_be uint64_net
69
+ # ushort ushort_le ushort_be ushort_net
70
+ # ulong ulong_le ulong_be ulong_net
71
+ # ulong_long ulong_long_le ulong_long_be ulong_long_net
72
+ # float float_le float_be float_net
73
+ # float32 float32_le float32_be float32_net
74
+ # float64 float64_le float64_be float64_net
75
+ # double double_le double_be double_net
76
+ # pointer pointer_le pointer_be pointer_net
77
+ #
78
+ # ## Examples
79
+ #
80
+ # ronin pack int32:-1 uint32:0x12345678 char:A string:hello
81
+ # ronin pack int32[4]:1,2,3,4 string[3]:hello,world
82
+ # ronin pack uint32_le:0x12345678
83
+ # ronin pack uint32_be:0x12345678
84
+ # ronin pack --endian big int:4096 uint:0x12345678
85
+ # ronin pack --arch arm_le int:4096 long:0x12345678
86
+ # ronin pack --arch x86_64 --os windows uint:0x12345678
87
+ #
88
+ # @since 2.1.0
89
+ #
90
+ class Pack < Command
91
+
92
+ include BinaryTemplate
93
+
94
+ option :hexdump, short: '-x',
95
+ desc: 'Hexdumps the packed data, instead of writing it out' do
96
+ require 'hexdump'
97
+ end
98
+
99
+ option :output, value: {
100
+ type: String,
101
+ usage: 'PATH'
102
+ },
103
+ desc: 'Optional output file to write to'
104
+
105
+ argument :element, required: true,
106
+ repeats: true,
107
+ usage: 'TYPE:VALUE',
108
+ desc: "A value and it's C type"
109
+
110
+ examples [
111
+ 'int32:-1 uint32:0x12345678 char:A string:hello',
112
+ 'int32[4]:1,2,3,4 string[3]:hello,world',
113
+ 'uint32_le:0x12345678',
114
+ 'uint32_be:0x12345678',
115
+ '--endian big int:4096 uint:0x12345678',
116
+ '--arch arm_le int:4096 long:0x12345678',
117
+ '--arch x86_64 --os windows uint:0x12345678'
118
+ ]
119
+
120
+ description "Packs values into binary data"
121
+
122
+ man_page 'ronin-pack.1'
123
+
124
+ #
125
+ # Runs the `ronin pack` command.
126
+ #
127
+ # @param [Array<String>] args
128
+ # The `TYPE:VALUE` strings to parse and pack.
129
+ #
130
+ def run(*args)
131
+ # perform an initial parsing of the arguments to extract types/values
132
+ types, values = parse_types_and_values(args)
133
+
134
+ # build the template using the parsed `TYPE`s
135
+ template = build_template(types)
136
+
137
+ # parse the values, but using the resolved C types.
138
+ values = parse_values(template.types,values)
139
+
140
+ # finally pack the parsed values using the binary template
141
+ data = template.pack(*values)
142
+
143
+ if options[:hexdump]
144
+ data.hexdump
145
+ else
146
+ write_output(data)
147
+ end
148
+ end
149
+
150
+ #
151
+ # Prints the help information for the arguments and lists `TYPE`s.
152
+ #
153
+ def help_arguments
154
+ super
155
+
156
+ puts
157
+ puts <<HELP
158
+ Types:
159
+
160
+ Native Little-endian Big-endian Network-endian
161
+ ------ ------------- ---------- --------------
162
+
163
+ char
164
+ uchar
165
+ byte
166
+ string
167
+ int int_le int_be int_net
168
+ int8
169
+ int16 int16_le int16_be int16_net
170
+ int32 int32_le int32_be int32_net
171
+ int64 int64_le int64_be int64_net
172
+ short short_le short_be short_net
173
+ long long_le long_be long_net
174
+ long_long long_long_le long_long_be long_long_net
175
+ uint uint_le uint_be uint_net
176
+ uint8
177
+ uint1616 uint16_le uint16_be uint16_net
178
+ uint3232 uint32_le uint32_be uint32_net
179
+ uint6464 uint64_le uint64_be uint64_net
180
+ ushort ushort_le ushort_be ushort_net
181
+ ulong ulong_le ulong_be ulong_net
182
+ ulong_long ulong_long_le ulong_long_be ulong_long_net
183
+ float float_le float_be float_net
184
+ float32 float32_le float32_be float32_net
185
+ float64 float64_le float64_be float64_net
186
+ double double_le double_be double_net
187
+ pointer pointer_le pointer_be pointer_net
188
+ HELP
189
+ end
190
+
191
+ #
192
+ # Performs an initial parsing of the `TYPE:VALUE` arguments into two
193
+ # separate lists of `TYPE`s and `VALUE`s.
194
+ #
195
+ # @param [Array<String>] args
196
+ # The `TYPE:VALUE` argumens to parse.
197
+ #
198
+ # @return [(Array<Symbol, (Symbol, Integer)>, Array<String>)]
199
+ # The parsed types and values.
200
+ #
201
+ def parse_types_and_values(args)
202
+ types = []
203
+ values = []
204
+
205
+ args.each do |string|
206
+ type, value = string.split(':',2)
207
+
208
+ types << parse_type(type)
209
+ values << value
210
+ end
211
+
212
+ return types, values
213
+ end
214
+
215
+ #
216
+ # Performs a second parsing of the values based on their desired
217
+ # C types.
218
+ #
219
+ # @param [Array<Ronin::Support::Binary::CTypes::Type>] types
220
+ # The desired types of the values.
221
+ #
222
+ # @param [Array<String, Array<String>>] values
223
+ # The values to further parse.
224
+ #
225
+ def parse_values(types,values)
226
+ # now parse the values based on their resolved CType types
227
+ values.map.with_index do |value,index|
228
+ parse_value(types[index],value)
229
+ end
230
+ end
231
+
232
+ #
233
+ # Parses the value based on it's C type.
234
+ #
235
+ # @param [Ronin::Support::Binary::CType::Type] ctype
236
+ # The C type of the value.
237
+ #
238
+ # @param [String] string
239
+ # The raw unparsed string.
240
+ #
241
+ # @return [Array<Integer>, Array<Float>, Array<String>, Integer, Float, String]
242
+ # The parsed value.
243
+ #
244
+ def parse_value(ctype,string)
245
+ case ctype
246
+ when Support::Binary::CTypes::ArrayType,
247
+ Support::Binary::CTypes::ArrayObjectType,
248
+ Support::Binary::CTypes::UnboundedArrayType
249
+ parse_array_value(ctype,string)
250
+ when Support::Binary::CTypes::IntType,
251
+ Support::Binary::CTypes::UIntType
252
+ parse_int(string)
253
+ when Support::Binary::CTypes::FloatType
254
+ parse_float(string)
255
+ when Support::Binary::CTypes::CharType,
256
+ Support::Binary::CTypes::StringType
257
+ string
258
+ else
259
+ raise(NotImplementedError,"unable to parse value for CType #{ctype.class}")
260
+ end
261
+ end
262
+
263
+ #
264
+ # Parses an array.
265
+ #
266
+ # @param [Ronin::Support::Binary::CTypes::Type] ctype
267
+ # The C type that represents the array type.
268
+ #
269
+ # @param [String] string
270
+ # The raw string to parse.
271
+ #
272
+ # @return [Array<Integer>, Array<Float>, Array<String>]
273
+ # The parsed array.
274
+ #
275
+ def parse_array_value(ctype,string)
276
+ # create array of the desired size
277
+ array = if ctype.length.finite?
278
+ Array.new(ctype.length,ctype.type.uninitialized_value)
279
+ else
280
+ []
281
+ end
282
+
283
+ string.split(/(?!\\),/).each_with_index do |element,index|
284
+ array[index] = parse_value(ctype.type,element)
285
+ end
286
+
287
+ return array
288
+ end
289
+
290
+ #
291
+ # Parses an integer value.
292
+ #
293
+ # @param [String] string
294
+ # The raw string to parse.
295
+ #
296
+ # @return [Integer]
297
+ # The parsed Integer.
298
+ #
299
+ def parse_int(string)
300
+ Integer(string)
301
+ rescue ArgumentError
302
+ print_error "cannot parse integer: #{string}"
303
+ exit(-1)
304
+ end
305
+
306
+ #
307
+ # Parses an float value.
308
+ #
309
+ # @param [String] string
310
+ # The raw string to parse.
311
+ #
312
+ # @return [Float]
313
+ # The parsed Float.
314
+ #
315
+ def parse_float(string)
316
+ Float(string)
317
+ rescue ArgumentError
318
+ print_error "cannot parse float: #{string}"
319
+ exit(-1)
320
+ end
321
+
322
+ #
323
+ # Writes the packed data to the `--output` file or stdout.
324
+ #
325
+ # @param [String] data
326
+ # The packed data to output.
327
+ #
328
+ def write_output(data)
329
+ if options[:output]
330
+ File.binwrite(options[:output],data)
331
+ else
332
+ stdout.write(data)
333
+ end
334
+ end
335
+
336
+ end
337
+ end
338
+ end
339
+ end
@@ -46,6 +46,8 @@ module Ronin
46
46
  include CommandKit::Options::Verbose
47
47
  include Core::CLI::Logging
48
48
 
49
+ command_name 'public-suffix-list'
50
+
49
51
  option :update, short: '-u',
50
52
  desc: 'Updates the public suffix list file'
51
53
 
@@ -46,6 +46,8 @@ module Ronin
46
46
  include CommandKit::Options::Verbose
47
47
  include Core::CLI::Logging
48
48
 
49
+ command_name 'tld-list'
50
+
49
51
  option :update, short: '-u',
50
52
  desc: 'Updates the TLD list file'
51
53
 
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2006-2024 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/file_processor_command'
20
+ require 'ronin/support/archive'
21
+
22
+ module Ronin
23
+ class CLI
24
+ module Commands
25
+ #
26
+ # Unarchive the file(s).
27
+ #
28
+ # ## Usage
29
+ #
30
+ # ronin unarchive [options] FILE ...
31
+ #
32
+ ## Options
33
+ #
34
+ # -f, --format tar|zip Explicit archive format
35
+ #
36
+ # ## Arguments
37
+ #
38
+ # FILE ... File(s) to unarchive
39
+ #
40
+ # @since 2.1.0
41
+ #
42
+ class Unarchive < FileProcessorCommand
43
+
44
+ usage '[options] FILE ...'
45
+
46
+ argument :file, required: true,
47
+ repeats: true,
48
+ desc: 'Archive files to unarchive'
49
+
50
+ option :format, short: '-f',
51
+ value: {
52
+ type: [:tar, :zip]
53
+ },
54
+ desc: 'Archive type'
55
+
56
+ description 'Unarchive the archive file(s)'
57
+
58
+ man_page 'ronin-unarchive.1'
59
+
60
+ #
61
+ # Runs the `unarchive` sub-command.
62
+ #
63
+ # @param [Array<String>] files
64
+ # File arguments.
65
+ #
66
+ def run(*files)
67
+ files.each do |file|
68
+ open_archive(file) do |archived_files|
69
+ archived_files.each do |archived_file|
70
+ File.binwrite(archived_file.name, archived_file.read)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # Archive file formats and archive types.
77
+ ARCHIVE_FORMATS = {
78
+ '.tar' => :tar,
79
+ '.zip' => :zip
80
+ }
81
+
82
+ #
83
+ # Returns the format for the given archive path.
84
+ #
85
+ # @param [String] path
86
+ # The path to the archive file.
87
+ #
88
+ # @return [:tar, :zip, nil]
89
+ # The archive format. `nil` is returned if the format cannot be
90
+ # guessed and the `--format` option was not given.
91
+ #
92
+ def format_for(path)
93
+ options.fetch(:format) do
94
+ ARCHIVE_FORMATS[File.extname(path)]
95
+ end
96
+ end
97
+
98
+ #
99
+ # Opens archive for read.
100
+ #
101
+ # @param [String] file
102
+ # File to open.
103
+ #
104
+ # @yield [archive_reader]
105
+ # Yielded archived file.
106
+ #
107
+ # @yieldparam [Ronin::Support::Archive::Zip::Reader,
108
+ # Ronin::Support::Archive::Tar::Reader] archive_reader
109
+ # Zip or tar reader object.
110
+ #
111
+ def open_archive(file,&block)
112
+ format = format_for(file)
113
+
114
+ case format
115
+ when :tar
116
+ Support::Archive.untar(file,&block)
117
+ when :zip
118
+ Support::Archive.unzip(file,&block)
119
+ when nil
120
+ print_error("unknown archive format: #{file}")
121
+ else
122
+ raise(NotImplementedError,"archive format not supported: #{format.inspect}")
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -23,7 +23,7 @@ module Ronin
23
23
  class CLI
24
24
  module Commands
25
25
  #
26
- # Hexdumps data in a variety of encodings and formats.
26
+ # Decodes a hexdump back into raw data.
27
27
  #
28
28
  # ## Usage
29
29
  #
@@ -149,6 +149,8 @@ module Ronin
149
149
  argument :file, required: false,
150
150
  desc: 'Optional file to unhexdump'
151
151
 
152
+ description 'Decodes a hexdump back into raw data'
153
+
152
154
  man_page 'ronin-unhexdump.1'
153
155
 
154
156
  #
@@ -0,0 +1,195 @@
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/cli/binary_template'
21
+
22
+ module Ronin
23
+ class CLI
24
+ module Commands
25
+ #
26
+ # Unpacks binary data.
27
+ #
28
+ # ## Usage
29
+ #
30
+ # ronin unpack [options] TYPE [...]
31
+ #
32
+ # ## Options
33
+ #
34
+ # -E, --endian little|big|net Sets the endianness
35
+ # -A x86|x86_64|ppc|ppc64|mips|mips_le|mips_be|mips64|mips64_le|mips64_be|arm|arm_le|arm_be|arm64|arm64_le|arm64_be,
36
+ # --arch Sets the architecture
37
+ # -O linux|macos|windows|android|apple_ios|bsd|freebsd|openbsd|netbsd,
38
+ # --os Sets the OS
39
+ # -S, --string $'\xXX\x..' The raw binary string to unpack
40
+ # -f, --file FILE The binary file to unpack
41
+ # -h, --help Print help information
42
+ #
43
+ # ## Arguments
44
+ #
45
+ # TYPE:VALUE A value and it's type.
46
+ #
47
+ # ### Types
48
+ #
49
+ # Native Little-endian Big-endian Network-endian
50
+ # ------ ------------- ---------- --------------
51
+ #
52
+ # char
53
+ # uchar
54
+ # byte
55
+ # string
56
+ # int int_le int_be int_net
57
+ # int8
58
+ # int16 int16_le int16_be int16_net
59
+ # int32 int32_le int32_be int32_net
60
+ # int64 int64_le int64_be int64_net
61
+ # short short_le short_be short_net
62
+ # long long_le long_be long_net
63
+ # long_long long_long_le long_long_be long_long_net
64
+ # uint uint_le uint_be uint_net
65
+ # uint8
66
+ # uint1616 uint16_le uint16_be uint16_net
67
+ # uint3232 uint32_le uint32_be uint32_net
68
+ # uint6464 uint64_le uint64_be uint64_net
69
+ # ushort ushort_le ushort_be ushort_net
70
+ # ulong ulong_le ulong_be ulong_net
71
+ # ulong_long ulong_long_le ulong_long_be ulong_long_net
72
+ # float float_le float_be float_net
73
+ # float32 float32_le float32_be float32_net
74
+ # float64 float64_le float64_be float64_net
75
+ # double double_le double_be double_net
76
+ # pointer pointer_le pointer_be pointer_net
77
+ #
78
+ # ## Examples
79
+ #
80
+ # ronin unpack int32 uint32 char string
81
+ # ronin unpack int32[4] string[3]
82
+ # ronin unpack uint32_le
83
+ # ronin unpack uint32_be
84
+ # ronin unpack --endian big int uint
85
+ # ronin unpack --arch arm_le int long
86
+ # ronin unpack --arch x86_64 --os windows uint
87
+ # ronin unpack --string $'\x44\x33\x22\x11' int32
88
+ # ronin unpack --file int32.dat int32
89
+ # ronin pack int32:0x11223344 | ronin unpack int32
90
+ #
91
+ # @since 2.1.0
92
+ #
93
+ class Unpack < Command
94
+
95
+ include BinaryTemplate
96
+
97
+ option :string, short: '-S',
98
+ value: {
99
+ type: String,
100
+ usage: "$'\\xXX\\x..'"
101
+ },
102
+ desc: 'The raw binary string to unpack'
103
+
104
+ option :file, short: '-f',
105
+ value: {
106
+ type: String,
107
+ usage: 'FILE'
108
+ },
109
+ desc: 'The binary file to unpack'
110
+
111
+ argument :type, required: true,
112
+ repeats: true,
113
+ desc: 'A C type to unpack'
114
+
115
+ examples [
116
+ 'int32 uint32 char string',
117
+ 'int32[4] string[3]',
118
+ 'uint32_le',
119
+ 'uint32_be',
120
+ '--endian big int uint',
121
+ '--arch arm_le int long',
122
+ '--arch x86_64 --os windows uint',
123
+ '--string $\'\x44\x33\x22\x11\' int32',
124
+ '--file int32.dat int32',
125
+ 'int32'
126
+ ]
127
+
128
+ description 'Unpacks binary data'
129
+
130
+ man_page 'ronin-unpack.1'
131
+
132
+ #
133
+ # Runs the `ronin unpack` command.
134
+ #
135
+ # @param [Array<String>] args
136
+ # The `TYPE` arguments to parse.
137
+ #
138
+ def run(*args)
139
+ types = args.map(&method(:parse_type))
140
+ template = build_template(types)
141
+
142
+ data = if options[:string]
143
+ options[:string]
144
+ elsif options[:file]
145
+ File.binread(options[:file])
146
+ else
147
+ stdin.read
148
+ end
149
+
150
+ values = template.unpack(data)
151
+
152
+ # remove the outer-most square brackets
153
+ print_array_value(values)
154
+ puts
155
+ end
156
+
157
+ #
158
+ # Prints an Array of values.
159
+ #
160
+ # @param [Array<Integer, Float, String, Ronin::Support::Binary::Array>] value
161
+ # The array value to print.
162
+ #
163
+ def print_array_value(value)
164
+ # convert Ronin::Support::Binary::Array objects to plain Arrays
165
+ value = value.to_a
166
+
167
+ print '['
168
+
169
+ value.each_with_index do |element,index|
170
+ print_value(element)
171
+ print(', ') unless (index == (value.length - 1))
172
+ end
173
+
174
+ print ']'
175
+ end
176
+
177
+ #
178
+ # Prints an individual value.
179
+ #
180
+ # @param [Integer, Float, String, Ronin::Support::Binary::Array] value
181
+ # The value to print.
182
+ #
183
+ def print_value(value)
184
+ case value
185
+ when Array, Support::Binary::Array
186
+ print_array_value(value)
187
+ else
188
+ print(value.inspect)
189
+ end
190
+ end
191
+
192
+ end
193
+ end
194
+ end
195
+ end