LANL CTF Token-Based Categories =============================== LANL's CTF contest allows for easy addition of new modules which can use "tokens". A token is a character string worth one point in the contest. A point may only be claimed once per team, but multiple teams can claim the same token and each will get a point. Tokens look like this: example:xylep-donut-nanox Tokens are issued by the token server using the tokencli program at the end of this document. They can also be issued before the beginning of a contest. If your category allows it, it will be much easier for you to simply request a number of tokens before the contest begins, and hard-code them into your category. You will want to arrange that participants get a token after having completed some sort of task. In existing categories, tokens are frequently what lie beneath some trail of hacking. For instance, one program provides a token when the proper printf formatting string is provided. Another embeds five tokens into log messages using different encodings. Any machine that you connect to our network will get a wired connection and should claim a static IP address on the 10.0.2.0/24 network. While it's unlikely you'll conflict with anyone else, be prepared to reconfigure it with a new IP on the morning of the event. If you plan to request tokens, please do so at least 2 weeks before the start of the event. I will need to know what you'd like your category to be called, and how many tokens you'd like. It's not a problem if you don't use all the tokens you request. Remember that this is a security contest, and contestants will be far more engaged with your category if they have to do real work to get the tokens. For example, a vendor might be tempted to leave tokens lying around in configuration boxes to reward people who explore its rich configurability, but this would probably result in people clicking through the UI as quickly as possible looking only for tokens. Far better would be to have the tokens lying under the products functionality somewhere, forcing contestants to interact with the product like they would in their day to day work after having purchased it. A Snort category, for instance, would do well to have tokens within packet captures which triggered alarms. I can't stress that last point enough: constestants have been known to spend over 2 hours on a single problem. Don't be afraid to really challenge them. /* tokencli.c - LANL CTF token client Author: Neale Pickett This program requires an arc4 implementation, email me if you can't find one you like. This also requires a shared 128-bit key. I need the key before you can start requesting tokens from the server :) This software has been authored by an employee or employees of Los Alamos National Security, LLC, operator of the Los Alamos National Laboratory (LANL) under Contract No. DE-AC52-06NA25396 with the U.S. Department of Energy. The U.S. Government has rights to use, reproduce, and distribute this software. The public may copy, distribute, prepare derivative works and publicly display this software without charge, provided that this Notice and any statement of authorship are reproduced on all copies. Neither the Government nor LANS makes any warranty, express or implied, or assumes any liability or responsibility for the use of this software. If software is modified to produce derivative works, such modified software should be clearly marked, so as not to confuse it with the version available from LANL. */ #include #include #include #include #include #include #include #include "arc4.h" /* I don't feel compelled to put all the TCP client code in here * when it's so simple to run this with netcat or ucspi. Plus, using * stdin and stdout makes it simpler to test. */ int read_key(char *filename, uint8_t *key, size_t *keylen) { int fd = open(filename, O_RDONLY); int len; if (-1 == fd) { perror("open"); return EX_NOINPUT; } len = read(fd, key, *keylen); if (-1 == len) { perror("read"); return EX_NOINPUT; } *keylen = (size_t)len; return 0; } int main(int argc, char *argv[]) { uint8_t skey[200]; size_t skeylen = sizeof(skey); char token[200]; size_t tokenlen; int ret; if (argc != 3) { fprintf(stderr, "Usage: %s SERVICE SERVICEKEY 3>TOKENFILE\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "SERVICEKEY is a filename.\n"); fprintf(stderr, "Server chatter happens over stdin and stdout.\n"); fprintf(stderr, "Tokens are written to file descriptor 3.\n"); fprintf(stderr, "\n"); fprintf(stderr, "To run with netcat:\n"); fprintf(stderr, " nc 10.0.0.2 1 -e tokencli cat cat.key 3> tokenfile\n"); return EX_USAGE; } /* read in keys */ ret = read_key(argv[2], skey, &skeylen); if (0 != ret) return ret; /* write service name */ write(1, argv[1], strlen(argv[1])); /* read nonce, send back encrypted version */ { uint8_t nonce[80]; int noncelen; noncelen = read(0, nonce, sizeof(nonce)); if (0 >= noncelen) { perror("read"); return EX_IOERR; } arc4_crypt_buffer(skey, skeylen, nonce, (size_t)noncelen); write(1, nonce, (size_t)noncelen); } /* read token */ { int len; len = read(0, token, sizeof(token)); if (0 >= len) { perror("read"); return EX_IOERR; } tokenlen = (size_t)len; } /* decrypt it */ arc4_crypt_buffer(skey, skeylen, (uint8_t *)token, tokenlen); /* write it to fd 3 */ write(3, token, tokenlen); return 0; }