# Tamu19 pwn1

Let's take a look at the binary:

```
$    file pwn1
pwn1: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=d126d8e3812dd7aa1accb16feac888c99841f504, not stripped
$    pwn checksec pwn1
[*] '/Hackery/pod/modules/bof_variable/tamu19_pwn1/pwn1'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled
$    ./pwn1
Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see.
What... is your name?
15935728
I don't know that! Auuuuuuuugh!
```

So we can see that it is a `32` bit binary with RELRO, a Non-Executable Stack, and PIE (those binary mitigations will be discussed later). We can see that when we run the binary, it prompts us for input, and prints some text. When we take a look at the main function in Ghidra we see this:

```
/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */
/* WARNING: Removing unreachable block (ram,0x000108bb) */

undefined4 main(void)

{
  int strcmpResult0;
  int strcmpResult1;
  char input [43];
 
  setvbuf(stdout,(char *)0x2,0,0);
  puts(
      "Stop! Who would cross the Bridge of Death must answer me these questions three, ere theother side he see."
      );
  puts("What... is your name?");
  fgets(input,0x2b,stdin);
  strcmpResult0 = strcmp(input,"Sir Lancelot of Camelot\n");
  if (strcmpResult0 != 0) {
    puts("I don\'t know that! Auuuuuuuugh!");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  puts("What... is your quest?");
  fgets(input,0x2b,stdin);
  strcmpResult1 = strcmp(input,"To seek the Holy Grail.\n");
  if (strcmpResult1 == 0) {
    puts("What... is my secret?");
    gets(input);
    puts("I don\'t know that! Auuuuuuuugh!");
    return 0;
  }
  puts("I don\'t know that! Auuuuuuuugh!");
                    /* WARNING: Subroutine does not return */
  exit(0);
}
```

So right off the back, we can see we are dealing with a reference to one of the greatest movies ever (Monty Python and the Holy Grail). We can see that it will scan in input into `input` using `fgets`, then compares our input with `strcmp`. It does this twice. The first time it checks for the string `Sir Lancelot of Camelot\n` and the second time it checks for the string `To seek the Holy Grail.\n`. If we don't pass the check the first time, it will print `I don\'t know that! Auuuuuuuugh!` and exit. For the second check if we pass it, the code will call the function `gets` with `input` as an argument. The function `gets` will scan in data until it either gets a newline character or an EOF. As a result on paper there is no limit to how much it can scan into memory. Since the are it is scanning into is finite, we will be able to overflow it and start overwriting subsequent things in memory.

Also looking at the assembly code for around the `gets` call, we see something interesting that the decompiled code doesn't show us:
```
        000108aa e8 71 fc        CALL       gets                                             char * gets(char * __s)
                 ff ff
        000108af 83 c4 10        ADD        ESP,0x10
        000108b2 81 7d f0        CMP        dword ptr [EBP + local_18],0xdea110c8
                 c8 10 a1 de
        000108b9 75 07           JNZ        LAB_000108c2
        000108bb e8 3d fe        CALL       print_flag                                       undefined print_flag()
                 ff ff
```

So we can see that it compares the contents of `local_18` to `0xdea110c8`, and if it is equal (which would mean it's zero) it calls the `print_flag` function. Looking at the decompiled code for `print_flag`, we see that it prints the contents of `flag.txt`:
```
/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */

void print_flag(void)

{
  FILE *flagFile;
  int flag;
 
  puts("Right. Off you go.");
  flagFile = fopen("flag.txt","r");
  while( true ) {
    flag = _IO_getc((_IO_FILE *)flagFile);
    if ((char)flag == -1) break;
    putchar((int)(char)flag);
  }
  putchar(10);
  return;
}
```

So if we can use the `gets` call to overwrite the contents of `local_18` to `0xdea110c8`, we should get the flag (if you're running this locally you will need to have a copy of `flag.txt` that is in the same directory as the binary). So in order to reach the `gets` call, we will need to send the program the string `Sir Lancelot of Camelot\n` and `To seek the Holy Grail.\n`. Looking at the stack layout in Ghidra (we can see it by double clicking on any of the variables in the variable declarations for the main function) shows us the offset between the start of our input and `local_18`:

```
                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined main(undefined1 param_1)
             undefined         AL:1           <RETURN>                                XREF[2]:     00010807(W),
                                                                                                   00010869(W)  
             undefined1        Stack[0x4]:1   param_1                                 XREF[1]:     00010779(*)  
             int               EAX:4          strcmpResult0                           XREF[1]:     00010807(W)  
             int               EAX:4          strcmpResult1                           XREF[1]:     00010869(W)  
             undefined4        Stack[0x0]:4   local_res0                              XREF[1]:     00010780(R)  
             undefined1        Stack[-0x10]:1 local_10                                XREF[1]:     000108d9(*)  
             undefined4        Stack[-0x14]:4 local_14                                XREF[1]:     000107ad(W)  
             undefined4        Stack[-0x18]:4 local_18                                XREF[2]:     000107b4(W),
                                                                                                   000108b2(R)  
             char[43]          Stack[-0x43]   input                                   XREF[5]:     000107ed(*),
                                                                                                   00010803(*),
                                                                                                   0001084f(*),
                                                                                                   00010865(*),
                                                                                                   000108a6(*)  
                             main                                            XREF[5]:     Entry Point(*),