diff --git a/25-Halifax/Halifax.asm b/25-Halifax/Halifax.asm new file mode 100644 index 0000000..0264847 --- /dev/null +++ b/25-Halifax/Halifax.asm @@ -0,0 +1,373 @@ + +Hex: +:10 4400 00 55425C0135D0085A8245002831400044 AD +:10 4410 00 3F4000000F930824924200285C012F83 44 +:10 4420 00 9F4F6E470024F8233F4000040F930724 5A +:10 4430 00 924200285C011F83CF430024F9233150 AE +:10 4440 00 E0FF3F403446B01286453F405846B012 28 +:10 4450 00 86450312031230124000B01250453150 0D +:10 4460 00 06003F406F46B0128645031203123012 19 +:10 4470 00 7F00B0125045315006003F409146B012 C7 +:10 4480 00 86453F40C646B01286453D4020000E43 5B +:10 4490 00 0F41B012C8453F40FC46B01286450D41 61 +:10 44A0 00 3E4000100F43B012B6450B430F410F5B 67 +:10 44B0 00 6E4F0F4E3FF00F005A4F104712C34E10 71 +:10 44C0 00 12C34E1012C34E1012C34E103EF00F00 16 +:10 44D0 00 5F4E1047B01278454F4AB01278451B53 D3 +:10 44E0 00 3B902000E3233F402147B01286453F40 E8 +:10 44F0 00 2247B01286453D4000040E433F400024 51 +:10 4500 00 B012C8453E40FF033F400024B0126845 4A +:10 4510 00 5B4200248B105F4201240BDF5A420224 CD +:10 4520 00 2A93052C3F403E47B0128645E03F3F40 6E +:10 4530 00 5547B01286450D4A3E4003240F4BB012 3A +:10 4540 00 A4458B12D43F32D0F000FD3F30403246 BC +:10 4550 00 1F41020002124F4F8F103FD00080024F C8 +:10 4560 00 B0121000324130410E120F122312B012 5D +:10 4570 00 50453150060030418F110F120312B012 16 +:10 4580 00 5045215230410B120B4F033C1B53B012 CC +:10 4590 00 78456F4B4F93FA237F400A00B0127845 5D +:10 45A0 00 3B4130410C4F043CFC4E00001C533D53 3A +:10 45B0 00 0D93FA2330410D120E120F1230124100 EA +:10 45C0 00 B0125045315230410B120A1209120812 32 +:10 45D0 00 3D900600092C0C4F043CCC4E00001C53 AF +:10 45E0 00 3D530D93FA23203C4E4E4B4E0B930324 28 +:10 45F0 00 0C4B8C100BDC1FB306243D53CF4E0000 38 +:10 4600 00 094F1953013C094F0C4D12C30C100A49 B4 +:10 4610 00 084C8A4B00002A533853FB230C5C0C59 7E +:10 4620 00 1DF30224CC4E0000384139413A413B41 50 +:04 4630 00 30410013 02 +Strings: +:10 4634 00 57656C636F6D6520746F207468652074 B2 +:10 4644 00 6573742070726F6772616D206C6F6164 42 +:10 4654 00 65722E00456E61626C696E6720686172 D6 +:10 4664 00 64656E6564206D6F6465005665726966 85 +:10 4674 00 79696E67203078376620696E74657272 66 +:10 4684 00 7570742064697361626C656400307837 96 +:10 4694 00 6620696E746572727570742064697361 E2 +:10 46A4 00 626C65642C206B65792073746F726564 29 +:10 46B4 00 20696E20696E7465726E616C20535241 7C +:10 46C4 00 4D00756E6C6F636B2062792070726F76 2B +:10 46D4 00 6964696E672074686520313620627974 74 +:10 46E4 00 65206B657920746F203078343120696E D1 +:10 46F4 00 7465727275707400496E7465726E616C 63 +:10 4704 00 205352414D20486173683A0030313233 AE +:10 4714 00 3435363738394142434445460000506C FD +:10 4724 00 6561736520656E746572206465627567 82 +:10 4734 00 207061796C6F61642E00496E76616C69 DA +:10 4744 00 64207061796C6F6164206C656E677468 55 +:10 4754 00 00457865637574696E67206465627567 82 +:0A 4764 00 207061796C6F61640000 41 +Vector_Table: +:10 FF80 00 4C454C454C454C454C454C454C454C45 E9 +:10 FF90 00 4C454C454C454C454C454C454C450044 26 +Entry: +:04 0000 03 00004400 B5 +:00 0000 01 FF + +Obj: +0010 <__trap_interrupt> +0010: 3041 ret +4400 <__watchdog_support> +4400: 5542 5c01 mov.b &0x015c, r5 +4404: 35d0 085a bis #0x5a08, r5 +4408: 8245 0028 mov r5, &0x2800 +440c <__init_stack> +440c: 3140 0044 mov #0x4400 <__watchdog_support>, sp +4410 <__do_copy_data> +4410: 3f40 0000 clr r15 +4414: 0f93 tst r15 +4416: 0824 jz #0x4428 <__do_clear_bss+0x0> +4418: 9242 0028 5c01 mov &0x2800, &0x015c +441e: 2f83 decd r15 +4420: 9f4f 6e47 0024 mov 0x476e(r15), 0x2400(r15) +4426: f823 jnz #0x4418 <__do_copy_data+0x8> +4428 <__do_clear_bss> +4428: 3f40 0004 mov #0x400, r15 +442c: 0f93 tst r15 +442e: 0724 jz #0x443e +4430: 9242 0028 5c01 mov &0x2800, &0x015c +4436: 1f83 dec r15 +4438: cf43 0024 mov.b #0x0, 0x2400(r15) +443c: f923 jnz #0x4430 <__do_clear_bss+0x8> + +443e
+; char sha_buf[0x20]; +443e: 3150 e0ff add #0xffe0, sp +; puts ("Welcome to the test program loader."); +4442: 3f40 3446 mov #0x4634 "Welcome to the test program loader." <__data_start+0x2234>, r15 +4446: b012 8645 call #0x4586 +; puts ("Enabling hardened mode"); +444a: 3f40 5846 mov #0x4658 "Enabling hardened mode" r15 +444e: b012 8645 call #0x4586 +; INT (0x40); +4452: 0312 push #0x0 +4454: 0312 push #0x0 +4456: 3012 4000 push #0x40 +445a: b012 5045 call #0x4550 +445e: 3150 0600 add #0x6, sp + +; puts ("Verifying 0x7f interrupt disabled"); +4462: 3f40 6f46 mov #0x466f "Verifying 0x7f interrupt disabled" r15 +4466: b012 8645 call #0x4586 +; INT (0x7f); +446a: 0312 push #0x0 +446c: 0312 push #0x0 +446e: 3012 7f00 push #0x7f +4472: b012 5045 call #0x4550 + +4476: 3150 0600 add #0x6, sp +; puts ("0x7f interrupt disabled, key stored in internal SRAM"); +447a: 3f40 9146 mov #0x4691 "0x7f interrupt disabled, key stored in internal SRAM" r15 +447e: b012 8645 call #0x4586 +; puts ("unlock by providing the 16 byte key to 0x41 interrupt"); +4482: 3f40 c646 mov #0x46c6 "unlock by providing the 16 byte key to 0x41 interrupt" r15 +4486: b012 8645 call #0x4586 +; memset (&sha_buf, 0, 0x20); +448a: 3d40 2000 mov #0x20, r13 +448e: 0e43 clr r14 +4490: 0f41 mov sp, r15 +4492: b012 c845 call #0x45c8 +; puts ("Internal SRAM Hash:"); +4496: 3f40 fc46 mov #0x46fc "Internal SRAM Hash:" r15 +449a: b012 8645 call #0x4586 +; sha256_internal (0, 0x1000, &sha_buf); +449e: 0d41 mov sp, r13 +44a0: 3e40 0010 mov #0x1000, r14 +44a4: 0f43 clr r15 +44a6: b012 b645 call #0x45b6 +print_hash_inline: +; for (i /* r11 */ = 0; i != 0x20; i++) +44aa: 0b43 clr r11 +pha_loop: +; byte /* r14 */ = hash[i]; +44ac: 0f41 mov sp, r15 +44ae: 0f5b add r11, r15 +44b0: 6e4f mov.b @r15, r14 +; lower_nibble /* r15 */ = byte & 0xf; +44b2: 0f4e mov r14, r15 +44b4: 3ff0 0f00 and #0xf, r15 +; lower_char /* r11 */ = "0123456789ABCDEF"[lower_nibble]; +44b8: 5a4f 1047 mov.b 0x4710(r15), r10 +; upper_nibble /* r14 */ = (byte >> 0x4) & 0xf; +44bc: 12c3 clrc +44be: 4e10 rrc.b r14 +44c0: 12c3 clrc +44c2: 4e10 rrc.b r14 +44c4: 12c3 clrc +44c6: 4e10 rrc.b r14 +44c8: 12c3 clrc +44ca: 4e10 rrc.b r14 +44cc: 3ef0 0f00 and #0xf, r14 +; putchar("0123456789ABCDEF"[upper_nibble]); +44d0: 5f4e 1047 mov.b 0x4710(r14), r15 +44d4: b012 7845 call #0x4578 +; putchar(lower_char) +44d8: 4f4a mov.b r10, r15 +44da: b012 7845 call #0x4578 +; ... i != 0x20; i++) +44de: 1b53 inc r11 +44e0: 3b90 2000 cmp #0x20, r11 +44e4: e323 jne #0x44ac +; puts (""); // prints newline +44e6: 3f40 2147 mov #0x4721, r15 +44ea: b012 8645 call #0x4586 +; while(true) { +; puts ("Please enter debug payload."); +44ee: 3f40 2247 mov #0x4722 "Please enter debug payload." r15 +44f2: b012 8645 call #0x4586 +; memset (0x2400, 0, 0x400); +44f6: 3d40 0004 mov #0x400, r13 +44fa: 0e43 clr r14 +44fc: 3f40 0024 mov #0x2400, r15 +4500: b012 c845 call #0x45c8 +; getsn (0x2400, 0x3ff); +4504: 3e40 ff03 mov #0x3ff, r14 +4508: 3f40 0024 mov #0x2400, r15 +450c: b012 6845 call #0x4568 +; loadaddr = (buf[0] << 8) + (buf[1]); +4510: 5b42 0024 mov.b &0x2400, r11 +4514: 8b10 swpb r11 +4516: 5f42 0124 mov.b &0x2401, r15 +451a: 0bdf bis r15, r11 +; +451c: 5a42 0224 mov.b &0x2402, r10 +4520: 2a93 cmp #0x2, r10 +4522: 052c jc #0x452e + +4524: 3f40 3e47 mov #0x473e "Invalid payload length" r15 +4528: b012 8645 call #0x4586 +; continue; +452c: e03f jmp #0x44ee +execute_debug_payload: +452e: 3f40 5547 mov #0x4755 "Executing debug payload" r15 +4532: b012 8645 call #0x4586 +; memcpy (loadaddr, 0x2403, len); +4536: 0d4a mov r10, r13 +4538: 3e40 0324 mov #0x2403, r14 +453c: 0f4b mov r11, r15 +453e: b012 a445 call #0x45a4 +; loadaddr(); +4542: 8b12 call r11 +; continue; +4544: d43f jmp #0x44ee + +4546 <__stop_progExec__> +4546: 32d0 f000 bis #0xf0, sr +454a: fd3f jmp #0x4546 <__stop_progExec__+0x0> +454c <__ctors_end> +454c: 3040 3246 br #0x4632 <_unexpected_> +4550 +4550: 1f41 0200 mov 0x2(sp), r15 +4554: 0212 push sr +4556: 4f4f mov.b r15, r15 +4558: 8f10 swpb r15 +455a: 3fd0 0080 bis #0x8000, r15 +455e: 024f mov r15, sr +4560: b012 1000 call #0x10 +4564: 3241 pop sr +4566: 3041 ret +4568 +4568: 0e12 push r14 +456a: 0f12 push r15 +456c: 2312 push #0x2 +456e: b012 5045 call #0x4550 +4572: 3150 0600 add #0x6, sp +4576: 3041 ret +4578 +4578: 8f11 sxt r15 +457a: 0f12 push r15 +457c: 0312 push #0x0 +457e: b012 5045 call #0x4550 +4582: 2152 add #0x4, sp +4584: 3041 ret +4586 +4586: 0b12 push r11 +4588: 0b4f mov r15, r11 +458a: 033c jmp #0x4592 +458c: 1b53 inc r11 +458e: b012 7845 call #0x4578 +4592: 6f4b mov.b @r11, r15 +4594: 4f93 tst.b r15 +4596: fa23 jnz #0x458c +4598: 7f40 0a00 mov.b #0xa, r15 +459c: b012 7845 call #0x4578 +45a0: 3b41 pop r11 +45a2: 3041 ret +45a4 +45a4: 0c4f mov r15, r12 +45a6: 043c jmp #0x45b0 +45a8: fc4e 0000 mov.b @r14+, 0x0(r12) +45ac: 1c53 inc r12 +45ae: 3d53 add #-0x1, r13 +45b0: 0d93 tst r13 +45b2: fa23 jnz #0x45a8 +45b4: 3041 ret +45b6 +45b6: 0d12 push r13 +45b8: 0e12 push r14 +45ba: 0f12 push r15 +45bc: 3012 4100 push #0x41 +45c0: b012 5045 call #0x4550 +45c4: 3152 add #0x8, sp +45c6: 3041 ret +45c8 +45c8: 0b12 push r11 +45ca: 0a12 push r10 +45cc: 0912 push r9 +45ce: 0812 push r8 +45d0: 3d90 0600 cmp #0x6, r13 +45d4: 092c jc #0x45e8 +45d6: 0c4f mov r15, r12 +45d8: 043c jmp #0x45e2 +45da: cc4e 0000 mov.b r14, 0x0(r12) +45de: 1c53 inc r12 +45e0: 3d53 add #-0x1, r13 +45e2: 0d93 tst r13 +45e4: fa23 jnz #0x45da +45e6: 203c jmp #0x4628 +45e8: 4e4e mov.b r14, r14 +45ea: 4b4e mov.b r14, r11 +45ec: 0b93 tst r11 +45ee: 0324 jz #0x45f6 +45f0: 0c4b mov r11, r12 +45f2: 8c10 swpb r12 +45f4: 0bdc bis r12, r11 +45f6: 1fb3 bit #0x1, r15 +45f8: 0624 jz #0x4606 +45fa: 3d53 add #-0x1, r13 +45fc: cf4e 0000 mov.b r14, 0x0(r15) +4600: 094f mov r15, r9 +4602: 1953 inc r9 +4604: 013c jmp #0x4608 +4606: 094f mov r15, r9 +4608: 0c4d mov r13, r12 +460a: 12c3 clrc +460c: 0c10 rrc r12 +460e: 0a49 mov r9, r10 +4610: 084c mov r12, r8 +4612: 8a4b 0000 mov r11, 0x0(r10) +4616: 2a53 incd r10 +4618: 3853 add #-0x1, r8 +461a: fb23 jnz #0x4612 +461c: 0c5c add r12, r12 +461e: 0c59 add r9, r12 +4620: 1df3 and #0x1, r13 +4622: 0224 jz #0x4628 +4624: cc4e 0000 mov.b r14, 0x0(r12) +4628: 3841 pop r8 +462a: 3941 pop r9 +462c: 3a41 pop r10 +462e: 3b41 pop r11 +4630: 3041 ret +4632 <_unexpected_> +4632: 0013 reti pc +4634 <__data_start+0x2234> +4634 .strings: +4634: "Welcome to the test program loader." +4658: "Enabling hardened mode" +466f: "Verifying 0x7f interrupt disabled" +4691: "0x7f interrupt disabled, key stored in internal SRAM" +46c6: "unlock by providing the 16 byte key to 0x41 interrupt" +46fc: "Internal SRAM Hash:" +4710: "0123456789ABCDEF" +4722: "Please enter debug payload." +473e: "Invalid payload length" +4755: "Executing debug payload" + +Prereqs: "Vancouver" +Name: "Halifax" +Text: +Lockitall LOCKIT 2 r A.01 +______________________________________________________________________ + +User Manual: Lockitall LockIT 2, rev a.01 +______________________________________________________________________ + + +OVERVIEW + +- This new lock adds a hardened mode and disables the 0x7f +interrupt. + + +DETAILS + +An example in-field debug payload follows. Any payload is +allowed, because the unlock key must be passed to the new +interrupt with code 0x41, and this key is only stored in +secure memory. + +8000023041 + +This is Hardware Version 4. + +This is Software Revision 2. + + + +(c) 2022 LOCKITALL Page 1/1 + +X:181 +Y:288 +Rating:20 +Patch:"" diff --git a/25-Halifax/halifax.c b/25-Halifax/halifax.c new file mode 100644 index 0000000..041d1d8 --- /dev/null +++ b/25-Halifax/halifax.c @@ -0,0 +1,64 @@ + +// uC includes +#include "../common/io.c" +#include "../common/lib.c" + +typedef unsigned char u8; +typedef unsigned short u16; + +const char * HEX_LUT = "0123456789ABCDEF"; + +int main () { + u8 *buf = (mem + 0x2400); // >=> 0x2400 + u8 sha_buf[0x20]; // >=> sp + + puts("Welcome to the test program loader."); + + puts ("Enabling hardened mode"); + INT (0x40); + + puts ("Verifying 0x7f interrupt disabled"); + INT (0x7f); + + puts ("0x7f interrupt disabled, key stored in internal SRAM"); + puts ("unlock by providing the 16 byte key to 0x41 interrupt"); + + memset (&sha_buf, 0, 0x20); + puts ("Internal SRAM Hash:"); + // address, size, out_buf + sha256_internal (0, 0x1000, (char*) &sha_buf); + +addr_44aa: + for (int i /* r11 */ = 0; i != 0x20; i++) { + u8 upper_nibble /* r14 */ = sha_buf[i]; + char lower_char /* r11 */ = HEX_LUT[upper_nibble & 0xf]; + upper_nibble /* r14 */ = (upper_nibble >> 0x4) & 0xf; + putchar (HEX_LUT[upper_nibble]); + putchar (lower_char); + } + puts (""); // prints newline + + while (1) { + u16 loadaddr /* r11 */; + u8 len /* r10 */; + puts ("Please enter debug payload."); + + memset (buf, 0, 0x400); + getsn (buf, 0x3ff); + + loadaddr = (buf[0] << 8) + (buf[1]); + len = buf[3]; + + // the program no longer checks the load address location or alignment + if (len - 6 > 0x3bb) { + puts ("Invalid payload length"); + continue; + } + + puts ("Executing debug payload"); + memcpy (mem + loadaddr, buf + 0x4, len); + + // todo: *loadaddr (); + + } +} diff --git a/25-Halifax/halifax.py b/25-Halifax/halifax.py new file mode 100644 index 0000000..3629207 --- /dev/null +++ b/25-Halifax/halifax.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +import re, os +from sys import byteorder +from hashlib import sha256 + +# match this many hexadigits +# must be corroborated within the script +depth = 6 +# bytes per message +message_size = 1 + +internal_sram_hash = input("Internal SRAM Hash: ").lower() + +target = re.sub(r'\s+', '', input("Encoded 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] + if value: + print(f"{value:x}", end="") + + except KeyError: + value = 0x00 + sram.append(value) + +# write to file +with open("carfax.bin", 'wb') as output: + output.write(sram) + +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}") + +if (sha256(sram).hexdigest().lower() == internal_sram_hash.lower()): + print("Hash match!") diff --git a/25-Halifax/notes.md b/25-Halifax/notes.md new file mode 100644 index 0000000..1425d20 --- /dev/null +++ b/25-Halifax/notes.md @@ -0,0 +1,28 @@ +### Run # vs. Internal SRAM hash + +| Run # | Internal SRAM Hash (sha256) | +|------:|:-------------------------------------------------------------------| +| 1 | `C19684234B668225647FAF0ADC8103131C0E70489B3A548E9223853005FA1E68` | +| 2 | `2A43E7A0C3508BB96BCFAE927776BFBC9ECAD114C022593E524AB0461AD0338A` | +| 3 | `C6E4A567CFB88E05C6F04B9AC93E94BC7AEFCA745B60C4934C02430DAB613B16` | + +Hash appears random each time +Hash is given prior to user input + +Approach: +Hash each individual byte of SRAM, and break the exfiltrated hashes +sha256(8 bit message) ~ identified by first 20 bits +smallest we can do on this mcu is 6 nybbles (24 bits) +Approach works! + +```sh +$ ./halifax.py +> 4AE8158A8DE82D711694455E5A6E7A966C7CD12110B7D2526E340BA9253D383E5D279504A1FCE41F184F087D80594E518C2574E9B0C05C62E067C872EF2D12DF7E70D16BD262C66A19152D043A715A6E7A04D6C072DFCF4E0740E4FF5E4E0740AE3F46E52D9C7C5BD226E5BFA318C2EF6CBD4B68AB36A9E76DA43B8E35C2D4735E5FECEBA9253D98722E333E0A683257A9F515591B7CFFE679333E0A94455E2D31931F18D6FB95AA2D711667586E26E5BFEF2D128D33F544BD7A7CB7C4AE3F46 +number of distinct values in all_hashes: 256 + +513f78eeaff2c4db005ccbdd799fab7a528950943542936dd973afb94c33c033c304c8bc2b0c58204a7132305cfc47bd45811f47ee8a1ddc7806bc35604816c3 +00000000: 513f 78ee aff2 c4db 005c cbdd 799f ab7a Q?x......\..y..z +00000010: 5289 5094 3542 936d d973 afb9 4c33 c033 R.P.5B.m.s..L3.3 +00000020: c304 c8bc 2b0c 5820 4a71 3230 5cfc 47bd ....+.X Jq20\.G. +00000030: 4581 1f47 ee8a 1ddc 7806 bc35 6048 16c3 E..G....x..5`H.. +``` diff --git a/25-Halifax/shellcode copy.asm b/25-Halifax/shellcode copy.asm new file mode 100644 index 0000000..fe1c3f7 --- /dev/null +++ b/25-Halifax/shellcode copy.asm @@ -0,0 +1,78 @@ +; 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 new file mode 100644 index 0000000..6d8fa37 --- /dev/null +++ b/25-Halifax/shellcode.asm @@ -0,0 +1,88 @@ +; 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 + + + +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 + +print_hex: +0b43 5e4b0080 4f4e 0f11 0f11 0f11 0f11 12c3 3ef00f00 3ff0 0f00 5f4f1047 b0127845 5f4e1047 b0127845 1b53 3b90 c000 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 c000 cmp #0x120, r11 ; do that 0x60*3 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.c b/25-Halifax/shellcode.c new file mode 100644 index 0000000..b137c77 --- /dev/null +++ b/25-Halifax/shellcode.c @@ -0,0 +1,126 @@ + +#include "../common/io.c" +#include "../common/lib.c" + +typedef u_int8_t u8; +typedef u_int16_t u16; + +/* +print_hash_inline: +; for (i (r11) = 0; i != 0x20; i++) +44aa: 0b43 clr r11 +pha_loop: +; byte (r14) = hash[i]; +44ac: 0f41 mov sp, r15 +44ae: 0f5b add r11, r15 +44b0: 6e4f mov.b @r15, r14 +; lower_nibble (r15) = byte & 0xf; +44b2: 0f4e mov r14, r15 +44b4: 3ff0 0f00 and #0xf, r15 +; lower_char (r11) = "0123456789ABCDEF"[lower_nibble]; +44b8: 5a4f 1047 mov.b 0x4710(r15), r10 +; upper_nibble (r14) = (byte >> 0x4) & 0xf; +44bc: 12c3 clrc +44be: 4e10 rrc.b r14 +44c0: 12c3 clrc +44c2: 4e10 rrc.b r14 +44c4: 12c3 clrc +44c6: 4e10 rrc.b r14 +44c8: 12c3 clrc +44ca: 4e10 rrc.b r14 +44cc: 3ef0 0f00 and #0xf, r14 +; putchar("0123456789ABCDEF"[upper_nibble]); +44d0: 5f4e 1047 mov.b 0x4710(r14), r15 +44d4: b012 7845 call #0x4578 +; putchar(lower_char) +44d8: 4f4a mov.b r10, r15 +44da: b012 7845 call #0x4578 +; ... i != 0x20; i++) +44de: 1b53 inc r11 +44e0: 3b90 2000 cmp #0x20, r11 +44e4: e323 jne #0x44ac +; puts (""); // prints newline +44e6: 3f40 2147 mov #0x4721, r15 +44ea: b012 8645 call #0x4586 +*/ + +const char *HEX_LUT = "0123456789ABCDEF"; + +void main () { + // consts don't need registers + const u16 start = 0, length = 0x40; + // technically a const as well, but + u8 *shabuffer = mem_get(0x8000); + + // assemble the shabuffer + + /*asm + clr r11 // loop variable in r11 + mov #1, r14 + mov shabuffer [0x8000], r13 + */ +get_sram_hashes: + for (u16 addr = start; addr < length; addr++) { + // we require at least 5 nibbles to determine the value + /*asm + loop: + 0f4b mov r11, r15; mov addr r15 + b012 b645 call #0x45b6 + 3d50 0300 add #3, r13 + 1b53 add 0(r3), r11; inc r11 + 3b90 0010 cmp #0x1000, r11 + jnc loop + + */ + sha256_internal (addr, 1, shabuffer + addr * 3); + } + +print_hex: + // print the buffer + /*asm + 0b43 clr r11; + */ + for (int i = 0; i < length*3; i++) { + /*asm + 1e4b 0080 mov 0x8000(r11), r14 + */ + u8 lower_nibble = shabuffer[i]; + /*asm + 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 + 3ef0 0f00 and #0xf, r14 + 3ff0 0f00 and #0xf, r15 + 12c3 clrc + */ + u8 upper_nibble = (lower_nibble >> 4) & 0xf; + lower_nibble &= 0xf; + /*asm + 5f4f 1047 mov.b 0x4710(r15), r15 + b012 7845 call #0x4578; + */ + putchar(HEX_LUT[upper_nibble]); + /*asm + 5f4e 1047 mov.b 0x4710(r14), r15 + b012 7845 call #0x4578; + */ + putchar(HEX_LUT[lower_nibble]); + /*asm + 1b53 add 0(r3), r11 + 3b90 c000 cmp #0xC0, r11 + e82b jnc $-0x28 + + */ + } + + getsn(mem_get(0x9000), 0x40); + sha256_internal(0, 0x40, 0x9000); + + /*asm + 3041 ret; + */ + return; +}