Class: String

Inherits:
Object
  • Object
show all
Defined in:
lib/ctf_party/hex.rb,
lib/ctf_party/rot.rb,
lib/ctf_party/flag.rb,
lib/ctf_party/base64.rb,
lib/ctf_party/digest.rb

Constant Summary collapse

@@flag =

The flag configuration hash. See flag=.

{
  prefix: '',
  suffix: '',
  enclosing: ['{', '}'],
  digest: nil
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.flagObject

Show the actual flag configuration. See flag=.



15
16
17
# File 'lib/ctf_party/flag.rb', line 15

def self.flag
  @@flag
end

.flag=(hash) ⇒ Hash

Note:

You can provide the full hash or only the key to update.

Update the flag configuration.

Examples:

String.flag # => {:prefix=>"", :suffix=>"", :enclosing=>["{", "}"], :digest=>nil}
String.flag = {prefix: 'sigsegv', digest: 'md5'}
String.flag # => {:prefix=>"sigsegv", :suffix=>"", :enclosing=>["{", "}"], :digest=>"md5"}
'this_1s_a_fl4g'.flag # => "sigsegv{a5bec9e2a86b6b70d288451eb38dfec8}"

Parameters:

  • hash (Hash)

    flag configuration

Options Hash (hash):

  • :prefix (String)

    prefix of the flag. Default: none.

  • :suffix (String)

    suffix of the flag. Default: none.

  • :enclosing (Array<String>)

    the characters used to surround the flag. Default are curly braces: {, }. The array must contain exactly 2 elements.

  • :digest (String)

    the hash algorithm to apply on the flag. Default: none. Allowed values: md5, sha1, sha2_256, sha2_384, sha2_512, rmd160.

Returns:

  • (Hash)

    hash of the updated options.



38
39
40
41
# File 'lib/ctf_party/flag.rb', line 38

def self.flag=(hash)
  hash.select! { |k, _v| @@flag.key?(k) }
  @@flag.merge!(hash)
end

Instance Method Details

#b64?(opts = {}) ⇒ Boolean

Is the string encoded in base64?

Examples:

'SGVsbG8gd29ybGQh'.b64? # => true
'SGVsbG8g@@d29ybGQh'.b64? # => false

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :mode (Symbol)

    Default value: :strict. Other values are :strict (:rfc4648) or :urlsafe.

Returns:

  • (Boolean)

    true if the string is a valid base64 string, false else.

See Also:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ctf_party/base64.rb', line 69

def b64?(opts = {})
  opts[:mode] ||= :strict
  b64 = false  # https://www.rexegg.com/regex-ruby.html

  reg1 = %r{\A(?:[a-zA-Z0-9+/]{4})*(?:|(?:[a-zA-Z0-9+/]{3}=)|
            (?:[a-zA-Z0-9+/]{2}==)|(?:[a-zA-Z0-9+/]{1}===))\Z}xn
  reg3 = /\A(?:[a-zA-Z0-9\-_]{4})*(?:|(?:[a-zA-Z0-9\-_]{3}=)|
          (?:[a-zA-Z0-9\-_]{2}==)|(?:[a-zA-Z0-9\-_]{1}===))\Z/xn
  if opts[:mode] == :strict || opts[:mode] == :rfc4648
    b64 = true if reg1.match?(self)
  elsif opts[:mode] == :rfc2045
    b64 = true
    split("\n").each do |s|
      b64 = false unless reg1.match?(s)
    end
  elsif opts[:mode] == :urlsafe
    b64 = true if reg3.match?(self)
  else
    raise ArgumentError 'Wrong mode'
  end
  return b64
end

#bin2hex(opts = {}) ⇒ String

Encode an binary string to a hexadecimal string

Examples:

'11110011'.bin2hex # => "f3"
'11110011'.bin2hex({prefix: '0x', case: :upper}) # => "0xF3"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the output. Default value is a void string. Example of values: 0x, \x.

  • :case (Symbol)

    Char case of the ouput. Default value :lower. Other valid value :upper.

Returns:

  • (String)

    the hexadecimal encoded string



171
172
173
174
175
176
177
178
179
180
# File 'lib/ctf_party/hex.rb', line 171

def bin2hex(opts = {})
  opts[:prefix] ||= ''
  opts[:case] ||= :lower  # convert

  out = to_i(2).to_s(16)  # char case management

  out = out.upcase if opts[:case] == :upper  # adding prefix must be done after case change

  return opts[:prefix] + out
end

#bin2hex!(opts = {}) ⇒ Object

Encode an binary string to a hexadecimal string in place as described for #bin2hex.

Examples:

a = '11110011'
a.bin2hex!
a # => "f3"


188
189
190
# File 'lib/ctf_party/hex.rb', line 188

def bin2hex!(opts = {})
  replace(bin2hex(opts))
end

#dec2hex(opts = {}) ⇒ String

Encode an decimal string to a hexadecimal string

Examples:

'255'.dec2hex # => "ff"
'255'.dec2hex({prefix: '0x', case: :upper}) # => "0xFF"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the output. Default value is a void string. Example of values: 0x, \x.

  • :case (Symbol)

    Char case of the ouput. Default value :lower. Other valid value :upper.

Returns:

  • (String)

    the hexadecimal encoded string



40
41
42
43
44
45
46
47
48
49
# File 'lib/ctf_party/hex.rb', line 40

def dec2hex(opts = {})
  opts[:prefix] ||= ''
  opts[:case] ||= :lower  # convert

  out = to_i.to_s(16)  # char case management

  out = out.upcase if opts[:case] == :upper  # adding prefix must be done after case change

  return opts[:prefix] + out
end

#dec2hex!(opts = {}) ⇒ Object

Encode an decimal string to a hexadecimal string in place as described for #dec2hex.

Examples:

a = '255'
a.dec2hex!
a # => "ff"


57
58
59
# File 'lib/ctf_party/hex.rb', line 57

def dec2hex!(opts = {})
  replace(dec2hex(opts))
end

#flagString

Format the current string into the configured flag format. See flag= example.

Returns:

  • (String)

    the format flag.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ctf_party/flag.rb', line 48

def flag
  flag = ''
  flag += @@flag[:prefix]
  flag += @@flag[:enclosing][0]
  if @@flag[:digest].nil?
    flag += self
  else
    case @@flag[:digest]
    when 'md5'
      flag += md5
    when 'sha1'
      flag += sha1
    when 'sha2_256'
      flag += sha2_256
    when 'sha2_384'
      flag += sha2_384
    when 'sha2_512'
      flag += sha2_512
    when 'rmd160'
      flag += rmd160
    end
  end
  flag += @@flag[:enclosing][1]
  flag + @@flag[:suffix]
end

#flag!Object

Format the current string into the configured flag format in place as described for #flag.



76
77
78
# File 'lib/ctf_party/flag.rb', line 76

def flag!
  replace(flag)
end

#flag?Boolean

Check if the string respect the defined flag format.

Examples:

String.flag = {prefix: 'flag'}
flag = 'Brav0!'
flag.flag! # => "flag{Brav0!}"
flag.flag? # => true
flag = 'ctf{Brav0!}'
flag.flag? # => false

Returns:

  • (Boolean)

    true if it respects the configured flag format. but it does not check digest used.



90
91
92
93
# File 'lib/ctf_party/flag.rb', line 90

def flag?
  /#{@@flag[:prefix]}#{@@flag[:enclosing][0]}[[:print:]]+
    #{@@flag[:enclosing][1]}#{@@flag[:suffix]}/ox.match?(self)
end

#from_b64(opts = {}) ⇒ String

Decode the string from base64

Examples:

'UnVieQ=='.from_b64 # => "Ruby"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :mode (Symbol)

    Default value: :strict. Other values are :strict (:rfc4648) or :urlsafe.

Returns:

  • (String)

    the Base64 decoded string

See Also:



41
42
43
44
45
46
47
# File 'lib/ctf_party/base64.rb', line 41

def from_b64(opts = {})
  opts[:mode] ||= :strict
  return Base64.strict_decode64(self) if opts[:mode] == :strict ||
                                         opts[:mode] == :rfc4648
  return Base64.decode64(self) if opts[:mode] == :rfc2045
  return Base64.urlsafe_decode64(self) if opts[:mode] == :urlsafe
end

#from_b64!(opts = {}) ⇒ nil

Decode the string from base64 in place as described for #from_b64.

Examples:

a = 'SGVsbG8gd29ybGQh' # => "SGVsbG8gd29ybGQh"
a.from_b64! # => nil
a # => "Hello world!"

Returns:

  • (nil)


55
56
57
# File 'lib/ctf_party/base64.rb', line 55

def from_b64!(opts = {})
  replace(from_b64(opts))
end

#from_hex(opts = {}) ⇒ String

Decode a hexadecimal string

Examples:

"6e6f72616a".from_hex # => "noraj"
"0x6e6f72616a".from_hex(prefix: '0x') # => "noraj"
"e6f62716a6".from_hex(nibble: :low) # => "noraj"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the input. Default value is a void string. Example of values: 0x, \x.

  • :nibble (Symbol)

    Display input with high nibble first (:high default) or low nibble first (:low).

Returns:

  • (String)

    the hexadecimal decoded string



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ctf_party/hex.rb', line 113

def from_hex(opts = {})
  opts[:prefix] ||= ''
  opts[:nibble] ||= :high  # remove prefix

  out = sub(opts[:prefix], '')  # convert

  return Array(out).pack('H*') if opts[:nibble] == :high
  return Array(out).pack('h*') if opts[:nibble] == :low

  raise ArgumentError ':nibble expects :high or :low'
end

#from_hex!(opts = {}) ⇒ Object

Decode a hexadecimal string in place as described for #from_hex.

Examples:

a = "6e6f72616a"
a.from_hex!
a # => "noraj"


131
132
133
# File 'lib/ctf_party/hex.rb', line 131

def from_hex!(opts = {})
  replace(from_hex(opts))
end

#hex2bin(opts = {}) ⇒ String

Encode an hexadecimal string to a binary string

Examples:

'ab'.hex2bin # => "10101011"
'\xf3'.hex2bin(prefix: '\x') # => "11110011"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the input. Default value is a void string. Example of values: 0x, \x.

Returns:

  • (String)

    the binary encoded string



143
144
145
146
147
148
149
# File 'lib/ctf_party/hex.rb', line 143

def hex2bin(opts = {})
  opts[:prefix] ||= ''  # remove prefix

  out = sub(opts[:prefix], '')  # convert

  return out.to_i(16).to_s(2)
end

#hex2bin!(opts = {}) ⇒ Object

Encode an hexadecimal string to a binary string in place as described for #hex2bin.

Examples:

a = 'ff'
a.hex2bin!
a # => => "11111111"


157
158
159
# File 'lib/ctf_party/hex.rb', line 157

def hex2bin!(opts = {})
  replace(hex2bin(opts))
end

#hex2dec(opts = {}) ⇒ String

Encode an hexadecimal string to a decimal string

Examples:

'ff'.hex2dec # => "255"
'\xf3'.hex2dec(prefix: '\x') # => "243"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the input. Default value is a void string. Example of values: 0x, \x.

Returns:

  • (String)

    the decimal encoded string



12
13
14
15
16
17
18
# File 'lib/ctf_party/hex.rb', line 12

def hex2dec(opts = {})
  opts[:prefix] ||= ''  # remove prefix

  out = sub(opts[:prefix], '')  # convert

  return out.hex.to_s
end

#hex2dec!(opts = {}) ⇒ Object

Encode an hexadecimal string to a decimal string in place as described for #hex2dec.

Examples:

a = 'ff'
a.hex2dec!
a # => => "255"


26
27
28
# File 'lib/ctf_party/hex.rb', line 26

def hex2dec!(opts = {})
  replace(hex2dec(opts))
end

#md5String

Calculate the md5 hash of the string.

Examples:

'noraj'.md5 # => "556cc23863fef20fab5c456db166bc6e"

Returns:

See Also:



12
13
14
# File 'lib/ctf_party/digest.rb', line 12

def md5
  Digest::MD5.hexdigest self
end

#md5!Object

Calculate the md5 hash of the string in place as described for #md5.

Examples:

a = '\o/' # => "\\o/"
a.md5! # => "881419964e480e66162da521ccc25ebf"
a # => "881419964e480e66162da521ccc25ebf"


21
22
23
# File 'lib/ctf_party/digest.rb', line 21

def md5!
  replace(md5)
end

#rmd160String

Calculate the RIPEMD-160 hash of the string.

Examples:

'payload'.rmd160 # => "3c6255c112d409dafdb84d5b0edba98dfd27b44f"

Returns:

  • (String)

    RIPEMD-160 hash

See Also:



104
105
106
# File 'lib/ctf_party/digest.rb', line 104

def rmd160
  Digest::RMD160.hexdigest self
end

#rmd160!Object

Calculate the RIPEMD-160 hash of the string in place as described for #rmd160.

Examples:

pl = 'payload' # => "payload"
pl.rmd160! # => "3c6255c112d409dafdb84d5b0edba98dfd27b44f"
pl # => "3c6255c112d409dafdb84d5b0edba98dfd27b44f"


114
115
116
# File 'lib/ctf_party/digest.rb', line 114

def rmd160!
  replace(rmd160)
end

#rot(opts = {}) ⇒ String

“Encrypt / Decrypt” the string with Caesar cipher. This will shift the alphabet letters by n, where n is the integer key. The same function is used for encryption / decryption.

Examples:

'Hello world!'.rot # => "Uryyb jbeyq!"
'Hello world!'.rot(shift: 11) # => "Spwwz hzcwo!"
'Uryyb jbeyq!'.rot # => "Hello world!"
'Spwwz hzcwo!'.rot(shift: 26-11) # => "Hello world!"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :shift (Integer)

    The shift key. Default value: 13.

Returns:

  • (String)

    the (de)ciphered string

See Also:



16
17
18
19
20
21
22
23
24
# File 'lib/ctf_party/rot.rb', line 16

def rot(opts = {})
  opts[:shift] ||= 13
  alphabet = Array('a'..'z')
  lowercase = Hash[alphabet.zip(alphabet.rotate(opts[:shift]))]
  alphabet = Array('A'..'Z')
  uppercasecase = Hash[alphabet.zip(alphabet.rotate(opts[:shift]))]
  encrypter = lowercase.merge(uppercasecase)
  chars.map { |c| encrypter.fetch(c, c) }.join
end

#rot!(opts = {}) ⇒ String

“Encrypt / Decrypt” the string with Caesar cipher in place as described for #rot.

Examples:

a = 'Bonjour le monde !' # => "Bonjour le monde !"
a.rot! # => "Obawbhe yr zbaqr !"
a # => "Obawbhe yr zbaqr !"

Returns:

  • (String)

    the (de)ciphered string as well as changing changing the object in place.



34
35
36
# File 'lib/ctf_party/rot.rb', line 34

def rot!(opts = {})
  replace(rot(opts))
end

#rot13Object

Alias for #rot with default value ( rot(shift: 13) ).



39
40
41
# File 'lib/ctf_party/rot.rb', line 39

def rot13
  rot
end

#rot13!Object

Alias for #rot! with default value ( rot!(shift: 13) ).



44
45
46
# File 'lib/ctf_party/rot.rb', line 44

def rot13!
  rot!
end

#sha1String

Calculate the sha1 hash of the string.

Examples:

'ctf-party'.sha1 # => "5a64f3bc491d0977e1e3578a48c65a89a16a5fe8"

Returns:

See Also:



30
31
32
# File 'lib/ctf_party/digest.rb', line 30

def sha1
  Digest::SHA1.hexdigest self
end

#sha1!Object

Calculate the sha1 hash of the string in place as described for

{String#sha1}.

Examples:

bob = 'alice' # => "alice"
bob.sha1! # => "522b276a356bdf39013dfabea2cd43e141ecc9e8"
bob # => "522b276a356bdf39013dfabea2cd43e141ecc9e8"


40
41
42
# File 'lib/ctf_party/digest.rb', line 40

def sha1!
  replace(sha1)
end

#sha2(opts = {}) ⇒ String

Calculate the sha2 hash of the string.

Examples:

'try harder'.sha2 # => "5321ff2d4b1389b3a350dfe8ca77e3889dc6259bb233ad..."
'try harder'.sha2(bitlen: 512) # => "a7b73a98c095b22e25407b15c4dec128c..."

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :bitlen (Integer)

    Defines the bit lenght of the digest. Default value: 256 (SHA2-256). other valid vales are 384 (SHA2-384) and 512 (SHA2-512).

Returns:

See Also:



54
55
56
57
# File 'lib/ctf_party/digest.rb', line 54

def sha2(opts = {})
  opts[:bitlen] ||= 256
  Digest::SHA2.new(opts[:bitlen]).hexdigest self
end

#sha2!(opts = {}) ⇒ Object

Calculate the sha2 hash of the string in place as described for

{String#sha2}.

Examples:

th = 'try harder' # => "try harder"
th.sha2!(bitlen: 384) # => "bb7f60b9562a19c3a83c23791440af11591c42ede9..."
th # => "bb7f60b9562a19c3a83c23791440af11591c42ede9988334cdfd7efa4261a..."


65
66
67
# File 'lib/ctf_party/digest.rb', line 65

def sha2!(opts = {})
  replace(sha2(opts))
end

#sha2_256Object

Alias for #sha2 with default value ( sha2(bitlen: 256) ).



70
71
72
# File 'lib/ctf_party/digest.rb', line 70

def sha2_256
  sha2
end

#sha2_256!Object

Alias for #sha2! with default value ( sha2!(bitlen: 256) ).



75
76
77
# File 'lib/ctf_party/digest.rb', line 75

def sha2_256!
  replace(sha2)
end

#sha2_384Object

Alias for #sha2 with default value ( sha2(bitlen: 384) ).



80
81
82
# File 'lib/ctf_party/digest.rb', line 80

def sha2_384
  sha2(bitlen: 384)
end

#sha2_384!Object

Alias for #sha2! with default value ( sha2!(bitlen: 384) ).



85
86
87
# File 'lib/ctf_party/digest.rb', line 85

def sha2_384!
  replace(sha2(bitlen: 384))
end

#sha2_512Object

Alias for #sha2 with default value ( sha2(bitlen: 512) ).



90
91
92
# File 'lib/ctf_party/digest.rb', line 90

def sha2_512
  sha2(bitlen: 512)
end

#sha2_512!Object

Alias for #sha2! with default value ( sha2!(bitlen: 512) ).



95
96
97
# File 'lib/ctf_party/digest.rb', line 95

def sha2_512!
  replace(sha2(bitlen: 512))
end

#to_b64(opts = {}) ⇒ String

Encode the string into base64

Examples:

'Super lib!'.to_b64 # => "U3VwZXIgbGliIQ=="

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :mode (Symbol)

    Default value: :strict. Other values are :strict (:rfc4648) or :urlsafe.

Returns:

  • (String)

    the Base64 encoded string

See Also:



15
16
17
18
19
20
21
# File 'lib/ctf_party/base64.rb', line 15

def to_b64(opts = {})
  opts[:mode] ||= :strict
  return Base64.strict_encode64(self) if opts[:mode] == :strict ||
                                         opts[:mode] == :rfc4648
  return Base64.encode64(self) if opts[:mode] == :rfc2045
  return Base64.urlsafe_encode64(self) if opts[:mode] == :urlsafe
end

#to_b64!(opts = {}) ⇒ nil

Encode the string into base64 in place as described for #to_b64.

Examples:

myStr = 'Ruby' # => "Ruby"
myStr.to_b64! # => nil
myStr # => "UnVieQ=="

Returns:

  • (nil)


29
30
31
# File 'lib/ctf_party/base64.rb', line 29

def to_b64!(opts = {})
  replace(to_b64(opts))
end

#to_hex(opts = {}) ⇒ String

Encode a string into hexadecimal

Examples:

'noraj'.to_hex # => "6e6f72616a"
'noraj'.to_hex(prefix: '0x') # => "0x6e6f72616a"
'noraj'.to_hex(case: :upper) # => "6E6F72616A"
'noraj'.to_hex(nibble: :low) # => "e6f62716a6"

Parameters:

  • opts (Hash) (defaults to: {})

    optional parameters

Options Hash (opts):

  • :prefix (String)

    Prefix of the output. Default value is a void string. Example of values: 0x, \x.

  • :case (Symbol)

    Char case of the ouput. Default value :lower. Other valid value :upper.

  • :nibble (Symbol)

    Display output with high nibble first (:high default) or low nibble first (:low).

Returns:

  • (String)

    the hexadecimal encoded string



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ctf_party/hex.rb', line 75

def to_hex(opts = {})
  opts[:prefix] ||= ''
  opts[:case] ||= :lower
  opts[:nibble] ||= :high  # convert

  out = ''
  if opts[:nibble] == :high
    out = unpack1('H*')
  elsif opts[:nibble] == :low
    out = unpack1('h*')
  end  # char case management

  out = out.upcase if opts[:case] == :upper  # adding prefix must be done after case change

  return opts[:prefix] + out
end

#to_hex!(opts = {}) ⇒ Object

Encode a string into hexadecimal in place as described for #to_hex.

Examples:

a = 'noraj'
a.to_hex!
a # => "6e6f72616a"


98
99
100
# File 'lib/ctf_party/hex.rb', line 98

def to_hex!(opts = {})
  replace(to_hex(opts))
end