diff options
| -rw-r--r-- | Content/posts/2023-10-04-bomb-lab.md | 278 | ||||
| -rw-r--r-- | Resources/assets/bomb-lab/phase-3.png | bin | 0 -> 69063 bytes | 
2 files changed, 276 insertions, 2 deletions
| diff --git a/Content/posts/2023-10-04-bomb-lab.md b/Content/posts/2023-10-04-bomb-lab.md index 4919f61..fdbf87c 100644 --- a/Content/posts/2023-10-04-bomb-lab.md +++ b/Content/posts/2023-10-04-bomb-lab.md @@ -1,15 +1,19 @@  ---  date: 2023-10-04 13:12 -description: Introduction, Phase 1 and Phase 2 of Bomb Lab for CSCI 2400 Lab - 2 +description: Introduction, Phases 1-3 of Bomb Lab for CSCI 2400 Lab - 2  tags: gdb, reverse-engineering, c++, csci2400, assembly  --- -# Bomb Lab +# Bomb Lab Phases 1 & 2  ## Introduction  Lab 2 for CSCI 2400 - Computer Systems.  +I like using objdump to disassemble the code and see a broad overview of what is happening.  + +`objdump -d bomb > dis.txt` +  ## Phase 1  ``` @@ -179,3 +183,273 @@ Breakpoint 1, 0x00005555555555eb in phase_2 ()  Continuing.  That's number 2.  Keep going!  ``` + +## Phase 3 + +Let us look at the disassembled code first + +``` +0000000000001638 <phase_3>: +    1638:	f3 0f 1e fa          	endbr64  +    163c:	48 83 ec 18          	sub    $0x18,%rsp +    1640:	48 8d 4c 24 07       	lea    0x7(%rsp),%rcx +    1645:	48 8d 54 24 0c       	lea    0xc(%rsp),%rdx +    164a:	4c 8d 44 24 08       	lea    0x8(%rsp),%r8 +    164f:	48 8d 35 60 1b 00 00 	lea    0x1b60(%rip),%rsi        # 31b6 <_IO_stdin_used+0x1b6> +    1656:	b8 00 00 00 00       	mov    $0x0,%eax +    165b:	e8 80 fc ff ff       	call   12e0 <__isoc99_sscanf@plt> +    1660:	83 f8 02             	cmp    $0x2,%eax +    1663:	7e 20                	jle    1685 <phase_3+0x4d> +    1665:	83 7c 24 0c 07       	cmpl   $0x7,0xc(%rsp) +    166a:	0f 87 0d 01 00 00    	ja     177d <phase_3+0x145> +    1670:	8b 44 24 0c          	mov    0xc(%rsp),%eax +    1674:	48 8d 15 55 1b 00 00 	lea    0x1b55(%rip),%rdx        # 31d0 <_IO_stdin_used+0x1d0> +    167b:	48 63 04 82          	movslq (%rdx,%rax,4),%rax +    167f:	48 01 d0             	add    %rdx,%rax +    1682:	3e ff e0             	notrack jmp *%rax +    1685:	e8 c0 06 00 00       	call   1d4a <explode_bomb> +    168a:	eb d9                	jmp    1665 <phase_3+0x2d> +    168c:	b8 63 00 00 00       	mov    $0x63,%eax +    1691:	81 7c 24 08 3d 02 00 	cmpl   $0x23d,0x8(%rsp) +    1698:	00  +    1699:	0f 84 e8 00 00 00    	je     1787 <phase_3+0x14f> +    169f:	e8 a6 06 00 00       	call   1d4a <explode_bomb> +    16a4:	b8 63 00 00 00       	mov    $0x63,%eax +    16a9:	e9 d9 00 00 00       	jmp    1787 <phase_3+0x14f> +    16ae:	b8 61 00 00 00       	mov    $0x61,%eax +    16b3:	81 7c 24 08 27 01 00 	cmpl   $0x127,0x8(%rsp) +    16ba:	00  +    16bb:	0f 84 c6 00 00 00    	je     1787 <phase_3+0x14f> +    16c1:	e8 84 06 00 00       	call   1d4a <explode_bomb> +    16c6:	b8 61 00 00 00       	mov    $0x61,%eax +    16cb:	e9 b7 00 00 00       	jmp    1787 <phase_3+0x14f> +    16d0:	b8 78 00 00 00       	mov    $0x78,%eax +    16d5:	81 7c 24 08 e7 02 00 	cmpl   $0x2e7,0x8(%rsp) +    16dc:	00  +    16dd:	0f 84 a4 00 00 00    	je     1787 <phase_3+0x14f> +    16e3:	e8 62 06 00 00       	call   1d4a <explode_bomb> +    16e8:	b8 78 00 00 00       	mov    $0x78,%eax +    16ed:	e9 95 00 00 00       	jmp    1787 <phase_3+0x14f> +    16f2:	b8 64 00 00 00       	mov    $0x64,%eax +    16f7:	81 7c 24 08 80 02 00 	cmpl   $0x280,0x8(%rsp) +    16fe:	00  +    16ff:	0f 84 82 00 00 00    	je     1787 <phase_3+0x14f> +    1705:	e8 40 06 00 00       	call   1d4a <explode_bomb> +    170a:	b8 64 00 00 00       	mov    $0x64,%eax +    170f:	eb 76                	jmp    1787 <phase_3+0x14f> +    1711:	b8 6d 00 00 00       	mov    $0x6d,%eax +    1716:	81 7c 24 08 ff 02 00 	cmpl   $0x2ff,0x8(%rsp) +    171d:	00  +    171e:	74 67                	je     1787 <phase_3+0x14f> +    1720:	e8 25 06 00 00       	call   1d4a <explode_bomb> +    1725:	b8 6d 00 00 00       	mov    $0x6d,%eax +    172a:	eb 5b                	jmp    1787 <phase_3+0x14f> +    172c:	b8 71 00 00 00       	mov    $0x71,%eax +    1731:	81 7c 24 08 75 03 00 	cmpl   $0x375,0x8(%rsp) +    1738:	00  +    1739:	74 4c                	je     1787 <phase_3+0x14f> +    173b:	e8 0a 06 00 00       	call   1d4a <explode_bomb> +    1740:	b8 71 00 00 00       	mov    $0x71,%eax +    1745:	eb 40                	jmp    1787 <phase_3+0x14f> +    1747:	b8 79 00 00 00       	mov    $0x79,%eax +    174c:	81 7c 24 08 94 02 00 	cmpl   $0x294,0x8(%rsp) +    1753:	00  +    1754:	74 31                	je     1787 <phase_3+0x14f> +    1756:	e8 ef 05 00 00       	call   1d4a <explode_bomb> +    175b:	b8 79 00 00 00       	mov    $0x79,%eax +    1760:	eb 25                	jmp    1787 <phase_3+0x14f> +    1762:	b8 79 00 00 00       	mov    $0x79,%eax +    1767:	81 7c 24 08 88 02 00 	cmpl   $0x288,0x8(%rsp) +    176e:	00  +    176f:	74 16                	je     1787 <phase_3+0x14f> +    1771:	e8 d4 05 00 00       	call   1d4a <explode_bomb> +    1776:	b8 79 00 00 00       	mov    $0x79,%eax +    177b:	eb 0a                	jmp    1787 <phase_3+0x14f> +    177d:	e8 c8 05 00 00       	call   1d4a <explode_bomb> +    1782:	b8 68 00 00 00       	mov    $0x68,%eax +    1787:	38 44 24 07          	cmp    %al,0x7(%rsp) +    178b:	75 05                	jne    1792 <phase_3+0x15a> +    178d:	48 83 c4 18          	add    $0x18,%rsp +    1791:	c3                   	ret     +    1792:	e8 b3 05 00 00       	call   1d4a <explode_bomb> +    1797:	eb f4                	jmp    178d <phase_3+0x155> +``` + +``` +... +    165b:	e8 80 fc ff ff       	call   12e0 <__isoc99_sscanf@plt> +... +``` + +We can see that `scanf` is being called which means we need to figure out what datatype(s) the program is expecting. + +Because I do not want to enter the solutions to phases 1 and 2 again and again, I am goig to pass a file which has these solutions. + +``` +jovyan@jupyter-nach6988:~/lab2-bomblab-navanchauhan/bombbomb$ gdb -ex 'break phase_3' -ex 'break explode_bomb' -ex 'run' -args ./bomb sol.txt  +GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 +Copyright (C) 2022 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +Type "show copying" and "show warranty" for details. +This GDB was configured as "x86_64-linux-gnu". +Type "show configuration" for configuration details. +For bug reporting instructions, please see: +<https://www.gnu.org/software/gdb/bugs/>. +Find the GDB manual and other documentation resources online at: +    <http://www.gnu.org/software/gdb/documentation/>. + +For help, type "help". +Type "apropos word" to search for commands related to "word"... +Reading symbols from ./bomb... +Breakpoint 1 at 0x1638 +Breakpoint 2 at 0x1d4a +Starting program: /home/jovyan/lab2-bomblab-navanchauhan/bombbomb/bomb sol.txt +[Thread debugging using libthread_db enabled] +Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". +Welcome to my fiendish little bomb. You have 6 phases with +which to blow yourself up. Have a nice day! +Phase 1 defused. How about the next one? +That's number 2.  Keep going! +random string + +Breakpoint 1, 0x0000555555555638 in phase_3 () +(gdb) disas +Dump of assembler code for function phase_3: +=> 0x0000555555555638 <+0>:     endbr64  +   0x000055555555563c <+4>:     sub    $0x18,%rsp +   0x0000555555555640 <+8>:     lea    0x7(%rsp),%rcx +   0x0000555555555645 <+13>:    lea    0xc(%rsp),%rdx +   0x000055555555564a <+18>:    lea    0x8(%rsp),%r8 +   0x000055555555564f <+23>:    lea    0x1b60(%rip),%rsi        # 0x5555555571b6 +   0x0000555555555656 <+30>:    mov    $0x0,%eax +   0x000055555555565b <+35>:    call   0x5555555552e0 <__isoc99_sscanf@plt> +   0x0000555555555660 <+40>:    cmp    $0x2,%eax +   0x0000555555555663 <+43>:    jle    0x555555555685 <phase_3+77> +   0x0000555555555665 <+45>:    cmpl   $0x7,0xc(%rsp) +   0x000055555555566a <+50>:    ja     0x55555555577d <phase_3+325> +   0x0000555555555670 <+56>:    mov    0xc(%rsp),%eax +   0x0000555555555674 <+60>:    lea    0x1b55(%rip),%rdx        # 0x5555555571d0 +   0x000055555555567b <+67>:    movslq (%rdx,%rax,4),%rax +   0x000055555555567f <+71>:    add    %rdx,%rax +   0x0000555555555682 <+74>:    notrack jmp *%rax +   0x0000555555555685 <+77>:    call   0x555555555d4a <explode_bomb> +   0x000055555555568a <+82>:    jmp    0x555555555665 <phase_3+45> +   0x000055555555568c <+84>:    mov    $0x63,%eax +   0x0000555555555691 <+89>:    cmpl   $0x23d,0x8(%rsp) +   0x0000555555555699 <+97>:    je     0x555555555787 <phase_3+335> +   0x000055555555569f <+103>:   call   0x555555555d4a <explode_bomb> +   0x00005555555556a4 <+108>:   mov    $0x63,%eax +   0x00005555555556a9 <+113>:   jmp    0x555555555787 <phase_3+335> +--Type <RET> for more, q to quit, c to continue without paging-- +``` + + +`gdb` has thankfully marked the address which is being passed to `scanf`. We can access the value: + +``` +(gdb) x/1s 0x5555555571b6 +0x5555555571b6: "%d %c %d" +(gdb)  +``` + +BINGO! The program expects an integer, character, and another integer. Onwards. + +``` +   0x0000555555555660 <+40>:    cmp    $0x2,%eax +   0x0000555555555663 <+43>:    jle    0x555555555685 <phase_3+77> +... +   0x0000555555555685 <+77>:    call   0x555555555d4a <explode_bomb> +``` + +The program checks whether `scanf` returns a value <= 2, if it does then it calls the `explode_bomb` function.  + +*Note: `scanf` returns the number of fields that were succesfully converted and assigned* + +``` +   0x0000555555555665 <+45>:    cmpl   $0x7,0xc(%rsp) +   0x000055555555566a <+50>:    ja     0x55555555577d <phase_3+325> +... +   0x000055555555577d <+325>:   call   0x555555555d4a <explode_bomb> +``` + +Similarly, the program checks and ensures the returned value is not > 7.  + + +``` +   0x0000555555555670 <+56>:    mov    0xc(%rsp),%eax +   0x0000555555555674 <+60>:    lea    0x1b55(%rip),%rdx        # 0x5555555571d0 +   0x000055555555567b <+67>:    movslq (%rdx,%rax,4),%rax +   0x000055555555567f <+71>:    add    %rdx,%rax +   0x0000555555555682 <+74>:    notrack jmp *%rax +   0x0000555555555685 <+77>:    call   0x555555555d4a <explode_bomb> +``` + +* `0x0000555555555670 <+56>:    mov    0xc(%rsp),%eax` - Moves value located at `0xc` (12 in Decimal) bytes above the stack pointer to `%eax` register.  +* `0x0000555555555674 <+60>:    lea    0x1b55(%rip),%rdx        # 0x5555555571d0` - This instruction calculates an effective address by adding `0x1b55` to the current instruction pointer (`%rip`). The result is stored in the `%rdx` register.  +* `0x000055555555567b <+67>:    movslq (%rdx,%rax,4),%rax` +   * `movslq` stands for "move with sign-extension from a 32-bit value to a 64-bit value." (if the 32-bit value is negative, the 64-bit result will have all its upper 32 bits set to 1; otherwise, they'll be set to 0).  +   * `(%rdx,%rax,4)` - First start with the value in the %rdx register, then add to it the value in the %rax register multiplied by 4. +   * `%rax` - Destination Register +* `0x000055555555567f <+71>:    add    %rdx,%rax` - Adds base address in `%rdx` to the offset in `%rax`  +* `0x0000555555555682 <+74>:    notrack jmp *%rax` - Jumps to the address stored in `%rax` +* `0x0000555555555685 <+77>:    call   0x555555555d4a <explode_bomb>` - If we are unable to jump to the specified instruction, call `explode_bomb` + +Let us try to run the program again with a valid input for the first number and see what the program is computing for the address. + +I used the input: `3 c 123`. + +To check what is the computed address, we can switch to the asm layout by running `layout asm`, and then going through instructions `ni` or `si` until we reach the line `movslq (%rdx,%rax,4),%rax` + +`%rax` should hold the value 3. + +``` +(gdb) print $rax +$1 = 3 +``` + + + +We can see that this makes us jump to `<phase_3+186>` (Continue to step through the code by using `ni`) + +``` +   0x00005555555556f2 <+186>:   mov    $0x64,%eax +   0x00005555555556f7 <+191>:   cmpl   $0x280,0x8(%rsp) +   0x00005555555556ff <+199>:   je     0x555555555787 <phase_3+335> +   0x0000555555555705 <+205>:   call   0x555555555d4a <explode_bomb> +``` + +We see that `0x64` (Decimal 100) is being stored in `%eax`. Then, the program compares `0x280` (Decimal 640) with memory address `0x8` bytes above the stack pointer (`%rsp`). If the values are equal, then it jumps to `<phase_3+335>`, otherwise `explode_bomb` is called. + +``` +   0x0000555555555787 <+335>:   cmp    %al,0x7(%rsp) +   0x000055555555578b <+339>:   jne    0x555555555792 <phase_3+346> +   0x000055555555578d <+341>:   add    $0x18,%rsp +   0x0000555555555791 <+345>:   ret     +   0x0000555555555792 <+346>:   call   0x555555555d4a <explode_bomb> +``` + +Here, the program is comparing the value of our given character to the value stored in `%al` (lower 8 bits of `EAX`), and checks if they are not equal. + +Knowing that the character is stored at an offset of 7 bytes to `%rsp`, we can print and check the value by running: + +``` +(gdb) x/1cw $rsp+7 +c +(gdb) print $al +$1 = 100 +``` + +We can simply lookup the [ASCII table](https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html), and see that 100 in decimal stands for the character `d`. Let us try this answer: + +``` +... +That's number 2.  Keep going! +3 d 640 + +Breakpoint 1, 0x0000555555555638 in phase_3 () +(gdb) continue +Continuing. +Halfway there! +``` diff --git a/Resources/assets/bomb-lab/phase-3.png b/Resources/assets/bomb-lab/phase-3.pngBinary files differ new file mode 100644 index 0000000..b247a5b --- /dev/null +++ b/Resources/assets/bomb-lab/phase-3.png | 
