# Tuctf 2018 shella-easy

Let's take a look at the binary:

```
$	file shella-easy 
shella-easy: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=38de[PII_REDACTED]023aadd2209673b21577463b66, not stripped
$	./shella-easy 
Yeah I'll have a 0xffd01f50 with a side of fries thanks
15935728
```

So we can see that we are dealing with a 32 bit binary. When we run it, it prints out what looks like a stack address and prompts us for input. When we take a look at the main function, we see this:

```
/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */
/* WARNING: Removing unreachable block (ram,0x08048551) */

void main(void)

{
  char input [64];
  
  setvbuf(stdout,(char *)0x0,2,0x14);
  setvbuf(stdin,(char *)0x0,2,0x14);
  printf("Yeah I\'ll have a %p with a side of fries thanks\n",input);
  gets(input);
                    /* WARNING: Subroutine does not return */
  exit(0);
}
```

So this is pretty similar to the other challenges in this module. There is a char array `input` which can hold 64 bytes, which it prints it's address. After that it runs the function `gets` with `input` as an argument, allowing us to do a buffer overflow attack and get the return address. With that we can get code execution. Our plan is to just push shellcode onto the stack, and we know where it is thanks to the infoleak. Then we will overwrite the return address to point to the start of our shellcode. We will use shellcode that pops a shell for us when we run it. The shellcode I will use is from `http://shell-storm.org/shellcode/files/shellcode-827.php`.

Also there is a slight problem with our plan. That is according to the decompiled code, the function `exit` is called. When this function is called, the `ret` instruction will not run in the context of this function, so we won't get our code execution. However the decompiled code isn't entirely correct. Looking at the assembly code gives us the full picture:

```
        08048539 e8 52 fe        CALL       gets                                             char * gets(char * __s)
                 ff ff
        0804853e 83 c4 04        ADD        ESP,0x4
        08048541 81 7d f8        CMP        dword ptr [EBP + local_c],0xdeadbeef
                 ef be ad de
        08048548 74 07           JZ         LAB_08048551
        0804854a 6a 00           PUSH       0x0
        0804854c e8 4f fe        CALL       exit                                             void exit(int __status)
                 ff ff
                             -- Flow Override: CALL_RETURN (CALL_TERMINATOR)
                             LAB_08048551                                    XREF[1]:     08048548(j)  
        08048551 b8 00 00        MOV        EAX,0x0
                 00 00
        08048556 8b 5d fc        MOV        EBX,dword ptr [EBP + local_8]
        08048559 c9              LEAVE
        0804855a c3              RET
```

So we can see that there is a check to see if `local_c` is equal to `0xdeadbeef`, and if it is the function does not call `exit(0)` and we get our code execution. When we look at the stack layout in Ghidra, we see that this variable is within our means to overwrite (and it is at an offset of `0x40`). So we just need to overwrite it with `0xdeadbeef` and we will be good to go:

```
                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined main()
             undefined         AL:1           <RETURN>
             undefined4        Stack[-0x8]:4  local_8                                 XREF[1]:     08048556(R)  
             undefined4        Stack[-0xc]:4  local_c                                 XREF[2]:     0804851b(W), 
                                                                                                   08048541(R)  
             char[64]          Stack[-0x4c]   input                                   XREF[2]:     08048522(*), 
                                                                                                   08048535(*)  
```

Next let's find the offset between the start of our input and the return address in gdb:

```
gef➤  disas main
Dump of assembler code for function main:
   0x080484db <+0>:	push   ebp
   0x080484dc <+1>:	mov    ebp,esp
   0x080484de <+3>:	push   ebx
   0x080484df <+4>:	sub    esp,0x44
   0x080484e2 <+7>:	call   0x8048410 <__x86.get_pc_thunk.bx>
   0x080484e7 <+12>:	add    ebx,0x1b19
   0x080484ed <+18>:	mov    eax,DWORD PTR [ebx-0x4]
   0x080484f3 <+24>:	mov    eax,DWORD PTR [eax]
   0x080484f5 <+26>:	push   0x14
   0x080484f7 <+28>:	push   0x2
   0x080484f9 <+30>:	push   0x0
   0x080484fb <+32>:	push   eax
   0x080484fc <+33>:	call   0x80483c0 <setvbuf@plt>
   0x08048501 <+38>:	add    esp,0x10
   0x08048504 <+41>:	mov    eax,DWORD PTR [ebx-0x8]
   0x0804850a <+47>:	mov    eax,DWORD PTR [eax]
   0x0804850c <+49>:	push   0x14
   0x0804850e <+51>:	push   0x2
   0x08048510 <+53>:	push   0x0
   0x08048512 <+55>:	push   eax
   0x08048513 <+56>:	call   0x80483c0 <setvbuf@plt>
   0x08048518 <+61>:	add    esp,0x10
   0x0804851b <+64>:	mov    DWORD PTR [ebp-0x8],0xcafebabe
   0x08048522 <+71>:	lea    eax,[ebp-0x48]
   0x08048525 <+74>:	push   eax
   0x08048526 <+75>:	lea    eax,[ebx-0x1a20]
   0x0804852c <+81>:	push   eax
   0x0804852d <+82>:	call   0x8048380 <printf@plt>
   0x08048532 <+87>:	add    esp,0x8
   0x08048535 <+90>:	lea    eax,[ebp-0x48]
   0x08048538 <+93>:	push   eax
   0x08048539 <+94>:	call   0x8048390 <gets@plt>
   0x0804853e <+99>:	add    esp,0x4
   0x08048541 <+102>:	cmp    DWORD PTR [ebp-0x8],0xdeadbeef
   0x08048548 <+109>:	je     0x8048551 <main+118>
   0x0804854a <+111>:	push   0x0
   0x0804854c <+113>:	call   0x80483a0 <exit@plt>
   0x08048551 <+118>:	mov    eax,0x0
   0x08048556 <+123>:	mov    ebx,DWORD PTR [ebp-0x4]
   0x08048559 <+126>:	leave  
   0x0804855a <+127>:	ret    
End of assembler dump.
gef➤  b *main+99
Breakpoint 1 at 0x804853e
gef➤  r
Starting program: /Hackery/pod/modules/bof_shellcode/tu18_shellaeasy/shella-easy 
Yeah I'll have a 0xffffd020 with a side of fries thanks
15935728
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0xffffd020  →  "15935728"
$ebx   : 0x0804a000  →  0x08049f0c  →  <_DYNAMIC+0> add DWORD PTR [eax], eax
$ecx   : 0xf7faf5c0  →  0xfbad208b
$edx   : 0xf7fb089c  →  0x00000000
$esp   : 0xffffd01c  →  0xffffd020  →  "15935728"
$ebp   : 0xffffd068  →  0x00000000
$esi   : 0xf7faf000  →  0x001d7d6c ("l}"?)
$edi   : 0x0       
$eip   : 0x0804853e  →  <main+99