ctf-party 1.5.0 → 2.2.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 +58 -8
- data/bin/{ctf_party_console → ctf-party_console} +0 -0
- data/lib/ctf_party/base64.rb +7 -7
- data/lib/ctf_party/binary.rb +2 -2
- data/lib/ctf_party/cgi.rb +41 -6
- data/lib/ctf_party/digest.rb +6 -6
- data/lib/ctf_party/flag.rb +1 -1
- data/lib/ctf_party/hex.rb +59 -28
- data/lib/ctf_party/rot.rb +3 -3
- data/lib/ctf_party/version.rb +1 -1
- data/lib/ctf_party/xor.rb +4 -4
- metadata +15 -137
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b19410e0b443bc237d10f61d2f85caff731309e95142c66d5d74897b3b296319
|
4
|
+
data.tar.gz: b446182ee4883bddcabb9cfa108d62712d74ab004fe9b1f4180db7ae42e4dcd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e38e7605cd1bf2bd7d9bcef501c93d6c5e1789a8488a6a150380e364822f24c981f265e319654527e0e804f6bcb7f3c6e2337d39abc54d081c602de43aca6056
|
7
|
+
data.tar.gz: 4cb5c641ec6cbdc40e35387068c8befc1b658d586bae0a52a8c13cdf5cd93068c05e250d48274810e2f276bb61681bf7be0b862da0699d672b857f47a66c50cc
|
data/bin/ctf-party
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
# Ruby internal
|
5
5
|
require 'pp'
|
6
|
+
require 'shellwords' # for shellescape cmd
|
6
7
|
# Project internal
|
7
8
|
require 'ctf_party'
|
8
9
|
require 'ctf_party/version'
|
@@ -10,6 +11,7 @@ require 'ctf_party/version'
|
|
10
11
|
require 'docopt'
|
11
12
|
|
12
13
|
cmd_whitelist = {
|
14
|
+
# ctf-party commands
|
13
15
|
alternatecase: 'Change one characte on two upcase and the other downcase',
|
14
16
|
bin2hex: 'Encode an binary string to a hexadecimal string',
|
15
17
|
bin2str: 'Alias for from_bin',
|
@@ -45,27 +47,62 @@ cmd_whitelist = {
|
|
45
47
|
to_hex: 'Encode a string into hexadecimal',
|
46
48
|
to_hexip: 'Encode a dotted decimal IP into a hexadecimal one',
|
47
49
|
urldecode: 'URL-decode the string',
|
48
|
-
|
50
|
+
urldecode_component: 'URL-decode the URL component string',
|
51
|
+
urlencode: 'URL-encode the string',
|
52
|
+
urlencode_component: 'URL-encode the URL component string',
|
53
|
+
# native string commands
|
54
|
+
bytesize: 'https://rubyapi.org/3.1/o/string#method-i-bytesize',
|
55
|
+
capitalize: 'https://rubyapi.org/3.1/o/string#method-i-capitalize',
|
56
|
+
chomp: 'https://rubyapi.org/3.1/o/string#method-i-chomp',
|
57
|
+
chop: 'https://rubyapi.org/3.1/o/string#method-i-chop',
|
58
|
+
downcase: 'https://rubyapi.org/3.1/o/string#method-i-downcase',
|
59
|
+
dump: 'https://rubyapi.org/3.1/o/string#method-i-dump',
|
60
|
+
hex: 'https://rubyapi.org/3.1/o/string#method-i-hex',
|
61
|
+
inspect: 'https://rubyapi.org/3.1/o/string#method-i-inspect',
|
62
|
+
length: 'https://rubyapi.org/3.1/o/string#method-i-length',
|
63
|
+
lstrip: 'https://rubyapi.org/3.1/o/string#method-i-lstrip',
|
64
|
+
reverse: 'https://rubyapi.org/3.1/o/string#method-i-reverse',
|
65
|
+
rstrip: 'https://rubyapi.org/3.1/o/string#method-i-rstrip',
|
66
|
+
scrub: 'https://rubyapi.org/3.1/o/string#method-i-scrub',
|
67
|
+
shellescape: 'https://rubyapi.org/3.1/o/string#method-i-shellescape',
|
68
|
+
size: 'https://rubyapi.org/3.1/o/string#method-i-size',
|
69
|
+
squeeze: 'https://rubyapi.org/3.1/o/string#method-i-squeeze',
|
70
|
+
strip: 'https://rubyapi.org/3.1/o/string#method-i-strip',
|
71
|
+
succ: 'https://rubyapi.org/3.1/o/string#method-i-succ',
|
72
|
+
swapcase: 'https://rubyapi.org/3.1/o/string#method-i-swapcase',
|
73
|
+
undump: 'https://rubyapi.org/3.1/o/string#method-i-undump',
|
74
|
+
unicode_normalize: 'https://rubyapi.org/3.1/o/string#method-i-unicode_normalize',
|
75
|
+
upcase: 'https://rubyapi.org/3.1/o/string#method-i-upcase'
|
49
76
|
}
|
50
77
|
|
51
78
|
doc = <<~DOCOPT
|
52
|
-
ctf-party by noraj
|
79
|
+
ctf-party v#{Version::VERSION} by noraj
|
53
80
|
|
54
81
|
Usage:
|
55
|
-
ctf-party <string> <cmd>... [--debug]
|
82
|
+
ctf-party <string> <cmd>... [--row --file] [--debug]
|
56
83
|
ctf-party --list-commands [--debug]
|
57
84
|
ctf-party -h | --help
|
58
85
|
ctf-party --version
|
59
86
|
|
87
|
+
Parameters:
|
88
|
+
<string> The string to manipulate, read from STDIN if equal to "-"
|
89
|
+
<cmd> Command to apply to the string, cf. --list-commands
|
90
|
+
|
60
91
|
Options:
|
61
92
|
-l, --list-commands List available commands (see https://noraj.github.io/ctf-party/yard/String.html)
|
93
|
+
-r, --row Apply the transformation to each row
|
94
|
+
-f, --file Interpret the string as a filename, if file doesn't exist it will still be treated as a string
|
62
95
|
--debug Display arguments
|
63
96
|
-h, --help Show this screen
|
64
97
|
--version Show version
|
65
98
|
|
66
99
|
Examples:
|
67
100
|
ctf-party 'security' to_hex
|
68
|
-
ctf-party 'NzQ2Zjc0NmY=' from_b64
|
101
|
+
ctf-party 'NzQ2Zjc0NmY=' from_b64 hex2bin
|
102
|
+
curl -s https://example.org | ctf-party - htmlescape
|
103
|
+
seq 1 10 | ctf-party - dec2hex hex2bin --row
|
104
|
+
cut -d : -f 1 /etc/passwd | ctf-party - randomcase --row
|
105
|
+
ctf-party /etc/passwd str2hex --row --file
|
69
106
|
DOCOPT
|
70
107
|
|
71
108
|
begin
|
@@ -73,11 +110,24 @@ begin
|
|
73
110
|
# use case 1, using the tool
|
74
111
|
pp args if args['--debug']
|
75
112
|
if args['<string>']
|
113
|
+
args['<string>'] = $stdin.read.chomp if args['<string>'] == '-'
|
114
|
+
args['<string>'] = File.read(args['<string>']) if args['--file'] && File.exist?(args['<string>'])
|
76
115
|
wrong_cmd = args['<cmd>'] - cmd_whitelist.keys.map(&:to_s)
|
77
116
|
if wrong_cmd.empty?
|
78
|
-
|
79
|
-
|
80
|
-
|
117
|
+
if args['--row']
|
118
|
+
output = ''
|
119
|
+
args['<string>'].each_line(chomp: true) do |line|
|
120
|
+
output_line = line
|
121
|
+
args['<cmd>'].each do |cmd|
|
122
|
+
output_line = output_line.public_send(cmd)
|
123
|
+
end
|
124
|
+
output += "#{output_line}\n"
|
125
|
+
end
|
126
|
+
else
|
127
|
+
output = args['<string>']
|
128
|
+
args['<cmd>'].each do |cmd|
|
129
|
+
output = output.public_send(cmd)
|
130
|
+
end
|
81
131
|
end
|
82
132
|
puts output
|
83
133
|
else
|
@@ -85,7 +135,7 @@ begin
|
|
85
135
|
end
|
86
136
|
elsif args['--list-commands']
|
87
137
|
cmd_whitelist.each do |k, v|
|
88
|
-
puts "#{k.to_s.ljust(
|
138
|
+
puts "#{k.to_s.ljust(25)}#{v}"
|
89
139
|
end
|
90
140
|
end
|
91
141
|
# use case 2, help: already handled by docopt
|
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"
|
data/lib/ctf_party/cgi.rb
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
|
3
3
|
# Ruby standard library
|
4
4
|
require 'cgi'
|
5
|
+
require 'uri'
|
5
6
|
|
6
7
|
class String
|
7
|
-
# URL-encode the string
|
8
|
+
# URL-encode the URL string (RFC2396)
|
8
9
|
# @return [String] the URL-encoded string
|
9
10
|
# @example
|
10
|
-
# "'
|
11
|
+
# '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"
|
12
|
+
# "'Stop!' said Fred" # => "'Stop!'%20said%20Fred"
|
11
13
|
def urlencode
|
12
|
-
|
14
|
+
URI::Parser.new.escape self
|
13
15
|
end
|
14
16
|
|
15
17
|
# URL-encode the string in place as described for {String#urlencode}.
|
@@ -17,12 +19,29 @@ class String
|
|
17
19
|
replace(urlencode)
|
18
20
|
end
|
19
21
|
|
20
|
-
# URL-
|
22
|
+
# URL-encode the URL component string
|
23
|
+
# @return [String] the URL-encoded string
|
24
|
+
# @example
|
25
|
+
# "'Stop!' said Fred".urlencode_component # => "%27Stop%21%27+said+Fred"
|
26
|
+
# '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"
|
27
|
+
def urlencode_component
|
28
|
+
CGI.escape self
|
29
|
+
end
|
30
|
+
|
31
|
+
# URL-encode the string in place as described for {String#urlencode_component}.
|
32
|
+
def urlencode_component!
|
33
|
+
replace(urlencode_component)
|
34
|
+
end
|
35
|
+
|
36
|
+
# URL-decode the URL string (RFC2396)
|
21
37
|
# @return [String] the URL-decoded string
|
22
38
|
# @example
|
23
|
-
#
|
39
|
+
# '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>"
|
40
|
+
# '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>"
|
41
|
+
# "'Stop!'%20said%20Fred".urldecode # => "'Stop!' said Fred"
|
42
|
+
# '%27Stop%21%27+said+Fred'.urldecode # => "'Stop!'+said+Fred"
|
24
43
|
def urldecode
|
25
|
-
|
44
|
+
URI::Parser.new.unescape self
|
26
45
|
end
|
27
46
|
|
28
47
|
# URL-decode the string in place as described for {String#urldecode}.
|
@@ -30,6 +49,22 @@ class String
|
|
30
49
|
replace(urldecode)
|
31
50
|
end
|
32
51
|
|
52
|
+
# URL-decode the URL component string
|
53
|
+
# @return [String] the URL-decoded string
|
54
|
+
# @example
|
55
|
+
# '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>"
|
56
|
+
# '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>"
|
57
|
+
# "'Stop!'%20said%20Fred".urldecode_component => "'Stop!' said Fred"
|
58
|
+
# '%27Stop%21%27+said+Fred'.urldecode_component # => "'Stop!' said Fred"
|
59
|
+
def urldecode_component
|
60
|
+
CGI.unescape self
|
61
|
+
end
|
62
|
+
|
63
|
+
# URL-decode the string in place as described for {String#urldecode_component}.
|
64
|
+
def urldecode_component!
|
65
|
+
replace(urldecode_component)
|
66
|
+
end
|
67
|
+
|
33
68
|
# HTML escape the string
|
34
69
|
# @return [String] the HTML escaped string
|
35
70
|
# @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,37 @@ 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
|
-
# adding prefix must be done after case change
|
62
|
+
# adding prefix must be done after case change, complex conditional to avoid cropping when odd byte lenght
|
63
|
+
out = (out.size.odd? ? [out[0]] + out[1..].scan(/.{1,2}/) : out.scan(/.{2}/)).map do |x|
|
64
|
+
opts[:prefixall] + x
|
65
|
+
end.join
|
53
66
|
return opts[:prefix] + out
|
54
67
|
end
|
55
68
|
|
@@ -66,19 +79,23 @@ class String
|
|
66
79
|
# Encode a string into hexadecimal
|
67
80
|
# @param opts [Hash] optional parameters
|
68
81
|
# @option opts [String] :prefix Prefix of the output. Default value is a void
|
69
|
-
# string. Example of values:
|
70
|
-
# @option opts [
|
71
|
-
#
|
82
|
+
# string. Example of values: `0x`, `\x`.
|
83
|
+
# @option opts [String] :prefixall Prefix each byte. Default value is a void
|
84
|
+
# string. Example of value: `\\x`.
|
85
|
+
# @option opts [Symbol] :case Char case of the output. Default value `:lower`.
|
86
|
+
# Other valid value `:upper`.
|
72
87
|
# @option opts [Symbol] :nibble Display output with high nibble first
|
73
|
-
# (
|
88
|
+
# (`:high` default) or low nibble first (`:low`).
|
74
89
|
# @return [String] the hexadecimal encoded string
|
75
90
|
# @example
|
76
91
|
# 'noraj'.to_hex # => "6e6f72616a"
|
77
92
|
# 'noraj'.to_hex(prefix: '0x') # => "0x6e6f72616a"
|
78
93
|
# 'noraj'.to_hex(case: :upper) # => "6E6F72616A"
|
79
94
|
# 'noraj'.to_hex(nibble: :low) # => "e6f62716a6"
|
95
|
+
# 'noraj'.to_hex(prefixall: '\\x') # => "\\x6e\\x6f\\x72\\x61\\x6a"
|
80
96
|
def to_hex(opts = {})
|
81
97
|
opts[:prefix] ||= ''
|
98
|
+
opts[:prefixall] ||= ''
|
82
99
|
opts[:case] ||= :lower
|
83
100
|
opts[:nibble] ||= :high
|
84
101
|
# convert
|
@@ -92,6 +109,7 @@ class String
|
|
92
109
|
# char case management
|
93
110
|
out = out.upcase if opts[:case] == :upper
|
94
111
|
# adding prefix must be done after case change
|
112
|
+
out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
|
95
113
|
return opts[:prefix] + out
|
96
114
|
end
|
97
115
|
|
@@ -118,19 +136,20 @@ class String
|
|
118
136
|
# Decode a hexadecimal string
|
119
137
|
# @param opts [Hash] optional parameters
|
120
138
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
121
|
-
# string. Example of values:
|
139
|
+
# string. Example of values: `0x`, `\x`, `\\x`.
|
122
140
|
# @option opts [Symbol] :nibble Display input with high nibble first
|
123
|
-
# (
|
141
|
+
# (`:high` default) or low nibble first (`:low`).
|
124
142
|
# @return [String] the hexadecimal decoded string
|
125
143
|
# @example
|
126
144
|
# "6e6f72616a".from_hex # => "noraj"
|
127
145
|
# "0x6e6f72616a".from_hex(prefix: '0x') # => "noraj"
|
128
146
|
# "e6f62716a6".from_hex(nibble: :low) # => "noraj"
|
147
|
+
# '\\x6e\\x6f\\x72\\x61\\x6a'.from_hex(prefix: '\\x') # => "noraj"
|
129
148
|
def from_hex(opts = {})
|
130
149
|
opts[:prefix] ||= ''
|
131
150
|
opts[:nibble] ||= :high
|
132
151
|
# remove prefix
|
133
|
-
out =
|
152
|
+
out = gsub(opts[:prefix], '')
|
134
153
|
# convert
|
135
154
|
return Array(out).pack('H*') if opts[:nibble] == :high
|
136
155
|
return Array(out).pack('h*') if opts[:nibble] == :low
|
@@ -161,15 +180,16 @@ class String
|
|
161
180
|
# Encode an hexadecimal string to a binary string
|
162
181
|
# @param opts [Hash] optional parameters
|
163
182
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
164
|
-
# string. Example of values:
|
183
|
+
# string. Example of values: `0x`, `\x`, `\\x`.
|
165
184
|
# @return [String] the binary encoded string
|
166
185
|
# @example
|
167
186
|
# 'ab'.hex2bin # => "10101011"
|
168
187
|
# '\xf3'.hex2bin(prefix: '\x') # => "11110011"
|
188
|
+
# '\\x6e\\x6f\\x72\\x61\\x6a'.hex2bin(prefix: '\\x') # => "110111001101111011100100110000101101010"
|
169
189
|
def hex2bin(opts = {})
|
170
190
|
opts[:prefix] ||= ''
|
171
191
|
# remove prefix
|
172
|
-
out =
|
192
|
+
out = gsub(opts[:prefix], '')
|
173
193
|
# convert
|
174
194
|
return out.to_i(16).to_s(2)
|
175
195
|
end
|
@@ -187,21 +207,26 @@ class String
|
|
187
207
|
# Encode an binary string to a hexadecimal string
|
188
208
|
# @param opts [Hash] optional parameters
|
189
209
|
# @option opts [String] :prefix Prefix of the output. Default value is a void
|
190
|
-
# string. Example of values:
|
191
|
-
# @option opts [
|
192
|
-
#
|
210
|
+
# string. Example of values: `0x`, `\x`.
|
211
|
+
# @option opts [String] :prefixall Prefix each byte. Default value is a void
|
212
|
+
# string. Example of value: `\\x`.
|
213
|
+
# @option opts [Symbol] :case Char case of the output. Default value `:lower`.
|
214
|
+
# Other valid value `:upper`.
|
193
215
|
# @return [String] the hexadecimal encoded string
|
194
216
|
# @example
|
195
217
|
# '11110011'.bin2hex # => "f3"
|
196
218
|
# '11110011'.bin2hex({prefix: '0x', case: :upper}) # => "0xF3"
|
219
|
+
# '0110111001101111011100100110000101101010'.bin2hex(prefixall: '\\x') # => "\\x6e\\x6f\\x72\\x61\\x6a"
|
197
220
|
def bin2hex(opts = {})
|
198
221
|
opts[:prefix] ||= ''
|
222
|
+
opts[:prefixall] ||= ''
|
199
223
|
opts[:case] ||= :lower
|
200
224
|
# convert
|
201
225
|
out = to_i(2).to_s(16)
|
202
226
|
# char case management
|
203
227
|
out = out.upcase if opts[:case] == :upper
|
204
228
|
# adding prefix must be done after case change
|
229
|
+
out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
|
205
230
|
return opts[:prefix] + out
|
206
231
|
end
|
207
232
|
|
@@ -218,18 +243,19 @@ class String
|
|
218
243
|
# Decode a hexadecimal IP string into a dotted decimal one
|
219
244
|
# @param opts [Hash] optional parameters
|
220
245
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
221
|
-
# string. Example of values:
|
246
|
+
# string. Example of values: `0x`, `\x`, '\\x'.
|
222
247
|
# @option opts [Symbol] :nibble Display input with high nibble first
|
223
|
-
# (
|
248
|
+
# (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
|
224
249
|
# @return [String] the dotted decimal IP
|
225
250
|
# @example
|
226
251
|
# '0100007F'.from_hexip(nibble: :low) # => "127.0.0.1"
|
227
252
|
# '0x7f000001'.from_hexip(prefix: '0x') # => "127.0.0.1"
|
253
|
+
# '\\x7f\\x00\\x00\\x01'.from_hexip(prefix: '\\x') # => "127.0.0.1"
|
228
254
|
def from_hexip(opts = {})
|
229
255
|
opts[:prefix] ||= ''
|
230
256
|
opts[:nibble] ||= :high
|
231
257
|
# remove prefix
|
232
|
-
out =
|
258
|
+
out = gsub(opts[:prefix], '')
|
233
259
|
# convert
|
234
260
|
out = out.scan(/.{2}/).map(&:hex2dec)
|
235
261
|
out = out.reverse if opts[:nibble] == :low
|
@@ -245,17 +271,21 @@ class String
|
|
245
271
|
# Encode a dotted decimal IP into a hexadecimal one
|
246
272
|
# @param opts [Hash] optional parameters
|
247
273
|
# @option opts [String] :prefix Prefix of the output. Default value is a void
|
248
|
-
# string. Example of values:
|
249
|
-
# @option opts [
|
250
|
-
#
|
274
|
+
# string. Example of values: `0x`, `\x`.
|
275
|
+
# @option opts [String] :prefixall Prefix each byte. Default value is a void
|
276
|
+
# string. Example of value: `\\x`.
|
277
|
+
# @option opts [Symbol] :case Char case of the output. Default value `:lower`.
|
278
|
+
# Other valid value `:upper`.
|
251
279
|
# @option opts [Symbol] :nibble Display output with high nibble first
|
252
|
-
# (
|
280
|
+
# (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
|
253
281
|
# @return [String] the hexadecimal encoded IP
|
254
282
|
# @example
|
255
283
|
# '127.0.0.1'.to_hexip # => "7f000001"
|
256
284
|
# '127.0.0.1'.to_hexip(nibble: :low) # => "0100007f"
|
285
|
+
# '127.0.0.1'.to_hexip(prefixall: '\\x') # => "\\x7f\\x00\\x00\\x01"
|
257
286
|
def to_hexip(opts = {})
|
258
287
|
opts[:prefix] ||= ''
|
288
|
+
opts[:prefixall] ||= ''
|
259
289
|
opts[:case] ||= :lower
|
260
290
|
opts[:nibble] ||= :high
|
261
291
|
# convert
|
@@ -265,6 +295,7 @@ class String
|
|
265
295
|
# char case management
|
266
296
|
out = out.upcase if opts[:case] == :upper
|
267
297
|
# adding prefix must be done after case change
|
298
|
+
out = out.scan(/.{2}/).map { |x| opts[:prefixall] + x }.join
|
268
299
|
return opts[:prefix] + out
|
269
300
|
end
|
270
301
|
|
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.
|
@@ -35,12 +35,12 @@ 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
|
data/lib/ctf_party/version.rb
CHANGED
data/lib/ctf_party/xor.rb
CHANGED
@@ -11,8 +11,8 @@ class String
|
|
11
11
|
b1 = unpack('U*')
|
12
12
|
b2 = key.unpack('U*')
|
13
13
|
longest = [b1.length, b2.length].max
|
14
|
-
b1 = [0] * (longest - b1.length) + b1
|
15
|
-
b2 = [0] * (longest - b2.length) + b2
|
14
|
+
b1 = ([0] * (longest - b1.length)) + b1
|
15
|
+
b2 = ([0] * (longest - b2.length)) + b2
|
16
16
|
b1.zip(b2).map { |a, b| a ^ b }.pack('U*')
|
17
17
|
end
|
18
18
|
|
@@ -36,8 +36,8 @@ class String
|
|
36
36
|
b1 = b1.chars.map(&:ord)
|
37
37
|
b2 = b2.chars.map(&:ord)
|
38
38
|
longest = [b1.length, b2.length].max
|
39
|
-
b1 = [0] * (longest - b1.length) + b1
|
40
|
-
b2 = [0] * (longest - b2.length) + b2
|
39
|
+
b1 = ([0] * (longest - b1.length)) + b1
|
40
|
+
b2 = ([0] * (longest - b2.length)) + b2
|
41
41
|
b1.zip(b2).map { |a, b| (a ^ b).chr }.join
|
42
42
|
end
|
43
43
|
|
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:
|
4
|
+
version: 2.2.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-07-28 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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
-
|
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/
|
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
|
@@ -187,6 +64,7 @@ metadata:
|
|
187
64
|
documentation_uri: https://noraj.github.io/ctf-party/
|
188
65
|
homepage_uri: https://noraj.github.io/ctf-party/
|
189
66
|
source_code_uri: https://github.com/noraj/ctf-party/
|
67
|
+
rubygems_mfa_required: 'true'
|
190
68
|
post_install_message:
|
191
69
|
rdoc_options: []
|
192
70
|
require_paths:
|
@@ -198,16 +76,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
198
76
|
version: 2.7.0
|
199
77
|
- - "<"
|
200
78
|
- !ruby/object:Gem::Version
|
201
|
-
version: '3.
|
79
|
+
version: '3.2'
|
202
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
81
|
requirements:
|
204
82
|
- - ">="
|
205
83
|
- !ruby/object:Gem::Version
|
206
84
|
version: '0'
|
207
85
|
requirements: []
|
208
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.3.3
|
209
87
|
signing_key:
|
210
88
|
specification_version: 4
|
211
|
-
summary: A CLI tool & library to enhance and speed up script/
|
212
|
-
|
89
|
+
summary: A CLI tool & library to enhance and speed up script/exploit writing with
|
90
|
+
string conversion/manipulation
|
213
91
|
test_files: []
|