An exploit may be a script on any programming language or a binary executable.
While writing the exploit:
-
Accept the victim's host (IP address or domain) as the first command-line argument (
sys.argv[1]
). -
Print flags to stdout or stderr. You can also print any other information there.
The flags are extracted from stdout and stderr using a regular expression (the flag format) configured in the config.py file on the farm server (for example,
[A-Z0-9]{31}=
for RuCTF(E)). -
Specify the interpreter if the exploit is a script. In case of Linux and macOS, add a shebang to the beginning of the file:
#!/usr/bin/env python3
Do not write
#!/usr/bin/python3
(for example, the interpreter is located in a different place in macOS).In case of Windows, the farm client tries to detect the interpreter by the file extension (see the
SCRIPT_EXTENSIONS
dictionary). If it fails to do this correctly, use the--interpreter
option. -
After printing flags, add a newline and perform
flush(stdout)
:print(html_with_flags, flush=True)
A part of the flags may be lost otherwise. For example, if the farm client kills long-running exploits, the flags may remain the stdout buffer and won't be read by the farm client.