# Csaw 2016 Quals Warmup

Let's take a look at the binary:

```
$    file warmup
warmup: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.24, BuildID[sha1]=ab209f3b8a3c2902e1a2ecd5bb06e258b45605a4, not stripped
$    ./warmup
-Warm Up-
WOW:0x40060d
>15935728
```

So we can see that we are dealing with a 64 bit binary. When we run it, it displays an address (looks like an address from the code section of the binary, versus another section like the libc) and prompts us for input. When we look at the main function in Ghidra, we see this:

```
void main(void)

{
  char easyFunctionAddress [64];
  char input [64];
 
  write(1,"-Warm Up-\n",10);
  write(1,&DAT_0040074c,4);
  sprintf(easyFunctionAddress,"%p\n",easy);
  write(1,easyFunctionAddress,9);
  write(1,&DAT_00400755,1);
  gets(input);
  return;
}
```

So we can see that the address being printed is the address of the function `easy` (which when we look at it's address in Ghidra we see it's `0x40060d`). After that we can see it calls the function `gets`, which is a bug since it doesn't limit how much data it scans in (and since `input` can only hold `64` bytes of data, after we write `64` bytes we overflow the buffer and start overwriting other things in memory). With that bug we can totally reach the return address (the address on the stack that is executed after the `ret` call to return execution back to whatever code called it). For what to call, we see that the `easy` function will print the flag for us (in order to print the flag, we will need to have a `flag.txt` file in the same directory as the executable):

```
void easy(void)

{
  system("cat flag.txt");
  return;
}
```

So let's use gdb to figure out how much data we need to send before overwriting the return address, so we can land the bug. I will just set a breakpoint for after the `gets` call:

```
gef➤  disas main
Dump of assembler code for function main:
   0x[PII_REDACTED]40061d <+0>:    push   rbp
   0x[PII_REDACTED]40061e <+1>:    mov    rbp,rsp
   0x[PII_REDACTED]400621 <+4>:    add    rsp,0xffffffffffffff80
   0x[PII_REDACTED]400625 <+8>:    mov    edx,0xa
   0x[PII_REDACTED]40062a <+13>:    mov    esi,0x400741
   0x[PII_REDACTED]40062f <+18>:    mov    edi,0x1
   0x[PII_REDACTED]400634 <+23>:    call   0x4004c0 <write@plt>
   0x[PII_REDACTED]400639 <+28>:    mov    edx,0x4
   0x[PII_REDACTED]40063e <+33>:    mov    esi,0x40074c
   0x[PII_REDACTED]400643 <+38>:    mov    edi,0x1
   0x[PII_REDACTED]400648 <+43>:    call   0x4004c0 <write@plt>
   0x[PII_REDACTED]40064d <+48>:    lea    rax,[rbp-0x80]
   0x[PII_REDACTED]400651 <+52>:    mov    edx,0x40060d
   0x[PII_REDACTED]400656 <+57>:    mov    esi,0x400751
   0x[PII_REDACTED]40065b <+62>:    mov    rdi,rax
   0x[PII_REDACTED]40065e <+65>:    mov    eax,0x0
   0x[PII_REDACTED]400663 <+70>:    call   0x400510 <sprintf@plt>
   0x[PII_REDACTED]400668 <+75>:    lea    rax,[rbp-0x80]
   0x[PII_REDACTED]40066c <+79>:    mov    edx,0x9
   0x[PII_REDACTED]400671 <+84>:    mov    rsi,rax
   0x[PII_REDACTED]400674 <+87>:    mov    edi,0x1
   0x[PII_REDACTED]400679 <+92>:    call   0x4004c0 <write@plt>
   0x[PII_REDACTED]40067e <+97>:    mov    edx,0x1
   0x[PII_REDACTED]400683 <+102>:    mov    esi,0x400755
   0x[PII_REDACTED]400688 <+107>:    mov    edi,0x1
   0x[PII_REDACTED]40068d <+112>:    call   0x4004c0 <write@plt>
   0x[PII_REDACTED]400692 <+117>:    lea    rax,[rbp-0x40]
   0x[PII_REDACTED]400696 <+121>:    mov    rdi,rax
   0x[PII_REDACTED]400699 <+124>:    mov    eax,0x0
   0x[PII_REDACTED]40069e <+129>:    call   0x400500 <gets@plt>
   0x[PII_REDACTED]4006a3 <+134>:    leave  
   0x[PII_REDACTED]4006a4 <+135>:    ret    
End of assembler dump.
gef➤  b *main+134
Breakpoint 1 at 0x4006a3
gef➤  r
Starting program: /Hackery/pod/modules/bof_callfunction/csaw16_warmup/warmup
-Warm Up-
WOW:0x40060d
>15935728
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────── registers ────
$rax   : 0x00007fffffffde50  →  "15935728"
$rbx   : 0x0               
$rcx   : 0x00007ffff7dcfa00  →  0x00000000fbad2288
$rdx   : 0x00007ffff7dd18d0  →  0x[PII_REDACTED]000000
$rsp   : 0x00007fffffffde10  →  "0x40060d"
$rbp   : 0x00007fffffffde90  →  0x[PII_REDACTED]4006b0  →  <__libc_csu_init+0> push r15
$rsi   : 0x35333935        
$rdi   : 0x00007fffffffde51  →  0x[PII_REDACTED]333935 ("5935728"?)
$rip   : 0x[PII_REDACTED]4006a3  →  <main+134> leave
$r8    : 0x[PII_REDACTED]602269  →  0x[PII_REDACTED]000000
$r9    : 0x00007ffff7fda4c0  →  0x00007ffff7fda4c0  →  [loop detected]
$r10   : 0x[PII_REDACTED]602010  →  0x[PII_REDACTED]000000
$r11   : 0x246             
$r12   : 0x[PII_REDACTED]400520  →  <_start+0> xor ebp, ebp
$r13   : 0x00007fffffffdf70  →  0x[PII_REDACTED]000001
$r14   : 0x0               
$r15   : 0x0               
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffde10│+0x0000: "0x40060d"     ← $rsp
0x00007fffffffde18│+0x0008: 0x[PII_REDACTED]00000a
0x00007fffffffde20│+0x0010: 0x[PII_REDACTED]000000
0x00007fffffffde28│+0x0018: 0x[PII_REDACTED]000000
0x00007fffffffde30│+0x0020: 0x[PII_REDACTED]000000
0x00007fffffffde38│+0x0028: 0x[PII_REDACTED]000000
0x00007fffffffde40│+0x0030: 0x[PII_REDACTED]000000
0x00007fffffffde48│+0x0038: 0x[PII_REDACTED]000000
─────────────────────────────────────────────────────────────── code:x86:64 ────
     0x400694 <main+119>       rex.RB ror BYTE PTR [r8-0x77], 0xc7
     0x400699 <main+124>       mov    eax, 0x0
     0x40069e <main+129>       call   0x400500 <gets@plt>
 →   0x4006a3 <main+134>       leave  
     0x4006a4 <main+135>       ret    
     0x4006a5                  nop    WORD PTR cs:[rax+rax*1+0x0]
     0x4006af                  nop    
     0x4006b0 <__libc_csu_init+0> push   r15
     0x4006b2 <__libc_csu_init+2> mov    r15d, edi
─────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "warmup", stopped, reason: BREAKPOINT
───────────────────────────────────────────────────────────────────── trace ────
[#0] 0x4006a3 → main()
────────────────────────────────────────────────────────────────────────────────

Breakpoint 1, 0x[PII_REDACTED]4006a3 in main ()
gef➤  search-pattern 15935728
[+] Searching '15935728' in memory
[+] In '[heap]'(0x602000-0x623000), permission=rw-
  0x602260 - 0x602268  →   "15935728"
[+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw-
  0x7fffffffde50 - 0x7fffffffde58  →   "15935728"
gef➤  i f
Stack level 0, frame at 0x7fffffffdea0:
 rip = 0x4006a3 in main; saved rip = 0x7ffff7a05b97
 Arglist at 0x7fffffffde90, args:
 Locals at 0x7fffffffde90, Previous frame's sp is 0x7fffffffdea0
 Saved registers:
  rbp at 0x7fffffffde90, rip at 0x7fffffffde98
```

With a bit of math, we see the offset:
```
>>> hex(0x7fffffffde98 - 0x7fffffffde50)
'0x48'
```

So we can see that after `0x48` bytes of input, we start overwriting the return address. With all o