Updated challenges showing off dojo features
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
This directory is a "category" of challenges. It can hold multiple levels (with multiple variants per level) along with global files.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
All files from the "_global" directory are also copied into /challenge and made SUID-executable. This can help with common resources for all levels in a module.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
The files from the level directory are copied into /challenge, set up to be owned by root, and made SUID-executable.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/opt/pwn.college/python
|
|
||||||
|
|
||||||
print(open("/flag").read())
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
You can have several variants of a level that will be randomly assigned to users. Just give each variant its own directory!
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/opt/pwn.college/python
|
|
||||||
|
|
||||||
print(open("/flag").read())
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cp /flag /tmp/here_it_is
|
|
||||||
chmod 644 /tmp/here_it_is
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
This level has a `.init` file that is run by root when the challenge is started!
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# hello
|
||||||
|
## apple
|
||||||
|
|
||||||
|
This challenge is named `apple`, and is located within module `hello`.
|
||||||
|
|
||||||
|
When users start this challenge, their environment will have:
|
||||||
|
- `/flag`
|
||||||
|
- `/challenge/apple`
|
||||||
|
|
||||||
|
`/flag` is read-only by root, and `/challenge/apple` is setuid root.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
print(f.read())
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# hello
|
||||||
|
## banana
|
||||||
|
|
||||||
|
This challenge is named `banana`, and is located within module `hello`.
|
||||||
|
|
||||||
|
When users start this challenge, their environment will have:
|
||||||
|
- `/flag`
|
||||||
|
- `/challenge/banana`
|
||||||
|
- `/chalenge/.config`
|
||||||
|
|
||||||
|
Within a challenge's definition, directories which begin with `_` are statically instanced.
|
||||||
|
Users will randomly, but deterministically, be assigned one instance of the challenge.
|
||||||
|
Every time they start the challenge, they will be assigned the same static instance.
|
||||||
|
This allows different users to receive different versions of the same challenge.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
config = (pathlib.Path(__file__).parent / ".config").read_text().strip()
|
||||||
|
|
||||||
|
print(f"Instance: {config}")
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
print(f.read())
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
dir = pathlib.Path(__file__).parent
|
||||||
|
planets = (dir / "planets.txt").read_text().strip().splitlines()
|
||||||
|
|
||||||
|
for planet in planets:
|
||||||
|
planet_path = dir / planet.lower()
|
||||||
|
planet_path.write_text(planet)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# world
|
||||||
|
## earth
|
||||||
|
|
||||||
|
This challenge is named `earth`, and is located within module `world`.
|
||||||
|
|
||||||
|
When users start this challenge, their environment will have:
|
||||||
|
- `/flag`
|
||||||
|
- `/challenge/earth`
|
||||||
|
- `/challenge/planets.txt`
|
||||||
|
- `/chalenge/.init`
|
||||||
|
|
||||||
|
Symbolic links which are relative to the dojo root-directory are supported.
|
||||||
|
|
||||||
|
When a challenge starts, and before users have access to their environment, `.init` will automatically be run as the root user.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
print(f.read())
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../planets.txt
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# world
|
||||||
|
## mars
|
||||||
|
|
||||||
|
This challenge is named `mars`, and is located within module `world`.
|
||||||
|
|
||||||
|
When users start this challenge, their environment will have:
|
||||||
|
- `/flag`
|
||||||
|
- `/challenge/orbit`
|
||||||
|
- `/challenge/planets.txt`
|
||||||
|
|
||||||
|
In this challenge, `orbit` reads in the flag and seeds random off of it.
|
||||||
|
While this is a challenge-specific detail, it is a broadly useful idea.
|
||||||
|
It allows for the challenge's behavior to be dynamically dependent on the flag.
|
||||||
|
This offers a similar paradigm to instanced challenge files.
|
||||||
|
However, it is dynamically instanced, rather than statically instanced.
|
||||||
|
Statically instanced values may be accessed by a student, while dynamically instanced values may not be (since they are dependent on the flag).
|
||||||
|
Which style is appropriate depends on the specifics of the challenge.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import random
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
random.seed(f.read())
|
||||||
|
|
||||||
|
planets = (pathlib.Path(__file__).parent / "planets.txt").read_text().strip().splitlines()
|
||||||
|
|
||||||
|
print("This is a flag-seeded random number: {}".format(random.randint(0, 1000)))
|
||||||
|
print(random.choice(planets))
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
print(f.read())
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../planets.txt
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Mercury
|
||||||
|
Venus
|
||||||
|
Earth
|
||||||
|
Mars
|
||||||
|
Jupiter
|
||||||
|
Saturn
|
||||||
|
Uranus
|
||||||
|
Neptune
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import random
|
||||||
|
|
||||||
|
import jinja2
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
random.seed(f.read())
|
||||||
|
|
||||||
|
init_path = pathlib.Path(__file__)
|
||||||
|
planets_path = (pathlib.Path(__file__).parent / "planets.txt")
|
||||||
|
launch_path = (pathlib.Path(__file__).parent / "launch")
|
||||||
|
launch_template_path = (pathlib.Path(__file__).parent / "launch.j2")
|
||||||
|
|
||||||
|
planet = random.choice(planets_path.read_text().strip().splitlines())
|
||||||
|
|
||||||
|
template = jinja2.Template(launch_template_path)
|
||||||
|
launch_path.write_text(template.render(planet=planet))
|
||||||
|
|
||||||
|
launch_template_path.unlink()
|
||||||
|
planets_path.unlink()
|
||||||
|
init_path.unlink()
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# world
|
||||||
|
## venus
|
||||||
|
|
||||||
|
This challenge is named `venus`, and is located within module `world`.
|
||||||
|
|
||||||
|
When users start this challenge, their environment will have:
|
||||||
|
- `/flag`
|
||||||
|
- `/challenge/takeoff`
|
||||||
|
- `/challenge/launch`
|
||||||
|
|
||||||
|
In this challenge, `takeoff` is a statically instanced file.
|
||||||
|
There is also files `.init`, `planets.txt`, and `launch.j2` which students will never see.
|
||||||
|
At run time, `.init` reads in `planets.txt` to construct `launch` from the templated file `launch.j2`.
|
||||||
|
This gives the challenge static instancing dependent upon the flag.
|
||||||
|
In general, it is best to define a pool of static instanced files prior, so that this setup does not need to be performed at runtime every challenge start.
|
||||||
|
However, for simple cases, this may be acceptable.
|
||||||
|
It is important to note, however, that the results of these static instances are still dependent upon the flag, which means running the challenge with a different flag (e.g. with a practice flag), will fundamentally change the instance.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("3.... 2... 1...")
|
||||||
|
print(sys.argv[1])
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("5... 4... 3.... 2... 1...")
|
||||||
|
print(sys.argv[1])
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#!/opt/pwn.college/python
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
subprocess.run(["/challenge/takeoff", "{{ planet }}"])
|
||||||
|
|
||||||
|
with open("/flag") as f:
|
||||||
|
print(f.read())
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../planets.txt
|
||||||
Reference in New Issue
Block a user