From 3532abb66e571647cf3911af10d6c9f3f6e889fc Mon Sep 17 00:00:00 2001 From: Val Date: Mon, 15 Aug 2022 03:57:45 -0500 Subject: [PATCH] Changes from August 15 --- 17-Chernobyl/Code/hashbrek.py | 2 +- 17-Chernobyl/Code/inc/chernobyl.h | 4 +-- 17-Chernobyl/Code/src/chernobyl.c | 22 +++++++++++-- 17-Chernobyl/Code/src/chernobyl_stdlib.c | 40 +++++++++++++++++++----- 17-Chernobyl/Notes | 16 +++++++--- 17-Chernobyl/mc-disasm.asm | 23 +++++++++++--- 6 files changed, 86 insertions(+), 21 deletions(-) diff --git a/17-Chernobyl/Code/hashbrek.py b/17-Chernobyl/Code/hashbrek.py index 1e69e5c..d24be9f 100644 --- a/17-Chernobyl/Code/hashbrek.py +++ b/17-Chernobyl/Code/hashbrek.py @@ -17,7 +17,7 @@ while True: h = hash(bytes.fromhex(line[1:])); else: h = hash(line.encode()) - print(f"hash: {h:x}, box: {h&7:x}"); + print(f"hash: {h:x}, box[3]: {h&7:x}, box[4]: {h&0xf:x}"); except EOFError: break diff --git a/17-Chernobyl/Code/inc/chernobyl.h b/17-Chernobyl/Code/inc/chernobyl.h index 00e159c..b69a10f 100644 --- a/17-Chernobyl/Code/inc/chernobyl.h +++ b/17-Chernobyl/Code/inc/chernobyl.h @@ -8,12 +8,12 @@ u16 walk (u16 r15); u16 run (); u16 *create_hash_table (u16 r15, u16 r14); -u16 add_to_table (u16 r15, u16 r14, u16 r13); +u16 add_to_table (u16 *table, char *username, u16 pin); // Return address of a buffer from the table // r15 = buffer address. r14 u16 get_from_table (void *r15, char *r14); u16 hash (char *str); -u16 rehash (u16 r15, u16 r14); +u16 rehash (u16 *table, u16 r14); // Strings, named after the position of the first character in memory // Strings associated with diff --git a/17-Chernobyl/Code/src/chernobyl.c b/17-Chernobyl/Code/src/chernobyl.c index 152464c..2ee4a1f 100644 --- a/17-Chernobyl/Code/src/chernobyl.c +++ b/17-Chernobyl/Code/src/chernobyl.c @@ -108,8 +108,23 @@ u16 hash (char *addr) { return hash; } -u16 add_to_table (u16 r15, u16 r14, u16 r13) { +u16 add_to_table (u16 *table, char *username, u16 pin) { // todo: add_to_table + u16 r14 = table[1]; // Box bitmask exponent? 3 + u16 r12 = table[2]; // Box bitmask mantissa? 5 + //! What the hell is going on here? + r12 <<= r14; // 3 <<= 5 + if (r12 < 0) { + r12 = r12 + 3; + } + r12 >>= 2; + if (table[0] < r12) { // if there are more names in table than 10: + rehash(*table, r14); // Make more boxes, and shuffle them around? + } + table[0]++; + hash(r14); + r12 = 1 << table[1]; + // Then do some boring stuff return 0; } @@ -124,7 +139,8 @@ u16 get_from_table (void *r15, char *r14) { return 0; } -u16 rehash (u16 r15, u16 r14) { - // todo: this function is very long and performs dynalloc +u16 rehash (u16 *table, u16 exponent) { // Now I see the problem + // This function makes the hash table 2^exponent units long + // and rehashes all the usernames stored in each box return 0; } diff --git a/17-Chernobyl/Code/src/chernobyl_stdlib.c b/17-Chernobyl/Code/src/chernobyl_stdlib.c index 1e51b90..fc5f763 100644 --- a/17-Chernobyl/Code/src/chernobyl_stdlib.c +++ b/17-Chernobyl/Code/src/chernobyl_stdlib.c @@ -23,13 +23,39 @@ u16 get_w (u16 *addr) { } void *_malloc (u16 size) { - // if heap not initialized, initialize the heap - // if (get_w (HEAP_BASE + 4)) { - // u16 heap_ptr = HEAP_BASE; - // set_w (heap_ptr, HEAP_BASE); - // set_w (heap_ptr + 2, HEAP_BASE); - // } - // create a new block on the heap + /* +4678: 0b12 push r11 +467a: c293 0424 tst.b &0x2404 +467e: 0f24 jz $+0x20 +4680: 1e42 0024 mov &0x2400, r14 +4684: 8e4e 0000 mov r14, 0x0(r14) +4688: 8e4e 0200 mov r14, 0x2(r14) +468c: 1d42 0224 mov &0x2402, r13 +4690: 3d50 faff add #0xfffa, r13 +4694: 0d5d add r13, r13 +4696: 8e4d 0400 mov r13, 0x4(r14) +469a: c243 0424 mov.b #0x0, &0x2404 +; malloc+0x26: +469e: 1b42 0024 mov &0x2400, r11 +46a2: 0e4b mov r11, r14 +46a4: 1d4e 0400 mov 0x4(r14), r13 +46a8: 1db3 bit #0x1, r13 +46aa: 2820 jnz $+0x52 <46fc> + +46fc: 0d4e mov r14, r13 +46fe: 1e4e 0200 mov 0x2(r14), r14 +4702: 0e9d cmp r13, r14 +4704: 0228 jnc $+0x6 +4706: 0e9b cmp r11, r14 +4708: cd23 jnz $-0x64 +; puts("Heap exhausted. Aborting") +470a: 3f40 5e46 mov #0x465e, r15 +470e: b012 504d call #0x4d50 +4712: 3040 3e44 br #0x443e <__stop_progExec__> +4716: 0f43 clr r15 +4718: 3b41 pop r11 +471a: 3041 ret +*/ // return the address of the new block return 0; diff --git a/17-Chernobyl/Notes b/17-Chernobyl/Notes index d7b3ad7..494d1a0 100644 --- a/17-Chernobyl/Notes +++ b/17-Chernobyl/Notes @@ -3,14 +3,14 @@ Hash Table, plus one full box: 5000: 0050 1050 1500 0b00 0300 0500 1650 2c50 .P.P.........P,P 5010: 0050 2650 2100 4250 a250 0251 6251 c251 .P&P!.BP.P.QbQ.Q -5020: 2252 8252 e252 1050 3c50 2100 0a00 0000 "R.R.R.P+1) - 1) 04: 0005: Parameter 2 (Rightshift?) 06: 5016: & Box Pointer List - 08: 502c: & Other Data Section + 08: 502c: & Per-box User Count List Box Pointer List: Box list header metadata @ 5010: 0050 2650 2100 @@ -50,3 +50,11 @@ Other Data Section (?) Section header metadata @ 5026: 1050 3c50 2100 [ Prev: 5010, Next: 503c, Size: 0010 ] Data: 0a00 0000 0000 0000 0000 0000 0000 0000 + + +The Exploit: +When an 11th user is added, the software will attempt to double the size of the heap. Overwriting a heap Next pointer allows us toAAAA + + +for c in ['1', '9', 'A', 'I', 'Q', '0', '8', '@', 'H', 'P', 'AAAAAAAAAAAAAAAA', '']: + print(f'new {c} ;',end="") diff --git a/17-Chernobyl/mc-disasm.asm b/17-Chernobyl/mc-disasm.asm index b1466eb..44f85f1 100644 --- a/17-Chernobyl/mc-disasm.asm +++ b/17-Chernobyl/mc-disasm.asm @@ -304,6 +304,7 @@ 46a4: 1d4e 0400 mov 0x4(r14), r13 46a8: 1db3 bit #0x1, r13 46aa: 2820 jnz $+0x52 +; This is all initialization 46ac: 0c4d mov r13, r12 46ae: 12c3 clrc 46b0: 0c10 rrc r12 @@ -339,6 +340,7 @@ 4704: 0228 jnc $+0x6 4706: 0e9b cmp r11, r14 4708: cd23 jnz $-0x64 +; puts("Heap exhausted. Aborting") 470a: 3f40 5e46 mov #0x465e, r15 470e: b012 504d call #0x4d50 4712: 3040 3e44 br #0x443e <__stop_progExec__> @@ -479,24 +481,33 @@ hash_loop_start: 483e: 1e4f 0200 mov 0x2(r15), r14 4842: 1c4f 0400 mov 0x4(r15), r12 4846: 0f4e mov r14, r15 +; r12 << r15 4848: 0f93 tst r15 484a: 0324 jz $+0x8 -484c: 0c5c add r12, r12 +484c: 0c5c add r12, r12 ; RLA r12 484e: 1f83 dec r15 4850: fd23 jnz $-0x4 +; if (r12 < 0): 4852: 0c93 tst r12 4854: 0234 jge $+0x6 +; r12 = (r12 + 3) >> 1 4856: 3c50 0300 add #0x3, r12 485a: 0c11 rra r12 +; r12 >>= 1 485c: 0c11 rra r12 +; if (r11[0] < r12): 485e: 2c9b cmp @r11, r12 4860: 0434 jge $+0xa +; rehash(r14, r11) 4862: 1e53 inc r14 4864: 0f4b mov r11, r15 4866: b012 d448 call #0x48d4 +; *r11++ 486a: 9b53 0000 inc 0x0(r11) +; r15 = hash (r10) 486e: 0f4a mov r10, r15 4870: b012 0e48 call #0x480e +; r12 = (1 << r11[2]) - 1 4874: 1c43 mov #0x1, r12 4876: 1e4b 0200 mov 0x2(r11), r14 487a: 0e93 tst r14 @@ -505,6 +516,7 @@ hash_loop_start: 4880: 1e83 dec r14 4882: fd23 jnz $-0x4 4884: 3c53 add #-0x1, r12 + 4886: 0cff and r15, r12 4888: 0c5c add r12, r12 488a: 1f4b 0800 mov 0x8(r11), r15 @@ -522,17 +534,20 @@ hash_loop_start: 48a6: 1e53 inc r14 48a8: 8f4e 0000 mov r14, 0x0(r15) 48ac: 0f43 clr r15 -48ae: 093c jmp $+0x14 +48ae: 093c jmp $+0x14 ; A +; *C 48b0: 0b4c mov r12, r11 48b2: 0b5f add r15, r11 48b4: cb4e 0000 mov.b r14, 0x0(r11) 48b8: 1f53 inc r15 48ba: 3f90 0f00 cmp #0xf, r15 -48be: 0424 jz $+0xa +48be: 0424 jz $+0xa ; B 48c0: 1a53 inc r10 +; *A 48c2: 6e4a mov.b @r10, r14 48c4: 4e93 tst.b r14 -48c6: f423 jnz $-0x16 +48c6: f423 jnz $-0x16 ; C +; *B 48c8: 8c49 1000 mov r9, 0x10(r12) 48cc: 3941 pop r9 48ce: 3a41 pop r10