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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41082df14f844e9d331e06352e00af3ab29af0899ad4a54f911ee6cef946258b
4
- data.tar.gz: ffb31de3ffd71d581c277f10ff0be95e9eaf2e75c161df8af1f9b8d415af64fc
3
+ metadata.gz: 1eb800f2b8374568f0f0caf62902e9851de280e60f136079486ddb1d80d597a3
4
+ data.tar.gz: 5202083c9dcfe5d3f917fd1a706d8bfc305d20e004f1857d406f7ef86c3a674f
5
5
  SHA512:
6
- metadata.gz: e09eff292c815cb2a5de04f8ae901a9ccc83ac30f7cd8b3a634b2b0674b32e3cd568cecfca774641afe23953afc1a9987d810655d236bf6f4fede7a2d48c62e2
7
- data.tar.gz: 425e78e522566abf5a67650de204e2feea57f800d81f85dd04c87a51c0cbfea1a8096344da8eea61ab9b0a857ef2c511eacb52f97f2e92fb333274897f05b8d9
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 IP string into a dotted decimal one',
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 IP into a hexadecimal one',
56
- urldecode: 'URL-decode the string',
57
- urldecode_component: 'URL-decode the URL component string',
58
- urlencode: 'URL-encode the string',
59
- urlencode_component: 'URL-encode the URL component string',
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.1/o/string#method-i-bytesize',
62
- capitalize: 'https://rubyapi.org/3.1/o/string#method-i-capitalize',
63
- chomp: 'https://rubyapi.org/3.1/o/string#method-i-chomp',
64
- chop: 'https://rubyapi.org/3.1/o/string#method-i-chop',
65
- downcase: 'https://rubyapi.org/3.1/o/string#method-i-downcase',
66
- dump: 'https://rubyapi.org/3.1/o/string#method-i-dump',
67
- hex: 'https://rubyapi.org/3.1/o/string#method-i-hex',
68
- inspect: 'https://rubyapi.org/3.1/o/string#method-i-inspect',
69
- length: 'https://rubyapi.org/3.1/o/string#method-i-length',
70
- lstrip: 'https://rubyapi.org/3.1/o/string#method-i-lstrip',
71
- reverse: 'https://rubyapi.org/3.1/o/string#method-i-reverse',
72
- rstrip: 'https://rubyapi.org/3.1/o/string#method-i-rstrip',
73
- scrub: 'https://rubyapi.org/3.1/o/string#method-i-scrub',
74
- shellescape: 'https://rubyapi.org/3.1/o/string#method-i-shellescape',
75
- size: 'https://rubyapi.org/3.1/o/string#method-i-size',
76
- squeeze: 'https://rubyapi.org/3.1/o/string#method-i-squeeze',
77
- strip: 'https://rubyapi.org/3.1/o/string#method-i-strip',
78
- succ: 'https://rubyapi.org/3.1/o/string#method-i-succ',
79
- swapcase: 'https://rubyapi.org/3.1/o/string#method-i-swapcase',
80
- undump: 'https://rubyapi.org/3.1/o/string#method-i-undump',
81
- unicode_normalize: 'https://rubyapi.org/3.1/o/string#method-i-unicode_normalize',
82
- upcase: 'https://rubyapi.org/3.1/o/string#method-i-upcase'
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
- pp args if args['--debug']
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>'])
@@ -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 `:strict` (`:rfc4648`) or `:urlsafe`.
11
- # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
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] == :strict ||
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 `:strict` (`:rfc4648`) or `:urlsafe`.
37
- # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
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] == :strict ||
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 `:strict` (`:rfc4648`) or `:urlsafe`.
63
- # @see https://ruby-doc.org/stdlib-2.6.5/libdoc/base64/rdoc/Base64.html
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
@@ -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 (RFC2396)
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::Parser.new.escape self
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 the URL component string
23
- # @return [String] the URL-encoded string
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".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
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 string in place as described for {String#urlencode_component}.
32
- def urlencode_component!
33
- replace(urlencode_component)
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 (RFC2396)
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::Parser.new.unescape self
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 URL component string
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'.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
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#urldecode_component}.
64
- def urldecode_component!
65
- replace(urldecode_component)
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
- str2hex.hex2dec
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.hex2str
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
- return out.hex.to_s
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 an decimal string to a hexadecimal string
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 lenght
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 an decimal string to a hexadecimal string in place as described
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
- return out.to_i(16).to_s(2)
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 { |x| opts[:prefixall] + x }.join
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 IP string into a dotted decimal one
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'.from_hexip(nibble: :low) # => "127.0.0.1"
252
- # '0x7f000001'.from_hexip(prefix: '0x') # => "127.0.0.1"
253
- # '\\x7f\\x00\\x00\\x01'.from_hexip(prefix: '\\x') # => "127.0.0.1"
254
- def from_hexip(opts = {})
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
- # Decode a hexadecimal IP string into a dotted decimal one in place as described
266
- # for {String#from_hexip}.
267
- def from_hexip!(opts = {})
268
- replace(from_hexip(opts))
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 IP into a hexadecimal one
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'.to_hexip # => "7f000001"
284
- # '127.0.0.1'.to_hexip(nibble: :low) # => "0100007f"
285
- # '127.0.0.1'.to_hexip(prefixall: '\\x') # => "\\x7f\\x00\\x00\\x01"
286
- def to_hexip(opts = {})
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
- # Encode a dotted decimal IP into a hexadecimal one in place as described
303
- # for {String#to_hexip}.
304
- def to_hexip!(opts = {})
305
- replace(to_hexip(opts))
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
@@ -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::DEFAULT_PARSER.make_regexp(%w[ftp http https ldap ldaps mailto ws wss]).match?(self)
53
- lax = URI::DEFAULT_PARSER.make_regexp.match?(self)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Version
4
- VERSION = '2.3.0'
3
+ module CTFParty
4
+ VERSION = '4.0.0'
5
5
  end
data/lib/ctf_party.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ctf_party/version'
3
4
  # Project internal
4
5
  require 'ctf_party/base64'
5
6
  require 'ctf_party/binary'
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: 2.3.0
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: 2023-01-21 00:00:00.000000000 Z
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: 2.7.0
111
+ version: 3.1.0
79
112
  - - "<"
80
113
  - !ruby/object:Gem::Version
81
- version: '3.3'
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.4.1
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