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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +3 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -1
- data/ChangeLog.md +56 -1
- data/Gemfile +66 -29
- data/README.md +162 -17
- data/Rakefile +9 -0
- data/data/completions/ronin +655 -0
- data/data/templates/dns_proxy.rb.erb +35 -0
- data/gemspec.yml +27 -13
- data/lib/ronin/cli/binary_template.rb +124 -0
- data/lib/ronin/cli/commands/archive.rb +104 -0
- data/lib/ronin/cli/commands/banner_grab.rb +2 -0
- data/lib/ronin/cli/commands/bitflip.rb +1 -1
- data/lib/ronin/cli/commands/bitsquat.rb +119 -0
- data/lib/ronin/cli/commands/cert_dump.rb +20 -4
- data/lib/ronin/cli/commands/cert_gen.rb +9 -19
- data/lib/ronin/cli/commands/cert_grab.rb +4 -3
- data/lib/ronin/cli/commands/completion.rb +115 -0
- data/lib/ronin/cli/commands/dns_proxy.rb +235 -0
- data/lib/ronin/cli/commands/http.rb +80 -8
- data/lib/ronin/cli/commands/ip.rb +101 -0
- data/lib/ronin/cli/commands/iprange.rb +25 -8
- data/lib/ronin/cli/commands/netcat.rb +2 -0
- data/lib/ronin/cli/commands/new/dns_listener.rb +37 -0
- data/lib/ronin/cli/commands/new/dns_proxy.rb +99 -0
- data/lib/ronin/cli/commands/new/exploit.rb +34 -0
- data/lib/ronin/cli/commands/new/http_listener.rb +37 -0
- data/lib/ronin/cli/commands/new/nokogiri.rb +33 -0
- data/lib/ronin/cli/commands/new/payload.rb +34 -0
- data/lib/ronin/cli/commands/new/project.rb +1 -1
- data/lib/ronin/cli/commands/new/script.rb +1 -1
- data/lib/ronin/cli/commands/new/web_app.rb +37 -0
- data/lib/ronin/cli/commands/new/web_server.rb +37 -0
- data/lib/ronin/cli/commands/new/web_spider.rb +37 -0
- data/lib/ronin/cli/commands/new.rb +3 -1
- data/lib/ronin/cli/commands/pack.rb +339 -0
- data/lib/ronin/cli/commands/public_suffix_list.rb +2 -0
- data/lib/ronin/cli/commands/tld_list.rb +2 -0
- data/lib/ronin/cli/commands/unarchive.rb +128 -0
- data/lib/ronin/cli/commands/unhexdump.rb +3 -1
- data/lib/ronin/cli/commands/unpack.rb +195 -0
- data/lib/ronin/cli/commands/url.rb +2 -0
- data/lib/ronin/cli/http_shell.rb +25 -0
- data/lib/ronin/cli.rb +10 -0
- data/lib/ronin/version.rb +1 -1
- data/man/ronin-archive.1.md +49 -0
- data/man/ronin-asn.1 +60 -77
- data/man/ronin-asn.1.md +25 -21
- data/man/ronin-banner-grab.1 +10 -21
- data/man/ronin-banner-grab.1.md +9 -5
- data/man/ronin-bitflip.1 +35 -61
- data/man/ronin-bitflip.1.md +30 -26
- data/man/ronin-bitsquat.1 +40 -0
- data/man/ronin-bitsquat.1.md +43 -0
- data/man/ronin-cert-dump.1 +44 -54
- data/man/ronin-cert-dump.1.md +18 -14
- data/man/ronin-cert-gen.1 +73 -94
- data/man/ronin-cert-gen.1.md +38 -34
- data/man/ronin-cert-grab.1 +29 -37
- data/man/ronin-cert-grab.1.md +12 -8
- data/man/ronin-completion.1 +78 -0
- data/man/ronin-completion.1.md +80 -0
- data/man/ronin-decode.1 +32 -63
- data/man/ronin-decode.1.md +29 -25
- data/man/ronin-decrypt.1 +42 -57
- data/man/ronin-decrypt.1.md +20 -16
- data/man/ronin-dns-proxy.1 +100 -0
- data/man/ronin-dns-proxy.1.md +70 -0
- data/man/ronin-dns.1 +10 -21
- data/man/ronin-dns.1.md +9 -5
- data/man/ronin-email-addr.1 +27 -40
- data/man/ronin-email-addr.1.md +15 -11
- data/man/ronin-encode.1 +93 -63
- data/man/ronin-encode.1.md +64 -26
- data/man/ronin-encrypt.1 +42 -57
- data/man/ronin-encrypt.1.md +20 -16
- data/man/ronin-entropy.1 +11 -21
- data/man/ronin-entropy.1.md +8 -4
- data/man/ronin-escape.1 +22 -46
- data/man/ronin-escape.1.md +22 -18
- data/man/ronin-extract.1 +74 -149
- data/man/ronin-extract.1.md +73 -69
- data/man/ronin-grep.1 +77 -155
- data/man/ronin-grep.1.md +76 -72
- data/man/ronin-help.1 +3 -14
- data/man/ronin-help.1.md +2 -2
- data/man/ronin-hexdump.1 +249 -265
- data/man/ronin-hexdump.1.md +93 -89
- data/man/ronin-highlight.1 +8 -18
- data/man/ronin-highlight.1.md +8 -4
- data/man/ronin-hmac.1 +17 -30
- data/man/ronin-hmac.1.md +14 -10
- data/man/ronin-homoglyph.1 +11 -22
- data/man/ronin-homoglyph.1.md +10 -6
- data/man/ronin-host.1 +23 -47
- data/man/ronin-host.1.md +22 -18
- data/man/ronin-http.1 +40 -69
- data/man/ronin-http.1.md +40 -30
- data/man/ronin-ip.1 +70 -80
- data/man/ronin-ip.1.md +44 -28
- data/man/ronin-iprange.1 +14 -22
- data/man/ronin-iprange.1.md +12 -5
- data/man/ronin-irb.1 +9 -17
- data/man/ronin-irb.1.md +7 -3
- data/man/ronin-md5.1 +13 -24
- data/man/ronin-md5.1.md +11 -7
- data/man/ronin-netcat.1 +25 -51
- data/man/ronin-netcat.1.md +25 -21
- data/man/ronin-new-dns-proxy.1 +45 -0
- data/man/ronin-new-dns-proxy.1.md +44 -0
- data/man/ronin-new-project.1 +32 -45
- data/man/ronin-new-project.1.md +11 -11
- data/man/ronin-new-script.1 +10 -22
- data/man/ronin-new-script.1.md +4 -4
- data/man/ronin-new.1 +56 -31
- data/man/ronin-new.1.md +48 -8
- data/man/ronin-pack.1 +977 -0
- data/man/ronin-pack.1.md +929 -0
- data/man/ronin-proxy.1 +37 -63
- data/man/ronin-proxy.1.md +29 -25
- data/man/ronin-public-suffix-list.1 +16 -32
- data/man/ronin-public-suffix-list.1.md +13 -9
- data/man/ronin-quote.1 +17 -36
- data/man/ronin-quote.1.md +17 -13
- data/man/ronin-rot.1 +26 -39
- data/man/ronin-rot.1.md +15 -11
- data/man/ronin-sha1.1 +13 -24
- data/man/ronin-sha1.1.md +11 -7
- data/man/ronin-sha256.1 +13 -24
- data/man/ronin-sha256.1.md +11 -7
- data/man/ronin-sha512.1 +13 -24
- data/man/ronin-sha512.1.md +11 -7
- data/man/ronin-strings.1 +30 -55
- data/man/ronin-strings.1.md +27 -23
- data/man/ronin-tips.1 +8 -16
- data/man/ronin-tips.1.md +7 -3
- data/man/ronin-tld-list.1 +16 -32
- data/man/ronin-tld-list.1.md +13 -9
- data/man/ronin-typo.1 +14 -28
- data/man/ronin-typo.1.md +13 -9
- data/man/ronin-typosquat.1 +15 -32
- data/man/ronin-typosquat.1.md +15 -11
- data/man/ronin-unarchive.1.md +41 -0
- data/man/ronin-unescape.1 +22 -46
- data/man/ronin-unescape.1.md +22 -18
- data/man/ronin-unhexdump.1 +81 -91
- data/man/ronin-unhexdump.1.md +16 -12
- data/man/ronin-unpack.1 +978 -0
- data/man/ronin-unpack.1.md +920 -0
- data/man/ronin-unquote.1 +17 -36
- data/man/ronin-unquote.1.md +17 -13
- data/man/ronin-url.1 +19 -40
- data/man/ronin-url.1.md +19 -15
- data/man/ronin-xor.1 +14 -28
- data/man/ronin-xor.1.md +13 -9
- data/man/ronin.1 +208 -29
- data/man/ronin.1.md +156 -11
- data/scripts/setup +58 -0
- metadata +162 -73
- data/lib/ronin/config.rb +0 -95
- /data/data/{new → templates}/project/.gitignore +0 -0
- /data/data/{new → templates}/project/.ruby-version.erb +0 -0
- /data/data/{new → templates}/project/Dockerfile.erb +0 -0
- /data/data/{new → templates}/project/Gemfile.erb +0 -0
- /data/data/{new → templates}/project/Rakefile +0 -0
- /data/data/{new → templates}/project/project.rb.erb +0 -0
- /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
|
@@ -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
|
-
#
|
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
|