From e002f16618f6cfa2508af311f16f4488d6ad31c9 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 27 Sep 2010 21:03:10 -0600 Subject: [PATCH] Start trying to get token distribution working --- common/arc4.c | 6 --- common/arc4.h | 6 ++- doc/tokens.txt | 32 ++++++++++-- mcp/bin/addteam | 2 +- mcp/src/in.tokend.c | 2 +- mcp/test.sh | 8 +-- mcp/tokend.keys/octopus | 2 + mcp/tokend.keys/pwnables | 1 + octopus/src/Makefile | 2 + pwnables/pwnables.mk | 2 + pwnables/setup | 13 +++-- pwnables/src/gimmie.c | 1 + pwnables/src/ltraceme.c | 2 +- pwnables/tokencli/gimmie/category | 1 + pwnables/tokencli/gimmie/category.key | 1 + pwnables/tokencli/gimmie/enc.key | 1 + tokencli/service/tokencli/run | 11 ----- .../service/{tokencli => tokengetd}/log/run | 0 tokencli/service/tokengetd/run | 4 ++ tokencli/service/tokengetd/tokengetd | 18 +++++++ tokencli/setup | 3 ++ tokencli/src/Makefile | 4 ++ tokencli/src/arc4-main.c | 49 +++++++++++++++++++ tokencli/tokencli.mk | 3 ++ 24 files changed, 139 insertions(+), 35 deletions(-) create mode 100644 mcp/tokend.keys/octopus create mode 100644 mcp/tokend.keys/pwnables create mode 100644 pwnables/tokencli/gimmie/category create mode 100644 pwnables/tokencli/gimmie/category.key create mode 100644 pwnables/tokencli/gimmie/enc.key delete mode 100755 tokencli/service/tokencli/run rename tokencli/service/{tokencli => tokengetd}/log/run (100%) create mode 100755 tokencli/service/tokengetd/run create mode 100755 tokencli/service/tokengetd/tokengetd create mode 100755 tokencli/setup create mode 100644 tokencli/src/arc4-main.c diff --git a/common/arc4.c b/common/arc4.c index 641d46d..63306ad 100644 --- a/common/arc4.c +++ b/common/arc4.c @@ -4,12 +4,6 @@ #define swap(a, b) do {int _swap=a; a=b, b=_swap;} while (0) -struct arc4_ctx { - uint8_t S[256]; - uint8_t i; - uint8_t j; -}; - void arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen) { diff --git a/common/arc4.h b/common/arc4.h index 5ae3bd7..7aa7428 100644 --- a/common/arc4.h +++ b/common/arc4.h @@ -4,7 +4,11 @@ #include #include -struct arc4_ctx; +struct arc4_ctx { + uint8_t S[256]; + uint8_t i; + uint8_t j; +}; void arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen); uint8_t arc4_pad(struct arc4_ctx *ctx); diff --git a/doc/tokens.txt b/doc/tokens.txt index dad9999..2184e63 100644 --- a/doc/tokens.txt +++ b/doc/tokens.txt @@ -29,14 +29,36 @@ CPU, or something that carries a high risk of local exploit. The token server listens on TCP port 1, issuing tokens encrypted with ARC4 (symmetric encryption). Here's how the transaction goes: - C: category - S: nonce (4 bytes) - C: nonce encrypted with symmetric key - S: token encrypted with symmetric key + C: category + S: nonce (4 bytes) + C: nonce encrypted with symmetric key + S: token encrypted with symmetric key Token client ------------ The token client (in package "tokencli") runs as a daemon, requesting a -new token every minute for each puzzle. +new token every minute for each puzzle. Because we want you to have +multiple puzzles within a category, and the server only knows about +categories, each puzzle needs to be associated with a category. +Additionally, tokens are encrypted before being written to the local +filesystem, with a different key for each puzzle. + +The token client thus needs a 4-tuple for each puzzle: + + (puzzle name, puzzle key, category, category key) + +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 + +And puzzles are stored in: + + /var/lib/ctf/tokens/puzzle_name + +Using this scheme, the token client has only to iterate over +/opt/*/tokencli/* instead of implementing some sort of parser. diff --git a/mcp/bin/addteam b/mcp/bin/addteam index 6be7af6..922815c 100755 --- a/mcp/bin/addteam +++ b/mcp/bin/addteam @@ -52,4 +52,4 @@ echo "$color" > $base/teams/colors/$hash echo "Registered with hash: $hash" # Write teams.html if it's an actual contest -/opt/mcp/bin/teams.sh > $www/teams.html.new && mv $www/teams.html.new $www/teams.html +$(dirname $0)/teams.sh > $www/teams.html.new && mv $www/teams.html.new $www/teams.html diff --git a/mcp/src/in.tokend.c b/mcp/src/in.tokend.c index d18898c..5a5ddba 100644 --- a/mcp/src/in.tokend.c +++ b/mcp/src/in.tokend.c @@ -93,7 +93,7 @@ main(int argc, char *argv[]) int fd; int ret; - fd = open(state_path("token.keys/%.*s", (int)servicelen, service), O_RDONLY); + fd = open(package_path("mcp/tokend.keys/%.*s", (int)servicelen, service), O_RDONLY); if (-1 == fd) { perror("Open key"); return 0; diff --git a/mcp/test.sh b/mcp/test.sh index c54b5b0..5a3f2f6 100755 --- a/mcp/test.sh +++ b/mcp/test.sh @@ -30,7 +30,7 @@ done mkdir -p $CTF_BASE/teams/names mkdir -p $CTF_BASE/teams/colors for team in team1 team2 team3; do - hash=$(bin/register $team | awk '{print $NF;}') + hash=$(bin/addteam $team | awk '{print $NF;}') done @@ -86,11 +86,11 @@ fi ## Token tests ## -mkdir -p $CTF_BASE/token.keys -echo -n '0123456789abcdef' > $CTF_BASE/token.keys/tokencat +mkdir -p $CTF_BASE/mcp/tokend.keys +echo -n '0123456789abcdef' > $CTF_BASE/mcp/tokend.keys/tokencat mkfifo $CTF_BASE/nancy -src/tokencli tokencat $CTF_BASE/token.keys/tokencat < $CTF_BASE/nancy 3>$CTF_BASE/t | src/in.tokend > $CTF_BASE/nancy +src/tokencli tokencat $CTF_BASE/mcp/tokend.keys/tokencat < $CTF_BASE/nancy 3>$CTF_BASE/t | src/in.tokend > $CTF_BASE/nancy if ! grep -q 'tokencat:x....-....x' $CTF_BASE/tokens.db; then die "in.tokend didn't write to database" diff --git a/mcp/tokend.keys/octopus b/mcp/tokend.keys/octopus new file mode 100644 index 0000000..8a5f356 --- /dev/null +++ b/mcp/tokend.keys/octopus @@ -0,0 +1,2 @@ + +Àñõ®¶'çå6Œ™²¤Y= \ No newline at end of file diff --git a/mcp/tokend.keys/pwnables b/mcp/tokend.keys/pwnables new file mode 100644 index 0000000..b9f44b7 --- /dev/null +++ b/mcp/tokend.keys/pwnables @@ -0,0 +1 @@ +‚Æt322˜/—0ãg†žji \ No newline at end of file diff --git a/octopus/src/Makefile b/octopus/src/Makefile index 38619cf..67085c3 100644 --- a/octopus/src/Makefile +++ b/octopus/src/Makefile @@ -1,6 +1,8 @@ # Octopus / Some kind of octopus / Tearing my shell apart / Letting the # sea get in / You make my insides outside +build: octopus + octopus: octopus.o token.o clean: diff --git a/pwnables/pwnables.mk b/pwnables/pwnables.mk index d07a528..6443e4b 100644 --- a/pwnables/pwnables.mk +++ b/pwnables/pwnables.mk @@ -9,6 +9,8 @@ pwnables-install: pwnables-build mkdir -p $(PWNABLES_PKGDIR)/bin/ $(MAKE) -C pwnables/src install DESTDIR=$(CURDIR)/$(PWNABLES_PKGDIR) + $(call COPYTREE, pwnables/tokencli, $(PWNABLES_PKGDIR)/tokencli) + $(call COPYTREE, pwnables/service, $(PWNABLES_PKGDIR)/service) pwnables-clean: diff --git a/pwnables/setup b/pwnables/setup index d22f4c9..7b20433 100755 --- a/pwnables/setup +++ b/pwnables/setup @@ -15,21 +15,24 @@ if [ ! -x /mnt/pwnables-root/bin/busybox ]; then # Make some skeleton junk install -o root -m 0755 -d /mnt/pwnables-root/var/lib + install -o root -m 0755 -d /mnt/pwnables-root/var/lib/ctf + install -o root -m 0755 -d /mnt/pwnables-root/var/lib/ctf/tokens install -o root -m 0755 -d /mnt/pwnables-root/var/log install -o root -m 0755 -d /mnt/pwnables-root/var/spool install -o root -m 0755 -d /mnt/pwnables-root/var/cache install -o root -m 0777 -d /mnt/pwnables-root/var/run install -o root -m 0777 -d /mnt/pwnables-root/var/cache + # Install the pwnables install -o root -d /mnt/pwnables-root/home/alice/ - install -o root -m 0111 bin/* /mnt/pwnables-root/home/alice/ + install -o bob -m 0111 bin/gimmie /mnt/pwnables-root/home/alice/ # ltrace needs to read the binary - chmod +r /mnt/pwnables-root/home/alice/ltraceme + install -o bob -m 0555 bin/ltraceme /mnt/pwnables-root/home/alice/ - # strace needs to be suid - chown bob /mnt/pwnables-root/home/alice/straceme - chmod 04511 /mnt/pwnables-root/home/alice/straceme + # straceme and killme need to be suid, to prevent LD_PRELOAD + install -o bob -m 04111 bin/straceme /mnt/pwnables-root/home/alice/ + install -o bob -m 04111 bin/killme /mnt/pwnables-root/home/alice/ fi cp -r service/* /var/service/ diff --git a/pwnables/src/gimmie.c b/pwnables/src/gimmie.c index 6f38ba7..460a0a7 100644 --- a/pwnables/src/gimmie.c +++ b/pwnables/src/gimmie.c @@ -16,6 +16,7 @@ main(int argc, char *argv[]) key, sizeof(key), token, sizeof(token) - 1); if (-1 == tokenlen) { + write(1, "Something's broken: I can't read my token.\n", 43); return 69; } diff --git a/pwnables/src/ltraceme.c b/pwnables/src/ltraceme.c index ceccd37..2902ab1 100644 --- a/pwnables/src/ltraceme.c +++ b/pwnables/src/ltraceme.c @@ -54,7 +54,7 @@ main(int argc, char *argv[]) * if (fmt[0] == 'T') write(1, buf, len); * } */ - printf("Token length %u at %p.\n", tokenlen, token); + printf("Token length %u at %p.\n", (unsigned int)tokenlen, token); return 0; } diff --git a/pwnables/tokencli/gimmie/category b/pwnables/tokencli/gimmie/category new file mode 100644 index 0000000..5e1d073 --- /dev/null +++ b/pwnables/tokencli/gimmie/category @@ -0,0 +1 @@ +pwnables diff --git a/pwnables/tokencli/gimmie/category.key b/pwnables/tokencli/gimmie/category.key new file mode 100644 index 0000000..b9f44b7 --- /dev/null +++ b/pwnables/tokencli/gimmie/category.key @@ -0,0 +1 @@ +‚Æt322˜/—0ãg†žji \ No newline at end of file diff --git a/pwnables/tokencli/gimmie/enc.key b/pwnables/tokencli/gimmie/enc.key new file mode 100644 index 0000000..b90c03d --- /dev/null +++ b/pwnables/tokencli/gimmie/enc.key @@ -0,0 +1 @@ +_d).FvÍeÿ褩OÙ \ No newline at end of file diff --git a/tokencli/service/tokencli/run b/tokencli/service/tokencli/run deleted file mode 100755 index 10e4fbe..0000000 --- a/tokencli/service/tokencli/run +++ /dev/null @@ -1,11 +0,0 @@ -#! /bin/sh - -exec 2>&1 - -while true; do - for fn in /opt/*/*.tokenkey; do - cat=$(basename $fn .tokenkey) - echo "XXX: not implemented yet" - done - sleep 60 -done diff --git a/tokencli/service/tokencli/log/run b/tokencli/service/tokengetd/log/run similarity index 100% rename from tokencli/service/tokencli/log/run rename to tokencli/service/tokengetd/log/run diff --git a/tokencli/service/tokengetd/run b/tokencli/service/tokengetd/run new file mode 100755 index 0000000..10642b0 --- /dev/null +++ b/tokencli/service/tokengetd/run @@ -0,0 +1,4 @@ +#! /bin/sh + +exec 2>&1 +exec ./tokengetd \ No newline at end of file diff --git a/tokencli/service/tokengetd/tokengetd b/tokencli/service/tokengetd/tokengetd new file mode 100755 index 0000000..e67553c --- /dev/null +++ b/tokencli/service/tokengetd/tokengetd @@ -0,0 +1,18 @@ +#! /bin/sh + +chat=/tmp/tokencli.chatter +token=/tmp/tokencli.token +trap "rm -f $chat $token" 0 + +mkfifo -m 0500 $chat $token + +while true; do + for dn in /opt/*/tokencli/*; do + [ -d $dn ] || continue + puzzle=$(basename $dn) + category=$(cat $dn/category) + nc 10.0.0.1 1 < $fifo | tokencli $category $dn/category.key > $fifo 3> $token + arc4 $dn/enc.key < $token > /var/lib/ctf/tokens/$category + done + sleep 60 +done diff --git a/tokencli/setup b/tokencli/setup new file mode 100755 index 0000000..075d5ec --- /dev/null +++ b/tokencli/setup @@ -0,0 +1,3 @@ +#! /bin/sh + +cp -r service/* /var/service diff --git a/tokencli/src/Makefile b/tokencli/src/Makefile index f387147..f3b32b3 100644 --- a/tokencli/src/Makefile +++ b/tokencli/src/Makefile @@ -1,3 +1,7 @@ +build: tokencli arc4 + +arc4: arc4.o arc4-main.o + tokencli: tokencli.o arc4.o clean: diff --git a/tokencli/src/arc4-main.c b/tokencli/src/arc4-main.c new file mode 100644 index 0000000..f1a0dd0 --- /dev/null +++ b/tokencli/src/arc4-main.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include "arc4.h" + +int +main(int argc, char *argv[]) +{ + struct arc4_ctx ctx; + + /* Read key and initialize context */ + { + uint8_t key[256]; + size_t keylen = 0; + FILE *f; + + if (argc == 2) { + if (! (f = fopen(argv[1], "r"))) { + perror(argv[0]); + } + } else { + f = fdopen(3, "r"); + } + + if (f) { + keylen = fread(key, 1, sizeof(key), f); + fclose(f); + } + + if (0 == keylen) { + fprintf(stderr, "Usage: %s [KEYFILE]