Start trying to get token distribution working

This commit is contained in:
Neale Pickett 2010-09-27 21:03:10 -06:00
parent 5fba528be5
commit e002f16618
24 changed files with 139 additions and 35 deletions

View File

@ -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)
{

View File

@ -4,7 +4,11 @@
#include <stdint.h>
#include <stdlib.h>
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);

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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"

2
mcp/tokend.keys/octopus Normal file
View File

@ -0,0 +1,2 @@
Àñõ®¶'çå6Œ™²¤Y=

1
mcp/tokend.keys/pwnables Normal file
View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji

View File

@ -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:

View File

@ -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:

View File

@ -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/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1 @@
pwnables

View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji

View File

@ -0,0 +1 @@
_d).Fvヘe<EFBE8D><65>、ゥOル

View File

@ -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

4
tokencli/service/tokengetd/run Executable file
View File

@ -0,0 +1,4 @@
#! /bin/sh
exec 2>&1
exec ./tokengetd

View File

@ -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

3
tokencli/setup Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
cp -r service/* /var/service

View File

@ -1,3 +1,7 @@
build: tokencli arc4
arc4: arc4.o arc4-main.o
tokencli: tokencli.o arc4.o
clean:

49
tokencli/src/arc4-main.c Normal file
View File

@ -0,0 +1,49 @@
#include <stdint.h>
#include <stdio.h>
#include <sysexits.h>
#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] <PLAINTEXT\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "You can also pass in the key on fd 3; omit\n");
fprintf(stderr, "KEYFILE in this case.\n");
return EX_IOERR;
}
arc4_init(&ctx, key, (size_t)keylen);
}
/* Encrypt */
while (1) {
int c = getchar();
if (EOF == c) break;
putchar(c ^ arc4_pad(&ctx));
}
return 0;
}

View File

@ -6,7 +6,10 @@ tokencli-install: tokencli-build
$(call COPYTREE, tokencli/service, $(TOKENCLI_PKGDIR)/service)
cp tokencli/setup $(TOKENCLI_PKGDIR)/
cp tokencli/src/tokencli $(TOKENCLI_PKGDIR)/bin/
cp tokencli/src/arc4 $(TOKENCLI_PKGDIR)/bin/
tokencli-clean:
rm -rf $(TOKENCLI_PKGDIR) $(TOKENCLI_PACKAGE)