crypto-toolbox 0.1.6 → 0.1.7

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
  SHA1:
3
- metadata.gz: 90662f9ce9a68130e6aec3b0a54e6026489d07be
4
- data.tar.gz: b58322bbce9f43e2bd7ae861768ebfaeb3a6ebec
3
+ metadata.gz: cb26fa406648e8e856c7aaf45c86b9c78b6cff6d
4
+ data.tar.gz: c9dcc5cd246e4547fd3e22c8be90725dd496aa08
5
5
  SHA512:
6
- metadata.gz: d2786c46319239decdb33da755f9581d310a86538ef33f9f0a3dc22f683f4b8db27d098331a637edb58832ae8aa49e79d87558e136ee1a30f56804cd138c23c9
7
- data.tar.gz: d3499d2c7e9ab1507bd125ece8892c85090995c76a1b3a6a6d06ce7172e8b39b198a5397bee1db14f4f7e83d99f93a49d432bdfae006bff317ccec4e537a516c
6
+ metadata.gz: 45e036a7da35bcead7b46b3036de35d73f0cb7642f4f6cc9a8edb316372b6304134b2a18babbad1bd044fc0d75d1572c64ccb18d52c2667bd10bb9a02056b493
7
+ data.tar.gz: 129d788d0a7139a2e2399c496cb83522ead7ff6c6f6c61530bb1c1576f7ec8f41277b7378e9ea5ae289c59db4563e35978cd47d372fb818ebf0227cae7efa597
@@ -0,0 +1,102 @@
1
+ require 'crypto-toolbox/analyzers/padding_oracle/oracles/http_oracle.rb'
2
+ require 'crypto-toolbox/analyzers/padding_oracle/oracles/tcp_oracle.rb'
3
+
4
+
5
+ module Analyzers
6
+ module PaddingOracle
7
+
8
+ class Analyzer
9
+ class FailedAnalysis < RuntimeError; end
10
+ attr_reader :result
11
+
12
+
13
+ def initialize(oracle_class = ::Analyzers::PaddingOracle::Oracles::TcpOracle)
14
+ @result = [ ]
15
+ @oracle = oracle_class.new
16
+ end
17
+
18
+
19
+ def analyze(cipher)
20
+ blocks = CryptBuffer.from_hex(cipher).chunks_of(16)
21
+
22
+ # start with the second to last block to manipulate the final block ( cbc xor behaviour )
23
+ (blocks.length - 1).downto(1) do |block_index|
24
+ result_part = []
25
+ # manipulate each byte of the 16 byte block
26
+ 1.upto(blocks[block_index -1 ].length) do |pad_index|
27
+ @oracle.connect
28
+
29
+ jot("processing byte #{pad_index} in block: #{block_index - 1} => #{block_index}",debug: true)
30
+ byte = read_byte(pad_index,result_part,blocks,block_index)
31
+ result_part.unshift byte
32
+
33
+ @oracle.disconnect
34
+ end
35
+ result.unshift result_part
36
+ end
37
+ jot(CryptBuffer(result.flatten).chars.inspect,debug: false)
38
+ jot("stripping padding!",debug: true)
39
+ jot(CryptBuffer(result.flatten).strip_padding.str,debug: false)
40
+ end
41
+
42
+
43
+ private
44
+ def jot(message, debug: false)
45
+ if debug == false || ENV["DEBUG_ANALYSIS"]
46
+ puts message
47
+ end
48
+ end
49
+
50
+ def apply_found_bytes(buf,cur_result,pad_index)
51
+ # first we have to apply all the already found bytes
52
+
53
+
54
+ # NOTE: to easily xor all already found byte and the current padding value
55
+ # We build up a byte-array with all the known values and "left-pad" them with zeros
56
+
57
+ other = ([0] * ( buf.length - cur_result.length)) + cur_result.map{|x| x ^ pad_index }
58
+ # => [0,0,0,...,cur[n] ^ pad_index,... ]
59
+ buf.xor(other)
60
+ end
61
+
62
+
63
+ def read_byte(pad_index,cur_result,blocks,block_index)
64
+ #iv, first, second, last
65
+ jot(cur_result.inspect,debug: true)
66
+
67
+ # create a copy to mess with without changing to current block
68
+ forge_buf = blocks[block_index - 1].dup
69
+
70
+ forge_buf = apply_found_bytes(forge_buf,cur_result,pad_index)
71
+
72
+ 1.upto 256 do |guess|
73
+ bytes = forge_buf.bytes.dup
74
+ new_byte = forge_buf[-1 * pad_index] ^ guess ^ pad_index
75
+
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
+ # skip the first correct guess on the first iteration of the first block
84
+ # otherwise the resulting ciphertext would eq the original input
85
+ #next if input == blocks.map(&:bytes).flatten
86
+ next if guess == pad_index && guess == 1 && block_index == 2
87
+
88
+ block_amount = block_index + 1
89
+ if @oracle.valid_padding?(input,block_amount)
90
+ return guess
91
+ end
92
+
93
+ end
94
+
95
+ raise FailedAnalysis, "No padding found... this should neve happen..."
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+
102
+
@@ -0,0 +1,37 @@
1
+
2
+ module Analyzers
3
+ module PaddingOracle
4
+ module Oracles
5
+ class HttpOracle
6
+ def initialize
7
+ require 'net/http'
8
+ @domain = "crypto-class.appspot.com"
9
+ @uri_base = "/po?er="
10
+ @port = 80
11
+ end
12
+ def connect
13
+ true
14
+ end
15
+ def disconnect
16
+ true
17
+ end
18
+ def valid_padding?(input,block_amount)
19
+
20
+ uri = @uri_base + input.hex
21
+
22
+ Net::HTTP.start(@domain,@port) do |http|
23
+ res = http.request(Net::HTTP::Get.new(uri))
24
+ code = res.code.to_i
25
+ sleep 0.001
26
+
27
+ # -> howto check this ? (block_index == 3 && pad_index == 9 && code == 200 )
28
+ (code == 404 || code == 200)
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'crypto-toolbox'
4
+
5
+ module Analyzers
6
+ module PaddingOracle
7
+ module Oracles
8
+
9
+ class TcpOracle
10
+ def initialize
11
+ require "socket"
12
+ require_relative "./tcp_oracle.rb"
13
+
14
+ @hostname = '54.165.60.84'
15
+ @port = 80
16
+ @socket = nil
17
+ end
18
+ def connect
19
+ @socket = TCPSocket.open(@hostname,@port)
20
+ end
21
+
22
+ def disconnect
23
+ if @socket
24
+ @socket.close
25
+ end
26
+ end
27
+
28
+ def valid_padding?(input,block_amount)
29
+ ret = send_msg(input, block_amount)
30
+ !ret.zero?
31
+ end
32
+
33
+ private
34
+ def send_msg(input,block_amount)
35
+ connect unless connected?
36
+
37
+ msg = ([block_amount] + input + [0]).map(&:chr)
38
+ @socket.write(msg.join(""))
39
+ @socket.read(2).to_i
40
+ end
41
+ def connected?
42
+ !!@socket
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+
@@ -0,0 +1 @@
1
+ require 'crypto-toolbox/analyzers/padding_oracle/analyzer.rb'
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.6
4
+ version: 0.1.7
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-04-20 00:00:00.000000000 Z
11
+ date: 2015-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aes
@@ -48,6 +48,10 @@ extra_rdoc_files: []
48
48
  files:
49
49
  - bin/break-vigenere-xor
50
50
  - lib/crypto-toolbox.rb
51
+ - lib/crypto-toolbox/analyzers/padding_oracle.rb
52
+ - lib/crypto-toolbox/analyzers/padding_oracle/analyzer.rb
53
+ - lib/crypto-toolbox/analyzers/padding_oracle/oracles/http_oracle.rb
54
+ - lib/crypto-toolbox/analyzers/padding_oracle/oracles/tcp_oracle.rb
51
55
  - lib/crypto-toolbox/analyzers/vigenere_xor.rb
52
56
  - lib/crypto-toolbox/ciphers/caesar.rb
53
57
  - lib/crypto-toolbox/ciphers/rot13.rb