mirror of https://github.com/dirtbags/moth.git
Begin unhooking in.tokend
This commit is contained in:
parent
2bc8ffee3e
commit
d14302b199
|
@ -0,0 +1,53 @@
|
||||||
|
Problems with Sandia
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* Tighter integration of scoreboard
|
||||||
|
* Spell out *exactly* what they can and cannot do:
|
||||||
|
* No posters with offensive text
|
||||||
|
* No machines at tables
|
||||||
|
* No grabbing our network while we're using it
|
||||||
|
* Give them exact network configuration information (they thought I
|
||||||
|
said /24, we needed /16)
|
||||||
|
* Specify where they get to project their scoreboard and what color
|
||||||
|
scheme it needs to be, including max luminosity
|
||||||
|
* They need to let me know well in advance if they want any links,
|
||||||
|
hosted files, or anything else in our game server
|
||||||
|
* Let Kevin know that we need everything planned out in advance and will
|
||||||
|
stubbornly refuse to accommodate any last-minute changes
|
||||||
|
* We handled power and network pretty well this year, do that again
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Other problems
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* We must have 8-foot rounds. We got 5-foot rounds this year. Bring
|
||||||
|
measuring tape and tell hotel immediately.
|
||||||
|
* Explain tokens even more clearly to vendors
|
||||||
|
* Have puzzles explain what format examples should be in
|
||||||
|
* TFTP tank submission
|
||||||
|
* Interfaces on pwnables are going down
|
||||||
|
* Specify how vendors can participate on IRC with ads
|
||||||
|
* Provide schedule to hotel well in advance
|
||||||
|
* Fewer categories. 20 is too many.
|
||||||
|
* Tanks unmatched comment
|
||||||
|
* Auto-refreshing tanks page
|
||||||
|
* Text announcement system in scoreboard
|
||||||
|
* No text to speech announcements, or at least display text as it's
|
||||||
|
being pronounced
|
||||||
|
* Have some 4" gaffer tape
|
||||||
|
* Classes need to start at the same time every day, danny thinks 9-4:30
|
||||||
|
* Go back to five days
|
||||||
|
* Have vendors sponsor a social event
|
||||||
|
* Pen testing class
|
||||||
|
* ltraceme needs to die
|
||||||
|
|
||||||
|
|
||||||
|
Bullshit
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Chash wants a $800 chair
|
||||||
|
* Open bar
|
||||||
|
* Chash wants a Segway
|
||||||
|
* Chash wants a trash can behind the uh the thing. And a terlet.
|
||||||
|
* Nerf weaponry
|
|
@ -3,28 +3,11 @@
|
||||||
PATH=/bin:/opt/ctfbase/bin; export PATH
|
PATH=/bin:/opt/ctfbase/bin; export PATH
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Get new tokens
|
|
||||||
for dn in /opt/*/tokens/*; do
|
|
||||||
[ -d $dn ] || continue
|
|
||||||
puzzle=$(basename $dn)
|
|
||||||
category=$(cat $dn/category)
|
|
||||||
busybox nc 10.0.0.2 1 \
|
|
||||||
-e tokencli $category $dn/category.key 3>&1 | \
|
|
||||||
arc4 $dn/enc.key > /var/lib/ctf/tokens/$puzzle
|
|
||||||
done
|
|
||||||
|
|
||||||
# Fetch list of teams
|
# Fetch list of teams
|
||||||
teams=/var/lib/ctf/teams.txt
|
teams=/var/lib/ctf/teams.txt
|
||||||
rm -f $teams.tmp
|
rm -f $teams.tmp
|
||||||
wget -q -O $teams.tmp http://10.0.0.2/teams.txt && \
|
wget -q -O $teams.tmp http://10.0.0.2/teams.txt && \
|
||||||
mv $teams.tmp $teams
|
mv $teams.tmp $teams
|
||||||
|
|
||||||
# Archive state
|
|
||||||
state=/var/www/state.tar.gz.rc4
|
|
||||||
tar cf - /var/lib/ctf | \
|
|
||||||
gzip -c | \
|
|
||||||
KEY='crashmaster' arc4 > $state.tmp
|
|
||||||
mv $state.tmp $state
|
|
||||||
|
|
||||||
sleep 60
|
sleep 60
|
||||||
done
|
done
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
# Set up networking for all CTF ip
|
# Set up networking for all CTF ips
|
||||||
ip link set eth0 up
|
ip link set eth0 up
|
||||||
if ! ip route | grep -q default; then
|
if ! ip route | grep -q default; then
|
||||||
ip route add default via 10.0.0.1 || exit 1
|
ip route add default via 10.0.0.1 || exit 1
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#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 server 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;
|
|
||||||
}
|
|
|
@ -1,7 +1,64 @@
|
||||||
diff -Naur fnord-1.10-orig//httpd.c fnord-1.10/httpd.c
|
diff -Naur fnord-1.10-orig//httpd.c fnord-1.10/httpd.c
|
||||||
--- fnord-1.10-orig//httpd.c 2011-03-08 22:28:18.000000000 -0700
|
--- fnord-1.10-orig//httpd.c 2005-08-03 05:32:50.000000000 -0600
|
||||||
+++ fnord-1.10/httpd.c 2011-03-08 22:31:12.000000000 -0700
|
+++ fnord-1.10/httpd.c 2011-03-14 17:05:57.000000000 -0600
|
||||||
@@ -663,8 +663,9 @@
|
@@ -163,9 +163,8 @@
|
||||||
|
|
||||||
|
#define MAXHEADERLEN 8192
|
||||||
|
|
||||||
|
-char* remote_ip;
|
||||||
|
+char* remote_addr;
|
||||||
|
#ifdef CGI
|
||||||
|
-char* remote_port;
|
||||||
|
char* remote_ident;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -186,7 +185,7 @@
|
||||||
|
time_t t=time(0);
|
||||||
|
struct tm* x=localtime(&t);
|
||||||
|
int l=-(timezone/60);
|
||||||
|
- buffer_puts(buffer_2,remote_ip?remote_ip:"0.0.0.0");
|
||||||
|
+ buffer_puts(buffer_2,remote_addr?remote_addr:"0.0.0.0");
|
||||||
|
buffer_puts(buffer_2," - - [");
|
||||||
|
|
||||||
|
buffer_put2digits(buffer_2,x->tm_mday);
|
||||||
|
@@ -219,7 +218,7 @@
|
||||||
|
buffer_putrange(buffer_2,len);
|
||||||
|
|
||||||
|
#else
|
||||||
|
- buffer_puts(buffer_2,remote_ip?remote_ip:"0.0.0.0");
|
||||||
|
+ buffer_puts(buffer_2,remote_addr?remote_addr:"0.0.0.0");
|
||||||
|
buffer_putspace(buffer_2);
|
||||||
|
buffer_putulong(buffer_2,retcode);
|
||||||
|
buffer_putspace(buffer_2);
|
||||||
|
@@ -271,7 +270,6 @@
|
||||||
|
"REQUEST_URI=",
|
||||||
|
"SCRIPT_NAME=",
|
||||||
|
"REMOTE_ADDR=",
|
||||||
|
- "REMOTE_PORT=",
|
||||||
|
"REMOTE_IDENT=",
|
||||||
|
"HTTP_USER_AGENT=",
|
||||||
|
"HTTP_COOKIE=",
|
||||||
|
@@ -337,17 +335,10 @@
|
||||||
|
*tmp=0; ++tmp;
|
||||||
|
|
||||||
|
i=7;
|
||||||
|
- if (remote_ip) {
|
||||||
|
+ if (remote_addr) {
|
||||||
|
cgi_env[++i]=tmp;
|
||||||
|
tmp+=str_copy(tmp,"REMOTE_ADDR=");
|
||||||
|
- tmp+=str_copy(tmp,remote_ip);
|
||||||
|
- *tmp=0; ++tmp;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (remote_port) {
|
||||||
|
- cgi_env[++i]=tmp;
|
||||||
|
- tmp+=str_copy(tmp,"REMOTE_PORT=");
|
||||||
|
- tmp+=str_copy(tmp,remote_port);
|
||||||
|
+ tmp+=str_copy(tmp,remote_addr);
|
||||||
|
*tmp=0; ++tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -663,8 +654,9 @@
|
||||||
static char* mimetype="text/plain";
|
static char* mimetype="text/plain";
|
||||||
|
|
||||||
static struct mimeentry { const char* name, *type; } mimetab[] = {
|
static struct mimeentry { const char* name, *type; } mimetab[] = {
|
||||||
|
@ -13,3 +70,21 @@ diff -Naur fnord-1.10-orig//httpd.c fnord-1.10/httpd.c
|
||||||
{ "css", "text/css" },
|
{ "css", "text/css" },
|
||||||
{ "dvi", "application/x-dvi" },
|
{ "dvi", "application/x-dvi" },
|
||||||
{ "ps", "application/postscript" },
|
{ "ps", "application/postscript" },
|
||||||
|
@@ -1060,16 +1052,7 @@
|
||||||
|
static void get_ucspi_env(void) {
|
||||||
|
char* ucspi=getenv("PROTO");
|
||||||
|
if (ucspi) {
|
||||||
|
- char* buf=alloca(str_len(ucspi)+20);
|
||||||
|
- unsigned int tmp=str_copy(buf,ucspi);
|
||||||
|
- buf[tmp+str_copy(buf+tmp,"REMOTEIP")]=0;
|
||||||
|
- remote_ip=getenv(buf);
|
||||||
|
-#ifdef CGI
|
||||||
|
- buf[tmp+str_copy(buf+tmp,"REMOTEPORT")]=0;
|
||||||
|
- remote_port=getenv(buf);
|
||||||
|
- buf[tmp+str_copy(buf+tmp,"REMOTEINFO")]=0;
|
||||||
|
- remote_ident=getenv(buf);
|
||||||
|
-#endif
|
||||||
|
+ remote_addr=getenv("REMOTEADDR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ mcp-install: $(MCP_BUILDDIR)/build
|
||||||
mkdir -p $(MCP_PKGDIR)
|
mkdir -p $(MCP_PKGDIR)
|
||||||
|
|
||||||
$(call COPYTREE, packages/mcp/bin, $(MCP_PKGDIR)/bin)
|
$(call COPYTREE, packages/mcp/bin, $(MCP_PKGDIR)/bin)
|
||||||
cp packages/mcp/src/in.tokend $(MCP_PKGDIR)/bin/
|
|
||||||
cp packages/mcp/src/pointscli $(MCP_PKGDIR)/bin/
|
cp packages/mcp/src/pointscli $(MCP_PKGDIR)/bin/
|
||||||
cp packages/mcp/src/puzzles.cgi $(MCP_PKGDIR)/bin/
|
cp packages/mcp/src/puzzles.cgi $(MCP_PKGDIR)/bin/
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
|
ip addr add 10.0.0.2/16 label eth0:mcp dev eth0
|
||||||
|
|
||||||
install -d /var/www
|
install -d /var/www
|
||||||
|
|
||||||
# Link in puzzles and web pages
|
# Link in puzzles and web pages
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
CFLAGS = -Wall -Werror
|
CFLAGS = -Wall -Werror
|
||||||
TARGETS = in.tokend claim.cgi
|
TARGETS = claim.cgi puzzler.cgi puzzles.cgi
|
||||||
TARGETS += puzzler.cgi puzzles.cgi
|
TARGETS += pointscli
|
||||||
TARGETS += pointscli mktoken
|
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build: $(TARGETS)
|
build: $(TARGETS)
|
||||||
|
|
||||||
in.tokend: in.tokend.o arc4.o md5.o common.o
|
|
||||||
tokencli: tokencli.o arc4.o
|
|
||||||
pointscli: pointscli.o common.o
|
pointscli: pointscli.o common.o
|
||||||
mktoken: mktoken.o common.o
|
|
||||||
arc4: arc4-main.o arc4.o
|
|
||||||
|
|
||||||
puzzles.cgi: puzzles.cgi.o common.o
|
puzzles.cgi: puzzles.cgi.o common.o
|
||||||
claim.cgi: claim.cgi.o common.o
|
claim.cgi: claim.cgi.o common.o
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../../include/arc4.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../include/arc4.h
|
|
|
@ -5,8 +5,8 @@
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char team[TEAM_MAX] = {0};
|
char team[TEAM_MAX] = {0};
|
||||||
char token[TOKEN_MAX] = {0};
|
char token[TOKEN_MAX] = {0};
|
||||||
|
|
||||||
if (-1 == cgi_init(argv)) {
|
if (-1 == cgi_init(argv)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -30,7 +30,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! team_exists(team)) {
|
if (! team_exists(team)) {
|
||||||
cgi_page("No such team", "");
|
cgi_result(409, "No such team", "<p>There is no team with that hash.</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any weird characters in token name? */
|
/* Any weird characters in token name? */
|
||||||
|
@ -38,13 +38,13 @@ main(int argc, char *argv[])
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if ('\0' == token[0]) {
|
if ('\0' == token[0]) {
|
||||||
cgi_page("Invalid token", "");
|
cgi_result(409, "Must supply token", "<p>Your request did not contain a k= parameter.</p>");
|
||||||
}
|
}
|
||||||
for (p = token; *p; p += 1) {
|
for (p = token; *p; p += 1) {
|
||||||
if ((! isalnum(*p)) &&
|
if ((! isalnum(*p)) &&
|
||||||
(*p != '-') &&
|
(*p != '-') &&
|
||||||
(*p != ':')) {
|
(*p != ':')) {
|
||||||
cgi_page("Invalid token", "");
|
cgi_result(409, "Not a token", "<p>This token has untokenlike characteristics.</p>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,31 +52,41 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Does the token exist? */
|
/* Does the token exist? */
|
||||||
if (! fgrepx(token, state_path("tokens.db"))) {
|
if (! fgrepx(token, state_path("tokens.db"))) {
|
||||||
cgi_page("Token does not exist", "");
|
cgi_result(409, "No such token", "<p>This token has not been issued.</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Award points */
|
/* Award points */
|
||||||
{
|
{
|
||||||
char category[40];
|
char *p = token;
|
||||||
int i;
|
char *q;
|
||||||
|
char category[40];
|
||||||
|
char points_s[40];
|
||||||
|
int points;
|
||||||
|
|
||||||
/* Pull category name out of the token */
|
/* Pull category name out of the token */
|
||||||
for (i = 0; token[i] != ':'; i += 1) {
|
for (q = category; *p && (*p != ':'); p += 1) {
|
||||||
category[i] = token[i];
|
*(q++) = *p;
|
||||||
}
|
}
|
||||||
category[i] = '\0';
|
*q = '\0';
|
||||||
|
if (p) p += 1;
|
||||||
|
|
||||||
|
/* Pull point value out of the token (if it has one) */
|
||||||
|
for (q = points_s; *p && (*p != ':'); p += 1) {
|
||||||
|
*(q++) = *p;
|
||||||
|
}
|
||||||
|
*q = '\0';
|
||||||
|
points = atoi(points_s);
|
||||||
|
if (0 == points) points = 1;
|
||||||
|
|
||||||
{
|
{
|
||||||
char line[200];
|
char line[200];
|
||||||
|
|
||||||
my_snprintf(line, sizeof(line),
|
my_snprintf(line, sizeof(line), "%s %s", team, token);
|
||||||
"%s %s", team, token);
|
award_and_log_uniquely(team, category, points, state_path("claim.db"), line);
|
||||||
award_and_log_uniquely(team, category, 1,
|
|
||||||
state_path("claim.db"), line);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cgi_page("Point awarded", "<!-- success -->");
|
cgi_page("Point awarded", "<p>Congratulations.</p>");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,22 @@ cgi_foot()
|
||||||
"</html>\n");
|
"</html>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cgi_result(int code, char *desc, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (is_cgi) {
|
||||||
|
printf("%d %s\r\n", code, desc);
|
||||||
|
}
|
||||||
|
cgi_head(desc);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
cgi_foot();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cgi_page(char *title, char *fmt, ...)
|
cgi_page(char *title, char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -226,18 +242,9 @@ cgi_page(char *title, char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cgi_error(char *fmt, ...)
|
cgi_error(char *text)
|
||||||
{
|
{
|
||||||
va_list ap;
|
cgi_result(500, "Internal error", "<p>%s</p>", text);
|
||||||
|
|
||||||
printf("500 Internal Error\r\n"
|
|
||||||
"Content-type: text/plain\r\n"
|
|
||||||
"\r\n");
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vprintf(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
printf("\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -492,11 +499,11 @@ award_and_log_uniquely(char const *team,
|
||||||
char const *dbpath,
|
char const *dbpath,
|
||||||
char const *line)
|
char const *line)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Make sure they haven't already claimed these points */
|
/* Make sure they haven't already claimed these points */
|
||||||
if (fgrepx(line, dbpath)) {
|
if (fgrepx(line, dbpath)) {
|
||||||
cgi_page("Already claimed",
|
cgi_result(409, "Already claimed",
|
||||||
"<p>Your team has already claimed these points.</p>");
|
"<p>Your team has already claimed these points.</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,54 +533,3 @@ award_and_log_uniquely(char const *team,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Compute bubble babble for input buffer.
|
|
||||||
*
|
|
||||||
* The generated output will be of length 6*((inlen/2)+1), including the
|
|
||||||
* trailing NULL.
|
|
||||||
*
|
|
||||||
* Test vectors:
|
|
||||||
* `' (empty string) `xexax'
|
|
||||||
* `1234567890' `xesef-disof-gytuf-katof-movif-baxux'
|
|
||||||
* `Pineapple' `xigak-nyryk-humil-bosek-sonax'
|
|
||||||
*/
|
|
||||||
static char const consonants[] = "bcdfghklmnprstvz";
|
|
||||||
static char const vowels[] = "aeiouy";
|
|
||||||
|
|
||||||
void
|
|
||||||
bubblebabble(unsigned char *out,
|
|
||||||
unsigned char const *in,
|
|
||||||
const size_t inlen)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
int seed = 1;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
out[pos++] = 'x';
|
|
||||||
while (1) {
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
if (i == inlen) {
|
|
||||||
out[pos++] = vowels[seed % 6];
|
|
||||||
out[pos++] = 'x';
|
|
||||||
out[pos++] = vowels[seed / 6];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = in[i++];
|
|
||||||
out[pos++] = vowels[(((c >> 6) & 3) + seed) % 6];
|
|
||||||
out[pos++] = consonants[(c >> 2) & 15];
|
|
||||||
out[pos++] = vowels[((c & 3) + (seed / 6)) % 6];
|
|
||||||
if (i == inlen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
seed = ((seed * 5) + (c * 7) + in[i]) % 36;
|
|
||||||
|
|
||||||
c = in[i++];
|
|
||||||
out[pos++] = consonants[(c >> 4) & 15];
|
|
||||||
out[pos++] = '-';
|
|
||||||
out[pos++] = consonants[c & 15];
|
|
||||||
}
|
|
||||||
|
|
||||||
out[pos++] = 'x';
|
|
||||||
out[pos] = '\0';
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,14 +9,13 @@
|
||||||
#define TOKEN_MAX 80
|
#define TOKEN_MAX 80
|
||||||
#define itokenlen 5
|
#define itokenlen 5
|
||||||
|
|
||||||
#define bubblebabble_len(n) (6*(((n)/2)+1))
|
|
||||||
|
|
||||||
int cgi_init(char *global_argv[]);
|
int cgi_init(char *global_argv[]);
|
||||||
size_t cgi_item(char *str, size_t maxlen);
|
size_t cgi_item(char *str, size_t maxlen);
|
||||||
void cgi_head(char *title);
|
void cgi_head(char *title);
|
||||||
void cgi_foot();
|
void cgi_foot();
|
||||||
|
void cgi_result(int code, char *desc, char *fmt, ...);
|
||||||
void cgi_page(char *title, char *fmt, ...);
|
void cgi_page(char *title, char *fmt, ...);
|
||||||
void cgi_error(char *fmt, ...);
|
void cgi_error(char *text);
|
||||||
|
|
||||||
|
|
||||||
int fgrepx(char const *needle, char const *filename);
|
int fgrepx(char const *needle, char const *filename);
|
||||||
|
@ -33,8 +32,5 @@ void award_and_log_uniquely(char const *team,
|
||||||
long points,
|
long points,
|
||||||
char const *logfile,
|
char const *logfile,
|
||||||
char const *line);
|
char const *line);
|
||||||
void bubblebabble(unsigned char *out,
|
|
||||||
unsigned char const *in,
|
|
||||||
const size_t inlen);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
#include <sys/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include "common.h"
|
|
||||||
#include "arc4.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char category[CAT_MAX];
|
|
||||||
size_t categorylen;
|
|
||||||
char token[TOKEN_MAX];
|
|
||||||
size_t tokenlen;
|
|
||||||
uint8_t key[256];
|
|
||||||
size_t keylen;
|
|
||||||
|
|
||||||
/* Read category name. */
|
|
||||||
{
|
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
len = read(0, category, sizeof(category));
|
|
||||||
if (0 >= len) return 0;
|
|
||||||
for (categorylen = 0;
|
|
||||||
(categorylen < len) && isalnum(category[categorylen]);
|
|
||||||
categorylen += 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in that category's key. */
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
fd = open(package_path("mcp/tokend.keys/%.*s", (int)categorylen, category), O_RDONLY);
|
|
||||||
if (-1 == fd) {
|
|
||||||
fprintf(stderr, "Open key %.*s: %s\n",
|
|
||||||
(int)categorylen, category, strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = read(fd, &key, sizeof(key));
|
|
||||||
if (-1 == ret) {
|
|
||||||
fprintf(stderr, "Read key %.*s: %s\n",
|
|
||||||
(int)categorylen, category, strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
keylen = (size_t)ret;
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send a nonce, expect it back encrypted */
|
|
||||||
{
|
|
||||||
int32_t nonce;
|
|
||||||
int32_t enonce = 0;
|
|
||||||
|
|
||||||
urandom((char *)&nonce, sizeof(nonce));
|
|
||||||
write(1, &nonce, sizeof(nonce));
|
|
||||||
arc4_crypt_buffer(key, keylen, (uint8_t *)&nonce, sizeof(nonce));
|
|
||||||
read(0, &enonce, sizeof(enonce));
|
|
||||||
if (nonce != enonce) {
|
|
||||||
write(1, ":<", 2);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the token. */
|
|
||||||
{
|
|
||||||
unsigned char crap[itokenlen];
|
|
||||||
unsigned char digest[bubblebabble_len(itokenlen)];
|
|
||||||
|
|
||||||
urandom((char *)crap, sizeof(crap));
|
|
||||||
|
|
||||||
/* Digest some random junk. */
|
|
||||||
bubblebabble(digest, (unsigned char *)&crap, itokenlen);
|
|
||||||
|
|
||||||
/* Append digest to category name. */
|
|
||||||
tokenlen = (size_t)snprintf(token, sizeof(token),
|
|
||||||
"%.*s:%s",
|
|
||||||
(int)categorylen, category, digest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write that token out now. */
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
do {
|
|
||||||
fd = open(state_path("tokens.db"), O_WRONLY | O_CREAT, 0666);
|
|
||||||
if (-1 == fd) break;
|
|
||||||
|
|
||||||
ret = lockf(fd, F_LOCK, 0);
|
|
||||||
if (-1 == ret) break;
|
|
||||||
|
|
||||||
ret = lseek(fd, 0, SEEK_END);
|
|
||||||
if (-1 == ret) break;
|
|
||||||
|
|
||||||
ret = write(fd, token, tokenlen);
|
|
||||||
if (-1 == ret) break;
|
|
||||||
|
|
||||||
ret = write(fd, "\n", 1);
|
|
||||||
if (-1 == ret) break;
|
|
||||||
|
|
||||||
ret = close(fd);
|
|
||||||
if (-1 == ret) break;
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
if ((-1 == fd) || (-1 == ret)) {
|
|
||||||
printf("!%s", strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encrypt the token. */
|
|
||||||
{
|
|
||||||
arc4_crypt_buffer(key, keylen, (uint8_t *)token, tokenlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send it back. If there's an error here, it's okay. Better to have
|
|
||||||
unclaimed tokens than unclaimable ones. */
|
|
||||||
write(1, token, tokenlen);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../../../include/md5.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../include/md5.h
|
|
|
@ -1,28 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (2 != argc) {
|
|
||||||
fprintf(stderr, "Usage: %s CATEGORY\n", argv[0]);
|
|
||||||
return EX_USAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the token. */
|
|
||||||
{
|
|
||||||
unsigned char crap[itokenlen];
|
|
||||||
unsigned char digest[bubblebabble_len(itokenlen)];
|
|
||||||
|
|
||||||
urandom((char *)crap, sizeof(crap));
|
|
||||||
|
|
||||||
/* Digest some random junk. */
|
|
||||||
bubblebabble(digest, (unsigned char *)&crap, itokenlen);
|
|
||||||
|
|
||||||
/* Append digest to category name. */
|
|
||||||
printf("%s:%s\n", argv[1], digest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
src-%:
|
|
||||||
$(MAKE) -C src $*
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
echo 'Content-type: application/octet-stream'
|
||||||
|
echo
|
||||||
|
|
||||||
|
tar czf - /var/lib/ctf | KEY=crashmaster arc4
|
|
@ -0,0 +1,2 @@
|
||||||
|
all: bubblebabble
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/** Compute bubble babble for input buffer.
|
||||||
|
*
|
||||||
|
* The generated output will be of length 6*((inlen/2)+1), including the
|
||||||
|
* trailing NULL.
|
||||||
|
*
|
||||||
|
* Test vectors:
|
||||||
|
* `' (empty string) `xexax'
|
||||||
|
* `1234567890' `xesef-disof-gytuf-katof-movif-baxux'
|
||||||
|
* `Pineapple' `xigak-nyryk-humil-bosek-sonax'
|
||||||
|
*/
|
||||||
|
static char const consonants[] = "bcdfghklmnprstvz";
|
||||||
|
static char const vowels[] = "aeiouy";
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int seed = 1;
|
||||||
|
|
||||||
|
putchar('x');
|
||||||
|
while (1) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
c = getchar();
|
||||||
|
if (EOF == c) {
|
||||||
|
putchar(vowels[seed % 6]);
|
||||||
|
putchar('x');
|
||||||
|
putchar(vowels[seed / 6]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar(vowels[(((c >> 6) & 3) + seed) % 6]);
|
||||||
|
putchar(consonants[(c >> 2) & 15]);
|
||||||
|
putchar(vowels[((c & 3) + (seed / 6)) % 6]);
|
||||||
|
|
||||||
|
seed = (seed * 5) + (c * 7);
|
||||||
|
c = getchar();
|
||||||
|
seed = (seed + c) % 36;
|
||||||
|
|
||||||
|
if (EOF == c) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
putchar(consonants[(c >> 4) & 15]);
|
||||||
|
putchar('-');
|
||||||
|
putchar(consonants[c & 15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar('x');
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
""|"-h"|"--help")
|
||||||
|
echo "Usage: $0 CATEGORY [POINTS]"
|
||||||
|
exit
|
||||||
|
esac
|
||||||
|
|
||||||
|
bb=$(dd bs=1 count=5 if=/dev/urandom 2>/dev/null | ./bubblebabble)
|
||||||
|
points=$2${2:+:}
|
||||||
|
|
||||||
|
echo $1:$points$bb
|
Loading…
Reference in New Issue