flag ticket
「チケットをご用意することができませんでした」
JSONをAES-CBCで暗号化したのがhexでcookieに入る
cryptopalsのChallenge 16で書いたのを流用
code:chal16.rb
# CBC bitflipping attacks
require 'openssl'
class Oracle
def initialize
@key = random_bytes
end
def encrypt number
encrypt_cbc padding_pkcs7('{"is_hit": false, "number": ' + number.to_s + '}', 16)
end
def decrypt_and_validate encrypted
decrypt_cbc(encrypted).include? 'true'
end
def random_bytes length = 16
length.times.map { (0x00..0xFF).to_a.sample.chr }.join
end
def padding_pkcs7 str, len # From Challenge 9
add = len - str.size % len
add == len ? str : str + add.chr * add
end
def encrypt_cbc plain
iv = random_bytes
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.encrypt
cipher.padding = 0
cipher.key = @key
cipher.iv = iv
iv + cipher.update(plain) + cipher.final
end
def decrypt_cbc encrypted
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
cipher.key = @key
cipher.iv = encrypted.byteslice(0...16)
cipher.update(encrypted.byteslice(16..-1)) + cipher.final
end
end
class Attacker
def initialize oracle
@oracle = oracle
end
def attack
number = 34259999999
# original_enc_bytes = @oracle.encrypt(number).bytes
puts "Before:"
puts original_enc_bytes.each_slice(16).to_a1.map { |x| x.to_s(2).rjust 8, '0' }.join ' ' # puts @oracle.decrypt_cbc(original_enc_bytes.pack("C*")).bytes.each_slice(16).to_a.map { |x| x.map { |y| y.to_s(2).rjust 8, '0' }.join " " }2 modified_enc_bytes = original_enc_bytes
pos = ('{"is_hit": false, "number":').index("false")
# modified_enc_bytes0 ^= 3 modified_enc_bytespos+0 ^= 'f'.ord ^ ' '.ord modified_enc_bytespos+1 ^= 'a'.ord ^ 't'.ord modified_enc_bytespos+2 ^= 'l'.ord ^ 'r'.ord modified_enc_bytespos+3 ^= 's'.ord ^ 'u'.ord modified_enc_bytespos+1 ^= 'e'.ord ^ 'e'.ord p modified_enc_bytes.pack("C*").unpack("H*")
puts "After:"
puts modified_enc_bytes.each_slice(16).to_a1.map { |x| x.to_s(2).rjust 8, '0'}.join ' ' puts @oracle.decrypt_cbc(modified_enc_bytes.pack("C*")).bytes.each_slice(16).to_a.map { |x| x.map { |y| y.to_s(2).rjust 8, '0' }.join " " }2 puts @oracle.decrypt_cbc(modified_enc_bytes.pack("C*"))
@oracle.decrypt_and_validate modified_enc_bytes.pack("C*")
end
end
attacker = Attacker.new Oracle.new
puts attacker.attack
KosenCTF{padding_orca1e_is_common_sense}
Padding Oracleで解いた人が多いらしい