Files
BinexProject/README.md
2026-05-29 23:32:05 +02:00

74 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CoPaaS — Compiler-oriented Programming as a Service
A startup offers an emulation service with a JIT engine for a custom instruction
set. The ISA is small and has no jumps, branches, or function calls — so it is
really just a glorified pocket calculator. You hand it a program, it compiles
that program to native x86-64 at runtime, runs it, and tells you the result.
In the free tier, every program runs inside a sandbox. Pay for the premium tier
and the sandbox comes off — the startup trusts its paying customers.
## How it works
On connect you may activate premium mode, then you enter a loop: submit a
program, the service JIT-compiles and runs it, and prints the result. Repeat as
often as you like.
Each round:
1. You are asked for a program length `n` (`1 ≤ n ≤ 0x1000`).
2. You send `n` instructions as raw fixed-size records (see format below).
3. The service validates the program, compiles it to x86-64, and executes it.
4. It prints `Your program exited with <code>!`, where `<code>` is the result.
### The machine
- **Registers (14):** named `A``N`. All registers are zeroed before your program runs.
- **Result:** the program's exit code is the low 8 bits of register `A`.
- **No control flow:** there are no jumps, branches, or calls.
### Instructions
Each instruction is a fixed-size record with the fields:
```
opcode | reg1 | (padding) | reg2_or_immediate
```
`reg2_or_immediate` is interpreted as a second register for register-form
instructions, or as a 32-bit immediate for immediate-form instructions.
| Opcode | Form | Effect |
| ------- | ----------------- | ------------------------------- |
| `LOADI` | `reg1, imm` | `reg1 = imm` |
| `ADDI` | `reg1, imm` | `reg1 += imm` |
| `ADD` | `reg1, reg2` | `reg1 += reg2` |
| `SUB` | `reg1, reg2` | `reg1 -= reg2` |
| `COPY` | `reg1, reg2` | `reg1 = reg2` |
Programs are validated before compilation: any out-of-range opcode or register
is rejected and the round is discarded. The compiler also applies small
optimizations — consecutive `ADDI`s to the same register are folded together,
redundant consecutive `LOADI`s collapse to one, and a `COPY` of a register onto
itself is dropped.
### Execution model
- **Free / demo tier:** the compiled code runs in a forked child under a
seccomp-BPF sandbox that permits only `read`, `write`, `execve`, and
`exit_group`. The child runs on a fresh stack at a randomized address, and
`stdin`, `stdout`, and `stderr` are all closed first — so the **only**
information that leaves the child is its exit code (the low byte of `A`).
- **Premium tier:** unlocked by supplying the correct activation key. Compiled
code then runs in-process with **no sandbox**.
### Mitigations
Full RELRO · Stack Canary · NX · PIE
## Goal
Break out of the calculator and run code of your choosing — capture the flag via
`/bin/get_flag` (or a shell). The interesting surface is the JIT: what the code
generator emits for your instructions is not always what you'd expect.