a fairly simple farm for A/D CTFs
To run it, you need to export the environment variables specified in .env.example and then just run ./farmina.py (I recommend making a simple script to export + run)
it's made up of 3 parts:
/configFastAPI endpoint to get the config (:mind_blown:)/flagsFastAPI endpoint to ingest the flags from the clientssubmission_worker, the main loop which submits the stolen flags to the game system in order to score points for the team
to store flags it uses a simple sqlite database (./flags.db by default) with the flag as primary key, where it also keeps track of the flag's status from the game system along with its message (so it will also have the points gained, depending on the game system type)
it can optionally print the sum of the points gained each time it submits a batch of flags, but it needs a regex like Accepted: ([0-9.]+) flag points1, with the first capture group being the one used to find the points in the message (if the game system provides them)
python-requestspython-fastapiuvicorn(to run fastapi)python-peewee(for sqlite)
a very simple client for farmina
it can be used like ./clientino.py -H host -P port exploit.py, and it will run exploit.py (which can be any file marked as executable2) every -i/--interval seconds3 using, each time, -j/--jobs concurrent subprocesses4, each ran against 1 team and will POST the flags found in the script's output (using FLAG_REGEX) to http://host:port/flags
as with the other farms, the exploit script has to take 1 argument, which will be the currently attacked team's vm's IP address
even tho it's a very simple farm, it's still strictly typed, so if you want to type check it, you need:
for farmina:
- a type checker for python (e.g.
mypy) python-types-requestspython-types-peeweenote:execute()as is not typed yet, so you will need to tell the checker to ignore its untyped calls
for clientino:
P.S. coming from haskell, type checking in python sucks, but it could also be that I don't have mypy set up correctly so idk