记一道密码学Padding Oracle Attack的题

前段时间打的某个ctf里遇到的...由于一些小问题当时并没有做出来...真的真的只差一点点了

嗨呀好气quq

那那那还是把解题的脚本发出来吧..如果有啥问题还请大佬指正呢..

只是表述一下思路 并不能实际运行...很多地方为了表述更清楚并没有按基本法来(逃

下文的0x00 == '\x00', 以此类推

#!/usr/bin/ruby
require "base64"  
require "..."

/*
  A demo for AES CBC Padding Oracle Attack
  author: Minty_He
*/

LENGTH = 16  
origin_iv = "AAAAAAAAAAAAAAAA" //初始iv  
flag = Base64.decode64("flag") //密文

/*  
    ...
    ...
    cchunk1 = flag[0..15]
    cchunk2 = flag[16..31]
    将密文分块 
    16个为一块
    ...
    ...
*/ 

def get_result(iv, chunk)  
  cipher = chunk
  // 使用cipher和当前iv调用nc
  result = file.readline
  // result是通过nc获取到的解密成功与否的结果
  // 如果返回结果为"Decrpytion Done" 说明解密成功,函数返回true
  return true or false
end

def get_plaintext(origin_iv, chunk)  
/*
  主要逻辑部分:
  从最后一位开始从右向左遍历整个块
  通过get_result返回的值猜测当前位iv(从0~255)
  如果猜测成功,当前位iv xor 0xpos xor 当前位原iv 结果即为当前位的明文
*/
  plaintext = 0x00 * LENGTH //储存明文
  mid = 0x00 * LENGTH //mid储存经过aes key解密后还未与iv进行xor运算的中间值
   //从块末往前遍历,pos表示在跑当前块的倒数第几位
  for pos in 1..16
    string = 0x00 * (length - pos) + (0xpos * pos) 
    /*
      string就是我们构造出来的明文
      string的构造为0x000000.......pos
      如果pos为1,string即为0x000000......01
      如果pos为2,string即为0x000000....0202
      依此类推
    */
    //开始爆破iv
    for char in 0..255
      iv = 0x00 * (length - pos) + 0xchar + (mid[(length - pos + 1)..15] xor (0xpos * (pos - 1))) //这里需要检查是否越界,越界返回空字符串
      if get_result(iv, chunk)
        mid[length - pos] = iv[length - pos] xor 0xpos
        plaintext[length - pos] = mid[length - pos] xor origin_iv[length - pos]
        break
      end
    end
  return plaintext
end

plaintext = get_plaintext(origin_iv, cchunk1) + get_plaintext(cchunk1, cchunk2) +  
            get_plaintext(cchunk2, cchunk3) + get_plaintext(cchunk3, cchunk4) +
            .......................................................................

附上题目:

#!/usr/bin/ruby -w
require 'openssl'  
require 'base64'

def banner()  
    puts ' ____________________________________________'
    puts '|                                            |'
    puts '| Welcome to our secure communication system |'
    puts '| Our system is secured by AES               |'    
    puts '| So...No key! No Message!                   |'
    puts '|____________________________________________|'
    puts ''
end

def option()  
    puts '1. Get the secret message.'
    puts '2. Encrypt the message'
    puts '3. Decrypt the message.'
    puts 'Give your option:'
    STDOUT.flush
    op=gets
    return op.to_i
end

def init()  
    file_key=File.new("./aeskey","r")
    $key=file_key.gets
    file_key.close()
end  
def aes_encrypt(iv,data)  
    cipher = OpenSSL::Cipher::AES.new(256, :CBC)
    cipher.encrypt
    cipher.key = $key
    cipher.iv  = iv
    cipher.update(data) << cipher.final
end

def aes_decrypt(iv,data)  
    cipher = OpenSSL::Cipher::AES.new(256, :CBC)
    cipher.decrypt
    cipher.key = $key
    cipher.iv  = iv
    data = cipher.update(data) << cipher.final
end

def output_secret()  
    file_secret=File.new("./flag","r")
    secret=file_secret.gets
    file_secret.close
    secret_enc=aes_encrypt("A"*16,secret)
    secret_enc_b64=Base64.encode64(secret_enc)
    puts secret_enc_b64 
end

init  
banner  
while true do  
    begin
        op=option
        if op==1
            output_secret
        elsif op==2
            puts "IV:"
            STDOUT.flush
            iv=Base64.decode64(gets)
            puts "Data:"
            STDOUT.flush
            data=Base64.decode64(gets)
            data_enc=aes_encrypt iv,data
            puts Base64.encode64(data_enc)
            puts "Encrytion Done"    
            STDOUT.flush
        elsif op==3
            puts "IV:"
            STDOUT.flush
            iv=Base64.decode64(gets)
            puts "Data:"
            STDOUT.flush
            data=Base64.decode64(gets)
            data_dec=aes_decrypt iv,data
            puts "Decrpytion Done"
            STDOUT.flush
        else
            puts 'Wrong Option'
            STDOUT.flush
        end
    rescue Exception => e  
        puts e.message
        STDOUT.flush
        retry
    end
end

于是又水了一篇呢 溜了溜了

点击右边的按钮加载评论,如果无法加载那估计是被墙啦..你看着办w