mirror of https://github.com/dirtbags/moth.git
Start trying to get token distribution working
This commit is contained in:
parent
5fba528be5
commit
e002f16618
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
Àñõ®¶'çå6Œ™²¤Y=
|
|
@ -0,0 +1 @@
|
|||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pwnables
|
|
@ -0,0 +1 @@
|
|||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
@ -0,0 +1 @@
|
|||
_d).Fvヘe<EFBE8D><65>、ゥOル
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec 2>&1
|
||||
exec ./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
|
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
cp -r service/* /var/service
|
|
@ -1,3 +1,7 @@
|
|||
build: tokencli arc4
|
||||
|
||||
arc4: arc4.o arc4-main.o
|
||||
|
||||
tokencli: tokencli.o arc4.o
|
||||
|
||||
clean:
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue