class CryptoToolchain::Tools::CbcPaddingOracleAttack

Attributes

blocksize[R]
oracle[R]

Public Class Methods

new(oracle: , blocksize: 16) click to toggle source
# File lib/crypto_toolchain/tools/cbc_padding_oracle_attack.rb, line 5
def initialize(oracle: , blocksize: 16)
  @oracle = oracle
  @blocksize = blocksize
end

Public Instance Methods

execute() click to toggle source
# File lib/crypto_toolchain/tools/cbc_padding_oracle_attack.rb, line 10
def execute
  _blocks = ciphertext.in_blocks(blocksize)
  _blocks[1..-1].map.with_index(1) do |block, i|
    preceding = _blocks[i - 1]
    intermediate = intermediate_block(preceding: preceding, target: block)
    intermediate ^ preceding
  end.
    join.
    without_pkcs7_padding(blocksize)
end

Private Instance Methods

ciphertext() click to toggle source
# File lib/crypto_toolchain/tools/cbc_padding_oracle_attack.rb, line 25
def ciphertext
  @ciphertext ||= oracle.ciphertext
end
intermediate_block(preceding: , target: ) click to toggle source
# File lib/crypto_toolchain/tools/cbc_padding_oracle_attack.rb, line 31
def intermediate_block(preceding: , target: )
  range = Array(0...blocksize).reverse
  range.each_with_object(0x00.chr * blocksize) do |index, memo|
    pad = blocksize - index
    padding = (pad.chr * pad).rjust(blocksize, 0x00.chr)
    candidate = padding ^ memo ^ preceding
    (0..255).each do |guess|
      next if (preceding.bytes[index] == guess && index == blocksize - 1)
      candidate = padding ^ memo
      candidate[index] = guess.chr
      attempt = candidate + target
      if oracle.execute(attempt)
        memo[index] = (guess ^ pad).chr
        break
      end
    end
  end
end