Example #1
0
def recoverBytes():
    # first, determine number of bytes needed to push prefix up to a block boundry
    # and where the first block fully controlled by my input lies (effectively, determine prefix length)
    numBytesForPrefix, firstControlledBlock = determinePrefixLength()
    # deterine target plaintext length
    targetPlaintextLength = prob14DeterminePlaintextLength() + (
        numBytesForPrefix) - (firstControlledBlock * 16)
    # do the problem 12 process
    knownPlaintext = b''
    blockSize = 16
    for i in range(targetPlaintextLength):
        # Set first unknown byte to be last byte in block
        padLen = numBytesForPrefix + (blockSize - 1) - (len(knownPlaintext) %
                                                        blockSize)
        pad = padStr * padLen
        # Collect cipher, identify cipher blocks of interest
        cipherOutput = prob14Encrypt(pad)
        blockOfInterest = firstControlledBlock + (len(knownPlaintext) // 16)
        cipherChunks = chunks(cipherOutput, blockSize)
        cipherOfInterest = cipherChunks[blockOfInterest]
        ###knownPlainChunks.append(b'');
        # prefix is last 15 bytes of (pad|knownPlaintext)
        prefix = (pad + knownPlaintext)[-15:]
        knownPlaintext += prob14DetermineNextByte(prefix, cipherOfInterest,
                                                  numBytesForPrefix,
                                                  firstControlledBlock)
    return knownPlaintext
def detectMode():
    plaintext = b'A' * 48; 
    cipher = append_and_encrypt(plaintext);
    blocks = chunks(cipher, 16);
    if (blocks[1] == blocks[2]):
        return "ECB";
    else:
        return "NOT ECB";
def detectMode():
    plaintext = b'A' * 48; #ensure that 2nd, 3rd blocks of cipher have same plaintext
    cipher = encryption_oracle(plaintext);
    blocks = chunks(cipher, 16);
    if (blocks[1] == blocks[2]):
        print("ECB");
    else:
        print("CBC");
Example #4
0
def aes_ctr(rawInput, rawKey, rawIV):
    inputBlocks = chunks(rawInput, 16);
    rawOutput = b'';
    for block in inputBlocks:
        keyStream = aes_ecb_enc(rawIV, rawKey);
        rawOutput += raw_xor(keyStream, block);
        rawIV = incrementIV(rawIV);
    return rawOutput;
Example #5
0
def detectMode():
    plaintext = b'A' * 48
    cipher = append_and_encrypt(plaintext)
    blocks = chunks(cipher, 16)
    if (blocks[1] == blocks[2]):
        return "ECB"
    else:
        return "NOT ECB"
Example #6
0
def recoverPlaintext():
    targetCipher, iv = encryptString();
    targetBlocks = chunks(targetCipher, 16);
    plaintext = b'';
    for i in range(len(targetBlocks)):
        plaintext += recoverBlock(targetBlocks[i], iv);
        iv = targetBlocks[i];
    return plaintext;
Example #7
0
def aes_ctr(rawInput, rawKey, rawIV):
    inputBlocks = chunks(rawInput, 16)
    rawOutput = b''
    for block in inputBlocks:
        keyStream = aes_ecb_enc(rawIV, rawKey)
        rawOutput += raw_xor(keyStream, block)
        rawIV = incrementIV(rawIV)
    return rawOutput
Example #8
0
def aes_cbc_dec(rawCipher, rawKey, rawIV):
    cipherBlocks = chunks(rawCipher, 16);
    plain = b'';
    for block in cipherBlocks:
        ecbOut = aes_ecb_dec(block, rawKey);
        cbcOut = hexToRaw(hex_xor(rawToHex(ecbOut), rawToHex(rawIV)));
        rawIV = block;
        plain += cbcOut;
    return plain;
Example #9
0
def aes_cbc_enc(rawPlain, rawKey, rawIV):
    plainBlocks = chunks(rawPlain, 16);
    cipher = b'';
    for block in plainBlocks:
        blockIn = hexToRaw(hex_xor(rawToHex(block), rawToHex(rawIV)));
        blockOut = aes_ecb_enc(blockIn, rawKey);
        rawIV = blockOut;
        cipher += blockOut;
    return cipher;
Example #10
0
def detectMode():
    plaintext = b'A' * 48
    #ensure that 2nd, 3rd blocks of cipher have same plaintext
    cipher = encryption_oracle(plaintext)
    blocks = chunks(cipher, 16)
    if (blocks[1] == blocks[2]):
        print("ECB")
    else:
        print("CBC")
Example #11
0
def aes_cbc_dec(rawCipher, rawKey, rawIV):
    cipherBlocks = chunks(rawCipher, 16)
    plain = b""
    for block in cipherBlocks:
        ecbOut = aes_ecb_dec(block, rawKey)
        cbcOut = hexToRaw(hex_xor(rawToHex(ecbOut), rawToHex(rawIV)))
        rawIV = block
        plain += cbcOut
    return plain
Example #12
0
def aes_cbc_dec(rawCipher, rawKey, rawIV):
    cipherBlocks = chunks(rawCipher, 16)
    plain = b''
    for block in cipherBlocks:
        ecbOut = aes_ecb_dec(block, rawKey)
        cbcOut = hexToRaw(hex_xor(rawToHex(ecbOut), rawToHex(rawIV)))
        rawIV = block
        plain += cbcOut
    return plain
Example #13
0
def aes_cbc_enc(rawPlain, rawKey, rawIV):
    plainBlocks = chunks(rawPlain, 16)
    cipher = b""
    for block in plainBlocks:
        blockIn = hexToRaw(hex_xor(rawToHex(block), rawToHex(rawIV)))
        blockOut = aes_ecb_enc(blockIn, rawKey)
        rawIV = blockOut
        cipher += blockOut
    return cipher
Example #14
0
def aes_cbc_enc(rawPlain, rawKey, rawIV):
    plainBlocks = chunks(rawPlain, 16)
    cipher = b''
    for block in plainBlocks:
        blockIn = hexToRaw(hex_xor(rawToHex(block), rawToHex(rawIV)))
        blockOut = aes_ecb_enc(blockIn, rawKey)
        rawIV = blockOut
        cipher += blockOut
    return cipher
Example #15
0
def determinePrefixLength():
    plainLength = 32
    while (True):
        plain = b'A' * plainLength
        cipher = prob14Encrypt(plain)
        cipherBlocks = chunks(cipher, 16)
        for i in range(len(cipherBlocks) - 1):
            if (cipherBlocks[i] == cipherBlocks[i + 1]):
                return (len(plain) % 16), i
        plainLength += 1
Example #16
0
def determinePrefixLength():
    plainLength = 32;
    while (True):
        plain = b'A' * plainLength;
        cipher = prob14Encrypt(plain);
        cipherBlocks = chunks(cipher, 16);
        for i in range(len(cipherBlocks)-1):
            if (cipherBlocks[i] == cipherBlocks[i+1]):
                return (len(plain)%16), i;
        plainLength += 1;
Example #17
0
def prob14DetermineNextByte(rawPrefix, observedCipher, numBytesForPrefix, firstControlledBlock):
    blockSize = 16;
    plain = (padStr) * (numBytesForPrefix + blockSize - 1 - len(rawPrefix));
    plain += rawPrefix;
    for i in range(256):
        thisPlain = plain + bytes(chr(i), 'UTF-8');
        thisCipher = prob14Encrypt(thisPlain);
        if (chunks(thisCipher, blockSize)[firstControlledBlock] == observedCipher):
            return bytes(chr(i), 'UTF-8');
    return b'***ERROR***';
Example #18
0
def prob14DetermineNextByte(rawPrefix, observedCipher, numBytesForPrefix,
                            firstControlledBlock):
    blockSize = 16
    plain = (padStr) * (numBytesForPrefix + blockSize - 1 - len(rawPrefix))
    plain += rawPrefix
    for i in range(256):
        thisPlain = plain + bytes(chr(i), 'UTF-8')
        thisCipher = prob14Encrypt(thisPlain)
        if (chunks(thisCipher,
                   blockSize)[firstControlledBlock] == observedCipher):
            return bytes(chr(i), 'UTF-8')
    return b'***ERROR***'
Example #19
0
def determineNextByte(rawPrefix, observedCipher):
    ''' Given a prefix, generates 256 blocks of the form:
    AA..AA|prefix|?, and checks for a match against the observed cipher
    '''
    blockSize = determineBlockSize()
    plain = (padStr) * (blockSize - 1 - len(rawPrefix))
    plain += rawPrefix
    for i in range(256):
        thisPlain = plain + bytes(chr(i), 'UTF-8')
        thisCipher = append_and_encrypt(thisPlain)
        if (chunks(thisCipher, blockSize)[0] == observedCipher):
            return bytes(chr(i), 'UTF-8')
    return b'***ERROR***'
def determineNextByte(rawPrefix, observedCipher):
    ''' Given a prefix, generates 256 blocks of the form:
    AA..AA|prefix|?, and checks for a match against the observed cipher
    '''
    blockSize = determineBlockSize()
    plain = (padStr) * (blockSize - 1 - len(rawPrefix));
    plain += rawPrefix;
    for i in range(256):
        thisPlain = plain + bytes(chr(i), 'UTF-8');
        thisCipher = append_and_encrypt(thisPlain);
        if (chunks(thisCipher, blockSize)[0] == observedCipher):
            return bytes(chr(i), 'UTF-8');
    return b'***ERROR***';
def determinePlaintext():
    blockSize = determineBlockSize()    
    plaintextLength = determinePlaintextLength();
    knownPlaintext = b'';
    for i in range(plaintextLength):
        # Set first unknown byte to be last byte in block
        padLen = (blockSize - 1) - (len(knownPlaintext) % blockSize);
        pad = padStr * padLen;
        # Collect cipher, identify cipher blocks of interest
        cipherOutput = append_and_encrypt(pad);
        blockOfInterest = len(knownPlaintext) // 16;
        cipherChunks = chunks(cipherOutput, blockSize);
        cipherOfInterest = cipherChunks[blockOfInterest];
        ###knownPlainChunks.append(b'');
        # prefix is last 15 bytes of (pad|knownPlaintext)
        prefix = (pad + knownPlaintext)[-15:];
        knownPlaintext += determineNextByte(prefix, cipherOfInterest);
    return knownPlaintext;
Example #22
0
def determinePlaintext():
    blockSize = determineBlockSize()
    plaintextLength = determinePlaintextLength()
    knownPlaintext = b''
    for i in range(plaintextLength):
        # Set first unknown byte to be last byte in block
        padLen = (blockSize - 1) - (len(knownPlaintext) % blockSize)
        pad = padStr * padLen
        # Collect cipher, identify cipher blocks of interest
        cipherOutput = append_and_encrypt(pad)
        blockOfInterest = len(knownPlaintext) // 16
        cipherChunks = chunks(cipherOutput, blockSize)
        cipherOfInterest = cipherChunks[blockOfInterest]
        ###knownPlainChunks.append(b'');
        # prefix is last 15 bytes of (pad|knownPlaintext)
        prefix = (pad + knownPlaintext)[-15:]
        knownPlaintext += determineNextByte(prefix, cipherOfInterest)
    return knownPlaintext
Example #23
0
def recoverBytes():
    # first, determine number of bytes needed to push prefix up to a block boundry
    # and where the first block fully controlled by my input lies (effectively, determine prefix length)
    numBytesForPrefix, firstControlledBlock = determinePrefixLength();
    # deterine target plaintext length
    targetPlaintextLength = prob14DeterminePlaintextLength() + (numBytesForPrefix) - (firstControlledBlock * 16);
    # do the problem 12 process
    knownPlaintext = b'';  
    blockSize = 16; 
    for i in range(targetPlaintextLength):
        # Set first unknown byte to be last byte in block
        padLen = numBytesForPrefix + (blockSize - 1) - (len(knownPlaintext) % blockSize);
        pad = padStr * padLen;
        # Collect cipher, identify cipher blocks of interest
        cipherOutput = prob14Encrypt(pad);
        blockOfInterest = firstControlledBlock + (len(knownPlaintext) // 16);
        cipherChunks = chunks(cipherOutput, blockSize);
        cipherOfInterest = cipherChunks[blockOfInterest];
        ###knownPlainChunks.append(b'');
        # prefix is last 15 bytes of (pad|knownPlaintext)
        prefix = (pad + knownPlaintext)[-15:];
        knownPlaintext += prob14DetermineNextByte(prefix, cipherOfInterest, numBytesForPrefix, firstControlledBlock);
    return knownPlaintext;
Example #24
0
def generateEncryptedAdminProfile():
    # get to a fresh block
    s = 'A' * (16 - (len(prefix) % 16));
    #locate the IV for my block
    myIVBlock = ((len(prefix) + len(s)) // 16) - 1;
    # add a known block value
    s += 'X' * 16;
    # encrypt
    cip = padAndEncryptString(s);
    # extract IV for block of interest
    allBlocks = chunks(cip, 16);
    myIV = allBlocks[myIVBlock];
    # xor in IV with desired value
    hexIV = rawToHex(myIV);
    hexKnown = rawToHex('X'*16);
    hexDesired = rawToHex(";admin=true;XXXX")
    newHexIV = hex_xor(hexIV, hex_xor(hexKnown, hexDesired));
    newIV = hexToRaw(newHexIV);
    # insert "error"
    allBlocks[myIVBlock] = newIV;
    myCipher = b'';
    for b in allBlocks:
        myCipher += b;
    return myCipher;