ctf-party 2.3.0 → 4.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 +36 -29
- data/lib/ctf_party/base64.rb +11 -13
- data/lib/ctf_party/binary.rb +28 -0
- data/lib/ctf_party/cgi.rb +50 -22
- data/lib/ctf_party/dec.rb +18 -16
- data/lib/ctf_party/hex.rb +75 -25
- data/lib/ctf_party/network.rb +4 -4
- data/lib/ctf_party/version.rb +2 -2
- data/lib/ctf_party.rb +1 -0
- metadata +41 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1eb800f2b8374568f0f0caf62902e9851de280e60f136079486ddb1d80d597a3
|
4
|
+
data.tar.gz: 5202083c9dcfe5d3f917fd1a706d8bfc305d20e004f1857d406f7ef86c3a674f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acfd29ec5d68b4904f60eb2331fd22773865aa80e549c366c285bc7ce3a0448a543729ac3ec8df00821942a70eec740d6ee20942939469463cd8cc15036e9793
|
7
|
+
data.tar.gz: b9cce70eaeaa54d167f2e657e5b120a776bb3510b9555916ea42739e1011bb335e493045ebf609a8cc2ca55041fbc93c40b30b930700f219193950f584fc10d4
|
data/bin/ctf-party
CHANGED
@@ -12,8 +12,10 @@ require 'docopt'
|
|
12
12
|
cmd_whitelist = {
|
13
13
|
# ctf-party commands
|
14
14
|
alternatecase: 'Change one characte on two upcase and the other downcase',
|
15
|
+
bin2dec: 'Convert a binary string to decimal',
|
15
16
|
bin2hex: 'Encode an binary string to a hexadecimal string',
|
16
17
|
bin2str: 'Alias for from_bin',
|
18
|
+
dec2bin: 'Convert a decimal string to binary',
|
17
19
|
dec2hex: 'Encode an decimal string to a hexadecimal string',
|
18
20
|
dec2str: 'Alias for from_dec',
|
19
21
|
defang_domain: 'Defang domain name',
|
@@ -24,7 +26,9 @@ cmd_whitelist = {
|
|
24
26
|
from_bin: 'Decode a binary string',
|
25
27
|
from_dec: 'Decode a decimal string (decimal to hexadecimal then hexadecimal to string)',
|
26
28
|
from_hex: 'Decode a hexadecimal string',
|
27
|
-
from_hexip: 'Decode a hexadecimal
|
29
|
+
from_hexip: 'Decode a hexadecimal IPv4 string into a dotted decimal one',
|
30
|
+
from_hexipv4: 'Decode a hexadecimal IPv4 string into a dotted decimal one',
|
31
|
+
from_hexipv6: 'Decode a hexadecimal IPv6 string into a the double-dotted hexadecimal format',
|
28
32
|
hex2bin: 'Encode an hexadecimal string to a binary string',
|
29
33
|
hex2dec: 'Encode an hexadecimal string to a decimal string',
|
30
34
|
hex2str: 'Alias for from_hex',
|
@@ -52,34 +56,37 @@ cmd_whitelist = {
|
|
52
56
|
to_bin: 'Encode a string into binary',
|
53
57
|
to_dec: 'Encode a string into decimal (string to hexadecimal then hexadecimal to decimal)',
|
54
58
|
to_hex: 'Encode a string into hexadecimal',
|
55
|
-
to_hexip: 'Encode a dotted decimal
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
to_hexip: 'Encode a dotted decimal IPv4 into a hexadecimal one',
|
60
|
+
to_hexipv4: 'Encode a dotted decimal IPv4 into a hexadecimal one',
|
61
|
+
urldecode: 'URL-decode the string (RFC 2396)',
|
62
|
+
urldecode_component: 'URL-decode the URL component string (RFC 3986)',
|
63
|
+
urldecode_data: 'URL-decode the form data (application/x-www-form-urlencoded) string',
|
64
|
+
urlencode: 'URL-encode the string (RFC 2396)',
|
65
|
+
urlencode_component: 'URL-encode the URL component string (RFC 3986)',
|
66
|
+
urlencode_data: 'URL-encode form data (application/x-www-form-urlencoded) string',
|
60
67
|
# native string commands
|
61
|
-
bytesize: 'https://rubyapi.org/3.
|
62
|
-
capitalize: 'https://rubyapi.org/3.
|
63
|
-
chomp: 'https://rubyapi.org/3.
|
64
|
-
chop: 'https://rubyapi.org/3.
|
65
|
-
downcase: 'https://rubyapi.org/3.
|
66
|
-
dump: 'https://rubyapi.org/3.
|
67
|
-
hex: 'https://rubyapi.org/3.
|
68
|
-
inspect: 'https://rubyapi.org/3.
|
69
|
-
length: 'https://rubyapi.org/3.
|
70
|
-
lstrip: 'https://rubyapi.org/3.
|
71
|
-
reverse: 'https://rubyapi.org/3.
|
72
|
-
rstrip: 'https://rubyapi.org/3.
|
73
|
-
scrub: 'https://rubyapi.org/3.
|
74
|
-
shellescape: 'https://rubyapi.org/3.
|
75
|
-
size: 'https://rubyapi.org/3.
|
76
|
-
squeeze: 'https://rubyapi.org/3.
|
77
|
-
strip: 'https://rubyapi.org/3.
|
78
|
-
succ: 'https://rubyapi.org/3.
|
79
|
-
swapcase: 'https://rubyapi.org/3.
|
80
|
-
undump: 'https://rubyapi.org/3.
|
81
|
-
unicode_normalize: 'https://rubyapi.org/3.
|
82
|
-
upcase: 'https://rubyapi.org/3.
|
68
|
+
bytesize: 'https://rubyapi.org/3.2/o/string#method-i-bytesize',
|
69
|
+
capitalize: 'https://rubyapi.org/3.2/o/string#method-i-capitalize',
|
70
|
+
chomp: 'https://rubyapi.org/3.2/o/string#method-i-chomp',
|
71
|
+
chop: 'https://rubyapi.org/3.2/o/string#method-i-chop',
|
72
|
+
downcase: 'https://rubyapi.org/3.2/o/string#method-i-downcase',
|
73
|
+
dump: 'https://rubyapi.org/3.2/o/string#method-i-dump',
|
74
|
+
hex: 'https://rubyapi.org/3.2/o/string#method-i-hex',
|
75
|
+
inspect: 'https://rubyapi.org/3.2/o/string#method-i-inspect',
|
76
|
+
length: 'https://rubyapi.org/3.2/o/string#method-i-length',
|
77
|
+
lstrip: 'https://rubyapi.org/3.2/o/string#method-i-lstrip',
|
78
|
+
reverse: 'https://rubyapi.org/3.2/o/string#method-i-reverse',
|
79
|
+
rstrip: 'https://rubyapi.org/3.2/o/string#method-i-rstrip',
|
80
|
+
scrub: 'https://rubyapi.org/3.2/o/string#method-i-scrub',
|
81
|
+
shellescape: 'https://rubyapi.org/3.2/o/string#method-i-shellescape',
|
82
|
+
size: 'https://rubyapi.org/3.2/o/string#method-i-size',
|
83
|
+
squeeze: 'https://rubyapi.org/3.2/o/string#method-i-squeeze',
|
84
|
+
strip: 'https://rubyapi.org/3.2/o/string#method-i-strip',
|
85
|
+
succ: 'https://rubyapi.org/3.2/o/string#method-i-succ',
|
86
|
+
swapcase: 'https://rubyapi.org/3.2/o/string#method-i-swapcase',
|
87
|
+
undump: 'https://rubyapi.org/3.2/o/string#method-i-undump',
|
88
|
+
unicode_normalize: 'https://rubyapi.org/3.2/o/string#method-i-unicode_normalize',
|
89
|
+
upcase: 'https://rubyapi.org/3.2/o/string#method-i-upcase'
|
83
90
|
}
|
84
91
|
|
85
92
|
doc = <<~DOCOPT
|
@@ -115,7 +122,7 @@ DOCOPT
|
|
115
122
|
begin
|
116
123
|
args = Docopt.docopt(doc, version: Version::VERSION)
|
117
124
|
# use case 1, using the tool
|
118
|
-
|
125
|
+
puts args if args['--debug']
|
119
126
|
if args['<string>']
|
120
127
|
args['<string>'] = $stdin.read.chomp if args['<string>'] == '-'
|
121
128
|
args['<string>'] = File.read(args['<string>']) if args['--file'] && File.exist?(args['<string>'])
|
data/lib/ctf_party/base64.rb
CHANGED
@@ -6,16 +6,15 @@ 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 `:
|
11
|
-
# @see https://ruby-doc.org/
|
9
|
+
# @option opts [Symbol] :mode Default value: `:strict` (`:rfc4648`).
|
10
|
+
# Other values are `:rfc2045` or `:urlsafe`.
|
11
|
+
# @see https://ruby-doc.org/3.2.2/stdlibs/base64/Base64.html
|
12
12
|
# @return [String] the Base64 encoded string
|
13
13
|
# @example
|
14
14
|
# 'Super lib!'.to_b64 # => "U3VwZXIgbGliIQ=="
|
15
15
|
def to_b64(opts = {})
|
16
16
|
opts[:mode] ||= :strict
|
17
|
-
return Base64.strict_encode64(self) if opts[:mode]
|
18
|
-
opts[:mode] == :rfc4648
|
17
|
+
return Base64.strict_encode64(self) if %i[strict rfc4648].include?(opts[:mode])
|
19
18
|
return Base64.encode64(self) if opts[:mode] == :rfc2045
|
20
19
|
return Base64.urlsafe_encode64(self) if opts[:mode] == :urlsafe
|
21
20
|
end
|
@@ -32,16 +31,15 @@ class String
|
|
32
31
|
|
33
32
|
# Decode the string from base64
|
34
33
|
# @param opts [Hash] optional parameters
|
35
|
-
# @option opts [Symbol] :mode Default value: `:strict
|
36
|
-
# Other values are `:
|
37
|
-
# @see https://ruby-doc.org/
|
34
|
+
# @option opts [Symbol] :mode Default value: `:strict` (`:rfc4648`).
|
35
|
+
# Other values are `:rfc2045` or `:urlsafe`.
|
36
|
+
# @see https://ruby-doc.org/3.2.2/stdlibs/base64/Base64.html
|
38
37
|
# @return [String] the Base64 decoded string
|
39
38
|
# @example
|
40
39
|
# 'UnVieQ=='.from_b64 # => "Ruby"
|
41
40
|
def from_b64(opts = {})
|
42
41
|
opts[:mode] ||= :strict
|
43
|
-
return Base64.strict_decode64(self) if opts[:mode]
|
44
|
-
opts[:mode] == :rfc4648
|
42
|
+
return Base64.strict_decode64(self) if %i[strict rfc4648].include?(opts[:mode])
|
45
43
|
return Base64.decode64(self) if opts[:mode] == :rfc2045
|
46
44
|
return Base64.urlsafe_decode64(self) if opts[:mode] == :urlsafe
|
47
45
|
end
|
@@ -58,9 +56,9 @@ class String
|
|
58
56
|
|
59
57
|
# Is the string encoded in base64?
|
60
58
|
# @param opts [Hash] optional parameters
|
61
|
-
# @option opts [Symbol] :mode Default value: `:strict
|
62
|
-
# Other values are `:
|
63
|
-
# @see https://ruby-doc.org/
|
59
|
+
# @option opts [Symbol] :mode Default value: `:strict` (`:rfc4648`).
|
60
|
+
# Other values are `:rfc2045` or `:urlsafe`.
|
61
|
+
# @see https://ruby-doc.org/3.2.2/stdlibs/base64/Base64.html
|
64
62
|
# @return [Boolean] `true` if the string is a valid base64 string, `false`
|
65
63
|
# else.
|
66
64
|
# @example
|
data/lib/ctf_party/binary.rb
CHANGED
@@ -74,4 +74,32 @@ class String
|
|
74
74
|
def bin2str!(opts = {})
|
75
75
|
from_bin!(opts)
|
76
76
|
end
|
77
|
+
|
78
|
+
# Convert a binary string to decimal (binary to hexadecimal then hexadecimal to decimal)
|
79
|
+
# @param opts [Hash] optional parameters (see {String#bin2hex} and {String#hex2dec})
|
80
|
+
# @return [String] the decimal encoded string
|
81
|
+
# @example
|
82
|
+
# '011000100110100101101110011000010111001001111001'.bin2dec # => "108204962968185"
|
83
|
+
def bin2dec(opts = {})
|
84
|
+
bin2hex(opts).hex2dec(opts)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Convert a binary string to decimal in place as described for {String#bin2dec}.
|
88
|
+
def bin2dec!(opts = {})
|
89
|
+
replace(bin2dec(opts))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Convert a decimal string to binary (decimal to hexadecimal then hexadecimal to binary)
|
93
|
+
# @param opts [Hash] optional parameters (see {String#dec2hex} and {String#hex2bin})
|
94
|
+
# @return [String] the binary encoded string
|
95
|
+
# @example
|
96
|
+
# '474316169578'.dec2bin # => "0110111001101111011100100110000101101010"
|
97
|
+
def dec2bin(opts = {})
|
98
|
+
dec2hex(opts).hex2bin(opts)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Convert a decimal string to binary in place as described for {String#dec2bin}.
|
102
|
+
def dec2bin!(opts = {})
|
103
|
+
replace(dec2bin(opts))
|
104
|
+
end
|
77
105
|
end
|
data/lib/ctf_party/cgi.rb
CHANGED
@@ -5,13 +5,13 @@ require 'cgi'
|
|
5
5
|
require 'uri'
|
6
6
|
|
7
7
|
class String
|
8
|
-
# URL-encode the URL string (
|
8
|
+
# URL-encode the URL string (RFC 2396)
|
9
9
|
# @return [String] the URL-encoded string
|
10
10
|
# @example
|
11
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"
|
12
|
+
# "'Stop!' said Fred".urlencode # => "'Stop!'%20said%20Fred"
|
13
13
|
def urlencode
|
14
|
-
URI::
|
14
|
+
URI::RFC2396_PARSER.escape self
|
15
15
|
end
|
16
16
|
|
17
17
|
# URL-encode the string in place as described for {String#urlencode}.
|
@@ -19,21 +19,21 @@ class String
|
|
19
19
|
replace(urlencode)
|
20
20
|
end
|
21
21
|
|
22
|
-
# URL-encode
|
23
|
-
# @return [String] the URL-encoded
|
22
|
+
# URL-encode form data (`application/x-www-form-urlencoded`) string
|
23
|
+
# @return [String] the URL-encoded data
|
24
24
|
# @example
|
25
|
-
# "'Stop!' said Fred".
|
26
|
-
# 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'.
|
27
|
-
def
|
25
|
+
# "'Stop!' said Fred".urlencode_data # => "%27Stop%21%27+said+Fred"
|
26
|
+
# 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'.urlencode_data # => "http%3A%2F%2Fvulnerable.site%2Fsearch.aspx%3Ftxt%3D%22%3E%3Cscript%3Ealert%28%2FRubyfu%2F.source%29%3C%2Fscript%3E"
|
27
|
+
def urlencode_data
|
28
28
|
CGI.escape self
|
29
29
|
end
|
30
30
|
|
31
|
-
# URL-encode the
|
32
|
-
def
|
33
|
-
replace(
|
31
|
+
# URL-encode the data in place as described for {String#urlencode_data}.
|
32
|
+
def urlencode_data!
|
33
|
+
replace(urlencode_data)
|
34
34
|
end
|
35
35
|
|
36
|
-
# URL-decode the URL string (
|
36
|
+
# URL-decode the URL string (RFC 2396)
|
37
37
|
# @return [String] the URL-decoded string
|
38
38
|
# @example
|
39
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>"
|
@@ -41,7 +41,7 @@ class String
|
|
41
41
|
# "'Stop!'%20said%20Fred".urldecode # => "'Stop!' said Fred"
|
42
42
|
# '%27Stop%21%27+said+Fred'.urldecode # => "'Stop!'+said+Fred"
|
43
43
|
def urldecode
|
44
|
-
URI::
|
44
|
+
URI::RFC2396_PARSER.unescape self
|
45
45
|
end
|
46
46
|
|
47
47
|
# URL-decode the string in place as described for {String#urldecode}.
|
@@ -49,20 +49,20 @@ class String
|
|
49
49
|
replace(urldecode)
|
50
50
|
end
|
51
51
|
|
52
|
-
# URL-decode the
|
52
|
+
# URL-decode the form data (`application/x-www-form-urlencoded`) string
|
53
53
|
# @return [String] the URL-decoded string
|
54
54
|
# @example
|
55
|
-
# 'http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E'.
|
56
|
-
# 'http%3A%2F%2Fvulnerable.site%2Fsearch.aspx%3Ftxt%3D%22%3E%3Cscript%3Ealert%28%2FRubyfu%2F.source%29%3C%2Fscript%3E'.
|
57
|
-
# "'Stop!'%20said%20Fred".
|
58
|
-
# '%27Stop%21%27+said+Fred'.
|
59
|
-
def
|
55
|
+
# 'http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E'.urldecode_data # => "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_data # => "http://vulnerable.site/search.aspx?txt=\"><script>alert(/Rubyfu/.source)</script>"
|
57
|
+
# "'Stop!'%20said%20Fred".urldecode_data => "'Stop!' said Fred"
|
58
|
+
# '%27Stop%21%27+said+Fred'.urldecode_data # => "'Stop!' said Fred"
|
59
|
+
def urldecode_data
|
60
60
|
CGI.unescape self
|
61
61
|
end
|
62
62
|
|
63
|
-
# URL-decode the string in place as described for {String#
|
64
|
-
def
|
65
|
-
replace(
|
63
|
+
# URL-decode the string in place as described for {String#urldecode_data}.
|
64
|
+
def urldecode_data!
|
65
|
+
replace(urldecode_data)
|
66
66
|
end
|
67
67
|
|
68
68
|
# HTML escape the string
|
@@ -90,4 +90,32 @@ class String
|
|
90
90
|
def htmlunescape!
|
91
91
|
replace(htmlunescape)
|
92
92
|
end
|
93
|
+
|
94
|
+
# URL-encode the URL component string (RFC 3986)
|
95
|
+
# @return [String] URL-encoded component string
|
96
|
+
# @example
|
97
|
+
# '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"
|
98
|
+
# "'Stop!' said Fred".urlencode_component # => "%27Stop%21%27%20said%20Fred"
|
99
|
+
def urlencode_component
|
100
|
+
CGI.escapeURIComponent self
|
101
|
+
end
|
102
|
+
|
103
|
+
# URL-encode the URL component string (RFC 3986) as described for {String#urlencode_component}.
|
104
|
+
def urlencode_component!
|
105
|
+
replace(urlencode_component)
|
106
|
+
end
|
107
|
+
|
108
|
+
# URL-decode the URL component string (RFC 3986)
|
109
|
+
# @return [String] URL-decoded component string
|
110
|
+
# @example
|
111
|
+
# '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>"
|
112
|
+
# '%27Stop%21%27%20said%20Fred'.urldecode_component # => "'Stop!' said Fred"
|
113
|
+
def urldecode_component
|
114
|
+
CGI.unescapeURIComponent self
|
115
|
+
end
|
116
|
+
|
117
|
+
# URL-decode the URL component string (RFC 3986) as described for {String#urldecode_component}.
|
118
|
+
def urldecode_component!
|
119
|
+
replace(urldecode_component)
|
120
|
+
end
|
93
121
|
end
|
data/lib/ctf_party/dec.rb
CHANGED
@@ -2,48 +2,50 @@
|
|
2
2
|
|
3
3
|
class String
|
4
4
|
# Encode a string into decimal (string to hexadecimal then hexadecimal to decimal)
|
5
|
+
# @param opts [Hash] optional parameters (see {String#to_hex} and {String#hex2dec})
|
5
6
|
# @return [String] the decimal encoded string
|
6
7
|
# @example
|
7
8
|
# 'noraj'.to_dec # => "474316169578"
|
8
|
-
def to_dec
|
9
|
-
|
9
|
+
def to_dec(opts = {})
|
10
|
+
to_hex(opts).hex2dec(opts)
|
10
11
|
end
|
11
12
|
|
12
13
|
# Encode a string into decimal in place as described for {String#to_dec}.
|
13
|
-
def to_dec!
|
14
|
-
replace(to_dec)
|
14
|
+
def to_dec!(opts = {})
|
15
|
+
replace(to_dec(opts))
|
15
16
|
end
|
16
17
|
|
17
18
|
# Decode a decimal string (decimal to hexadecimal then hexadecimal to string)
|
19
|
+
# @param opts [Hash] optional parameters (see {String#dec2hex} and {String#from_hex})
|
18
20
|
# @return [String] the decimal decoded string
|
19
21
|
# @example
|
20
22
|
# '1834615104613964215417'.from_dec # => "ctf-party"
|
21
|
-
def from_dec
|
22
|
-
dec2hex.
|
23
|
+
def from_dec(opts = {})
|
24
|
+
dec2hex(opts).from_hex(opts)
|
23
25
|
end
|
24
26
|
|
25
27
|
# Decode a decimal string in place as described for {String#from_dec}.
|
26
|
-
def from_dec!
|
27
|
-
replace(from_dec)
|
28
|
+
def from_dec!(opts = {})
|
29
|
+
replace(from_dec(opts))
|
28
30
|
end
|
29
31
|
|
30
32
|
# Alias for {String#to_dec}.
|
31
|
-
def str2dec
|
32
|
-
to_dec
|
33
|
+
def str2dec(opts = {})
|
34
|
+
to_dec(opts)
|
33
35
|
end
|
34
36
|
|
35
37
|
# Alias for {String#to_dec!}.
|
36
|
-
def str2dec!
|
37
|
-
replace(str2dec)
|
38
|
+
def str2dec!(opts = {})
|
39
|
+
replace(str2dec(opts))
|
38
40
|
end
|
39
41
|
|
40
42
|
# Alias for {String#from_dec}.
|
41
|
-
def dec2str
|
42
|
-
from_dec
|
43
|
+
def dec2str(opts = {})
|
44
|
+
from_dec(opts)
|
43
45
|
end
|
44
46
|
|
45
47
|
# Alias for {String#from_dec!}.
|
46
|
-
def dec2str!
|
47
|
-
replace(dec2str)
|
48
|
+
def dec2str!(opts = {})
|
49
|
+
replace(dec2str(opts))
|
48
50
|
end
|
49
51
|
end
|
data/lib/ctf_party/hex.rb
CHANGED
@@ -5,18 +5,25 @@ class String
|
|
5
5
|
# @param opts [Hash] optional parameters
|
6
6
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
7
7
|
# string. Example of values: `0x`, `\x`, `\\x`.
|
8
|
+
# @option opts [Symbol] :padding Minimum size of the decimal display
|
9
|
+
# (number of characters) for the output. Default is no padding.
|
8
10
|
# @return [String] the decimal encoded string
|
9
11
|
# @example
|
10
12
|
# 'ff'.hex2dec # => "255"
|
11
13
|
# '\xf3'.hex2dec(prefix: '\x') # => "243"
|
12
14
|
# '6e6f72616a'.hex2dec # => "474316169578"
|
13
15
|
# '\\x6e\\x6f\\x72\\x61\\x6a'.hex2dec(prefix: '\\x') # => "474316169578"
|
16
|
+
# '41'.hex2dec(padding: 3) # => "065"
|
14
17
|
def hex2dec(opts = {})
|
15
18
|
opts[:prefix] ||= ''
|
19
|
+
opts[:padding] ||= 0
|
16
20
|
# remove prefix
|
17
21
|
out = gsub(opts[:prefix], '')
|
18
22
|
# convert
|
19
|
-
|
23
|
+
out = out.hex.to_s
|
24
|
+
# padding
|
25
|
+
out = ('0' * (opts[:padding] - out.size)) + out if out.size < opts[:padding]
|
26
|
+
return out
|
20
27
|
end
|
21
28
|
|
22
29
|
# Encode an hexadecimal string to a decimal string in place as described
|
@@ -29,7 +36,7 @@ class String
|
|
29
36
|
replace(hex2dec(opts))
|
30
37
|
end
|
31
38
|
|
32
|
-
# Encode
|
39
|
+
# Encode a decimal string to a hexadecimal string
|
33
40
|
# @param opts [Hash] optional parameters
|
34
41
|
# @option opts [String] :prefix Prefix of the output. Default value is a void
|
35
42
|
# string. Example of values: `0x`, `\x`.
|
@@ -59,14 +66,14 @@ class String
|
|
59
66
|
out = ('0' * (opts[:padding] - out.size)) + out if out.size < opts[:padding]
|
60
67
|
# char case management
|
61
68
|
out = out.upcase if opts[:case] == :upper
|
62
|
-
# adding prefix must be done after case change, complex conditional to avoid cropping when odd byte
|
69
|
+
# adding prefix must be done after case change, complex conditional to avoid cropping when odd byte length
|
63
70
|
out = (out.size.odd? ? [out[0]] + out[1..].scan(/.{1,2}/) : out.scan(/.{2}/)).map do |x|
|
64
71
|
opts[:prefixall] + x
|
65
72
|
end.join
|
66
73
|
return opts[:prefix] + out
|
67
74
|
end
|
68
75
|
|
69
|
-
# Encode
|
76
|
+
# Encode a decimal string to a hexadecimal string in place as described
|
70
77
|
# for {String#dec2hex}.
|
71
78
|
# @example
|
72
79
|
# a = '255'
|
@@ -181,6 +188,8 @@ class String
|
|
181
188
|
# @param opts [Hash] optional parameters
|
182
189
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
183
190
|
# string. Example of values: `0x`, `\x`, `\\x`.
|
191
|
+
# @option opts [Integer] :even Returns an even number of chars (pad with `0`). Default value is a 1.
|
192
|
+
# `0` for false and `1` for true.
|
184
193
|
# @return [String] the binary encoded string
|
185
194
|
# @example
|
186
195
|
# 'ab'.hex2bin # => "10101011"
|
@@ -188,10 +197,14 @@ class String
|
|
188
197
|
# '\\x6e\\x6f\\x72\\x61\\x6a'.hex2bin(prefix: '\\x') # => "110111001101111011100100110000101101010"
|
189
198
|
def hex2bin(opts = {})
|
190
199
|
opts[:prefix] ||= ''
|
200
|
+
opts[:even] ||= 1
|
191
201
|
# remove prefix
|
192
202
|
out = gsub(opts[:prefix], '')
|
193
203
|
# convert
|
194
|
-
|
204
|
+
out = out.to_i(16).to_s(2)
|
205
|
+
# padding
|
206
|
+
out = "0#{out}" if out.size.odd? && opts[:even] == 1
|
207
|
+
return out
|
195
208
|
end
|
196
209
|
|
197
210
|
# Encode an hexadecimal string to a binary string in place as described
|
@@ -225,8 +238,10 @@ class String
|
|
225
238
|
out = to_i(2).to_s(16)
|
226
239
|
# char case management
|
227
240
|
out = out.upcase if opts[:case] == :upper
|
228
|
-
# adding prefix must be done after case change
|
229
|
-
out = out.scan(/.{2}/).map
|
241
|
+
# adding prefix must be done after case change, complex conditional to avoid cropping when odd byte length
|
242
|
+
out = (out.size.odd? ? [out[0]] + out[1..].scan(/.{1,2}/) : out.scan(/.{2}/)).map do |x|
|
243
|
+
opts[:prefixall] + x
|
244
|
+
end.join
|
230
245
|
return opts[:prefix] + out
|
231
246
|
end
|
232
247
|
|
@@ -240,7 +255,7 @@ class String
|
|
240
255
|
replace(bin2hex(opts))
|
241
256
|
end
|
242
257
|
|
243
|
-
# Decode a hexadecimal
|
258
|
+
# Decode a hexadecimal IPv4 string into a dotted decimal one
|
244
259
|
# @param opts [Hash] optional parameters
|
245
260
|
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
246
261
|
# string. Example of values: `0x`, `\x`, '\\x'.
|
@@ -248,10 +263,10 @@ class String
|
|
248
263
|
# (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
|
249
264
|
# @return [String] the dotted decimal IP
|
250
265
|
# @example
|
251
|
-
# '0100007F'.
|
252
|
-
# '0x7f000001'.
|
253
|
-
# '\\x7f\\x00\\x00\\x01'.
|
254
|
-
def
|
266
|
+
# '0100007F'.from_hexipv4(nibble: :low) # => "127.0.0.1"
|
267
|
+
# '0x7f000001'.from_hexipv4(prefix: '0x') # => "127.0.0.1"
|
268
|
+
# '\\x7f\\x00\\x00\\x01'.from_hexipv4(prefix: '\\x') # => "127.0.0.1"
|
269
|
+
def from_hexipv4(opts = {})
|
255
270
|
opts[:prefix] ||= ''
|
256
271
|
opts[:nibble] ||= :high
|
257
272
|
# remove prefix
|
@@ -262,13 +277,44 @@ class String
|
|
262
277
|
out.join('.')
|
263
278
|
end
|
264
279
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
280
|
+
alias from_hexip from_hexipv4
|
281
|
+
|
282
|
+
# Decode a hexadecimal IPv4 string into a dotted decimal one in place as described
|
283
|
+
# for {String#from_hexipv4}.
|
284
|
+
def from_hexipv4!(opts = {})
|
285
|
+
replace(from_hexipv4(opts))
|
286
|
+
end
|
287
|
+
|
288
|
+
alias from_hexip! from_hexipv4!
|
289
|
+
|
290
|
+
# Decode a hexadecimal IPv6 string into a the double-dotted hexadecimal format
|
291
|
+
# @param opts [Hash] optional parameters
|
292
|
+
# @option opts [String] :prefix Prefix of the input. Default value is a void
|
293
|
+
# string. Example of values: `0x`, `\x`, '\\x'.
|
294
|
+
# @return [String] the double-dotted hexadecimal format
|
295
|
+
# @example
|
296
|
+
# '000080FE00000000FF005450B6AD1DFE'.from_hexipv6 # => "[fe80::5054:ff:fe1d:adb6]"
|
297
|
+
# '0x000080FE00000000FF005450B6AD1DFE'.from_hexipv6(prefix: '0x') # => "[fe80::5054:ff:fe1d:adb6]"
|
298
|
+
# '00000000000000000000000000000000'.from_hexipv6 # => "[::]"
|
299
|
+
def from_hexipv6(opts = {})
|
300
|
+
opts[:prefix] ||= ''
|
301
|
+
# remove prefix
|
302
|
+
out = gsub(opts[:prefix], '')
|
303
|
+
# convert
|
304
|
+
out = out.scan(/.{2}/).reverse.join
|
305
|
+
out = out.scan(/.{8}/).reverse.join
|
306
|
+
out = out.scan(/.{4}/).map { |x| x.sub(/^0+/, '') }.join(':')
|
307
|
+
out = out.sub(/:{3,}/, '::').downcase
|
308
|
+
"[#{out}]"
|
309
|
+
end
|
310
|
+
|
311
|
+
# Decode a hexadecimal IPv6 string into a the double-dotted hexadecimal format in place as described
|
312
|
+
# for {String#from_hexipv6}.
|
313
|
+
def from_hexipv6!(opts = {})
|
314
|
+
replace(from_hexipv6(opts))
|
269
315
|
end
|
270
316
|
|
271
|
-
# Encode a dotted decimal
|
317
|
+
# Encode a dotted decimal IPv4 into a hexadecimal one
|
272
318
|
# @param opts [Hash] optional parameters
|
273
319
|
# @option opts [String] :prefix Prefix of the output. Default value is a void
|
274
320
|
# string. Example of values: `0x`, `\x`.
|
@@ -280,10 +326,10 @@ class String
|
|
280
326
|
# (`:high` default) or low nibble first (`:low`, used on Unix `/proc/net/tcp`).
|
281
327
|
# @return [String] the hexadecimal encoded IP
|
282
328
|
# @example
|
283
|
-
# '127.0.0.1'.
|
284
|
-
# '127.0.0.1'.
|
285
|
-
# '127.0.0.1'.
|
286
|
-
def
|
329
|
+
# '127.0.0.1'.to_hexipv4 # => "7f000001"
|
330
|
+
# '127.0.0.1'.to_hexipv4(nibble: :low) # => "0100007f"
|
331
|
+
# '127.0.0.1'.to_hexipv4(prefixall: '\\x') # => "\\x7f\\x00\\x00\\x01"
|
332
|
+
def to_hexipv4(opts = {})
|
287
333
|
opts[:prefix] ||= ''
|
288
334
|
opts[:prefixall] ||= ''
|
289
335
|
opts[:case] ||= :lower
|
@@ -299,9 +345,13 @@ class String
|
|
299
345
|
return opts[:prefix] + out
|
300
346
|
end
|
301
347
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
348
|
+
alias to_hexip to_hexipv4
|
349
|
+
|
350
|
+
# Encode a dotted decimal IPv4 into a hexadecimal one in place as described
|
351
|
+
# for {String#to_hexipv4}.
|
352
|
+
def to_hexipv4!(opts = {})
|
353
|
+
replace(to_hexipv4(opts))
|
306
354
|
end
|
355
|
+
|
356
|
+
alias to_hexip! to_hexipv4!
|
307
357
|
end
|
data/lib/ctf_party/network.rb
CHANGED
@@ -35,22 +35,22 @@ class String
|
|
35
35
|
ipv4? || ipv6?
|
36
36
|
end
|
37
37
|
|
38
|
-
# Is the string a valid URI?
|
38
|
+
# Is the string a valid (RFC 2396) URI?
|
39
39
|
# @param opts [Hash] optional parameters
|
40
40
|
# @option opts [Symbol] :lax Default value: `false`.
|
41
41
|
# When `lax: false`, only URI matching common protocols (ftp http https ldap ldaps mailto ws wss) are recognized,
|
42
42
|
# but is still a bit lax (eg. `http://` is seen as valid).
|
43
43
|
# When `lax: true`, the parser will accept more types of URI (gopher magnet matrix), but will be very lax and accept
|
44
44
|
# nearly anything including `:`.
|
45
|
-
# @return [Boolean] `true` if the string is a valid URI, `false` else.
|
45
|
+
# @return [Boolean] `true` if the string is a valid (RFC 2396) URI, `false` else.
|
46
46
|
# @example
|
47
47
|
# 'ftp://ftp.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0.tar.xz'.uri? # => true
|
48
48
|
# 'a:'.uri? # => false
|
49
49
|
# 'a:'.uri?(lax: true) # => true
|
50
50
|
def uri?(opts = {})
|
51
51
|
opts[:lax] ||= false
|
52
|
-
strict = URI::
|
53
|
-
lax = URI::
|
52
|
+
strict = URI::RFC2396_PARSER.make_regexp(%w[ftp http https ldap ldaps mailto ws wss]).match?(self)
|
53
|
+
lax = URI::RFC2396_PARSER.make_regexp.match?(self)
|
54
54
|
if opts[:lax] == true
|
55
55
|
strict || lax
|
56
56
|
else
|
data/lib/ctf_party/version.rb
CHANGED
data/lib/ctf_party.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ctf-party
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre ZANNI
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: base64
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 0.2.0
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.2.0
|
13
26
|
- !ruby/object:Gem::Dependency
|
14
27
|
name: docopt
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,12 +37,32 @@ dependencies:
|
|
24
37
|
- - "~>"
|
25
38
|
- !ruby/object:Gem::Version
|
26
39
|
version: '0.6'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: uri
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 1.0.2
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '1.0'
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.0.2
|
27
60
|
description: A CLI tool & library to enhance and speed up script/exploit writing for
|
28
61
|
CTF players (or security researchers, bug bounty hunters, pentesters but mostly
|
29
62
|
focused on CTF) by patching the String class to add a short syntax of usual code
|
30
63
|
patterns. Methods for base64, digest (hash), flag, rot (Caesar), hexadecimal, case,
|
31
64
|
cgi (URL encoding/decoding, HTML escaping/unescaping), binary, leet (1337), decimal,
|
32
|
-
XOR, whitespace strip.
|
65
|
+
XOR, whitespace strip, IP/URI/domain/email defang/refang.
|
33
66
|
email: alexandre.zanni@engineer.com
|
34
67
|
executables:
|
35
68
|
- ctf-party
|
@@ -66,8 +99,8 @@ metadata:
|
|
66
99
|
documentation_uri: https://noraj.github.io/ctf-party/
|
67
100
|
homepage_uri: https://noraj.github.io/ctf-party/
|
68
101
|
source_code_uri: https://github.com/noraj/ctf-party/
|
102
|
+
funding_uri: https://github.com/sponsors/noraj
|
69
103
|
rubygems_mfa_required: 'true'
|
70
|
-
post_install_message:
|
71
104
|
rdoc_options: []
|
72
105
|
require_paths:
|
73
106
|
- lib
|
@@ -75,18 +108,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
108
|
requirements:
|
76
109
|
- - ">="
|
77
110
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
111
|
+
version: 3.1.0
|
79
112
|
- - "<"
|
80
113
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
114
|
+
version: '4.0'
|
82
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
116
|
requirements:
|
84
117
|
- - ">="
|
85
118
|
- !ruby/object:Gem::Version
|
86
119
|
version: '0'
|
87
120
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
89
|
-
signing_key:
|
121
|
+
rubygems_version: 3.6.2
|
90
122
|
specification_version: 4
|
91
123
|
summary: A CLI tool & library to enhance and speed up script/exploit writing with
|
92
124
|
string conversion/manipulation
|