This is an old revision of the document!


Lab 06 - TLS Attacks - BEAST

Cipher Block Chaining (CBC)

SSLv3/TLS1.0 are protocols to encrypt/decrypt and secure your data. In our case, they both use the CBC cipher mode chaining. The plaintext is divided into block regarding the encryption algorithm (AES, DES, 3DES) and the length is a multiple of 8 or 16. If the plaintext does not fill the length, a padding is added at the end to complete the missing space. In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block depends on all plaintext blocks processed up to that point.

C[i] = Ek(P[i] XOR C[i-1]), C[0] = IV

P[i] = Dk(C[i]) XOR C[i-1], P[0] = IV

To make each message unique, an initialization vector must be used in the first block. When encrypting with CBC mode, the Initialization Vector (IV) is:

  • Random
  • Unpredictable
  • Not secret

CBC encryption CBC decryption

#!/usr/bin/env python # -*- coding: utf-8 -*- import pdb

' TLS BEAST attack - PoC Implementation of the cryptographic path behind the attack '

import random import binascii import sys from Crypto.Cipher import AES from Crypto import Random

SECRET_COOKIE = b”ID=3ef729ccf0cc5” BLOCK_LENGTH = 16

last_iv = None

”””

  AES-CBC
  function encrypt, decrypt, pad, unpad
  You can fix the IV in the function encrypt() because TLS 1.0 fix the IV
  for the second, third... request (to gain time)

”””

def pad(s):

  return s + (16 - len(s) % 16) * chr(16 - len(s) % 16).encode()

def unpad(s):

  return s[:-ord(s[len(s)-1:])]

# we admit the handshake produce a secret key for the session # of course we do not have any HMAC etc .. but there are not usefull in this attack # we can use this function without having access to the secret key def encrypt(msg, iv_p=None):

  raw = pad(msg) + SECRET_COOKIE
  if iv_p is None:
      iv = Random.new().read(AES.block_size)
  else:
      iv = iv_p
  global key
  key = Random.new().read(AES.block_size)
  cipher = AES.new(b'V38lKILOJmtpQMHp', AES.MODE_CBC, iv)
  return cipher.encrypt(raw)

”””

  The PoC of BEAST attack -
  Implementation of the cryptographic path behind the attack
  - the attacker can retrieve the request send be the client
  - but also make the client send requests with the plain text of his choice

”””

def xor_strings(xs, ys, zs):

  return "".join(chr(ord(x) ^ ord(y) ^ ord(z)) for x, y, z in zip(xs, ys, zs))

def xor_block(vector_init, previous_cipher, p_guess):

  xored = xor_strings(vector_init, previous_cipher, p_guess)
  return xored

def split_len(seq, length):

  return [seq[i:i+length] for i in range(0, len(seq), length)]

def send_request(msg):

  global last_iv
  enc = encrypt(msg, last_iv)
  last_iv = enc[-BLOCK_LENGTH:]
  return enc

# the PoC start here def run_three_request():

  secret = []

# the part of the request the atacker knows, can be null

  known_so_far = b"ID="

# retrieve all the bytes of the cookie (in total 16 bytes, all fit in one block)

  for t in range(len(SECRET_COOKIE)):
      padding = 16 - len(known_so_far) - 1

for i in range(0,256):

          # TODO send first request

# TODO send second request

# TODO craft and send third request

# TODO check if the guess is correct

          if False: # change condition here
              known_so_far += chr(i)
              break
          elif i == 255:
              print("Unable to find the char...")
              return known_so_far
  return known_so_far

# the attacker doesn't know the cookie secret = run_three_request()

print(secret)

ac/laboratoare/06.1699552547.txt.gz · Last modified: 2023/11/09 19:55 by vlad_andrei.badoiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0