ctf-party 1.4.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10a305673b24e2d87a3bfa4323788418ebae0df79afca8214e6b61144c521aa9
4
- data.tar.gz: 26bd71e348d16938441a50f0e31cd9d27140b30dfa8eb47042166934a9334978
3
+ metadata.gz: 1a891b890cdf81188caac863846fef9ddd4492126a34645de0bb9c09d4e4ab44
4
+ data.tar.gz: bcce5f84823d802900e4d1ff7750eb1a58c370d26f1895603091a237a62e7f2b
5
5
  SHA512:
6
- metadata.gz: ff8243a49da5b97cbe1978a9c2243541ec5ede71ecaabdd9520fc38b59705506e98d3c3e9b5c1dc75ccfcbb41bc505c66424401c77873d5d08b762766f877ae8
7
- data.tar.gz: d56fa0d1eba3673f3799a797582a809fddc86ea1a0b5e952db00aa7ac699be6760d0c4f275d903ef6c30a9d7659f29904c23a086e4c120fe4141e0133d4de10f
6
+ metadata.gz: ce15b05e7b38dfe927a6c7035d07fe843f2106b3897d716f685f7b98c3b1a851b09337657d8ee46916c2e7f36aa9ff1a48462b23c989357ad8be59f701e26c9e
7
+ data.tar.gz: f76df14283f2002dec8896e1b21ecf0bfb1cf4b778340a000074406a03558c483f262aa026912876cdca34c8353a5a949e8873b4e4fc537640d1e2aa65975e8d
data/bin/ctf-party CHANGED
@@ -25,6 +25,7 @@ cmd_whitelist = {
25
25
  hex2str: 'Alias for from_hex',
26
26
  htmlescape: 'HTML escape the string',
27
27
  htmlunescape: 'HTML unescape the string',
28
+ istrip: 'Remove leading and trailing whitespace but also all inner whitespace',
28
29
  leet: 'Transform into leet speak (l337 5p34k)',
29
30
  md5: 'Calculate the md5 hash of the string',
30
31
  randomcase: 'Change the case of characters randomly',
File without changes
@@ -6,8 +6,8 @@ require 'base64'
6
6
  class String
7
7
  # Encode the string into base64
8
8
  # @param opts [Hash] optional parameters
9
- # @option opts [Symbol] :mode Default value: +:strict+.
10
- # Other values are +:strict+ (+:rfc4648+) or +:urlsafe+.
9
+ # @option opts [Symbol] :mode Default value: `:strict`.
10
+ # Other values are `:strict` (`:rfc4648`) or `:urlsafe`.
11
11
  # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
12
12
  # @return [String] the Base64 encoded string
13
13
  # @example
@@ -32,8 +32,8 @@ class String
32
32
 
33
33
  # Decode the string from base64
34
34
  # @param opts [Hash] optional parameters
35
- # @option opts [Symbol] :mode Default value: +:strict+.
36
- # Other values are +:strict+ (+:rfc4648+) or +:urlsafe+.
35
+ # @option opts [Symbol] :mode Default value: `:strict`.
36
+ # Other values are `:strict` (`:rfc4648`) or `:urlsafe`.
37
37
  # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
38
38
  # @return [String] the Base64 decoded string
39
39
  # @example
@@ -58,10 +58,10 @@ class String
58
58
 
59
59
  # Is the string encoded in base64?
60
60
  # @param opts [Hash] optional parameters
61
- # @option opts [Symbol] :mode Default value: +:strict+.
62
- # Other values are +:strict+ (+:rfc4648+) or +:urlsafe+.
61
+ # @option opts [Symbol] :mode Default value: `:strict`.
62
+ # Other values are `:strict` (`:rfc4648`) or `:urlsafe`.
63
63
  # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
64
- # @return [Boolean] +true+ if the string is a valid base64 string, +false+
64
+ # @return [Boolean] `true` if the string is a valid base64 string, `false`
65
65
  # else.
66
66
  # @example
67
67
  # 'SGVsbG8gd29ybGQh'.b64? # => true
@@ -4,7 +4,7 @@ class String
4
4
  # Encode a string into binary
5
5
  # @param opts [Hash] optional parameters
6
6
  # @option opts [Symbol] :bitnumbering Display output with most significant bit
7
- # first (+:MSB+ default) or least significant bit first (+:LSB+).
7
+ # first (`:MSB` default) or least significant bit first (`:LSB`).
8
8
  # @return [String] the binary encoded string
9
9
  # @example
10
10
  # 'binary'.to_bin # => "011000100110100101101110011000010111001001111001"
@@ -41,7 +41,7 @@ class String
41
41
  # Decode a binary string
42
42
  # @param opts [Hash] optional parameters
43
43
  # @option opts [Symbol] :bitnumbering Display input with most significant bit
44
- # first (+:MSB+ default) or least significant bit first (+:LSB+).
44
+ # first (`:MSB` default) or least significant bit first (`:LSB`).
45
45
  # @return [String] the binary decoded string
46
46
  # @example
47
47
  # '011000100110100101101110011000010111001001111001'.from_bin # => "binary"
@@ -74,4 +74,4 @@ class String
74
74
  def bin2str!(opts = {})
75
75
  from_bin!(opts)
76
76
  end
77
- end
77
+ end
data/lib/ctf_party/cgi.rb CHANGED
@@ -4,12 +4,13 @@
4
4
  require 'cgi'
5
5
 
6
6
  class String
7
- # URL-encode the string
7
+ # URL-encode the URL string (RFC2396)
8
8
  # @return [String] the URL-encoded string
9
9
  # @example
10
- # "'Stop!' said Fred".urlencode # => "%27Stop%21%27+said+Fred"
10
+ # 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'.urlencode # => "http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E"
11
+ # "'Stop!' said Fred" # => "'Stop!'%20said%20Fred"
11
12
  def urlencode
12
- CGI.escape self
13
+ URI::Parser.new.escape self
13
14
  end
14
15
 
15
16
  # URL-encode the string in place as described for {String#urlencode}.
@@ -17,12 +18,29 @@ class String
17
18
  replace(urlencode)
18
19
  end
19
20
 
20
- # URL-decode the string
21
+ # URL-encode the URL component string
22
+ # @return [String] the URL-encoded string
23
+ # @example
24
+ # "'Stop!' said Fred".urlencode_component # => "%27Stop%21%27+said+Fred"
25
+ # 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'.urlencode_component # => "http%3A%2F%2Fvulnerable.site%2Fsearch.aspx%3Ftxt%3D%22%3E%3Cscript%3Ealert%28%2FRubyfu%2F.source%29%3C%2Fscript%3E"
26
+ def urlencode_component
27
+ CGI.escape self
28
+ end
29
+
30
+ # URL-encode the string in place as described for {String#urlencode_component}.
31
+ def urlencode_component!
32
+ replace(urlencode_component)
33
+ end
34
+
35
+ # URL-decode the URL string (RFC2396)
21
36
  # @return [String] the URL-decoded string
22
37
  # @example
23
- # "%27Stop%21%27+said+Fred".urldecode # => "'Stop!' said Fred"
38
+ # 'http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E'.urldecode # => "http://vulnerable.site/search.aspx?txt=\"><script>alert(/Rubyfu/.source)</script>"
39
+ # 'http%3A%2F%2Fvulnerable.site%2Fsearch.aspx%3Ftxt%3D%22%3E%3Cscript%3Ealert%28%2FRubyfu%2F.source%29%3C%2Fscript%3E'.urldecode # => "http://vulnerable.site/search.aspx?txt=\"><script>alert(/Rubyfu/.source)</script>"
40
+ # "'Stop!'%20said%20Fred".urldecode # => "'Stop!' said Fred"
41
+ # '%27Stop%21%27+said+Fred'.urldecode # => "'Stop!'+said+Fred"
24
42
  def urldecode
25
- CGI.unescape self
43
+ URI::Parser.new.unescape self
26
44
  end
27
45
 
28
46
  # URL-decode the string in place as described for {String#urldecode}.
@@ -30,6 +48,22 @@ class String
30
48
  replace(urldecode)
31
49
  end
32
50
 
51
+ # URL-decode the URL component string
52
+ # @return [String] the URL-decoded string
53
+ # @example
54
+ # 'http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E'.urldecode_component # => "http://vulnerable.site/search.aspx?txt=\"><script>alert(/Rubyfu/.source)</script>"
55
+ # 'http%3A%2F%2Fvulnerable.site%2Fsearch.aspx%3Ftxt%3D%22%3E%3Cscript%3Ealert%28%2FRubyfu%2F.source%29%3C%2Fscript%3E'.urldecode_component # => "http://vulnerable.site/search.aspx?txt=\"><script>alert(/Rubyfu/.source)</script>"
56
+ # "'Stop!'%20said%20Fred".urldecode_component => "'Stop!' said Fred"
57
+ # '%27Stop%21%27+said+Fred'.urldecode_component # => "'Stop!' said Fred"
58
+ def urldecode_component
59
+ CGI.unescape self
60
+ end
61
+
62
+ # URL-decode the string in place as described for {String#urldecode_component}.
63
+ def urldecode_component!
64
+ replace(urldecode_component)
65
+ end
66
+
33
67
  # HTML escape the string
34
68
  # @return [String] the HTML escaped string
35
69
  # @example
@@ -66,32 +66,32 @@ class String
66
66
  replace(sha2(opts))
67
67
  end
68
68
 
69
- # Alias for {String#sha2} with default value ( +sha2(bitlen: 256)+ ).
69
+ # Alias for {String#sha2} with default value ( `sha2(bitlen: 256)` ).
70
70
  def sha2_256
71
71
  sha2
72
72
  end
73
73
 
74
- # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 256)+ ).
74
+ # Alias for {String#sha2!} with default value ( `sha2!(bitlen: 256)` ).
75
75
  def sha2_256!
76
76
  replace(sha2)
77
77
  end
78
78
 
79
- # Alias for {String#sha2} with default value ( +sha2(bitlen: 384)+ ).
79
+ # Alias for {String#sha2} with default value ( `sha2(bitlen: 384)` ).
80
80
  def sha2_384
81
81
  sha2(bitlen: 384)
82
82
  end
83
83
 
84
- # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 384)+ ).
84
+ # Alias for {String#sha2!} with default value ( `sha2!(bitlen: 384)` ).
85
85
  def sha2_384!
86
86
  replace(sha2(bitlen: 384))
87
87
  end
88
88
 
89
- # Alias for {String#sha2} with default value ( +sha2(bitlen: 512)+ ).
89
+ # Alias for {String#sha2} with default value ( `sha2(bitlen: 512)` ).
90
90
  def sha2_512
91
91
  sha2(bitlen: 512)
92
92
  end
93
93
 
94
- # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 512)+ ).
94
+ # Alias for {String#sha2!} with default value ( `sha2!(bitlen: 512)` ).
95
95
  def sha2_512!
96
96
  replace(sha2(bitlen: 512))
97
97
  end
@@ -21,7 +21,7 @@ class String
21
21
  # @option hash [String] :prefix prefix of the flag. Default: none.
22
22
  # @option hash [String] :suffix suffix of the flag. Default: none.
23
23
  # @option hash [Array<String>] :enclosing the characters used to surround
24
- # the flag. Default are curly braces: +{+, +}+. The array must contain
24
+ # the flag. Default are curly braces: `{`, `}`. The array must contain
25
25
  # exactly 2 elements.
26
26
  # @option hash [String] :digest the hash algorithm to apply on the flag.
27
27
  # Default: none. Allowed values: md5, sha1, sha2_256, sha2_384, sha2_512,
data/lib/ctf_party/hex.rb CHANGED
@@ -4,15 +4,17 @@ class String
4
4
  # Encode an hexadecimal string to a decimal string
5
5
  # @param opts [Hash] optional parameters
6
6
  # @option opts [String] :prefix Prefix of the input. Default value is a void
7
- # string. Example of values: +0x+, +\x+.
7
+ # string. Example of values: `0x`, `\x`, `\\x`.
8
8
  # @return [String] the decimal encoded string
9
9
  # @example
10
10
  # 'ff'.hex2dec # => "255"
11
11
  # '\xf3'.hex2dec(prefix: '\x') # => "243"
12
+ # '6e6f72616a'.hex2dec # => "474316169578"
13
+ # '\\x6e\\x6f\\x72\\x61\\x6a'.hex2dec(prefix: '\\x') # => "474316169578"
12
14
  def hex2dec(opts = {})
13
15
  opts[:prefix] ||= ''
14
16
  # remove prefix
15
- out = sub(opts[:prefix], '')
17
+ out = gsub(opts[:prefix], '')
16
18
  # convert
17
19
  return out.hex.to_s
18
20
  end
@@ -30,26 +32,35 @@ class String
30
32
  # Encode an decimal string to a hexadecimal string
31
33
  # @param opts [Hash] optional parameters
32
34
  # @option opts [String] :prefix Prefix of the output. Default value is a void
33
- # string. Example of values: +0x+, +\x+.
34
- # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+.
35
- # Other valid value +:upper+.
35
+ # string. Example of values: `0x`, `\x`.
36
+ # @option opts [String] :prefixall Prefix each byte. Default value is a void
37
+ # string. Example of value: `\\x`.
38
+ # @option opts [Symbol] :case Char case of the output. Default value `:lower`.
39
+ # Other valid value `:upper`.
36
40
  # @option opts [Symbol] :padding Minimum size of the hexadecimal display
37
- # (number of characters). Eg. 10 -> 0xA or 0x0A
41
+ # (number of characters). Must be even.
38
42
  # @return [String] the hexadecimal encoded string
39
43
  # @example
40
44
  # '255'.dec2hex # => "ff"
41
45
  # '255'.dec2hex({prefix: '0x', case: :upper}) # => "0xFF"
46
+ # '10'.dec2hex(padding: 2) # => "0a"
47
+ # '10'.dec2hex(padding: 8) # => "0000000a"
48
+ # '474316169578'.dec2hex(prefixall: '\\x') # => "\\x6e\\x6f\\x72\\x61\\x6a"
42
49
  def dec2hex(opts = {})
43
50
  opts[:prefix] ||= ''
51
+ opts[:prefixall] ||= ''
44
52
  opts[:case] ||= :lower
45
- opts[:padding] ||= 1
53
+ opts[:padding] ||= 2
54
+ raise(ArgumentError, 'Padding must be even') if opts[:padding].odd?
55
+
46
56
  # convert
47
57
  out = to_i.to_s(16)
48
58
  # padding
49
- out = ('0' * (opts[:padding] - 1)) + out if out.size < opts[:padding]
59
+ out = ('0' * (opts[:padding] - out.size)) + out if out.size < opts[:padding]
50
60
  # char case management
51
61
  out = out.upcase if opts[:case] == :upper
52
62
  # adding prefix must be done after case change
63
+ out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
53
64
  return opts[:prefix] + out
54
65
  end
55
66
 
@@ -66,19 +77,23 @@ class String
66
77
  # Encode a string into hexadecimal
67
78
  # @param opts [Hash] optional parameters
68
79
  # @option opts [String] :prefix Prefix of the output. Default value is a void
69
- # string. Example of values: +0x+, +\x+.
70
- # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+.
71
- # Other valid value +:upper+.
80
+ # string. Example of values: `0x`, `\x`.
81
+ # @option opts [String] :prefixall Prefix each byte. Default value is a void
82
+ # string. Example of value: `\\x`.
83
+ # @option opts [Symbol] :case Char case of the output. Default value `:lower`.
84
+ # Other valid value `:upper`.
72
85
  # @option opts [Symbol] :nibble Display output with high nibble first
73
- # (+:high+ default) or low nibble first (+:low+).
86
+ # (`:high` default) or low nibble first (`:low`).
74
87
  # @return [String] the hexadecimal encoded string
75
88
  # @example
76
89
  # 'noraj'.to_hex # => "6e6f72616a"
77
90
  # 'noraj'.to_hex(prefix: '0x') # => "0x6e6f72616a"
78
91
  # 'noraj'.to_hex(case: :upper) # => "6E6F72616A"
79
92
  # 'noraj'.to_hex(nibble: :low) # => "e6f62716a6"
93
+ # 'noraj'.to_hex(prefixall: '\\x') # => "\\x6e\\x6f\\x72\\x61\\x6a"
80
94
  def to_hex(opts = {})
81
95
  opts[:prefix] ||= ''
96
+ opts[:prefixall] ||= ''
82
97
  opts[:case] ||= :lower
83
98
  opts[:nibble] ||= :high
84
99
  # convert
@@ -92,6 +107,7 @@ class String
92
107
  # char case management
93
108
  out = out.upcase if opts[:case] == :upper
94
109
  # adding prefix must be done after case change
110
+ out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
95
111
  return opts[:prefix] + out
96
112
  end
97
113
 
@@ -118,19 +134,20 @@ class String
118
134
  # Decode a hexadecimal string
119
135
  # @param opts [Hash] optional parameters
120
136
  # @option opts [String] :prefix Prefix of the input. Default value is a void
121
- # string. Example of values: +0x+, +\x+.
137
+ # string. Example of values: `0x`, `\x`, `\\x`.
122
138
  # @option opts [Symbol] :nibble Display input with high nibble first
123
- # (+:high+ default) or low nibble first (+:low+).
139
+ # (`:high` default) or low nibble first (`:low`).
124
140
  # @return [String] the hexadecimal decoded string
125
141
  # @example
126
142
  # "6e6f72616a".from_hex # => "noraj"
127
143
  # "0x6e6f72616a".from_hex(prefix: '0x') # => "noraj"
128
144
  # "e6f62716a6".from_hex(nibble: :low) # => "noraj"
145
+ # '\\x6e\\x6f\\x72\\x61\\x6a'.from_hex(prefix: '\\x') # => "noraj"
129
146
  def from_hex(opts = {})
130
147
  opts[:prefix] ||= ''
131
148
  opts[:nibble] ||= :high
132
149
  # remove prefix
133
- out = sub(opts[:prefix], '')
150
+ out = gsub(opts[:prefix], '')
134
151
  # convert
135
152
  return Array(out).pack('H*') if opts[:nibble] == :high
136
153
  return Array(out).pack('h*') if opts[:nibble] == :low
@@ -161,15 +178,16 @@ class String
161
178
  # Encode an hexadecimal string to a binary string
162
179
  # @param opts [Hash] optional parameters
163
180
  # @option opts [String] :prefix Prefix of the input. Default value is a void
164
- # string. Example of values: +0x+, +\x+.
181
+ # string. Example of values: `0x`, `\x`, `\\x`.
165
182
  # @return [String] the binary encoded string
166
183
  # @example
167
184
  # 'ab'.hex2bin # => "10101011"
168
185
  # '\xf3'.hex2bin(prefix: '\x') # => "11110011"
186
+ # '\\x6e\\x6f\\x72\\x61\\x6a'.hex2bin(prefix: '\\x') # => "110111001101111011100100110000101101010"
169
187
  def hex2bin(opts = {})
170
188
  opts[:prefix] ||= ''
171
189
  # remove prefix
172
- out = sub(opts[:prefix], '')
190
+ out = gsub(opts[:prefix], '')
173
191
  # convert
174
192
  return out.to_i(16).to_s(2)
175
193
  end
@@ -187,21 +205,26 @@ class String
187
205
  # Encode an binary string to a hexadecimal string
188
206
  # @param opts [Hash] optional parameters
189
207
  # @option opts [String] :prefix Prefix of the output. Default value is a void
190
- # string. Example of values: +0x+, +\x+.
191
- # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+.
192
- # Other valid value +:upper+.
208
+ # string. Example of values: `0x`, `\x`.
209
+ # @option opts [String] :prefixall Prefix each byte. Default value is a void
210
+ # string. Example of value: `\\x`.
211
+ # @option opts [Symbol] :case Char case of the output. Default value `:lower`.
212
+ # Other valid value `:upper`.
193
213
  # @return [String] the hexadecimal encoded string
194
214
  # @example
195
215
  # '11110011'.bin2hex # => "f3"
196
216
  # '11110011'.bin2hex({prefix: '0x', case: :upper}) # => "0xF3"
217
+ # '0110111001101111011100100110000101101010'.bin2hex(prefixall: '\\x') # => "\\x6e\\x6f\\x72\\x61\\x6a"
197
218
  def bin2hex(opts = {})
198
219
  opts[:prefix] ||= ''
220
+ opts[:prefixall] ||= ''
199
221
  opts[:case] ||= :lower
200
222
  # convert
201
223
  out = to_i(2).to_s(16)
202
224
  # char case management
203
225
  out = out.upcase if opts[:case] == :upper
204
226
  # adding prefix must be done after case change
227
+ out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
205
228
  return opts[:prefix] + out
206
229
  end
207
230
 
@@ -218,18 +241,19 @@ class String
218
241
  # Decode a hexadecimal IP string into a dotted decimal one
219
242
  # @param opts [Hash] optional parameters
220
243
  # @option opts [String] :prefix Prefix of the input. Default value is a void
221
- # string. Example of values: +0x+, +\x+.
244
+ # string. Example of values: `0x`, `\x`, '\\x'.
222
245
  # @option opts [Symbol] :nibble Display input with high nibble first
223
- # (+:high+ default) or low nibble first (+:low+, used on Unix +/proc/net/tcp+).
246
+ # (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
224
247
  # @return [String] the dotted decimal IP
225
248
  # @example
226
249
  # '0100007F'.from_hexip(nibble: :low) # => "127.0.0.1"
227
250
  # '0x7f000001'.from_hexip(prefix: '0x') # => "127.0.0.1"
251
+ # '\\x7f\\x00\\x00\\x01'.from_hexip(prefix: '\\x') # => "127.0.0.1"
228
252
  def from_hexip(opts = {})
229
253
  opts[:prefix] ||= ''
230
254
  opts[:nibble] ||= :high
231
255
  # remove prefix
232
- out = sub(opts[:prefix], '')
256
+ out = gsub(opts[:prefix], '')
233
257
  # convert
234
258
  out = out.scan(/.{2}/).map(&:hex2dec)
235
259
  out = out.reverse if opts[:nibble] == :low
@@ -245,17 +269,21 @@ class String
245
269
  # Encode a dotted decimal IP into a hexadecimal one
246
270
  # @param opts [Hash] optional parameters
247
271
  # @option opts [String] :prefix Prefix of the output. Default value is a void
248
- # string. Example of values: +0x+, +\x+.
249
- # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+.
250
- # Other valid value +:upper+.
272
+ # string. Example of values: `0x`, `\x`.
273
+ # @option opts [String] :prefixall Prefix each byte. Default value is a void
274
+ # string. Example of value: `\\x`.
275
+ # @option opts [Symbol] :case Char case of the output. Default value `:lower`.
276
+ # Other valid value `:upper`.
251
277
  # @option opts [Symbol] :nibble Display output with high nibble first
252
- # (+:high+ default) or low nibble first (+:low+, used on Unix +/proc/net/tcp+).
278
+ # (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
253
279
  # @return [String] the hexadecimal encoded IP
254
280
  # @example
255
281
  # '127.0.0.1'.to_hexip # => "7f000001"
256
282
  # '127.0.0.1'.to_hexip(nibble: :low) # => "0100007f"
283
+ # '127.0.0.1'.to_hexip(prefixall: '\\x') # => "\\x7f\\x00\\x00\\x01"
257
284
  def to_hexip(opts = {})
258
285
  opts[:prefix] ||= ''
286
+ opts[:prefixall] ||= ''
259
287
  opts[:case] ||= :lower
260
288
  opts[:nibble] ||= :high
261
289
  # convert
@@ -265,6 +293,7 @@ class String
265
293
  # char case management
266
294
  out = out.upcase if opts[:case] == :upper
267
295
  # adding prefix must be done after case change
296
+ out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
268
297
  return opts[:prefix] + out
269
298
  end
270
299
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ # Remove leading and trailing whitespace (like {String#strip}) but also all
5
+ # inner whitespace.
6
+ # @return [String] the whitespace-free string
7
+ # @example
8
+ # "\t\n\v\f\r Hello \t\n\v\f\r World !\t\n\v\f\r ".istrip # => "HelloWorld!"
9
+ # '73 74 72 69 70'.istrip # => "7374726970"
10
+ def istrip
11
+ strip.gsub(/\s/, '')
12
+ end
13
+
14
+ # Remove all whitespace in place as described for {String#istrip}.
15
+ def istrip!
16
+ replace(innerstrip)
17
+ end
18
+ end
data/lib/ctf_party/rot.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  class String
4
4
  # "Encrypt / Decrypt" the string with Caesar cipher. This will shift the
5
- # alphabet letters by +n+, where +n+ is the integer key. The same function
5
+ # alphabet letters by `n`, where `n` is the integer key. The same function
6
6
  # is used for encryption / decryption.
7
7
  # @param opts [Hash] optional parameters
8
8
  # @option opts [Integer] :shift The shift key. Default value: 13.
@@ -16,9 +16,9 @@ class String
16
16
  def rot(opts = {})
17
17
  opts[:shift] ||= 13
18
18
  alphabet = Array('a'..'z')
19
- lowercase = Hash[alphabet.zip(alphabet.rotate(opts[:shift]))]
19
+ lowercase = alphabet.zip(alphabet.rotate(opts[:shift])).to_h
20
20
  alphabet = Array('A'..'Z')
21
- uppercasecase = Hash[alphabet.zip(alphabet.rotate(opts[:shift]))]
21
+ uppercasecase = alphabet.zip(alphabet.rotate(opts[:shift])).to_h
22
22
  encrypter = lowercase.merge(uppercasecase)
23
23
  chars.map { |c| encrypter.fetch(c, c) }.join
24
24
  end
@@ -35,13 +35,22 @@ class String
35
35
  replace(rot(opts))
36
36
  end
37
37
 
38
- # Alias for {String#rot} with default value ( +rot(shift: 13)+ ).
38
+ # Alias for {String#rot} with default value ( `rot(shift: 13)` ).
39
39
  def rot13
40
40
  rot
41
41
  end
42
42
 
43
- # Alias for {String#rot!} with default value ( +rot!(shift: 13)+ ).
43
+ # Alias for {String#rot!} with default value ( `rot!(shift: 13)` ).
44
44
  def rot13!
45
45
  rot!
46
46
  end
47
+
48
+ # Compute all possibilities with {String#rot}
49
+ # @return [Hash] All possibilities with the shift index as key and the
50
+ # (de)ciphered text as value
51
+ # @example
52
+ # 'noraj'.rot_all # => {1=>"opsbk", 2=>"pqtcl", 3=>"qrudm", ... }
53
+ def rot_all
54
+ (1..26).each_with_object({}) { |i, h| h[i] = rot(shift: i) }
55
+ end
47
56
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Version
4
- VERSION = '1.4.0'
4
+ VERSION = '2.1.0'
5
5
  end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ # UTF-8 XOR with key, padding left the shortest element
5
+ # @param key [String] the element to xor the string with
6
+ # @return [String] the xored string (UTF-8)
7
+ # @example
8
+ # 'hello'.ulxor('key') # => "he\a\t\u0016"
9
+ # 'key'.ulxor('hello') # => "he\a\t\u0016"
10
+ def ulxor(key)
11
+ b1 = unpack('U*')
12
+ b2 = key.unpack('U*')
13
+ longest = [b1.length, b2.length].max
14
+ b1 = ([0] * (longest - b1.length)) + b1
15
+ b2 = ([0] * (longest - b2.length)) + b2
16
+ b1.zip(b2).map { |a, b| a ^ b }.pack('U*')
17
+ end
18
+
19
+ # UTF-8 XOR with key (padding left) in place as described for {String#ulxor}.
20
+ def ulxor!(key)
21
+ replace(ulxor(key))
22
+ end
23
+
24
+ # ASCII XOR with key, padding left the shortest element
25
+ # @param key [String] the element to xor the string with
26
+ # @return [String] the xored string (ASCII)
27
+ # @example
28
+ # 'hello'.alxor('key') # => "he\a\t\x16"
29
+ # 'key'.alxor('hello') # => "he\a\t\x16"
30
+ def alxor(key)
31
+ b1 = force_encoding('UTF-8')
32
+ b2 = key.force_encoding('UTF-8')
33
+ raise 'The string is not ASCII' unless b1.ascii_only?
34
+ raise 'The key is not ASCII' unless b2.ascii_only?
35
+
36
+ b1 = b1.chars.map(&:ord)
37
+ b2 = b2.chars.map(&:ord)
38
+ longest = [b1.length, b2.length].max
39
+ b1 = ([0] * (longest - b1.length)) + b1
40
+ b2 = ([0] * (longest - b2.length)) + b2
41
+ b1.zip(b2).map { |a, b| (a ^ b).chr }.join
42
+ end
43
+
44
+ # ASCII XOR with key (padding left) in place as described for {String#alxor}.
45
+ def alxor!(key)
46
+ replace(alxor(key))
47
+ end
48
+
49
+ # UTF-8 XOR with key, padding right the shortest element
50
+ # @param key [String] the element to xor the string with
51
+ # @return [String] the xored string (UTF-8)
52
+ # @example
53
+ # 'hello'.urxor('key') # => "\u0003\u0000\u0015lo"
54
+ # 'key'.urxor('hello') # => "\u0003\u0000\u0015lo"
55
+ def urxor(key)
56
+ b1 = unpack('U*')
57
+ b2 = key.unpack('U*')
58
+ longest = [b1.length, b2.length].max
59
+ b1 += [0] * (longest - b1.length)
60
+ b2 += [0] * (longest - b2.length)
61
+ b1.zip(b2).map { |a, b| a ^ b }.pack('U*')
62
+ end
63
+
64
+ # UTF-8 XOR with key (padding right) in place as described for {String#urxor}.
65
+ def urxor!(key)
66
+ replace(urxor(key))
67
+ end
68
+
69
+ # ASCII XOR with key, padding right the shortest element
70
+ # @param key [String] the element to xor the string with
71
+ # @return [String] the xored string (ASCII)
72
+ # @example
73
+ # 'hello'.arxor('key') # => "\x03\x00\x15lo"
74
+ # 'key'.arxor('hello') # => "\x03\x00\x15lo"
75
+ def arxor(key)
76
+ b1 = force_encoding('UTF-8')
77
+ b2 = key.force_encoding('UTF-8')
78
+ raise 'The string is not ASCII' unless b1.ascii_only?
79
+ raise 'The key is not ASCII' unless b2.ascii_only?
80
+
81
+ b1 = b1.chars.map(&:ord)
82
+ b2 = b2.chars.map(&:ord)
83
+ longest = [b1.length, b2.length].max
84
+ b1 += [0] * (longest - b1.length)
85
+ b2 += [0] * (longest - b2.length)
86
+ b1.zip(b2).map { |a, b| (a ^ b).chr }.join
87
+ end
88
+
89
+ # ASCII XOR with key (padding right) in place as described for {String#arxor}.
90
+ def arxor!(key)
91
+ replace(arxor(key))
92
+ end
93
+ end
data/lib/ctf_party.rb CHANGED
@@ -11,3 +11,5 @@ require 'ctf_party/cgi'
11
11
  require 'ctf_party/binary'
12
12
  require 'ctf_party/leet'
13
13
  require 'ctf_party/dec'
14
+ require 'ctf_party/misc'
15
+ require 'ctf_party/xor'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ctf-party
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre ZANNI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-10 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docopt
@@ -24,145 +24,22 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.6'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '2.1'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '2.1'
41
- - !ruby/object:Gem::Dependency
42
- name: commonmarker
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.20'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.20'
55
- - !ruby/object:Gem::Dependency
56
- name: github-markup
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '4.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '4.0'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '5'
83
- - !ruby/object:Gem::Dependency
84
- name: minitest-skip
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '0.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0.0'
97
- - !ruby/object:Gem::Dependency
98
- name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '13.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '13.0'
111
- - !ruby/object:Gem::Dependency
112
- name: redcarpet
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '3.5'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '3.5'
125
- - !ruby/object:Gem::Dependency
126
- name: rubocop
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '1.8'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '1.8'
139
- - !ruby/object:Gem::Dependency
140
- name: yard
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.9'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '0.9'
153
- description: A CLI tool & library to enhance and speed up script/exploitwriting for
154
- CTF players (or security researchers, bug bountyhunters, pentesters but mostly focused
155
- on CTF) bypatching the String class to add a short syntax of usualcode patterns.
27
+ description: A CLI tool & library to enhance and speed up script/exploit writing for
28
+ CTF players (or security researchers, bug bounty hunters, pentesters but mostly
29
+ focused on CTF) by patching the String class to add a short syntax of usual code
30
+ patterns. Methods for base64, digest (hash), flag, rot (Caesar), hexadecimal, case,
31
+ cgi (URL encoding/decoding, HTML escaping/unescaping), binary, leet (1337), decimal,
32
+ XOR, whitespace strip.
156
33
  email: alexandre.zanni@engineer.com
157
34
  executables:
158
35
  - ctf-party
159
- - ctf_party_console
36
+ - ctf-party_console
160
37
  extensions: []
161
38
  extra_rdoc_files: []
162
39
  files:
163
40
  - LICENSE.txt
164
41
  - bin/ctf-party
165
- - bin/ctf_party_console
42
+ - bin/ctf-party_console
166
43
  - lib/ctf_party.rb
167
44
  - lib/ctf_party/base64.rb
168
45
  - lib/ctf_party/binary.rb
@@ -173,8 +50,10 @@ files:
173
50
  - lib/ctf_party/flag.rb
174
51
  - lib/ctf_party/hex.rb
175
52
  - lib/ctf_party/leet.rb
53
+ - lib/ctf_party/misc.rb
176
54
  - lib/ctf_party/rot.rb
177
55
  - lib/ctf_party/version.rb
56
+ - lib/ctf_party/xor.rb
178
57
  homepage: https://noraj.github.io/ctf-party/
179
58
  licenses:
180
59
  - MIT
@@ -185,24 +64,28 @@ metadata:
185
64
  documentation_uri: https://noraj.github.io/ctf-party/
186
65
  homepage_uri: https://noraj.github.io/ctf-party/
187
66
  source_code_uri: https://github.com/noraj/ctf-party/
67
+ rubygems_mfa_required: 'true'
188
68
  post_install_message:
189
69
  rdoc_options: []
190
70
  require_paths:
191
71
  - lib
192
72
  required_ruby_version: !ruby/object:Gem::Requirement
193
73
  requirements:
194
- - - "~>"
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 2.7.0
77
+ - - "<"
195
78
  - !ruby/object:Gem::Version
196
- version: '2.7'
79
+ version: '3.2'
197
80
  required_rubygems_version: !ruby/object:Gem::Requirement
198
81
  requirements:
199
82
  - - ">="
200
83
  - !ruby/object:Gem::Version
201
84
  version: '0'
202
85
  requirements: []
203
- rubygems_version: 3.1.4
86
+ rubygems_version: 3.3.3
204
87
  signing_key:
205
88
  specification_version: 4
206
- summary: A CLI tool & library to enhance and speed up script/exploitwriting for CTF
207
- players
89
+ summary: A CLI tool & library to enhance and speed up script/exploit writing with
90
+ string conversion/manipulation
208
91
  test_files: []