コード例 #1
0
ファイル: c11.py プロジェクト: tonyb486/cryptopals
def detect_mode(enc_function):
    sample = enc_function(b"A" * 256)
    blocks = to_blocks(sample, 16)
    # We should've made at least 14 identical blocks of all "A"'s
    if len(blocks) - len(set(blocks)) >= 14:
        return AES.MODE_ECB
    else:
        return AES.MODE_CBC
コード例 #2
0
ファイル: c18.py プロジェクト: tonyb486/cryptopals
def aes_ctr(key, nonce, data):
    crypt = AES.new(key, AES.MODE_ECB)
    blocks = to_blocks(data, 16)
    plaintext = b''
    for i in range(0, len(blocks)):
        f = struct.pack("<qq", nonce, i)
        k = crypt.encrypt(f)
        plaintext += xorstr(blocks[i], k)
    return plaintext
コード例 #3
0
def cbc_decrypt(data, key, iv):
    crypt = AES.new(key, AES.MODE_ECB)
    blocks = [iv] + to_blocks(data, len(key))

    blocks = [
        xorstr(crypt.decrypt(blocks[i]), blocks[i - 1])
        for i in range(1, len(blocks))
    ]
    plaintext = b"".join(blocks)
    assert check_padding(plaintext)
    return plaintext
コード例 #4
0
ファイル: c17.py プロジェクト: tonyb486/cryptopals
def padding_oracle_attack(ciphertext, oracle):
    def padding_oracle(c1, c2):
        token = b"".join([c1,c2])
        try: return oracle(token)
        except: return False

    blocks = to_blocks(ciphertext, 16)
    known = b''
    for i in range(len(blocks)-1):
        known += padding_oracle_block(blocks[i], blocks[i+1], padding_oracle)

    return known
コード例 #5
0
def detect_ecb(data, blocksize):
    blocks = to_blocks(data, 16)
    if len(blocks) != len(set(blocks)):
        return True
    return False
コード例 #6
0
ファイル: c16.py プロジェクト: tonyb486/cryptopals

def check_admin(token):
    global key
    crypt = AES.new(key, AES.MODE_CBC, token[0:16])
    plaintext = unpad(crypt.decrypt(
        token[16:]))  # oh no, padding oracles! (for later)
    pairs = [i.rsplit(b"=") for i in plaintext.rsplit(b";")]

    return ([b"admin", b"true"] in pairs)


##########################################################

# Generate a token, what is in it doesn't really matter the way we're
# doing it, since we know what lives in the last block - let's just make it
# "TOKEN," because that makes us land on an even padding :)
token = gen_token(b"TOKEN")

# The last two blocks are going to be filled with, like, a pound of bacon
# so we know what they are, and we know we can edit them at will without
# really breaking anything important.

blocks = to_blocks(token, 16)
bits_to_flip = xorstr(b";admin=true;A=A\x01", b"nd%20of%20bacon\x01")
blocks[-2] = xorstr(blocks[-2], bits_to_flip)

token = b"".join(blocks)

print(check_admin(token))
コード例 #7
0

# Boundry is how far we have to go to force it into a new block
#
# "email=AAAAAAAAAA|&uid=10&role=use|r

boundry, blocksize = get_blocksize_and_boundry(encrypted_profile_for)

# Everything after boundry gets put into a new block, so we can control
# a whole block this way, in this case, our block will be "admin&uid=10&rol"
# which is close enough for urldecoding!
#
# "email=AAAAAAAAAA|admin&uid=10&rol|e=user

payload = (b"A" * boundry) + b"admin"
admin_block = to_blocks(encrypted_profile_for(payload), blocksize)[1]

# Now we push off just enough to get the "user" alone in the last block
# So, "A"*(len("user"))-1 will do exactly that, and give us:
#
# "email=AAAAAAAAAA|AAA&uid=10&role=|user

payload = b'A' * (boundry + len("user") - 1)
blocks = to_blocks(encrypted_profile_for(payload), blocksize)[:-1]

# Then, swap the last block with our new one that starts with "admin"
#
# "email=AAAAAAAAAA|AAA&uid=10&role=|admin&uid=10&rol

blocks.append(admin_block)
modified_payload = b"".join(blocks)
コード例 #8
0
def get_boundry(enc_function, blocksize):
    for i in range(blocksize,blocksize*3):
        b = to_blocks(enc_function(b"A"*i), blocksize)
        for x in range(len(b)-1):
            if b[x]==b[x+1]: 
                return (x+2)*blocksize, i