summaryrefslogtreecommitdiff
path: root/Content
diff options
context:
space:
mode:
Diffstat (limited to 'Content')
-rw-r--r--Content/posts/2023-10-04-bomb-lab.md131
1 files changed, 128 insertions, 3 deletions
diff --git a/Content/posts/2023-10-04-bomb-lab.md b/Content/posts/2023-10-04-bomb-lab.md
index d235186..98c5272 100644
--- a/Content/posts/2023-10-04-bomb-lab.md
+++ b/Content/posts/2023-10-04-bomb-lab.md
@@ -1,10 +1,10 @@
---
date: 2023-10-04 13:12
-description: Introduction, Phases 1-4 of Bomb Lab for CSCI 2400 Lab - 2
+description: Introduction, Phases 1-5 of Bomb Lab for CSCI 2400 Lab - 2
tags: gdb, reverse-engineering, c++, csci2400, assembly
---
-# Bomb Lab Phases 1-4
+# Bomb Lab Phases 1-5
## Introduction
@@ -621,7 +621,7 @@ def func4(edi, esi=0, edx=20):
else:
return 0
-for x in range(10):
+for x in range(15): # We can limit to 14
if func4(x) == 2:
print(f"answer is {x}")
break
@@ -653,3 +653,128 @@ Continuing.
So you got that one. Try this one.
```
+## Phase 5
+
+```
+So you got that one. Try this one.
+test string
+
+Breakpoint 1, 0x0000555555555830 in phase_5 ()
+(gdb) disas phase_5
+Dump of assembler code for function phase_5:
+=> 0x0000555555555830 <+0>: endbr64
+ 0x0000555555555834 <+4>: push %rbx
+ 0x0000555555555835 <+5>: sub $0x10,%rsp
+ 0x0000555555555839 <+9>: mov %rdi,%rbx
+ 0x000055555555583c <+12>: call 0x555555555b10 <string_length>
+ 0x0000555555555841 <+17>: cmp $0x6,%eax
+ 0x0000555555555844 <+20>: jne 0x55555555588b <phase_5+91>
+ 0x0000555555555846 <+22>: mov $0x0,%eax
+ 0x000055555555584b <+27>: lea 0x199e(%rip),%rcx # 0x5555555571f0 <array.0>
+ 0x0000555555555852 <+34>: movzbl (%rbx,%rax,1),%edx
+ 0x0000555555555856 <+38>: and $0xf,%edx
+ 0x0000555555555859 <+41>: movzbl (%rcx,%rdx,1),%edx
+ 0x000055555555585d <+45>: mov %dl,0x9(%rsp,%rax,1)
+ 0x0000555555555861 <+49>: add $0x1,%rax
+ 0x0000555555555865 <+53>: cmp $0x6,%rax
+ 0x0000555555555869 <+57>: jne 0x555555555852 <phase_5+34>
+ 0x000055555555586b <+59>: movb $0x0,0xf(%rsp)
+ 0x0000555555555870 <+64>: lea 0x9(%rsp),%rdi
+ 0x0000555555555875 <+69>: lea 0x1943(%rip),%rsi # 0x5555555571bf
+ 0x000055555555587c <+76>: call 0x555555555b31 <strings_not_equal>
+ 0x0000555555555881 <+81>: test %eax,%eax
+ 0x0000555555555883 <+83>: jne 0x555555555892 <phase_5+98>
+ 0x0000555555555885 <+85>: add $0x10,%rsp
+ 0x0000555555555889 <+89>: pop %rbx
+ 0x000055555555588a <+90>: ret
+ 0x000055555555588b <+91>: call 0x555555555d4a <explode_bomb>
+ 0x0000555555555890 <+96>: jmp 0x555555555846 <phase_5+22>
+ 0x0000555555555892 <+98>: call 0x555555555d4a <explode_bomb>
+ 0x0000555555555897 <+103>: jmp 0x555555555885 <phase_5+85>
+End of assembler dump.
+(gdb)
+```
+
+```
+...
+ 0x000055555555583c <+12>: call 0x555555555b10 <string_length>
+ 0x0000555555555841 <+17>: cmp $0x6,%eax
+ 0x0000555555555844 <+20>: jne 0x55555555588b <phase_5+91>
+...
+ 0x000055555555588b <+91>: call 0x555555555d4a <explode_bomb>
+...
+```
+
+First things first, these instructions check to make sure the passed string is of length 6, otherwise `explode_bomb` is called.
+
+We can also see a similar pattern compared to Phase 2, where we had a loop:
+
+* The looping part:
+ * `mov $0x0,%eax` - Initialise `%eax` and set it to 0 (our counter/iterator)
+ * `movzbl (%rbx,%rax,1),%edx` - Access `%rbx + 1 * %rax` and store it in `%edx`
+ * `and $0xf,%edx` - Take the least significant 4 bits of the byte.
+ * `movzbl (%rcx,%rdx,1),%edx` - Use the 4 bits as an index into another array and load the corresponding byte into `%edx`
+ * `mov %dl,0x9(%rsp,%rax,1)` - Store the transformed byte into a buffer on the stack
+ * `add $0x1,%rax` - Increment `%rax`
+ * `cmp $0x6,%rax` - If the index is not yet 6, loop again
+* `movb $0x0,0xf(%rsp)` - Null-terminate the transformed string
+* `lea 0x9(%rsp),%rdi` and `lea 0x1943(%rip),%rsi`
+* `all 0x555555555b31 <strings_not_equal>` check if the two strings loaded up just before this are equal or not.
+
+We can check the reference string we need, which `gdb` has marked as `# 0x5555555571bf`, and the lookup table marked as `# 0x5555555571f0 <array.0>`
+
+```
+(gdb) x/s 0x5555555571bf
+0x5555555571bf: "bruins"
+(gdb) x/s 0x5555555571f0
+0x5555555571f0 <array.0>: "maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?"
+(gdb)
+```
+
+To summarize the transformation process:
+
+* The function takes each byte of the string
+* It keeps only the least significant 4 bits of each byte
+* It uses these 4 bits as an index into the lookup table (`array.0`)
+* The value from the array is then stored in a buffer
+
+Here's how the transformation process can be reversed for each character in "bruins":
+1. Find the index of `b` in the lookup table (in our case, it is 13 since we index starting 0)
+2. Calculate binary representation of this index (in our case 13 can be written as 1101 in binary)
+3. Find ASCII character whose least significant 4 bits match (in our case, `m` has binary representation `01101101`)
+
+Repeat for all 6 characters
+
+*Hint: Using an [ASCII - Binary Table](http://sticksandstones.kstrom.com/appen.html) can save you time.*
+
+Thus, we can have the following transformation:
+
+```
+b -> m
+r -> f
+u -> c
+i -> d
+n -> h
+s -> g
+```
+
+
+Let us try out this answer:
+
+```
+...
+That's number 2. Keep going!
+Halfway there!
+So you got that one. Try this one.
+mfcdhg
+
+Breakpoint 1, 0x0000555555555830 in phase_5 ()
+(gdb) continue
+Continuing.
+Good work! On to the next...
+```
+
+Awesome!
+
+## Phase 6
+