# Backdoorctf Funsignals

Let's take a look at the binary (also the goal of this challenge will be to print the flag, not pop a shell):

```
$    file funsignals_player_bin
funsignals_player_bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$    pwn checksec funsignals_player_bin
[*] '/Hackery/pod/modules/srop/backdoor_funsignals/funsignals_player_bin'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x10000000)
    RWX:      Has RWX segments
$    /funsignals_player_bin
15935728
Segmentation fault (core dumped)
```

So we can see that it is a `64` bit statically linked binary, with none of the standard binary mitigations. When we run it, we see that it scans in input, then seg faults.

## Reversing

Looking at the code in Ghidra, we see that this isn't a normal binary (probably just assembled versus compiled). Looking at the assembly code we see this:

```
                             //
                             // .shellcode
                             // SHT_PROGBITS  [0x10000000 - 0x1000004a]
                             // ram: 10[PII_REDACTED]004a
                             //
                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined entry()
             undefined         AL:1           <RETURN>
                             _start                                          XREF[4]:     Entry Point(*),
                             __start                                                      _elfHeader::00000018(*),
                             entry                                                        _elfProgramHeaders::00000010(*),
                                                                                          _elfSectionHeaders::00000050(*)  
        10000000 31 c0           XOR        EAX,EAX
        10000002 31 ff           XOR        EDI,EDI
        10000004 31 d2           XOR        EDX,EDX
        10000006 b6 04           MOV        DH,0x4
        10000008 48 89 e6        MOV        RSI,RSP
        1000000b 0f 05           SYSCALL
        1000000d 31 ff           XOR        EDI,EDI
        1000000f 6a 0f           PUSH       0xf
        10000011 58              POP        RAX
        10000012 0f 05           SYSCALL
        10000014 cc              INT        3
```

So we can see here, it executes two syscalls. For the first, the registers are equal to this:

```
RAX:    0x0
RDI:    0x0
RDX:    0x400
RSI:    ptr to top of stack (stack pointer rsp)
```

So here it is making a read syscall (check https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ for more details). It is scanning in `0x400` bytes of data via stdin into the top of the stack.

For the next syscall, the registers are equal to this:

```
RAX:    0xf
RDI:    0x0
```

So here it is performing a Sigreturn syscall. When the kernel delivers a signal from a program, it creates a frame on the stack before it is passed to the signal handler. Then after that is done that frame is used as context for a sigreturn syscall to return code execution to where it was interrupted. It does this by popping values off of the top of the stack into registers, which were stored there so execution could continue after the signal is dealt with. The syscall itself takes a single argument in the rdi register (however for our use, it's not important in this context). We can tell that a sigreturn syscall is being made since it pops the value 0xf into the rax register before making the syscall to specify a sigreturn syscall. Checkout https://lwn.net/Articles/676803/ and https://thisissecurity.stormshield.com/2015/01/03/playing-with-signals-an-overview-on-sigreturn-oriented-programming/ for more.

Also another important thing to note, we can see that the flag is stored in the binary at the address `0x10000023`:

```
                             flag
        10000023 66 61 6b        ds         "fake_flag_here_as_original_is_at_server"
                 65 5f 66
                 6c 61 67
```

## Exploitation

So for our exploitation, we will be doing a Sigreturn Oriented Programming attack (SROP). Essentially what that is is when we use a sigreturn to take control of the all of the registers. Since we get to scan in `0x400` bytes worth of data to the top of the stack which is pointed to by the `rsp` register (along with the fact that it makes a sigreturn call after that), and a sigreturn pops values off of the top of the stack into the registers.

SROP is really useful in a lot of cases where traditional ROP won't work. It gives us control of the instruction pointer which is executed, and all other registers.

Just if you're curious, this is the sigcontext structure that is stored on the stack, which is used by the `sigreturn` to pop values into the register (for `x64`). This diagram is originally from https://amriunix.com/post/sigreturn-oriented-programming-srop/:

```
+--------------------+--------------------+
| rt_sigeturn()      | uc_flags           |
+--------------------+--------------------+
| &uc                | uc_stack.ss_sp     |
+--------------------+--------------------+
| uc_stack.ss_flags  | uc.stack.ss_size   |
+--------------------+--------------------+
| r8                 | r9                 |
+--------------------+--------------------+
| r10                | r11                |
+--------------------+--------------------+
| r12                | r13                |
+--------------------+--------------------+
| r14                | r15                |
+--------------------+--------------------+
| rdi                | rsi                |
+--------------------+--------------------+
| rbp                | rbx                |
+--------------------+--------------------+
| rdx                | rax                |
+--------------------+--------------------+
| rcx                | rsp                |
+--------------------+--------------------+
| rip                | eflags             |
+--------------------+--------------------+
| cs / gs / fs       | err                |
+--------------------+--------------------+
| trapno             | oldmask (unused)   |
+--------------------+--------------------+
| cr2 (segfault addr)| &fpstate           |
+--------------------+--------------------+
| __reserved         | sigmask            |
+--------------------+--------------------+
```

So now is the question of what will we do with our syscall. Looking through the code, we can see multiple syscalls (both will work for our purposes, doesn't matter too much for our purposes):

```
        1000000b 0f 05           SYSCALL
```

```
        10000012 0f 05           SYSCALL
```

So using the sigreturn, we can set `rip`