crypto-toolbox 0.1.17 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/crypto-toolbox/analyzers/padding_oracle/analyzer.rb +16 -17
- data/lib/crypto-toolbox/analyzers/padding_oracle/oracles/tcp_oracle.rb +4 -7
- data/lib/crypto-toolbox/analyzers/utils/spell_checker.rb +8 -0
- data/lib/crypto-toolbox/crypt_buffer.rb +0 -5
- data/lib/crypto-toolbox/crypt_buffer/concerns/xor.rb +13 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37d4aab806c87b5df97642e506ea938733be2b79
|
4
|
+
data.tar.gz: 0527ceaba2da2046e998194405f3b7d5a48394d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5e20456aa954a252cf3c7407ecacbabb1cd09c53fbaa5773fc0468283f18a5a2f80a4ded360e83bffe84b7cd058120194fbb2191c04f915d23eaba0c5bb070d
|
7
|
+
data.tar.gz: 8e41fdd52797f51022df4a97abc30320df50e95f29038ffb96e844ee74fb53d4d7aa681eaf80aa99168f05d142cc4234efbc5856559ded55ad7c7016066dcc2e
|
@@ -15,11 +15,16 @@ module Analyzers
|
|
15
15
|
@oracle = oracle_class.new
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# start with the second to last block to manipulate the final block ( cbc xor behaviour )
|
19
|
+
# from there on we move to the left until we have used the first block (iv) to decrypt
|
20
|
+
# the second blick ( first plain text block )
|
21
|
+
#
|
22
|
+
# we have to manipulate the block before the one we want to change
|
23
|
+
# xxxxxxxxx xxxxxxxxx xxxxxxxxxx
|
24
|
+
# changing this byte ^- will change ^- this byte at decryption
|
19
25
|
def analyze(cipher)
|
20
26
|
blocks = CryptBuffer.from_hex(cipher).chunks_of(16)
|
21
27
|
|
22
|
-
# start with the second to last block to manipulate the final block ( cbc xor behaviour )
|
23
28
|
(blocks.length - 1).downto(1) do |block_index|
|
24
29
|
result_part = []
|
25
30
|
# manipulate each byte of the 16 byte block
|
@@ -50,10 +55,8 @@ module Analyzers
|
|
50
55
|
def apply_found_bytes(buf,cur_result,pad_index)
|
51
56
|
# first we have to apply all the already found bytes
|
52
57
|
|
53
|
-
|
54
58
|
# NOTE: to easily xor all already found byte and the current padding value
|
55
59
|
# We build up a byte-array with all the known values and "left-pad" them with zeros
|
56
|
-
|
57
60
|
other = ([0] * ( buf.length - cur_result.length)) + cur_result.map{|x| x ^ pad_index }
|
58
61
|
# => [0,0,0,...,cur[n] ^ pad_index,... ]
|
59
62
|
buf.xor(other)
|
@@ -64,22 +67,18 @@ module Analyzers
|
|
64
67
|
#iv, first, second, last
|
65
68
|
jot(cur_result.inspect,debug: true)
|
66
69
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
forge_buf = apply_found_bytes(
|
70
|
+
# apply all the current-result bytes to the block corresponding to <block_index>
|
71
|
+
# and store the result in a buffer we will mess with
|
72
|
+
#
|
73
|
+
forge_buf = apply_found_bytes(blocks[block_index - 1],cur_result,pad_index)
|
71
74
|
|
72
75
|
1.upto 256 do |guess|
|
73
|
-
bytes
|
74
|
-
|
76
|
+
# the bytes from the subset we will send to the padding oracle
|
77
|
+
subset = blocks[0,block_index+1]
|
78
|
+
subset[block_index -1 ] = forge_buf.xor_at([guess,pad_index], -1 * pad_index)
|
79
|
+
|
80
|
+
input = subset.map(&:bytes).flatten
|
75
81
|
|
76
|
-
bytes[-1 * pad_index] = new_byte
|
77
|
-
|
78
|
-
oracle_blocks = blocks[0,block_index+1].map(&:bytes)
|
79
|
-
oracle_blocks[block_index -1 ] = bytes
|
80
|
-
|
81
|
-
input = oracle_blocks.flatten
|
82
|
-
|
83
82
|
# skip the first correct guess on the first iteration of the first block
|
84
83
|
# otherwise the resulting ciphertext would eq the original input
|
85
84
|
#next if input == blocks.map(&:bytes).flatten
|
@@ -26,16 +26,16 @@ module Analyzers
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def valid_padding?(input,block_amount)
|
29
|
-
|
30
|
-
!ret.zero?
|
29
|
+
! send_msg(input, block_amount).zero?
|
31
30
|
end
|
32
31
|
|
33
32
|
private
|
34
33
|
def send_msg(input,block_amount)
|
35
34
|
connect unless connected?
|
36
35
|
|
37
|
-
msg = ([block_amount] + input + [0]).map(&:chr)
|
38
|
-
|
36
|
+
msg = ([block_amount] + input + [0]).map(&:chr).join
|
37
|
+
sleep 0.01
|
38
|
+
@socket.write(msg)
|
39
39
|
@socket.read(2).to_i
|
40
40
|
end
|
41
41
|
def connected?
|
@@ -46,6 +46,3 @@ module Analyzers
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
@@ -28,6 +28,14 @@ Some statistics about it:
|
|
28
28
|
words = str.split(" ").select{|w| @dict.check?(w) }
|
29
29
|
end
|
30
30
|
|
31
|
+
def human_word?(str)
|
32
|
+
@dict.check?(str)
|
33
|
+
end
|
34
|
+
|
35
|
+
def human_phrase?(string)
|
36
|
+
string.split(" ").all?{|part| human_word?(part)}
|
37
|
+
end
|
38
|
+
|
31
39
|
def suggest(str)
|
32
40
|
@dict.suggest(str)
|
33
41
|
end
|
@@ -13,7 +13,8 @@ module CryptBufferConcern
|
|
13
13
|
when true
|
14
14
|
# map our current data to xor all inputs with the given bytepos.
|
15
15
|
# all other bytes are kept as they were
|
16
|
-
|
16
|
+
abs_pos = normalize_pos(pos)
|
17
|
+
tmp = bytes.map.with_index{|b,i| i == abs_pos ? xor_multiple(b,input.to_ary) : b }
|
17
18
|
CryptBuffer(tmp)
|
18
19
|
else
|
19
20
|
tmp = bytes
|
@@ -50,6 +51,17 @@ module CryptBufferConcern
|
|
50
51
|
x = hex2bytes(hex)
|
51
52
|
xor_bytes(x)
|
52
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def xor_multiple(byte,bytes)
|
57
|
+
|
58
|
+
([byte] + bytes).reduce(:^)
|
59
|
+
end
|
60
|
+
def normalize_pos(pos)
|
61
|
+
(pos < 0) ? (length() + pos ) : pos
|
62
|
+
end
|
63
|
+
|
64
|
+
|
53
65
|
end
|
54
66
|
|
55
67
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crypto-toolbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dennis Sivia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aes
|