# 0ctf 2018 Babystack

This writeup is based off of these resources:
```
https://github.com/sajjadium/ctf-writeups/tree/master/0CTFQuals/2018/babystack
https://kileak.github.io/ctf/2018/0ctf-qual-babystack/
```

The objective of this challenge is to pop a shell, but without using an infoleak. The challenge originally used some python scripting to enforce this, however I did not use it. I know people could take the easy way out with how I have it, but where is the fun in that?

Let's take a look at the binary:

```
$    file babystack
babystack: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=76b50d733400542b34d5e8fa23f0f12dc951d4ef, stripped
$    pwn checksec babystack
[*] '/Hackery/pod/modules/ret2_csu_dl/0ctf18_babystack/babystack'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
$    ./babystack
15935728
```

So we can see that we are dealing with a `32` bit elf, that has a Non-Executable stack. When we run it, it prompts us for input.

## Reversing

When we take a look at the binary in Ghidra, we don't immediately see a `main` function. However we see this function at `0x0804843b`:

```
void scanInput(void)

{
  undefined input [40];
 
  read(0,input,0x40);
  return;
}
```

We can see here that it is scanning in `0x40` (`64`) bytes worth of data in a `40` byte chunk, giving us a `24` byte overflow. When we set a breakpoint for the `read` call in the function at `0x804844c`, we see that it is indeed called (so this function is what was scanning in our input). When we check the offset between the start of our input and the return address, we see that it is `44` bytes.

## Exploitation

So we have an obvious stack overflow bug. However how will we land it? Infoleaks are out of the question, so we can't do a ret2libc attack (returning to gadgets/functions/code in the libc). Also we don't have a libc file provided, so one more reason why ret2libc isn't feasible. It is a dynamically linked binary with a small code base, so we don't have many gadgets to work with. The only imported functions are `alarm` and `read`, and since our input has to be given as a single chunk, that doesn't help us too much. The answer to this is we will be performing a `ret2dlresolve` attack.

#### ret2dlresolve

So dynamically linked binaries are linked with a libc file when they are executed. This provides several advantages such as a smaller binary size. However since when the binary is compiled it doesn't know where functions in libc will be since it is linked at runtime, it has to go through a process of linking it at run time. The tl;dr of this is it essentially just looks up what the libc address of a function it is trying to link, and writes it to a section of memory in the binary, so it can call the libc function. A ret_2_dlresolve attack targets that functionality. First let's talk about how this process works before we talk about how we will attack it.

Elf binaries use something called `Delayed Binding`, which means that the linking process happens when the binary first tries to execute a libc function. To understand that, let's look at what the GOT addresses are for `read` before it is called:

Got table entries for `read` and `alarm` in `.got.plt`:
```
                             PTR_read_0804a00c                               XREF[1]:     read:08048300  
        0804a00c 00 b0 04 08     addr       read                                             = ??
                             PTR_alarm_0804a010                              XREF[1]:     alarm:08048310  
        0804a010 04 b0 04 08     addr       alarm                                            = ??
```

Now let's see what it is

```
gef➤  b *0x804844c
Breakpoint 1 at 0x804844c
gef➤  r
Starting program: /Hackery/pod/modules/ret2_csu_dl/0ctf18_babystack/babystack

Breakpoint 1, 0x0804844c in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0xffffd0d0  →  0xffffd108  →  0x00000000
$ebx   : 0x0       
$ecx   : 0xffffd120  →  0x00000001
$edx   : 0x0       
$esp   : 0xffffd0c0  →  0x00000000
$ebp   : 0xffffd0f8  →  0xffffd108  →  0x00000000
$esi   : 0xf7fb5000  →  0x001dbd6c
$edi   : 0xf7fb5000  →  0x001dbd6c
$eip   : 0x0804844c  →  0xfffeafe8  →  0x00000000
$eflags: [zero carry PARITY ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063
────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffd0c0│+0x0000: 0x00000000     ← $esp
0xffffd0c4│+0x0004: 0xffffd0d0  →  0xffffd108  →  0x00000000
0xffffd0c8│+0x0008: 0x00000040 ("@"?)
0xffffd0cc│+0x000c: 0xf7fb5000  →  0x001dbd6c
0xffffd0d0│+0x0010: 0xffffd108  →  0x00000000
0xffffd0d4│+0x0014: 0xf7fe9790  →   pop edx
0xffffd0d8│+0x0018: 0xffffd144  →  0x00000000
0xffffd0dc│+0x001c: 0xffffd108  →  0x00000000
──────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
    0x8048446                  lea    eax, [ebp-0x28]
    0x8048449                  push   eax
    0x804844a                  push   0x0
 →  0x804844c                  call   0x8048300 <read@plt>
   ↳   0x8048300 <read@plt+0>     jmp    DWORD PTR ds:0x804a00c
       0x8048306 <read@plt+6>     push   0x0
       0x804830b <read@plt+11>    jmp    0x80482f0
       0x8048310 <alarm@plt+0>    jmp    DWORD PTR ds:0x804a010
       0x8048316 <alarm@plt+6>    push   0x8
       0x804831b <alarm@plt+11>   jmp    0x80482f0
──────────────────────────────────────────────────────────────────────────────── arguments (guessed) ────
read@plt (
   [sp + 0x0] = 0x00000000,
   [sp + 0x4] = 0xffffd0d0 → 0xffffd108 → 0x00000000,
   [sp + 0x8] = 0x00000040,
   [sp + 0xc] = 0xf7fb5000 → 0x001dbd6c
)
──────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "babystack", stopped, reason: BREAKPOINT
────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x804844c → call 0x8048300 <read@plt>
[#1] 0x804847a → mov eax, 0x0
[#2] 0xf7df7751 → __libc_start_main()
[#3] 0x8048361 → hlt
─────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  x/w 0x804a00c
0x804a00c <read@got.plt>:    0x8048306
gef➤  x/i 0x8048306
   0x8048306 <read@plt+6>:    push   0x0
gef➤  x/6i 0x8048300
   0x8048300 <read@plt>:    jmp    DWORD PTR ds:0x804a00c
   0x8048306 <read@plt+6>:    push   0x0
   0x804830b <read@plt+11>:    jmp    0x80482f0
   0x8048310 <alarm@plt>:    jmp    DWORD PTR ds:0x804a010
   0x8048316 <alarm@plt+6>:    push   0x8
   0x804831b <alarm@plt+11>:    jmp    0x80482f0
```

So w