# Mary Morton

So after we download and extract the file, we have a binary. Let's take a look at the binary (also one thing, I slightly modified this binary, but we'll cover that in more detail later):

```
$    file mary_morton
mary_morton: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b7971b84c2309bdb896e6e39073303fc13668a38, stripped
$    pwn checksec mary_morton
[*] '/Hackery/asis/mary/mary_morton'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
```

So we see that it is a 64 bit Elf, with a stack canary and non executable stack. Let's see what happens when we run the binary:

```
$    ./mary_morton
Welcome to the battle !
[Great Fairy] level pwned
Select your weapon
1. Stack Bufferoverflow Bug
2. Format String Bug
3. Exit the battle
2
%x.%x.%x.%x.%x
c743ca40.7f.14b4a890.0.0
1. Stack Bufferoverflow Bug
2. Format String Bug
3. Exit the battle
Alarm clock
```

So we see we are given a prompt for a Buffer Overflow, format string, or just to exit the battle. We confirmed that the format string bug indeed works with the `%x` flags. We can also that there is an alarm feature which will kill the program after a set amount of time. We can run it in gdb, that way when the Alarm Clock triggers it won't kill the program.

```
gef➤  r
Starting program: /Hackery/pod/modules/ret_2_system/asis17_marymorton/mary_morton 
Welcome to the battle ! 
[Great Fairy] level pwned 
Select your weapon 
1. Stack Bufferoverflow Bug 
2. Format String Bug 
3. Exit the battle 
[PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED]
->[PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED]
�;U���7P
@
*** stack smashing detected ***: <unknown> terminated
```

So we also verified that the buffer overflow bug is legit. Let's take a look at the binary in Ghidra.

## Reversing

Looking through the list of functions in Ghidra, we find this one at `0x400826`:

```

void menu(void)

{
  int choice;
  
  FUN_004009ff();
  puts("Welcome to the battle ! ");
  puts("[Great Fairy] level pwned ");
  puts("Select your weapon ");
  while( true ) {
    while( true ) {
      printMenu();
      __isoc99_scanf(&DAT_00400b1c,&choice);
      if (choice != 2) break;
      fmtBug();
    }
    if (choice == 3) break;
    if (choice == 1) {
      overflowBug();
    }
    else {
      puts("Wrong!");
    }
  }
  puts("Bye ");
                    /* WARNING: Subroutine does not return */
  exit(0);
}

```

So we can see here the function prints out the starting prompt, then enters into a loop where it will print out the menu options, then scan in input. Based upon the input, it will either trigger the `fmtBug` function, `overflowBug` function, or just exit the program. Let's take a look at the `fmtBug` function.

```
void fmtBug(void)

{
  long i;
  undefined8 *inputCpy;
  long in_FS_OFFSET;
  undefined8 input [17];
  long canary;
  
  canary = *(long *)(in_FS_OFFSET + 0x28);
  i = 0x10;
  inputCpy = input;
  while (i != 0) {
    i = i + -1;
    *inputCpy = 0;
    inputCpy = inputCpy + 1;
  }
  read(0,input,0x7f);
  printf((char *)input);
  if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
```

So we can see here, it pretty much does what we expected. It first clears out a space of memory, then scans in input to that space (`0x7f` bytes). Proceeding that it prints it unformatted using `printf` to have a format string vulnerability. Let's take a look at the `overflowBug`:

```
void overflowBug(void)

{
  long i;
  undefined8 *inputCpy;
  long in_FS_OFFSET;
  undefined8 input [17];
  long canary;
  
  canary = *(long *)(in_FS_OFFSET + 0x28);
  i = 0x10;
  inputCpy = input;
  while (i != 0) {
    i = i + -1;
    *inputCpy = 0;
    inputCpy = inputCpy + 1;
  }
  read(0,input,0x100);
  printf("-> %s\n",input);
  if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
```

Looking at this, we can see that it reads in `0x100` (`256`) bytes of data into the buffer that Ghidra says only has `17` bytes. Thing is, when we look at the stack layout we see that the buffer is bigger than that:

```
                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined overflowBug()
             undefined         AL:1           <RETURN>
             long              RCX:8          i                                       XREF[1]:     00400986(W)  
             undefined8 *      RDI:8          inputCpy                                XREF[1]:     0040098e(W)  
             long              Stack[-0x10]:8 canary                                  XREF[2]:     00400974(W), 
                                                                                                   004009c4(R)  
             undefined8[17]    Stack[-0x98]   input                                   XREF[3]:     0040097a(*), 
                                                                                                   00400991(*), 
                                                                                                   004009aa(*)  
                             overflowBug                                     XREF[3]:     menu:004008a7(c), 00400bc0, 
                                                                                          00400cc0(*)  
        00400960 55              PUSH       RBP
```
So we can see that `input` is at offset `-0x98`, and that `canary` is at offset `-0x10`. That gives us `0x98 - 0x10 = 0x88` byte offset. Since we can scan in `0x100` bytes this is is a buffer overflow bug. Also after it scans in the input, it prints the data you scanned in. So we should be able to use the buffer overflow vulnerability to pop a shell. However our first hurdle will be to defeat the stack canary.

## Exploitation

In order to reach the return address to gain code flow execution, we will have to write over the stack canary. Before we do that, we will need to leak the stack canary, so we can write over the stack canary with itself. That way when the stack canary is checked, everything will check out. We should be able to accomplish this using the format string exploit to leak an address. Also as a sidenote we could probably use the buffer o