Challenge 9:
import binascii BLOCK_SIZE = 16 def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s)).encode()*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def main(): pt = b"YELLOW SUBMARINE" print (PKCS7_padding(pt)) if __name__ == "__main__": main()
Challenge 10:
from Crypto.Cipher import AES import base64 def cbc_decrypt(ct,passphrase,iv): aes = AES.new(passphrase, AES.MODE_CBC, iv) return aes.decrypt(base64.b64decode(ct)) def main(): with open("10.txt","r") as file: s = "".join(line[:-1] for line in file) passphrase = b"YELLOW SUBMARINE" iv = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" print (cbc_decrypt(s,passphrase,iv)) if __name__ == "__main__": main()
Challenge 11:
from Crypto.Cipher import AES from os import urandom from random import randint from base64 import b64encode, b64decode KEY_SIZE = 16 IV_SIZE = 16 BLOCK_SIZE = 16 PLAINTEXT_SIZE = 1337 def genkey(size): return urandom(size) def appendbytes(pt): prefix = randint(5,10) suffix = randint(5,10) return urandom(prefix) + pt + urandom(suffix) def genIV(): return urandom(IV_SIZE) def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s)).encode()*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def encrypt(pt): key = genkey(KEY_SIZE) pt = PKCS7_padding(pt) iv = genIV() if randint(0,1) == 0: aes = AES.new(key, AES.MODE_ECB) mode = "ECB" else: aes = AES.new(key, AES.MODE_CBC, iv) mode = "CBC" ct = b64encode(aes.encrypt(pt)) return (ct,mode) def AES_ECB_Score(ct): ct = b64decode(ct) blocks = [ct[i:i + BLOCK_SIZE] for i in range(0, len(ct), BLOCK_SIZE)] score = len(blocks) - len(set(blocks)) return score def main(): pt = appendbytes(urandom(PLAINTEXT_SIZE)) ct = encrypt(pt+b"A"*1337) print ("Ciphertext > " + str(ct[0]) + "\nAES mode used > " + str(ct[1])) if AES_ECB_Score(ct[0]) > 0: print ("Guessed mode > ECB") else: print ("Guessed mode > CBC") if __name__ == '__main__': main()
Challenge 12:
from Crypto.Cipher import AES from os import urandom import base64 import string KEY_SIZE = 16 IV_SIZE = 16 BLOCK_SIZE = 16 HOW_MANY_BLOCKS = 9 PT_LEN = HOW_MANY_BLOCKS * BLOCK_SIZE def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s)).encode()*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def enc(pt,key): pt = PKCS7_padding(pt) aes = AES.new(key, AES.MODE_ECB) ct = aes.encrypt(pt) return ct def brute_force_ECB(pt,key): known_bytes = b"" for i in range(0,PT_LEN): cur = enc(b'A'*(PT_LEN - 1 - i) + pt,key)[:(PT_LEN -1 )] for byte in string.printable.encode(): if enc(b'A'*(PT_LEN - 1 - i) + known_bytes + chr(byte).encode(),key)[:(PT_LEN-1)] == cur: known_bytes += chr(byte).encode() break return known_bytes.decode() def main(): pt = base64.b64decode('''Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK''') key = urandom(KEY_SIZE) print (brute_force_ECB(pt,key)) if __name__ == '__main__': main()
Challenge 13:
from Crypto.Cipher import AES from os import urandom import base64 import random import re import sys BLOCK_SIZE =16 KEY_SIZE = 16 key = urandom(KEY_SIZE) def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s))*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def enc(pt): pt = PKCS7_padding(pt) aes = AES.new(key, AES.MODE_ECB) return aes.encrypt(pt.encode()) def dec(ct): aes = AES.new(key, AES.MODE_ECB) return aes.decrypt(ct).decode() def parser(cookie): parts = cookie.split("&") dict = {} for part in parts: key_value = part.split("=") dict[key_value[0]] = key_value[1] return dict def profile(email): if re.match(".[&=].",email): return "Invalid characters" profile = { 'email':email, 'uid':1337, 'role':'user', } ret = "email={}&uid={}&role={}".format(profile["email"],profile["uid"],profile["role"]) return ret def ECB_cut_and_paste(profile,newrole): return dec(enc(profile)[:32] + enc("admin"))[:-11] def main(): email = "42@mail.com" #Since len(email) = 11 the second block of enc(profile(email)) will end in "role=" #To create a valid admin profile we'll take the first 2 blocks of enc(profile(email)) and concat enc("admin") #The decrypted result will be a valid admin profile #block1 block2 block3 #email=42@mail.co m&uid=1337&role= admin(padding) admin_profile = parser(ECB_cut_and_paste(profile(email),"admin")) print ("Registered the email > {}\nCorrespondent uid > {}\nRespective role > {}".format(admin_profile["email"],admin_profile["uid"],admin_profile["role"])) if __name__ == '__main__': main()
Challenge 14:
from Crypto.Cipher import AES from os import urandom from random import randint import base64 import string KEY_SIZE = 16 IV_SIZE = 16 BLOCK_SIZE = 16 HOW_MANY_BLOCKS = 9 PT_LEN = HOW_MANY_BLOCKS * BLOCK_SIZE def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s)).encode()*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def enc(pt,key): pt = PKCS7_padding(pt) aes = AES.new(key, AES.MODE_ECB) ct = aes.encrypt(pt) return ct def brute_force_ECB(pt,key): known_bytes = b"" flag = enc(b"STIMULUSRESPONSE",key) for i in range(0,PT_LEN): cur_try = b"" while True: cur_try = enc(urandom(randint(0,255)) + b"STIMULUSRESPONSE" + b"A"*(PT_LEN - 1 - i) + pt,key) if flag in cur_try: break for byte in string.printable.encode(): while True: cur_byte = enc(urandom(randint(0,255)) + b"STIMULUSRESPONSE" + b"A"*(PT_LEN-1-i) + known_bytes + chr(byte).encode(),key) if flag in cur_byte: break if cur_byte.split(flag)[1][:PT_LEN - 1] == cur_try.split(flag)[1][:PT_LEN - 1]: known_bytes += chr(byte).encode() break return known_bytes.decode() def main(): pt = base64.b64decode('''Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK''') key = urandom(KEY_SIZE) print (brute_force_ECB(pt,key)) if __name__ == '__main__': main()
Challenge 15:
BLOCK_SIZE = 16 def PKCS7_padding_validation(pt): if len(pt)%BLOCK_SIZE != 0: return "Invalid padding" else: if pt[len(pt)-1] >= BLOCK_SIZE: return (b"Valid padding > " + pt).decode() elif chr(pt[len(pt)-1]).encode()*(pt[len(pt)-1]) == pt[-pt[len(pt)-1]:]: return (b"Valid padding, plaintext > " + pt).decode() return "Invalid padding!" def main(): pt = b"YELLOW SUBMARINE" print (PKCS7_padding_validation(pt)) if __name__ == "__main__": main()
Challenge 16:
from Crypto.Cipher import AES from os import urandom BLOCK_SIZE = 16 KEY_SIZE = 16 IV_SIZE = 16 key = urandom(KEY_SIZE) iv = urandom(IV_SIZE) prefix = b"comment1=cooking%20MCs;userdata=" suffix = b";comment2=%20like%20a%20pound%20of%20bacon" def filter_and_pad(pt): pt = pt.replace(b";",b"%").replace(b"=",b"%") return prefix + pt + suffix def PKCS7_padding(s): if len(s)%BLOCK_SIZE != 0: return s + chr((BLOCK_SIZE*(len(s)//BLOCK_SIZE)+BLOCK_SIZE)-len(s)).encode()*((BLOCK_SIZE*(len(s)//BLOCK_SIZE + 1))-len(s)) return s def encrypt(pt): pt = PKCS7_padding(pt) aes = AES.new(key, AES.MODE_CBC, iv) ct = aes.encrypt(pt) return ct def cbc_decrypt(ct): aes = AES.new(key, AES.MODE_CBC, iv) dec = aes.decrypt(ct) if b";admin=true;" in dec: return True return False def CBC_bitflipping_attack(ct): semicolon = ct[len(prefix)-16] ^ ord("%") ^ ord(";") equals = ct[len(prefix)-10] ^ ord("%") ^ ord("=") return ct[:len(prefix) - 16] + bytes([semicolon]) + ct[len(prefix)-15:len(prefix) - 10] + bytes([equals]) + ct[len(prefix) - 9:] def main(): pt = b";admin=true" ct = encrypt(filter_and_pad(pt)) alt_ct = (CBC_bitflipping_attack(ct)) print (cbc_decrypt(alt_ct)) if __name__ == "__main__": main()