Esempio n. 1
0
def c17(filename):
    """
    This program performs the padding oracle attack
    on AES cipher in CBC mode
    """
    with open(filename, "r") as file:
        lines = file.readlines()

    bsize = 16
    for line in lines:
        # convert each line to ASCII
        data = base.base64_to_hex(line).decode('hex')
        # obtain ciphertext from encryption oracle
        # this is equivalent to getting a cookie
        ct, iv = base.c17_encrypt_oracle(data)
        size = len(ct) / bsize
        # divide the ciphertext into blocks - size 16
        blocks = [ct[i * bsize: (i + 1) * bsize] for i in range(size)]
        sol = []
        prev = iv
        padding = 0x1
        for block in blocks:
            # decrypt current block (cur)
            # by modifying previous block (prev)
            base.solve_po(block, prev, bsize - 1, "", padding, bsize, iv, sol)
            prev = block
        print ''.join(sol)
Esempio n. 2
0
def c12():
    unknown_string = ''
    with open("ip12.txt","r") as file:
        b64_unknown_string = file.read().strip('\n')

    unknown_string = base.base64_to_hex(b64_unknown_string).decode('hex')
    unknown_size = len(unknown_string)
    unknown_ct = base.AES_128_ECB(unknown_string)
    prefix_size = len(unknown_ct)  - 1
    print prefix_size

    prefix = "A" * prefix_size
    known = ""

    while prefix_size > 0:
      pt = prefix + unknown_string
      ct = base.AES_128_ECB(pt)
      size = len(prefix) + len(known) + 1

      # brute force byte by byte
      for i in range(256):
        pt2 = prefix + known + chr(i)
        ct2 = base.AES_128_ECB(pt2)
        if ct[0:size] == ct2[0:size]:
          known += chr(i)
          break
      # adjust prefix by popping the last byte, since we know a new byte
      prefix = prefix[:-1]

      prefix_size = len(prefix)


    print known
Esempio n. 3
0
def c18():
    """
    This program performs AES decryption in CTR mode
    """
    ciphertext = base.base64_to_hex("L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==").decode('hex')
    key = "YELLOW SUBMARINE"
    # print base.aes_ctr_decrypt(ciphertext, key, 16)
    print base.aes_ctr_manual_decrypt(ciphertext, key)
Esempio n. 4
0
def c19(filename):
    """
    This program reads 40 strings and encrypts them under AES - CTR
    Then it attempts to crack the CTR mode without knowing the key
    using the fact that the nonce is repeated
    """
    with open(filename, "r") as file:
        lines = file.readlines()
    ciphers = []
    key = Random.get_random_bytes(16)
    nonce = 0xdeadbeef
    for line in lines:
        plaintext = base.base64_to_hex(line.strip("\n")).decode('hex')
        ciphers.append(base.aes_ctr_encrypt(plaintext, key, nonce, 16))

    # get tbe minimum length cipher
    min_len = 10000000
    for cipher in ciphers:
        cur_len = len(cipher)
        if min_len > cur_len:
            min_len = cur_len

    # brute force each byte, column-wise, since each column entry
    # is encrypted with the same byte of the keystream as it is
    # repeated.
    key_bytes = [0x0] * min_len
    idx = 0
    for i in range(min_len):
        for brute in range(256):
            deciphered = [ord(cipher[i]) ^ brute for cipher in ciphers]
            if base.is_all_ascii(deciphered):
                key_bytes[idx] = brute
                idx += 1
                break

    # expand key now, start from 11th byte of key
    key_bytes = base.expand_ctr_key(ciphers[-12], key_bytes, 've', 10)
    key_bytes = base.expand_ctr_key(ciphers[-4], key_bytes, 'l', 12)
    key_bytes = base.expand_ctr_key(ciphers[3], key_bytes, 'ntury', 13)
    key_bytes = base.expand_ctr_key(ciphers[20], key_bytes, 'eet', 18)
    key_bytes = base.expand_ctr_key(ciphers[21], key_bytes, 'ful', 21)
    key_bytes = base.expand_ctr_key(ciphers[19], key_bytes, 'ill', 24)
    key_bytes = base.expand_ctr_key(ciphers[-7], key_bytes, 'rt', 27)
    key_bytes = base.expand_ctr_key(ciphers[-11], key_bytes, 'ht', 29)
    key_bytes = base.expand_ctr_key(ciphers[-15], key_bytes, 'd', 31)
    key_bytes = base.expand_ctr_key(ciphers[-13], key_bytes, 'd', 32)
    key_bytes = base.expand_ctr_key(ciphers[4], key_bytes, 'ead', 33)
    key_bytes = base.expand_ctr_key(ciphers[-3], key_bytes, 'n', 36)
    # decipher all ciphertexts now with the guessed key
    plaintexts = []
    for cipher in ciphers:
        pbytes = base.equal_size_xor(bytearray(cipher), key_bytes)
        plaintexts.append(''.join([chr(byte) for byte in pbytes]))
    print '\n'.join(plaintexts)
Esempio n. 5
0
def c10(filename):
    f = open(filename,"r")
    data = f.readlines()
    f.close()

    pad = "\x04"
    decoded_data = base.base64_to_hex(''.join(data).strip()).decode('hex')
    block_size = 16
    key = "YELLOW SUBMARINE"

    iv = ''.join(["\x00" for i in range(block_size)])
    blocks = [str(decoded_data[i*block_size : (i+1)*block_size]) for i in range(int(len(decoded_data)/block_size))]

    op = []
    size = len(blocks)
    for i in range(size):
        pt = base.AES_ECB_decrypt(blocks[i],key)
        res = base.equal_size_xor(bytearray(pt),bytearray(iv))
        res = base.bytearray_to_ASCII(res)
        op.append(res)
        iv = blocks[i]

    plaintext = base.pkcs7_unpad(''.join(op))
    print plaintext
Esempio n. 6
0
def c20(filename):
    """
    This program reads 40 strings and encrypts them under AES - CTR
    Then it attempts to crack the CTR mode without knowing the key
    using the fact that the nonce is repeated
    """
    with open(filename, "r") as file:
        lines = file.readlines()
    ciphers = []
    key = Random.get_random_bytes(16)
    nonce = 0xdeadbeef
    for line in lines:
        plaintext = base.base64_to_hex(line.strip("\n")).decode('hex')
        #print plaintext
        ciphers.append(base.aes_ctr_encrypt(plaintext, key, nonce, 16))

    # get tbe minimum length cipher
    min_len = 10000000
    for cipher in ciphers:
        cur_len = len(cipher)
        if min_len > cur_len:
            min_len = cur_len

    # brute force each byte, column-wise, since each column entry
    # is encrypted with the same byte of the keystream as it is
    # repeated.
    key_bytes = [0x0] * min_len
    idx = 0
    for i in range(min_len):
        for brute in range(256):
            deciphered = [ord(cipher[i]) ^ brute for cipher in ciphers]
            if base.is_all_ascii_expanded(deciphered):
                #print ''.join([chr(byte) for byte in deciphered])
                key_bytes[idx] = brute
                idx += 1
                break

    # expand key now, start from 11th byte of key
    key_bytes = base.expand_ctr_key(ciphers[8], key_bytes, 'irteenth', 13)
    key_bytes = base.expand_ctr_key(ciphers[4], key_bytes, 'e', 21)
    key_bytes = base.expand_ctr_key(ciphers[-9], key_bytes, 'rite', 22)
    key_bytes = base.expand_ctr_key(ciphers[-4], key_bytes, 'ing', 26)
    key_bytes = base.expand_ctr_key(ciphers[-8], key_bytes, 'out', 29)
    key_bytes = base.expand_ctr_key(ciphers[-26], key_bytes, 'and', 32)
    key_bytes = base.expand_ctr_key(ciphers[-17], key_bytes, 'ey', 35)
    key_bytes = base.expand_ctr_key(ciphers[-16], key_bytes, 'ence', 37)
    key_bytes = base.expand_ctr_key(ciphers[25], key_bytes, 'n', 41)
    key_bytes = base.expand_ctr_key(ciphers[29], key_bytes, 're', 42)
    key_bytes = base.expand_ctr_key(ciphers[-17], key_bytes, 'nt', 44)
    key_bytes = base.expand_ctr_key(ciphers[-11], key_bytes, 'n', 46)
    key_bytes = base.expand_ctr_key(ciphers[-24], key_bytes, 'dge', 47)
    key_bytes = base.expand_ctr_key(ciphers[5], key_bytes, 'ypse', 50)
    key_bytes = base.expand_ctr_key(ciphers[-23], key_bytes, 'y', 54)
    key_bytes = base.expand_ctr_key(ciphers[-18], key_bytes, 't', 55)
    key_bytes = base.expand_ctr_key(ciphers[16], key_bytes, 'ime', 56)
    key_bytes = base.expand_ctr_key(ciphers[-2], key_bytes, 'kin', 59)
    key_bytes = base.expand_ctr_key(ciphers[22], key_bytes, 'ate', 62)
    key_bytes = base.expand_ctr_key(ciphers[6], key_bytes, 'lty', 65)
    key_bytes = base.expand_ctr_key(ciphers[16], key_bytes, 'ght', 68)
    key_bytes = base.expand_ctr_key(ciphers[22], key_bytes, 'ate', 71)
    key_bytes = base.expand_ctr_key(ciphers[7], key_bytes, 'ssion', 74)
    key_bytes = base.expand_ctr_key(ciphers[-17], key_bytes, 'n', 79)
    key_bytes = base.expand_ctr_key(ciphers[8], key_bytes, 't', 80)
    key_bytes = base.expand_ctr_key(ciphers[5], key_bytes, 'e', 81)
    key_bytes = base.expand_ctr_key(ciphers[-28], key_bytes, 'lance', 82)
    key_bytes = base.expand_ctr_key(ciphers[4], key_bytes, 'row', 87)
    key_bytes = base.expand_ctr_key(ciphers[17], key_bytes, 'ble', 90)
    key_bytes = base.expand_ctr_key(ciphers[11], key_bytes, 'st', 93)
    key_bytes = base.expand_ctr_key(ciphers[-26], key_bytes, 'on', 95)
    key_bytes = base.expand_ctr_key(ciphers[26], key_bytes, 'rve', 97)
    key_bytes = base.expand_ctr_key(ciphers[-19], key_bytes, 'ull', 100)
    key_bytes = base.expand_ctr_key(ciphers[21], key_bytes, 'ace', 103)
    key_bytes = base.expand_ctr_key(ciphers[26], key_bytes, 'hole', 106)
    # decipher all ciphertexts now with the guessed key
    plaintexts = []
    for cipher in ciphers:
        pbytes = base.equal_size_xor(bytearray(cipher), key_bytes)
        plaintexts.append(''.join([chr(byte) for byte in pbytes]))
    print '\n'.join(plaintexts)
Esempio n. 7
0
def c14():
  """
    This function performs leverages ECB's statelessnes to exploit ciphers
    where we have the form <RandomMessage, AttackerMessage, Cipher>

    The challenge encountered by an attacker in this case is that the
    attacker does not know the size of the random prefix, and therefore does
    not know where the ciphertext begins.

    To circumvent this, the attacker can inject 3 contiguous blocks with the
    same plaintext. There are 2 possible cases
      a)  If the random prefix is a multiple of block_size, then we get 3
          consecutive ciphertext blocks that have the same value
      b)  If the random prefix is not a multiple of the block_size, then we
          get 2 blocks that have the same value in the ciphertext

    In either case, we can read the consecutive blocks and identify the
    location where they end. This allows the attacker to identify the position
    of the actual ciphertext.

    Now the attacker can allocate another block whose last byte is filled by
    the ciphertext and brute force the ciphertext byte by byte as before.

  """
    # read the encrypted target string
  target_string = ''
  blk_size = 16
  with open("../inputs/ip12.txt", "r") as file:
      target_string = file.read().strip('\n')
  target_string = base.base64_to_hex(target_string).decode('hex')
  # generate a random prefix
  prefix_size = random.randint(0, 100)
  prefix = ''
  for i in range(prefix_size):
    prefix += chr(random.randint(0, 255))

  # create 3 blocks
  attacker_test = "a" * blk_size * 3
  test_cipher = base.AES_128_ECB(prefix + attacker_test + target_string)
  # detect 2 consecutive blocks
  pos = 0
  # divide the input into blocks of size blk_size
  blocks = [test_cipher[i*blk_size:(i+1)*blk_size] for i in range(len(test_cipher)/blk_size)]
  blocks_size = len(blocks)
  # look for 2 consecutive blocks that have the exact same value
  for i in range(blocks_size - 1):
    if blocks[i] == blocks[i+1]:
      pos = (i+1)*blk_size + blk_size
      print blocks[i] , i
      # check if there is a 3rd consecutive block
      if i < blocks_size - 2:
        if blocks[i+1] == blocks[i+2]:
          pos = (i+2)*blk_size + blk_size
          break
  # now we know where our blocks end, so we can reliably identify where the
  # ciphertext begins
  prefix_len = pos - blk_size*3
  while prefix_len < pos - blk_size*2:
    attack_size = blk_size
    attack_pad_size = attack_size - prefix_len % attack_size
    attacker_string = "A" * attack_pad_size
    # input to the AES ECB oracle will be plaintext
    # which has a random prefix, attacker controlled data, followed by
    # the target string that we intend to decrypt
    plaintext = prefix + attacker_string + target_string
    known = 0
    recover = ""
    unknown = len(target_string)
    pre = prefix + attacker_string
    sz = len(pre)
    print prefix_len, prefix_size
    # brute force each byte of the ciphertext
    # until we uncover the entire ciphertext
    while known < unknown:
      plaintext = pre[:-1] + target_string[known:]
      ciphertext = base.AES_128_ECB(plaintext)
      # brute force the byte
      for b in range(256):
        fake_plaintext = pre[:-1] + chr(b) + target_string[known + 1:]
        fake_ciphertext = base.AES_128_ECB(fake_plaintext)
        if fake_ciphertext[0:sz] == ciphertext[0:sz]:
          known += 1
          recover += chr(b)
          break
    print recover,"\n\n"
    prefix_len += 1