📦 OliveTin
What is it?
- Concept: OliveTin is a lightweight web application that gives non-technical users buttons for a fixed list of shell commands defined by an administrator in a YAML config. The security model is the allow-list: you cannot run arbitrary commands, only the ones an admin pre-approved, with arguments constrained by declared types.
- Impact: The whole model rests on argument validation, and it is normally deployed as root so its buttons can restart services and write to system paths. A single argument whose declared type performs no character validation therefore turns a fixed command into arbitrary root command execution.
How it works
- OliveTin serves an HTTP UI and a JSON API, by default on port
1337, typically bound to127.0.0.1behind a reverse proxy. /etc/OliveTin/config.yamldefines every action: a title, ashellstring, and anargumentslist. The shell string interpolates arguments via{{ name }}placeholders.- Each argument carries a declared
type—int,ascii_identifier,password, and so on — which is the only input filtering that exists. POST /api/StartActionexecutes an action by id, with anargumentsarray of{name, value}objects. The UI is a client of this API; nothing about the API requires the UI.- The interpolated string is handed to a shell, so the placeholder is textual substitution into a command line, not a parameterised exec.
Security Quirks & Niche Facts
- It usually runs as root by design. That is the point of the tool — expose privileged operations safely to unprivileged people — and it is precisely why an injection here is a full privilege escalation rather than a lateral step. An unfamiliar root process in
ps auxwwis the tell. config.yamlis the exploit map. It contains every command, every placeholder, and every argument type. Reading it converts blind guessing into a targeted search for the one argument whose type does not filter.- Argument types are not uniformly strict.
intandascii_identifierreject quotes and semicolons; apasswordtype is designed to accept arbitrary characters, because passwords legitimately contain them. That asymmetry is the vulnerability class: the permissive argument in an otherwise well-validated action. - The classic injectable shape is a quoted password on a command line, e.g.
mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }}. A value of' ; id > /tmp/proof ; echo 'closes the quote, runs a command, and reopens a quote so the remainder still parses. {{ output }}and{{ exit_code }}are not attacker-controlled — they are populated by the server. Time spent on them is wasted; only user-supplied arguments matter.- The API field name is
bindingId, notactionId. Payloads copied from blog posts frequently use the wrong key and silently do nothing; proxying one real UI request through (incomplete) BurpSuite settles the exact schema in seconds. - Binding to
127.0.0.1is not a boundary once you have a shell. Confirm withss -lntp, then eithercurlit locally or forward the port out with Chisel to drive it from a browser. - Command output is not returned to the injecting caller — the injected command runs in a different context to the response you see. Redirect to a world-readable file (
> /tmp/proof ; chmod 666 /tmp/proof) and read it separately. - Version
3000.10.0is affected by CVE-2026-27626, a critical RCE;OliveTin --versionfingerprints it directly.
Notes
- Enumeration order that works:
ps auxww | grep root→OliveTin --version→ss -lntpto confirm the port →cat /etc/OliveTin/config.yamlto pick the argument. - Prove the primitive with
idbefore going for the flag; a failedcat /root/root.txtis ambiguous, a successfulidis not. - If the injected command appears to run but not as root, the action may be configured with a lower-privilege user — re-read the action definition rather than assuming the injection failed.
Mitigation
- Fix: Never interpolate an unvalidated argument into a shell string. Pass arguments as an argv array so the shell never re-parses them, which removes the injection regardless of the value.
- Run OliveTin as a dedicated unprivileged user and grant only the specific escalations individual actions need via narrowly scoped sudo rules.
- Avoid free-form argument types in shell contexts; where a secret genuinely must be passed, hand it through an environment variable or a file, not the command line.
- Keep the service bound to localhost and patched — localhost binding delays an attacker who already has a shell, it does not stop them.
Related Usage
| File | Created |
|---|---|
| HTB Machine - Enigma | September 07, 2026 |
References: