require_relative '../util' require 'set' SNIPPET = "alert('MZA who was that?');\n".bytes KEY = 'YELLOW SUBMARINE'.bytes IV = Array.new(16, 0) MAC = '296b8d7cb78a243dda4d0a61d33bbdd1'.freeze assert(cbc_mac(pkcs7pad(SNIPPET, 16), KEY, IV) == MAC) # alert('Ayo, the Wu is back!');//???????????????????????????????. # | | | # E(0 xor M1) E(C1 xor M2) E(C2 xor M3) E(C3 xor M4) == MAC charset = (32..126).to_a base = "alert('Ayo, the Wu is back!');//".bytes M1, M2 = base.each_slice(16).to_a C1 = aes_ecb_encrypt(M1, KEY) C2 = aes_ecb_encrypt(xor_buffers(C1, M2), KEY) message = nil charset.repeated_combination(16) do |m3| c3 = aes_ecb_encrypt(xor_buffers(C2, m3), KEY) m4 = xor_buffers(aes_ecb_decrypt(hexdecode(MAC), KEY), c3) next unless m4[-1] == 0x01 && m4[-2] != 0x02 # valid PKCS7 padding message = M1 + M2 + m3 + m4 break end M = pkcs7unpad(message) info(str(M).inspect) assert(cbc_mac(pkcs7pad(M, 16), KEY, IV) == MAC) File.open('50.js', 'wb') { |f| f.print(str(M)) }