ctf-party 1.4.1 → 1.5.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 +1 -0
- data/lib/ctf_party.rb +2 -0
- data/lib/ctf_party/misc.rb +18 -0
- data/lib/ctf_party/rot.rb +9 -0
- data/lib/ctf_party/version.rb +1 -1
- data/lib/ctf_party/xor.rb +93 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de422839915f8e5fe2e71975678b8966aecf94edc75d4a29e7337ba80c728537
|
4
|
+
data.tar.gz: 1ae611ce6ed8a42cb088c5ce27d75979f589a69413713f2165b109305a85d9c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d941c1d060a2ecec96d396b6ff0c7f692bd138b7962956dfd98b8a092c534755f965cb77e3a72fa2cfad770c71a73783c791d01dfdca835b7ef7abd42d1ef552
|
7
|
+
data.tar.gz: c65a093261672e00c56eadb7d5dce1bae86a7ac41b6755a0c72e13b48ffdd967256e50dadbc74b41533d616799d1972ee737ce4fe7f0ecd2eda0227c86692aaf
|
data/bin/ctf-party
CHANGED
@@ -25,6 +25,7 @@ cmd_whitelist = {
|
|
25
25
|
hex2str: 'Alias for from_hex',
|
26
26
|
htmlescape: 'HTML escape the string',
|
27
27
|
htmlunescape: 'HTML unescape the string',
|
28
|
+
istrip: 'Remove leading and trailing whitespace but also all inner whitespace',
|
28
29
|
leet: 'Transform into leet speak (l337 5p34k)',
|
29
30
|
md5: 'Calculate the md5 hash of the string',
|
30
31
|
randomcase: 'Change the case of characters randomly',
|
data/lib/ctf_party.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
# Remove leading and trailing whitespace (like {String#strip}) but also all
|
5
|
+
# inner whitespace.
|
6
|
+
# @return [String] the whitespace-free string
|
7
|
+
# @example
|
8
|
+
# "\t\n\v\f\r Hello \t\n\v\f\r World !\t\n\v\f\r ".istrip # => "HelloWorld!"
|
9
|
+
# '73 74 72 69 70'.istrip # => "7374726970"
|
10
|
+
def istrip
|
11
|
+
strip.gsub(/\s/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Remove all whitespace in place as described for {String#istrip}.
|
15
|
+
def istrip!
|
16
|
+
replace(innerstrip)
|
17
|
+
end
|
18
|
+
end
|
data/lib/ctf_party/rot.rb
CHANGED
@@ -44,4 +44,13 @@ class String
|
|
44
44
|
def rot13!
|
45
45
|
rot!
|
46
46
|
end
|
47
|
+
|
48
|
+
# Compute all possibilities with {String#rot}
|
49
|
+
# @return [Hash] All possibilities with the shift index as key and the
|
50
|
+
# (de)ciphered text as value
|
51
|
+
# @example
|
52
|
+
# 'noraj'.rot_all # => {1=>"opsbk", 2=>"pqtcl", 3=>"qrudm", ... }
|
53
|
+
def rot_all
|
54
|
+
(1..26).each_with_object({}) { |i, h| h[i] = rot(shift: i) }
|
55
|
+
end
|
47
56
|
end
|
data/lib/ctf_party/version.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
# UTF-8 XOR with key, padding left the shortest element
|
5
|
+
# @param key [String] the element to xor the string with
|
6
|
+
# @return [String] the xored string (UTF-8)
|
7
|
+
# @example
|
8
|
+
# 'hello'.ulxor('key') # => "he\a\t\u0016"
|
9
|
+
# 'key'.ulxor('hello') # => "he\a\t\u0016"
|
10
|
+
def ulxor(key)
|
11
|
+
b1 = unpack('U*')
|
12
|
+
b2 = key.unpack('U*')
|
13
|
+
longest = [b1.length, b2.length].max
|
14
|
+
b1 = [0] * (longest - b1.length) + b1
|
15
|
+
b2 = [0] * (longest - b2.length) + b2
|
16
|
+
b1.zip(b2).map { |a, b| a ^ b }.pack('U*')
|
17
|
+
end
|
18
|
+
|
19
|
+
# UTF-8 XOR with key (padding left) in place as described for {String#ulxor}.
|
20
|
+
def ulxor!(key)
|
21
|
+
replace(ulxor(key))
|
22
|
+
end
|
23
|
+
|
24
|
+
# ASCII XOR with key, padding left the shortest element
|
25
|
+
# @param key [String] the element to xor the string with
|
26
|
+
# @return [String] the xored string (ASCII)
|
27
|
+
# @example
|
28
|
+
# 'hello'.alxor('key') # => "he\a\t\x16"
|
29
|
+
# 'key'.alxor('hello') # => "he\a\t\x16"
|
30
|
+
def alxor(key)
|
31
|
+
b1 = force_encoding('UTF-8')
|
32
|
+
b2 = key.force_encoding('UTF-8')
|
33
|
+
raise 'The string is not ASCII' unless b1.ascii_only?
|
34
|
+
raise 'The key is not ASCII' unless b2.ascii_only?
|
35
|
+
|
36
|
+
b1 = b1.chars.map(&:ord)
|
37
|
+
b2 = b2.chars.map(&:ord)
|
38
|
+
longest = [b1.length, b2.length].max
|
39
|
+
b1 = [0] * (longest - b1.length) + b1
|
40
|
+
b2 = [0] * (longest - b2.length) + b2
|
41
|
+
b1.zip(b2).map { |a, b| (a ^ b).chr }.join
|
42
|
+
end
|
43
|
+
|
44
|
+
# ASCII XOR with key (padding left) in place as described for {String#alxor}.
|
45
|
+
def alxor!(key)
|
46
|
+
replace(alxor(key))
|
47
|
+
end
|
48
|
+
|
49
|
+
# UTF-8 XOR with key, padding right the shortest element
|
50
|
+
# @param key [String] the element to xor the string with
|
51
|
+
# @return [String] the xored string (UTF-8)
|
52
|
+
# @example
|
53
|
+
# 'hello'.urxor('key') # => "\u0003\u0000\u0015lo"
|
54
|
+
# 'key'.urxor('hello') # => "\u0003\u0000\u0015lo"
|
55
|
+
def urxor(key)
|
56
|
+
b1 = unpack('U*')
|
57
|
+
b2 = key.unpack('U*')
|
58
|
+
longest = [b1.length, b2.length].max
|
59
|
+
b1 += [0] * (longest - b1.length)
|
60
|
+
b2 += [0] * (longest - b2.length)
|
61
|
+
b1.zip(b2).map { |a, b| a ^ b }.pack('U*')
|
62
|
+
end
|
63
|
+
|
64
|
+
# UTF-8 XOR with key (padding right) in place as described for {String#urxor}.
|
65
|
+
def urxor!(key)
|
66
|
+
replace(urxor(key))
|
67
|
+
end
|
68
|
+
|
69
|
+
# ASCII XOR with key, padding right the shortest element
|
70
|
+
# @param key [String] the element to xor the string with
|
71
|
+
# @return [String] the xored string (ASCII)
|
72
|
+
# @example
|
73
|
+
# 'hello'.arxor('key') # => "\x03\x00\x15lo"
|
74
|
+
# 'key'.arxor('hello') # => "\x03\x00\x15lo"
|
75
|
+
def arxor(key)
|
76
|
+
b1 = force_encoding('UTF-8')
|
77
|
+
b2 = key.force_encoding('UTF-8')
|
78
|
+
raise 'The string is not ASCII' unless b1.ascii_only?
|
79
|
+
raise 'The key is not ASCII' unless b2.ascii_only?
|
80
|
+
|
81
|
+
b1 = b1.chars.map(&:ord)
|
82
|
+
b2 = b2.chars.map(&:ord)
|
83
|
+
longest = [b1.length, b2.length].max
|
84
|
+
b1 += [0] * (longest - b1.length)
|
85
|
+
b2 += [0] * (longest - b2.length)
|
86
|
+
b1.zip(b2).map { |a, b| (a ^ b).chr }.join
|
87
|
+
end
|
88
|
+
|
89
|
+
# ASCII XOR with key (padding right) in place as described for {String#arxor}.
|
90
|
+
def arxor!(key)
|
91
|
+
replace(arxor(key))
|
92
|
+
end
|
93
|
+
end
|
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: 1.
|
4
|
+
version: 1.5.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: 2021-
|
11
|
+
date: 2021-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docopt
|
@@ -173,8 +173,10 @@ files:
|
|
173
173
|
- lib/ctf_party/flag.rb
|
174
174
|
- lib/ctf_party/hex.rb
|
175
175
|
- lib/ctf_party/leet.rb
|
176
|
+
- lib/ctf_party/misc.rb
|
176
177
|
- lib/ctf_party/rot.rb
|
177
178
|
- lib/ctf_party/version.rb
|
179
|
+
- lib/ctf_party/xor.rb
|
178
180
|
homepage: https://noraj.github.io/ctf-party/
|
179
181
|
licenses:
|
180
182
|
- MIT
|