Permalink
Browse files

Major update: re-named most of the files, added a README.md file, and…

… added a decryption module. This change breaks compatibility with previous versions, unfortunately.
  • Loading branch information...
1 parent 0b21db6 commit a5cfad76ada97862bdc1eb558937f03ad96d4ee6 iagox86 committed Dec 18, 2016
Showing with 323 additions and 341 deletions.
  1. +33 −31 Demo.rb
  2. +0 −111 DoTests.rb
  3. +0 −69 LocalTestModule.rb
  4. +141 −86 Poracle.rb
  5. +135 −0 README.md
  6. +0 −36 RemoteTestModule.rb
  7. +14 −8 RemoteTestServer.rb
View
@@ -1,3 +1,5 @@
+# encoding: ASCII-8BIT
+
##
# Demo.rb
# Created: February 10, 2013
@@ -7,36 +9,36 @@
##
#
require 'httparty'
-require './poracle'
-
-class DemoModule
- attr_reader :iv, :data, :blocksize
-
- NAME = "DemoModule(tm)"
-
- # This function should load @data, @iv, and @blocksize appropriately
- def initialize()
- @data = HTTParty.get("http://localhost:20222/encrypt").parsed_response
- # Parse 'data' here
- @data = [@data].pack("H*")
- @iv = nil
- @blocksize = 16
- end
-
- # This should make a decryption attempt and return true/false
- def attempt_decrypt(data)
- result = HTTParty.get("http://localhost:20222/decrypt/#{data.unpack("H*").pop}").parsed_response
-
- # Match 'result' appropriately
- return result !~ /Fail/
- end
-
- # Optionally define a character set, with the most common characters first
- def character_set()
- return ' eationsrlhdcumpfgybw.k:v-/,CT0SA;B#G2xI1PFWE)3(*M\'!LRDHN_"9UO54Vj87q$K6zJY%?Z+=@QX&|[]<>^{}'.chars.to_a
- end
-end
+require './Poracle'
+
+BLOCKSIZE = 16
-mod = DemoModule.new
-puts "DECRYPTED: #{Poracle.decrypt(mod, mod.data, mod.iv, true)}"
+poracle = Poracle.new(BLOCKSIZE, true) do |data|
+ url = "http://localhost:20222/decrypt/#{data.unpack('H*').pop()}"
+ result = HTTParty.get(url)
+
+ # Return
+ result.parsed_response !~ /Fail/
+end
+data = HTTParty.get("http://localhost:20222/encrypt").parsed_response
+print "Trying to decrypt: %s" % data
+
+result = poracle.decrypt([data].pack('H*'))
+puts("-----------------------------")
+puts("Decryption result")
+puts("-----------------------------")
+puts result
+puts("-----------------------------")
+puts()
+
+data = "The most merciful thing in the world, I think, is the inability of the human mind to correlate all its contents."
+print "Trying to encrypt: %s" % data
+result = poracle.encrypt(data)
+
+puts("-----------------------------")
+puts("Encrypted string")
+puts("-----------------------------")
+puts result.unpack('H*')
+puts("-----------------------------")
+puts()
View
@@ -1,111 +0,0 @@
-$LOAD_PATH << File.dirname(__FILE__) # A hack to make this work on 1.8/1.9
-
-require 'benchmark'
-require 'openssl'
-
-require 'LocalTestModule'
-require 'RemoteTestModule'
-require 'Poracle'
-
-if(ARGV[0] == 'remote')
- # Attempt a remote check
- puts("Starting remote test (this requires RemoteTestServer.rb to be running on localhost:20222)")
- begin
- mod = RemoteTestModule.new
-
- time = Benchmark.measure do
- puts Poracle.decrypt(mod, mod.data, mod.iv, true)
- end
-
- puts("Guesses: #{Poracle.guesses}")
- puts("Time: #{time}")
-
- rescue Errno::ECONNREFUSED => e
- puts(e.class)
- puts("Couldn't connect to remote server: #{e}")
- end
-end
-
-# Perform local checks
-ciphers = OpenSSL::Cipher::ciphers.grep(/cbc/)
-srand(123456)
-
-passes = 0
-failures = 0
-
-print("> AES-256-CBC with known data... ")
-mod = LocalTestModule.new("AES-256-CBC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
-d = Poracle.decrypt(mod, mod.ciphertext, mod.iv, true)
-if(d == "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
- passes += 1
- puts "Passed!"
-else
- failures += 1
- puts "Failed!"
- puts "Expected: ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- puts "Received: #{d}"
- puts
- puts "First test failed; bailing"
- exit
-end
-
-# Test strings that require backtracking
-0.upto(512) do
- print("> AES-128-CBC that requires backtracking...")
-
- data_length = rand(15).to_i + 1
- data = (1..data_length).map{(rand(0x60) + 0x20).to_i.chr}.join
- cipher = "AES-128-CBC"
- #iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00"
- iv = (1..16).map{rand(255).to_i.chr}.join
- iv[14] = ((16 - data_length) ^ 2).chr
- mod = LocalTestModule.new(cipher, data, nil, iv)
- d = Poracle.decrypt(mod, mod.ciphertext, mod.iv, false)
- if(d == data)
- passes += 1
- puts "Passed!"
- else
- failures += 1
- puts "Failed!"
- end
-end
-
-# Do a bunch of very short strings
-(0..512).to_a.each do |i|
- data = (0..rand(8)).map{rand(255).to_i.chr}.join
- cipher = ciphers.shuffle[0]
- print("> #{cipher} with random short data... ")
- mod = LocalTestModule.new(cipher, data, nil, nil)
- d = Poracle.decrypt(mod, mod.ciphertext, mod.iv)
- if(d == data)
- passes += 1
- puts "Passed!"
- else
- failures += 1
- puts "Failed!"
- end
-end
-
-# Try the different ciphers
-ciphers.each do |cipher|
- (0..128).to_a.shuffle[0, 8].each do |i|
- print("> #{cipher} with random data (#{i} bytes)... ")
-
- data = (0..i).map{(rand(0x7E - 0x20) + 0x20).chr}.join
- mod = LocalTestModule.new(cipher, data)
- d = Poracle.decrypt(mod, mod.ciphertext, mod.iv, false)
- if(d == data)
- passes += 1
- puts "Passed!"
- else
- failures += 1
- puts "Failed!"
- end
- end
-end
-
-puts("Ciphers tested: #{ciphers.join(", ")}")
-puts("Tests passed: #{passes}")
-puts("Tests failed: #{failures}")
-
-
View
@@ -1,69 +0,0 @@
-## LocaltestModule.rb
-# Created: December 10, 2012
-# By: Ron Bowes
-#
-# A very simple application that's vulnerable to a padding oracle attack. It's
-# initialized with data and a mode, and the decrypt() function will try to
-# decrypt the given ciphertext with the given key.
-##
-
-require 'openssl'
-
-class LocalTestModule
- attr_reader :iv, :ciphertext, :blocksize
-
- NAME = "LocalTestModule(tm)"
-
- def initialize(mode, data, key = nil, iv = nil, verbose = false, delay = 0)
- # Save these variables
- @mode = mode
- @verbose = verbose
- @delay = delay
-
- # Create the cipher
- c = OpenSSL::Cipher::Cipher.new(mode)
-
- # Set up the required variables
- @blocksize = c.block_size
- @key = key.nil? ? (1..c.key_len).map{rand(255).chr}.join : key
- @iv = iv.nil? ? (1..c.iv_len).map{rand(255).chr}.join : iv
-
- # Set up the cipher
- c.encrypt
- c.key = @key
- c.iv = @iv
-
- @ciphertext = c.update(data) + c.final
-
- if(verbose)
- puts()
- puts("-" * 80)
- puts("Generated test data: #{data} (#{data.unpack("H*")})")
- puts("-" * 80)
- puts("mode: #{mode}")
- puts("key: #{@key.unpack("H*")}")
- puts("iv: #{@iv.unpack("H*")}")
- puts("enc: #{@ciphertext.unpack("H*")}")
- puts("-" * 80)
- end
- end
-
- def attempt_decrypt(ciphertext)
- begin
- if(@delay > 0)
- sleep(@delay)
- end
-
- c = OpenSSL::Cipher::Cipher.new(@mode)
- c.decrypt
- c.key = @key
- c.update(ciphertext)
- c.final()
-
- return true
- rescue OpenSSL::Cipher::CipherError
- return false
- end
- end
-end
-
Oops, something went wrong.

0 comments on commit a5cfad7

Please sign in to comment.