ctf-party 1.3.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/ctf-party +95 -0
- data/bin/{ctf_party_console → ctf-party_console} +0 -0
- data/lib/ctf_party/base64.rb +7 -7
- data/lib/ctf_party/binary.rb +3 -3
- data/lib/ctf_party/cgi.rb +40 -6
- data/lib/ctf_party/digest.rb +6 -6
- data/lib/ctf_party/flag.rb +1 -1
- data/lib/ctf_party/hex.rb +56 -27
- data/lib/ctf_party/misc.rb +18 -0
- data/lib/ctf_party/rot.rb +14 -5
- data/lib/ctf_party/version.rb +1 -1
- data/lib/ctf_party/xor.rb +93 -0
- data/lib/ctf_party.rb +2 -0
- metadata +27 -127
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d60cac63a1449a4ddc3bf3b34ab1ff58db23b62adb3f5710b7bfe4822827088
|
4
|
+
data.tar.gz: 9fdc5fdaced3468d7003865e2e334ee756f6162a7204b64d99665c6e378a7bf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4212f6d4908cf82c3921b581424109c05d3bdd06d26bb8531c61cd903754260de7732bd019ee04dbf8d500dd1d947773701fb41a29ddf8142dd3f0388d59f778
|
7
|
+
data.tar.gz: ab4919f51fe339643dd6f6a4da0086e42451245f68438049c66f81ebf9f9ad14aadfe6ef2f04c28f4b26b473d0440283e9324be331e6643519e7b462a798de55
|
data/bin/ctf-party
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Ruby internal
|
5
|
+
require 'pp'
|
6
|
+
# Project internal
|
7
|
+
require 'ctf_party'
|
8
|
+
require 'ctf_party/version'
|
9
|
+
# External
|
10
|
+
require 'docopt'
|
11
|
+
|
12
|
+
cmd_whitelist = {
|
13
|
+
alternatecase: 'Change one characte on two upcase and the other downcase',
|
14
|
+
bin2hex: 'Encode an binary string to a hexadecimal string',
|
15
|
+
bin2str: 'Alias for from_bin',
|
16
|
+
dec2hex: 'Encode an decimal string to a hexadecimal string',
|
17
|
+
dec2str: 'Alias for from_dec',
|
18
|
+
from_b64: 'Decode the string from base64',
|
19
|
+
from_bin: 'Decode a binary string',
|
20
|
+
from_dec: 'Decode a decimal string (decimal to hexadecimal then hexadecimal to string)',
|
21
|
+
from_hex: 'Decode a hexadecimal string',
|
22
|
+
from_hexip: 'Decode a hexadecimal IP string into a dotted decimal one',
|
23
|
+
hex2bin: 'Encode an hexadecimal string to a binary string',
|
24
|
+
hex2dec: 'Encode an hexadecimal string to a decimal string',
|
25
|
+
hex2str: 'Alias for from_hex',
|
26
|
+
htmlescape: 'HTML escape the string',
|
27
|
+
htmlunescape: 'HTML unescape the string',
|
28
|
+
istrip: 'Remove leading and trailing whitespace but also all inner whitespace',
|
29
|
+
leet: 'Transform into leet speak (l337 5p34k)',
|
30
|
+
md5: 'Calculate the md5 hash of the string',
|
31
|
+
randomcase: 'Change the case of characters randomly',
|
32
|
+
rmd160: 'Calculate the RIPEMD-160 hash of the string',
|
33
|
+
rot13: 'Encrypt / Decrypt the string with Caesar cipher with a shift of 13',
|
34
|
+
sha1: 'Calculate the sha1 hash of the string',
|
35
|
+
sha2: 'Calculate the sha2 hash of the string',
|
36
|
+
sha2_256: 'Alias for sha2 with bitlen of 256',
|
37
|
+
sha2_384: 'Alias for sha2 with bitlen of 384',
|
38
|
+
sha2_512: 'Alias for sha2 with bitlen of 512',
|
39
|
+
str2bin: 'Alias for to_bin',
|
40
|
+
str2dec: 'Alias for to_dec',
|
41
|
+
str2hex: 'Alias for to_hex',
|
42
|
+
to_b64: 'Encode the string into base64',
|
43
|
+
to_bin: 'Encode a string into binary',
|
44
|
+
to_dec: 'Encode a string into decimal (string to hexadecimal then hexadecimal to decimal)',
|
45
|
+
to_hex: 'Encode a string into hexadecimal',
|
46
|
+
to_hexip: 'Encode a dotted decimal IP into a hexadecimal one',
|
47
|
+
urldecode: 'URL-decode the string',
|
48
|
+
urlencode: 'URL-encode the string'
|
49
|
+
}
|
50
|
+
|
51
|
+
doc = <<~DOCOPT
|
52
|
+
ctf-party by noraj
|
53
|
+
|
54
|
+
Usage:
|
55
|
+
ctf-party <string> <cmd>... [--debug]
|
56
|
+
ctf-party --list-commands [--debug]
|
57
|
+
ctf-party -h | --help
|
58
|
+
ctf-party --version
|
59
|
+
|
60
|
+
Options:
|
61
|
+
-l, --list-commands List available commands (see https://noraj.github.io/ctf-party/yard/String.html)
|
62
|
+
--debug Display arguments
|
63
|
+
-h, --help Show this screen
|
64
|
+
--version Show version
|
65
|
+
|
66
|
+
Examples:
|
67
|
+
ctf-party 'security' to_hex
|
68
|
+
ctf-party 'NzQ2Zjc0NmY=' from_b64 hex2str str2bin
|
69
|
+
DOCOPT
|
70
|
+
|
71
|
+
begin
|
72
|
+
args = Docopt.docopt(doc, version: Version::VERSION)
|
73
|
+
# use case 1, using the tool
|
74
|
+
pp args if args['--debug']
|
75
|
+
if args['<string>']
|
76
|
+
wrong_cmd = args['<cmd>'] - cmd_whitelist.keys.map(&:to_s)
|
77
|
+
if wrong_cmd.empty?
|
78
|
+
output = args['<string>']
|
79
|
+
args['<cmd>'].each do |cmd|
|
80
|
+
output = output.public_send(cmd)
|
81
|
+
end
|
82
|
+
puts output
|
83
|
+
else
|
84
|
+
abort "Those commands don't exist: #{wrong_cmd}"
|
85
|
+
end
|
86
|
+
elsif args['--list-commands']
|
87
|
+
cmd_whitelist.each do |k, v|
|
88
|
+
puts "#{k.to_s.ljust(15)}#{v}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
# use case 2, help: already handled by docopt
|
92
|
+
# use case 3, version: already handled by docopt
|
93
|
+
rescue Docopt::Exit => e
|
94
|
+
puts e.message
|
95
|
+
end
|
File without changes
|
data/lib/ctf_party/base64.rb
CHANGED
@@ -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:
|
10
|
-
# Other values are
|
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:
|
36
|
-
# Other values are
|
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:
|
62
|
-
# Other values are
|
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]
|
64
|
+
# @return [Boolean] `true` if the string is a valid base64 string, `false`
|
65
65
|
# else.
|
66
66
|
# @example
|
67
67
|
# 'SGVsbG8gd29ybGQh'.b64? # => true
|
data/lib/ctf_party/binary.rb
CHANGED
@@ -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 (
|
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 (
|
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
|
-
# "'
|
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
|
-
|
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-
|
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
|
-
#
|
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
|
-
|
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
|
data/lib/ctf_party/digest.rb
CHANGED
@@ -66,32 +66,32 @@ class String
|
|
66
66
|
replace(sha2(opts))
|
67
67
|
end
|
68
68
|
|
69
|
-
# Alias for {String#sha2} with default value (
|
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 (
|
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 (
|
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 (
|
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 (
|
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 (
|
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
|
data/lib/ctf_party/flag.rb
CHANGED
@@ -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:
|
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:
|
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 =
|
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:
|
34
|
-
# @option opts [
|
35
|
-
#
|
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).
|
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] ||=
|
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] -
|
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:
|
70
|
-
# @option opts [
|
71
|
-
#
|
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
|
-
# (
|
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:
|
137
|
+
# string. Example of values: `0x`, `\x`, `\\x`.
|
122
138
|
# @option opts [Symbol] :nibble Display input with high nibble first
|
123
|
-
# (
|
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 =
|
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:
|
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 =
|
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:
|
191
|
-
# @option opts [
|
192
|
-
#
|
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:
|
244
|
+
# string. Example of values: `0x`, `\x`, '\\x'.
|
222
245
|
# @option opts [Symbol] :nibble Display input with high nibble first
|
223
|
-
# (
|
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 =
|
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:
|
249
|
-
# @option opts [
|
250
|
-
#
|
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
|
-
# (
|
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
|
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 =
|
19
|
+
lowercase = alphabet.zip(alphabet.rotate(opts[:shift])).to_h
|
20
20
|
alphabet = Array('A'..'Z')
|
21
|
-
uppercasecase =
|
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 (
|
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 (
|
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
|
data/lib/ctf_party/version.rb
CHANGED
@@ -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
metadata
CHANGED
@@ -1,152 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ctf-party
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.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:
|
11
|
+
date: 2022-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: docopt
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
version: '0.20'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.20'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: github-markup
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '4.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '4.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '5'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '5'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest-skip
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0.0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '13.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '13.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: redcarpet
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '3.5'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '3.5'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '1.8'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '1.8'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yard
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0.9'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0.9'
|
139
|
-
description: A library to enhance and speed up script/exploit writingfor CTF players
|
140
|
-
(or security researchers, bug bountyhunters, pentesters but mostly focused on CTF)
|
141
|
-
bypatching the String class to add a short syntax of usual code patterns.
|
26
|
+
version: '0.6'
|
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.
|
142
33
|
email: alexandre.zanni@engineer.com
|
143
34
|
executables:
|
144
|
-
-
|
35
|
+
- ctf-party
|
36
|
+
- ctf-party_console
|
145
37
|
extensions: []
|
146
38
|
extra_rdoc_files: []
|
147
39
|
files:
|
148
40
|
- LICENSE.txt
|
149
|
-
- bin/
|
41
|
+
- bin/ctf-party
|
42
|
+
- bin/ctf-party_console
|
150
43
|
- lib/ctf_party.rb
|
151
44
|
- lib/ctf_party/base64.rb
|
152
45
|
- lib/ctf_party/binary.rb
|
@@ -157,8 +50,10 @@ files:
|
|
157
50
|
- lib/ctf_party/flag.rb
|
158
51
|
- lib/ctf_party/hex.rb
|
159
52
|
- lib/ctf_party/leet.rb
|
53
|
+
- lib/ctf_party/misc.rb
|
160
54
|
- lib/ctf_party/rot.rb
|
161
55
|
- lib/ctf_party/version.rb
|
56
|
+
- lib/ctf_party/xor.rb
|
162
57
|
homepage: https://noraj.github.io/ctf-party/
|
163
58
|
licenses:
|
164
59
|
- MIT
|
@@ -169,23 +64,28 @@ metadata:
|
|
169
64
|
documentation_uri: https://noraj.github.io/ctf-party/
|
170
65
|
homepage_uri: https://noraj.github.io/ctf-party/
|
171
66
|
source_code_uri: https://github.com/noraj/ctf-party/
|
67
|
+
rubygems_mfa_required: 'true'
|
172
68
|
post_install_message:
|
173
69
|
rdoc_options: []
|
174
70
|
require_paths:
|
175
71
|
- lib
|
176
72
|
required_ruby_version: !ruby/object:Gem::Requirement
|
177
73
|
requirements:
|
178
|
-
- - "
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.7.0
|
77
|
+
- - "<"
|
179
78
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
79
|
+
version: '3.1'
|
181
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
81
|
requirements:
|
183
82
|
- - ">="
|
184
83
|
- !ruby/object:Gem::Version
|
185
84
|
version: '0'
|
186
85
|
requirements: []
|
187
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.2.15
|
188
87
|
signing_key:
|
189
88
|
specification_version: 4
|
190
|
-
summary: A library to enhance and speed up script/exploit writing
|
89
|
+
summary: A CLI tool & library to enhance and speed up script/exploit writing with
|
90
|
+
string conversion/manipulation
|
191
91
|
test_files: []
|