Merge branch 'master' of ssh://fozzie/home/neale/projects/ctf

This commit is contained in:
Neale Pickett 2011-10-17 07:31:51 -06:00
commit 3619508209
186 changed files with 4807 additions and 9824 deletions

View File

@ -10,7 +10,6 @@ CACHE = cache
# The end result
BIN = bin
all: packages
dist: ctf-install.zip

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
doc/ipv6.txt Normal file
View File

@ -0,0 +1,15 @@
IPv6 in Dirtbags CTF
====================
The contest network uses IPs in the unique local address space
fd82:b410:3441::/48. Each team gets a /64 internal subnet, with
their team number (generally the same as the switch port).
Each subnet's gateway is ::1.
Team 5, in switch port 5, on VLAN 5, gets fd82:b410:3441:5::/64.
Server network is fd84:b410:3441::/64 (AKA fd84:b410:3441:0::/64). To
make things easier to type, use hosts in the /112. The MCP server lives
at fd84:b410:3441::2.

View File

@ -0,0 +1,6 @@
00ADMIN_PKGDIR = $(TARGET)/00admin
00admin-install:
$(call COPYTREE, packages/00admin/service, $(00ADMIN_PKGDIR)/service)
PACKAGES += 00admin

View File

@ -0,0 +1,14 @@
#! /bin/sh
exec 2>&1
[ -r /etc/passwd ] || echo 'root:x:0:0:root:/tmp:/bin/sh' > /etc/passwd
# Always do this, in case something else set a root password
echo 'root:$1$bEGCYemG$pAo9KXWQKgQNijRGKSb7e1' | chpasswd --encrypted
# Bring up the NIC; this will get us at least a link-local address, and
# hopefully a global address with stateless autoconfiguration.
ip link set eth0 up
exec dropbear -r ./rsa.key -E -F

View File

@ -1,20 +0,0 @@
ARMADILLO_PKGDIR = $(TARGET)/armadillo
armadillo-install: armadillo-build
mkdir -p $(ARMADILLO_PKGDIR)
mkdir -p $(ARMADILLO_PKGDIR)/bin/
$(MAKE) -C packages/armadillo/src install DESTDIR=$(CURDIR)/$(ARMADILLO_PKGDIR)
$(call COPYTREE, packages/armadillo/tokens, $(ARMADILLO_PKGDIR)/tokens)
$(call COPYTREE, packages/armadillo/service, $(ARMADILLO_PKGDIR)/service)
armadillo-clean:
rm -rf $(ARMADILLO_PKGDIR)
$(MAKE) -C packages/armadillo/src clean
armadillo-build:
$(MAKE) -C packages/armadillo/src build
PACKAGES += armadillo

View File

@ -1 +0,0 @@
10.0.0.3/24

View File

@ -1,4 +0,0 @@
.::7777::-.
/:'////' `::>/|/
.', |||| `/( e\
-==~-'`-Xm````-mr' `-_\

View File

@ -1,4 +0,0 @@
#! /bin/sh
[ -f motd ] && cat motd
exec chroot /mnt/pwnables-root login -f alice

View File

@ -1,40 +0,0 @@
#! /bin/sh -e
# Configure IP address
IP=$(cat ip.txt)
ip addr add $IP label eth0:armadillo dev eth0
# Set up chroot environment
# We never umount any of this since it's all just in RAM
mkdir -p /mnt/armadillo-root
grep -q armadillo-root /proc/mounts || mount -o bind / /mnt/armadillo-root
grep -q armadillo-var /proc/mounts || mount -t tmpfs -o size=5m,mode=0755 armadillo-var /mnt/armadillo-root/var
grep -q armadillo-tmp /proc/mounts || mount -t tmpfs -o size=15k armadillo-tmp /mnt/armadillo-root/tmp
grep -q armadillo-home /proc/mounts || mount -t tmpfs -o size=5m,mode=0755 armadillo-home /mnt/armadillo-root/home
# Make some skeleton junk
install -o root -m 0755 -d /mnt/armadillo-root/var/lib
install -o root -m 0755 -d /mnt/armadillo-root/var/lib/ctf
install -o root -m 0755 -d /mnt/armadillo-root/var/lib/ctf/tokens
install -o root -m 0755 -d /mnt/armadillo-root/var/log
install -o root -m 0755 -d /mnt/armadillo-root/var/spool
install -o root -m 0755 -d /mnt/armadillo-root/var/cache
install -o root -m 0777 -d /mnt/armadillo-root/var/run
install -o root -m 0777 -d /mnt/armadillo-root/var/cache
# Install the binaries
install -o root -d /mnt/armadillo-root/home/alice/
install -o bob -m 0111 /opt/armadillo/bin/gimmie /mnt/armadillo-root/home/alice/
install -o bob -m 0111 /opt/armadillo/bin/dillo /mnt/armadillo-root/home/alice/
# straceme and killme need to be suid, to prevent LD_PRELOAD
install -o bob -m 04111 /opt/armadillo/bin/straceme /mnt/armadillo-root/home/alice/
install -o bob -m 04111 /opt/armadillo/bin/killme /mnt/armadillo-root/home/alice/
# Set up links for tokens
mkdir -p /var/lib/ctf/tokens
for puzzle in gimmie straceme killme dillo; do
ln -sf /mnt/armadillo-root/var/lib/ctf/tokens/$puzzle /var/lib/ctf/tokens/$puzzle
done
exec tcpsvd -C 5:"Let's not be greedy" ${IP%/*} 23 /sbin/telnetd -l ./pwnie

View File

@ -1,17 +0,0 @@
CFLAGS = -Wall -Werror
TARGETS = gimmie straceme killme dillo
all: build
build: $(TARGETS)
gimmie: gimmie.o token.o arc4.o
straceme: straceme.o token.o arc4.o
killme: killme.o token.o arc4.o
dillo: dillo.o token.o arc4.o
install: $(TARGETS)
install -m 0755 $(TARGETS) $(DESTDIR)/bin
clean:
rm -f *.o $(TARGETS)

View File

@ -1 +0,0 @@
../../../src/arc4.c

View File

@ -1 +0,0 @@
../../../src/arc4.h

View File

@ -1,22 +0,0 @@
#! /usr/bin/python
import subprocess
# In the actual contest you'd want to run netcat or just
# open your own TCP connection to port 23 and run commands.
d = subprocess.Popen(['./dillo'],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
o = d.stdout
i = d.stdin
c = o.read(1)
v = chr(ord(c) ^ 0x20)
i.write(v)
o.readline()
o.readline()
o.readline()
o.readline()
o.readline()
d.poll()

View File

@ -1,59 +0,0 @@
#include <unistd.h>
#include <time.h>
#include <stdint.h>
#include "arc4.h"
#include "token.h"
const uint8_t key[] =
{0xa5, 0xb1, 0x6f, 0xce,
0x59, 0x2d, 0xb1, 0xe9,
0x4b, 0x07, 0x91, 0x6d,
0x9f, 0x3b, 0xc8, 0xc6};
const char dillo[] =
(" .::7777::-.\n"
" /:'////' `::>/|/\n"
" .', |||| `/( e\\\n"
" -==~-'`-Xm````-mr' `-_\\\n");
int
main(int argc, char *argv[])
{
uint8_t v;
int i;
/* Pick a random non-zero xor value */
do {
v = arc4_rand8();
} while (! v);
/* Print the dillo */
for (i = 0; dillo[i]; i += 1) {
struct timespec req = {0, 33333333};
uint8_t c = dillo[i];
if ('\n' != c) {
c ^= v;
}
write(1, &c, 1);
nanosleep(&req, NULL);
}
/* Read a single byte; strace will help with solution */
{
uint8_t c;
read(0, &c, 1);
if (c != v) {
return 1;
}
}
if (-1 == print_token("dillo", key, sizeof(key))) {
write(2, "Something is broken; I can't read my token.\n", 44);
return 69;
}
return 0;
}

View File

@ -1,19 +0,0 @@
#include <stdio.h>
#include <sysexits.h>
#include "token.h"
uint8_t const key[] = {0x5f, 0x64, 0x13, 0x29,
0x2e, 0x46, 0x76, 0xcd,
0x65, 0xff, 0xe8, 0x03,
0xa4, 0xa9, 0x4f, 0xd9};
int
main(int argc, char *argv[])
{
if (-1 == print_token("gimmie", key, sizeof(key))) {
fprintf(stderr, "Something is broken; I can't read my token.\n");
return EX_UNAVAILABLE;
}
return 0;
}

View File

@ -1,59 +0,0 @@
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sysexits.h>
#include "arc4.h"
#include "token.h"
#define ROUNDS 20
uint8_t const key[] = {0x51, 0x91, 0x6d, 0x81,
0x14, 0x21, 0xf8, 0x95,
0xb8, 0x09, 0x87, 0xa6,
0xa8, 0xb0, 0xa0, 0x46};
int lastsig;
void
handler(int signum)
{
lastsig = signum;
}
int
main(int argc, char *argv[])
{
int i;
for (i = 1; i < 8; i += 1) {
signal(i, handler);
}
for (i = 0; i < ROUNDS; i += 1) {
int desired = (arc4_rand8() % 7) + 1;
lastsig = 0;
printf("%d\n", desired);
fflush(stdout);
if (i == 0) {
sleep(5);
} else {
sleep(1);
}
if (0 == lastsig) {
printf("Too slow.\n");
return 1;
}
if (lastsig != desired) {
printf("Wrong one.\n");
return 1;
}
}
if (-1 == print_token("killme", key, sizeof(key))) {
fprintf(stderr, "Something is broken; I can't read my token.\n");
return EX_UNAVAILABLE;
}
return 0;
}

View File

@ -1,85 +0,0 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdarg.h>
#include <sysexits.h>
#include <stdio.h>
#include <ctype.h>
#include "token.h"
uint8_t const key[] = {0x30, 0x00, 0x55, 0x0f,
0xc2, 0xf6, 0x52, 0x2a,
0x31, 0xfd, 0x00, 0x92,
0x9d, 0x49, 0x24, 0xce};
int
main(int argc, char *argv[])
{
/* Check argv[1].
*
* If no args, argv[1] will be NULL, which causes a segfault.
* This is what we want.
*
* To pass this, run ./straceme $$.
* But you have to do it from a shell script, because if you run
* strace ./straceme $$
* getppid() will return the PID of strace!
*/
if (getppid() != atoi(argv[1])) {
write(2, "argv[1] incorrect\n", 18);
return EX_USAGE;
}
/* Read an rc file.
*
* To pass this, set $HOME to someplace you have access.
*/
{
int fd;
char fn[128];
char bs[1000];
int len;
len = snprintf(fn, sizeof(fn) - 1, "%s/.stracemerc", getenv("HOME"));
if (len < 0) {
len = 0;
}
fn[len] = '\0';
if (-1 == (fd = open(fn, O_RDONLY))) {
fd = open("/etc/stracemerc", O_RDONLY);
}
if (-1 == fd) {
return EX_NOINPUT;
}
/* We don't actually care about contents */
read(fd, bs, sizeof(bs));
close(fd);
}
/* Read in category name from fd 5
*
* echo -n straceme > foo.txt
* ./straceme $$ 5< foo.txt
*/
{
char cat[50];
int catlen;
int i;
catlen = read(5, cat, sizeof(cat) - 1);
for (i = 0; i < catlen; i += 1) {
if (! isalnum(cat[i])) break;
}
cat[i] = '\0';
if (-1 == print_token(cat, key, sizeof(key))) {
write(2, "Something is broken; I can't read my token.\n", 44);
return 69;
}
}
return 0;
}

View File

@ -1 +0,0 @@
../../../src/token.c

View File

@ -1 +0,0 @@
../../../src/token.h

View File

@ -1 +0,0 @@
pwnables

View File

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

View File

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

View File

@ -1 +0,0 @@
pwnables

View File

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

View File

@ -1 +0,0 @@
Q<EFBFBD>m<EFBFBD>!ј<>И <09>ІЈА F

View File

@ -1 +0,0 @@
pwnables

View File

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

View File

@ -1 +0,0 @@
pwnables

View File

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

View File

@ -1,17 +0,0 @@
CTFBASE_PKGDIR = $(TARGET)/ctfbase
ctfbase-install: ctfbase-build
mkdir -p $(CTFBASE_PKGDIR)/bin/
$(call COPYTREE, packages/ctfbase/service, $(CTFBASE_PKGDIR)/service)
cp packages/ctfbase/src/arc4 $(CTFBASE_PKGDIR)/bin/
ctfbase-clean:
rm -rf $(CTFBASE_PKGDIR)
$(MAKE) -C packages/ctfbase/src clean
ctfbase-build:
$(MAKE) -C packages/ctfbase/src build
PACKAGES += ctfbase

View File

@ -1,13 +0,0 @@
#! /bin/sh -e
PATH=/bin:/opt/ctfbase/bin; export PATH
while true; do
# Fetch list of teams
teams=/var/lib/ctf/teams.txt
rm -f $teams.tmp
wget -q -O $teams.tmp http://10.0.0.2/teams.txt && \
mv $teams.tmp $teams
sleep 60
done

View File

@ -1,12 +0,0 @@
#! /bin/sh -e
exec 2>&1
# Set up networking for all CTF ips
ip link set eth0 up
if ! ip route | grep -q default; then
ip route add default via 10.0.0.1 || exit 1
fi
install -o root -m 0755 -d /var/lib/ctf/tokens
exec ./ctfd

View File

@ -1,4 +0,0 @@
#! /bin/sh
iptables -D INPUT -s 10.0.0.0/16 --proto tcp --dport 55 -j ACCEPT
iptables -D INPUT --proto tcp --dport 55 -j REJECT

View File

@ -1,6 +0,0 @@
#! /bin/sh
exec 2>&1
iptables -A INPUT -s 10.0.0.0/16 --proto tcp --dport 22 -j ACCEPT
iptables -A INPUT --proto tcp --dport 22 -j REJECT
exec dropbear -r ./rsa.key -E -F

View File

@ -1,7 +0,0 @@
build: arc4
arc4: arc4.c
arc4: CFLAGS += -DARC4_MAIN
clean:
rm -f *.o arc4

View File

@ -1 +0,0 @@
../../../src/arc4.c

View File

@ -1 +0,0 @@
../../../src/arc4.h

View File

@ -1,8 +0,0 @@
fireeye-source:
fireeye-build:
fireeye-install: packages/fireeye/tokens.txt
mkdir -p $(TARGET)/fireeye/
cp $< $(TARGET)/fireeye/
PACKAGES += fireeye

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
#! /bin/sh
for i in $(seq 100); do
if [ $(expr $i % 15) = 0 ]; then
echo 'FizzBuzz'
elif [ $(expr $i % 3) = 0 ]; then
echo 'Fizz'
elif [ $(expr $i % 5) = 0 ]; then
echo 'Buzz'
else
echo $i
fi
done

View File

@ -0,0 +1,29 @@
FIZZBUZZ_PKGDIR = $(TARGET)/fizzbuzz
FIZZBUZZ_BUILDDIR = $(BUILD)/fizzbuzz
$(FIZZBUZZ_BUILDDIR)/token.enc: packages/fizzbuzz/tokens.txt
$(FIZZBUZZ_BUILDDIR)/token.enc: packages/fizzbuzz/fizzbuzz-client.sh
$(FIZZBUZZ_BUILDDIR)/token.enc: $(FIZZBUZZ_BUILDDIR)/fizzbuzz-native
packages/fizzbuzz/fizzbuzz-client.sh | $(FIZZBUZZ_BUILDDIR)/fizzbuzz-native 3< packages/fizzbuzz/tokens.txt > $@
$(FIZZBUZZ_BUILDDIR)/fizzbuzz-native: packages/fizzbuzz/src/fizzbuzz.c
@ mkdir -p $(@D)
cc -o $@ $<
fizzbuzz-install: fizzbuzz-build
mkdir -p $(FIZZBUZZ_PKGDIR)/bin/
$(call COPYTREE, packages/fizzbuzz/service, $(FIZZBUZZ_PKGDIR)/service)
cp packages/fizzbuzz/tokens.txt $(FIZZBUZZ_PKGDIR)/
cp $(FIZZBUZZ_BUILDDIR)/token.enc $(FIZZBUZZ_PKGDIR)/
cp packages/fizzbuzz/src/fizzbuzz $(FIZZBUZZ_PKGDIR)/bin/
fizzbuzz-clean:
rm -rf $(FIZZBUZZ_PKGDIR) $(FIZZBUZZ_BUILDDIR)
$(MAKE) -C packages/fizzbuzz/src clean
fizzbuzz-build: $(FIZZBUZZ_BUILDDIR)/token.enc
$(MAKE) -C packages/fizzbuzz/src build
PACKAGES += fizzbuzz

View File

@ -0,0 +1 @@
fd84:b410:3441::a0d/64

View File

@ -0,0 +1,8 @@
#! /bin/sh -e
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 /opt/fizzbuzz/bin/fizzbuzz 3</opt/fizzbuzz/token.enc

View File

@ -1,12 +1,9 @@
CFLAGS = -Wall -Werror
LDFLAGS = -static
TARGETS = logger
TARGETS = fizzbuzz
all: build
build: $(TARGETS)
logger: logger.o arc4.o token.o
install: $(TARGETS)
install -m 0755 $(TARGETS) $(DESTDIR)/bin

View File

@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* How this works:
*
* You have to provide this with the output of a fizzbuzz program to get
* it to decode the token.
*
* Provide the encoded token on fd 3, and it will output the decode
* provided correct input. If you provided the decoded token, it will
* encode it. In other words, encode(x) = decode(x).
*
*
* Here's a fizzbuzz program in bourne shell:
*
* for i in $(seq 100); do
* if [ $(expr $i % 15) = 0 ]; then
* echo 'FizzBuzz'
* elif [ $(expr $i % 3) = 0 ]; then
* echo 'Fizz'
* elif [ $(expr $i % 5) = 0 ]; then
* echo 'Buzz'
* else
* echo $i
* fi
* done
*
*/
char craptable[] = {
0x64, 0xd4, 0x11, 0x55, 0x50, 0x16, 0x61, 0x02,
0xf7, 0xfd, 0x63, 0x36, 0xd9, 0xa6, 0xf2, 0x29,
0xad, 0xfb, 0xed, 0x7a, 0x06, 0x91, 0xe7, 0x67,
0x80, 0xb6, 0x53, 0x2c, 0x43, 0xf9, 0x3c, 0xf2,
0x83, 0x5c, 0x25, 0xee, 0x21
};
int
main(int argc, char *argv[])
{
int i;
char token[100];
size_t tokenlen;
{
FILE *tokenin = fdopen(3, "r");
if (! tokenin) {
printf("Somebody didn't read the instructions.\n");
return 1;
}
tokenlen = fread(token, 1, sizeof(token), tokenin);
fclose(tokenin);
}
for (i=1; i <= 100; i += 1) {
char l[100];
fgets(l, sizeof(l), stdin);
if (0 == i % 15) {
if (0 != strcmp("FizzBuzz\n", l)) break;
} else if (0 == i % 3) {
if (0 != strcmp("Fizz\n", l)) break;
} else if (0 == i % 5) {
if (0 != strcmp("Buzz\n", l)) break;
} else {
if (atoi(l) != i) break;
}
token[i % tokenlen] ^= i;
token[i % tokenlen] ^= craptable[i % sizeof(craptable)];
}
if (101 == i) {
fwrite(token, tokenlen, 1, stdout);
} else {
printf("Next time, FizzBuzz me.\n");
}
return 0;
}

View File

@ -0,0 +1 @@
net:xuhen-fizuv-syvex

View File

@ -25,4 +25,4 @@ inferno-install: $(INFERNO_BUILDDIR)/build
inferno-clean:
rm -rf $(INFERNO_PKGDIR) $(INFERNO_BUILDDIR)
PACKAGES += inferno
PACKAGES += inferno

View File

@ -1,13 +1,12 @@
IRCD_PKGDIR = $(TARGET)/ircd
IRCD_BUILDDIR = $(BUILD)/ircd
IRCD_VERSION = 17.1
IRCD_VERSION = 18
IRCD_TAR = $(CACHE)/ngircd-$(IRCD_VERSION).tar.gz
IRCD_URL = ftp://ftp.berlios.de/pub/ngircd/ngircd-$(IRCD_VERSION).tar.gz
IRCD_SRCDIR = $(IRCD_BUILDDIR)/ngircd-$(IRCD_VERSION)
# Prevents automake from mangling cross-compiled binary names
IRCD_CC_HOST := $(shell $(CC) -v 2>&1 | awk '/Target:/{print $$2}')
IRCD_CONF_OPT := --host=i686-unknown-linux-uclibc --program-transform-name=
ircd-install: ircd-build
@ -23,7 +22,7 @@ $(IRCD_BUILDDIR)/source: $(IRCD_TAR)
ircd-build: $(IRCD_BUILDDIR)/built
$(IRCD_BUILDDIR)/built: $(IRCD_BUILDDIR)/source
cd $(IRCD_SRCDIR) && ./configure $(IRCD_CONF_OPT)
cd $(IRCD_SRCDIR) && ./configure $(CONFIG_XCOMPILE_FLAGS) --enable-ipv6
$(MAKE) -C $(IRCD_SRCDIR)
touch $@
@ -36,4 +35,4 @@ ircd-install: ircd-build
ircd-clean:
rm -rf $(IRCD_BUILDDIR)
PACKAGES += ircd
PACKAGES += ircd

View File

@ -0,0 +1 @@
fd84:b410:3441::6/64

View File

@ -1,8 +1,12 @@
[Global]
Name = irc.ctf
Info = CTF IRC
OperCanUseMode = yes
AdminInfo1 = CTF IRC Server
AdminInfo2 = The table at the front of the room
AdminEmail = zephyr@dirtbags.net
MotdPhrase = "welcome datacomp"
Listen = fd84:b410:3441::6
[Operator]
Name = oper
Password = opsplz
Password = operpass

View File

@ -1,4 +1,12 @@
#! /bin/sh
exec 2>&1
exec /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon
IP=$(cat ip.txt)
ip addr add $IP label eth0:ircd dev eth0
ip monitor | grep -q $IP
adduser -S -H -u 65534 nobody
adduser -S -H irc
exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon

28
packages/libcap/libcap.mk Normal file
View File

@ -0,0 +1,28 @@
LIBCAP_PKGDIR = $(TARGET)/libcap
LIBCAP_BUILDDIR = $(BUILD)/libcap
LIBCAP_VERSION = 2.22
LIBCAP_TAR = $(CACHE)/libcap-$(LIBCAP_VERSION).tar.gz
# XXX: kernel.org was down when I wrote this, but is the canonical source
LIBCAP_URL = http://ftp.debian.org/debian/pool/main/libc/libcap2/libcap2_$(LIBCAP_VERSION).orig.tar.gz
LIBCAP_SRCDIR = $(LIBCAP_BUILDDIR)/libcap-$(LIBCAP_VERSION)
LIBCAP_LDFLAGS = -L$(CURDIR)/$(LIBCAP_SRCDIR)/libcap
LIBCAP_CFLAGS = -I$(CURDIR)/$(LIBCAP_SRCDIR)/libcap/include
$(LIBCAP_TAR):
mkdir -p $(@D)
wget -O $@ $(LIBCAP_URL)
libcap-source: $(LIBCAP_BUILDDIR)/source
$(LIBCAP_BUILDDIR)/source: $(LIBCAP_TAR)
mkdir -p $(@D)
zcat $< | ( cd $(@D) && tar xf -)
touch $@
# This library's build sort of blows.
libcap-build: $(LIBCAP_BUILDDIR)/built
$(LIBCAP_BUILDDIR)/built: $(LIBCAP_BUILDDIR)/source
$(MAKE) -C $(LIBCAP_SRCDIR)/libcap _makenames
$(MAKE) -C $(LIBCAP_SRCDIR) CC=$(CC)
touch $@

View File

@ -1,20 +0,0 @@
LOGGER_PKGDIR = $(TARGET)/logger
logger-install: logger-build
mkdir -p $(LOGGER_PKGDIR)
mkdir -p $(LOGGER_PKGDIR)/bin/
$(MAKE) -C packages/logger/src install DESTDIR=$(CURDIR)/$(LOGGER_PKGDIR)
$(call COPYTREE, packages/logger/tokens, $(LOGGER_PKGDIR)/tokens)
$(call COPYTREE, packages/logger/service, $(LOGGER_PKGDIR)/service)
logger-clean:
rm -rf $(LOGGER_PKGDIR)
$(MAKE) -C packages/logger/src clean
logger-build:
$(MAKE) -C packages/logger/src build
PACKAGES += logger

View File

@ -1 +0,0 @@
10.0.0.14/24

View File

@ -1,6 +0,0 @@
#! /bin/sh -e
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP label eth0:logger dev eth0
exec tcpsvd ${IP%/*} 1958 /opt/logger/bin/logger

View File

@ -1,20 +0,0 @@
Base64 code was taken from
http://cvs.savannah.gnu.org/viewvc/*checkout*/gnulib/gnulib/lib/base64.c?revision=HEAD
/* base64.c -- Encode binary data using printable characters.
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

View File

@ -1 +0,0 @@
../../../src/arc4.c

View File

@ -1 +0,0 @@
../../../src/arc4.h

View File

@ -1,652 +0,0 @@
/** logger.c - generate fake log messages (part of dirtbags CTF)
*
* Author: Neale Pickett <neale@lanl.gov>
*
* 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 <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#ifdef STANDALONE
# define TOKEN_MAX 50
#else
# include "token.h"
#endif
#define PID_MAX 32768
#define QSIZE 200
#define MSGS_PER_SEC_MIN 10
#define MSGS_PER_SEC_MAX 40
const uint8_t key[] = {0x99, 0xeb, 0xc0, 0xce,
0xe0, 0xc9, 0xed, 0x5b,
0xbd, 0xc8, 0xb5, 0xfd,
0xdd, 0x0b, 0x03, 0x10};
/* Storage space for tokens */
char token[3][TOKEN_MAX];
void
read_tokens()
{
int i;
ssize_t len;
char name[40];
for (i = 0; i < sizeof(token)/sizeof(*token); i += 1) {
#ifdef STANDALONE
strcpy(token[i], "logger:xylep-donut-nanox");
#else
/* This can't grow beyond 40. Think about it. */
sprintf(name, "logger%d", i);
len = get_token(token[i], sizeof(token[i]), name, key, sizeof(key));
if ((-1 == len) || (len >= sizeof(token[i]))) abort();
token[i][len] = '\0';
#endif
}
}
/*
* Base 64 (GPL: see COPYING)
*/
/* C89 compliant way to cast 'char' to 'unsigned char'. */
static inline unsigned char
to_uchar (char ch)
{
return ch;
}
/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
terminate the output buffer. */
void
base64_encode (const char *in, size_t inlen,
char *out, size_t outlen)
{
static const char b64str[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while (inlen && outlen) {
*out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f];
if (!--outlen)
break;
*out++ = b64str[((to_uchar(in[0]) << 4)
+ (--inlen ? to_uchar(in[1]) >> 4 : 0))
& 0x3f];
if (!--outlen)
break;
*out++ = (inlen
? b64str[((to_uchar(in[1]) << 2)
+ (--inlen ? to_uchar(in[2]) >> 6 : 0))
& 0x3f]
: '=');
if (!--outlen)
break;
*out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '=';
if (!--outlen)
break;
if (inlen)
inlen--;
if (inlen)
in += 3;
}
if (outlen)
*out = '\0';
}
/*
* Bubble Babble
*/
char const consonants[] = "bcdfghklmnprstvz";
char const vowels[] = "aeiouy";
#define bubblebabble_len(n) (6*(((n)/2)+1))
/** 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'
*/
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';
}
int
randint(int max)
{
return random() % max;
}
#define itokenlen 5
char const *
bogus_token()
{
static char token[TOKEN_MAX];
unsigned char crap[itokenlen];
unsigned char digest[bubblebabble_len(itokenlen)];
int i;
for (i = 0; i < sizeof(crap); i += 1 ) {
crap[i] = (unsigned char)randint(256);
}
bubblebabble(digest, (unsigned char *)&crap, itokenlen);
snprintf(token, sizeof(token), "bogus:%s", digest);
token[sizeof(token) - 1] = '\0';
return token;
}
#define choice(a) (a[randint(sizeof(a)/sizeof(*a))])
char const *users[] = {"alice", "bob", "carol", "dave",
"eve", "fran", "gordon",
"isaac", "justin", "mallory",
"oscar", "pat", "steve",
"trent", "vanna", "walter", "zoe"};
char const *
user()
{
return choice(users);
}
char const *filenames[] = {"about", "request", "page", "buttons",
"images", "overview"};
char const *extensions[] = {"html", "htm", "jpg", "png", "css", "cgi"};
char const *fields[] = {"q", "s", "search", "id", "req", "oid", "pmt",
"u", "page", "xxnp", "stat", "jk", "ttb",
"access", "domain", "needle", "service", "client"};
char const *values[] = {"1", "turnip", "chupacabra", "58", "identify",
"parthenon", "jellyfish", "pullman", "auth",
"xa4Jmwl", "cornmeal", "ribbon", "49299248",
"javaWidget", "crashdump", "priority",
"blogosphere"};
char const *
url()
{
static char url[200];
int i, parts;
strcpy(url, "/");
parts = randint(4);
for (i = 0; i < parts; i += 1) {
if (i > 0) {
strcat(url, "/");
}
strcat(url, choice(filenames));
}
if (randint(5) > 1) {
if (i > 0) {
strcat(url, ".");
strcat(url, choice(extensions));
}
} else {
parts = randint(8) + 1;
for (i = 0; i < parts; i += 1) {
if (0 == i) {
strcat(url, "?");
} else {
strcat(url, "&");
}
strcat(url, choice(fields));
strcat(url, "=");
strcat(url, choice(values));
}
}
return url;
}
struct message {
time_t when;
char text[300];
struct message *next;
};
/* Allocate some messages */
struct message heap[QSIZE];
struct message *pool;
struct message *queue;
struct message *
get_message()
{
struct message *ret = pool;
if (pool) {
pool = pool->next;
}
return ret;
}
void
free_message(struct message *msg)
{
if (msg) {
msg->next = pool;
pool = msg;
}
}
/* Either get count messages, or don't get any at all. */
int
get_many_messages(struct message **msgs, size_t count)
{
int i;
for (i = 0; i < count; i += 1) {
msgs[i] = get_message();
}
if (NULL == msgs[i-1]) {
for (i = 0; i < count; i += 1) {
free_message(msgs[i]);
}
return -1;
}
return 0;
}
void
enqueue_message(struct message *msg)
{
struct message *cur;
/* In some cases, we want msg to be at the head */
if ((NULL == queue) || (queue->when > msg->when)) {
msg->next = queue;
queue = msg;
return;
}
/* Find where to stick it */
for (cur = queue; NULL != cur->next; cur = cur->next) {
if (cur->next->when > msg->when) break;
}
/* Insert it after cur */
msg->next = cur->next;
cur->next = msg;
}
void
enqueue_messages(struct message **msgs, size_t count)
{
int i;
for (i = 0; i < count; i += 1) {
enqueue_message(msgs[i]);
}
}
struct message *
dequeue_message(time_t now)
{
if ((NULL != queue) && (queue->when <= now)) {
struct message *ret = queue;
queue = queue->next;
free_message(ret);
return ret;
}
return NULL;
}
int
main(int argc, char *argv[])
{
int i;
int pid = 52;
time_t then = time(NULL) - 100; /* Assure we get new tokens right away */
/* Seed RNG */
srandom(then);
/* Initialize free messages */
{
pool = &(heap[0]);
for (i = 0; i < QSIZE - 1; i += 1) {
heap[i].next = &(heap[i+1]);
}
heap[i].next = NULL;
}
/* Now let's make some crap! */
while (! feof(stdout)) {
struct message *msg;
time_t now = time(NULL);
int i, max;
/* Print messages */
while ((msg = dequeue_message(now))) {
char ftime[80];
struct tm *tm;
tm = gmtime(&msg->when);
if (! tm) {
snprintf(ftime, sizeof(ftime), "%ld", now);
} else {
strftime(ftime, sizeof(ftime), "%b %d %T", tm);
}
printf("%s loghost %s\n", ftime, msg->text);
}
fflush(stdout);
/* Time for new tokens? */
if (then + 60 <= now) {
read_tokens();
then = now;
}
/* Make some messages */
max = MSGS_PER_SEC_MIN + randint(MSGS_PER_SEC_MAX - MSGS_PER_SEC_MIN);
for (i = 0; i < max; i += 1) {
time_t start = now + 1;
struct message *messages[10];
/* Increment the PID */
pid = (pid + 1 + randint(20)) % PID_MAX;
switch (randint(90)) {
case 0:
/* Internal diagnostic! */
if (-1 != get_many_messages(messages, 1)) {
int queued, pooled;
struct message *msg;
for (pooled = 0, msg = pool;
msg;
msg = msg->next, pooled += 1);
/* Start at one because of this message */
for (queued = 1, msg = queue;
msg;
msg = msg->next, queued += 1);
messages[0]->when = now;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"DEBUG: %d in pool, %d in queue (%d total)",
pooled, queued, pooled + queued);
enqueue_messages(messages, 1);
}
case 1:
/* Lame-o "token" service */
if (-1 != get_many_messages(messages, 1)) {
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"tokenserv[%d]: token is %s",
pid, token[0]);
enqueue_messages(messages, 1);
}
/* Always follow this with a couple lines of fluff so it's
not the last thing in a batch */
max += 2;
break;
case 2:
/* IMAP */
{
char const *mytoken;
char const *u;
char btoken[TOKEN_MAX * 2];
if (randint(5) == 0) {
mytoken = token[1];
u = "token";
} else {
mytoken = bogus_token();
u = user();
}
base64_encode(mytoken, strlen(mytoken), btoken, sizeof(btoken));
if (-1 != get_many_messages(messages, 2)) {
const int offset=15;
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"imapd[%d]: Login: user=%s method=PLAIN token1=%.*s",
pid, u, offset, btoken);
messages[1]->when = start + 4 + randint(60);
snprintf(messages[1]->text, sizeof(messages[1]->text),
"imapd[%d]: Disconnected: Logged out token2=%s",
pid, btoken + offset);
enqueue_messages(messages, 2);
}
}
case 3:
/* IRC */
if (-1 != get_many_messages(messages, 3)) {
int connection = randint(512);
int port = randint(65536);
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"ircd: Accepted connection %d from %d.%d.%d.%d:%d on socket %d.",
connection,
randint(256), randint(256),
randint(256), randint(256),
port,
randint(256));
messages[1]->when = start + randint(5);
snprintf(messages[1]->text, sizeof(messages[1]->text),
"ircd: User \"%s!~%s@dirtbags.net\" registered (connection %d).",
user(), user(), connection);
messages[2]->when = messages[1]->when + randint(600);
snprintf(messages[2]->text, sizeof(messages[2]->text),
"ircd: Shutting down connection %d (Got QUIT command.) with dirtbags.net:%d.",
connection, port);
enqueue_messages(messages, 3);
}
break;
case 4:
/* cron */
if (-1 != get_many_messages(messages, 1)) {
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"/USR/SBIN/CRON[%d]: (root) CMD ( /opt/bloatware/cleanup.sh )",
pid);
enqueue_messages(messages, 1);
}
break;
case 5:
/* sudo */
if (-1 != get_many_messages(messages, 1)) {
char const *u = user();
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"sudo: %12s : TTY=pts/%d ; PWD=/home/%s ; USER=root; COMMAND=/usr/bin/less /var/log/syslog",
u, randint(12), u);
enqueue_messages(messages, 1);
}
break;
case 6 ... 20:
/* SMTP */
{
char const *mytoken;
size_t tokenlen;
char const *host;
size_t hostlen;
char const *from;
size_t fromlen;
char const *to;
int is_token;
if (randint(10) == 0) {
is_token = 1;
mytoken = token[2];
} else {
is_token = 0;
mytoken = bogus_token();
}
tokenlen = strlen(mytoken);
host = mytoken;
hostlen = tokenlen/3;
from = mytoken + hostlen;
fromlen = tokenlen/3;
to = mytoken + hostlen + fromlen;
if (-1 != get_many_messages(messages, 8)) {
int o1 = randint(256);
int o2 = randint(256);
int o3 = randint(256);
int o4 = randint(256);
long int mid = random();
long int mid2 = random();
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"smtp/smtpd[%d]: connect from %.*s[%d.%d.%d.%d]",
pid, hostlen, host, o1, o2, o3, o4);
messages[1]->when = messages[0]->when + randint(1);
snprintf(messages[1]->text, sizeof(messages[1]->text),
"smtp/smtpd[%d]: %08lX: client=%.*s[%d.%d.%d.%d]",
pid, mid, hostlen, host, o1, o2, o3, o4);
messages[2]->when = messages[1]->when + 2 + randint(3);
snprintf(messages[2]->text, sizeof(messages[2]->text),
"smtp/smtpd[%d]: disconnect from [%d.%d.%d.%d]",
pid, o1, o2, o3, o4);
pid = (pid + 1 + randint(5)) % PID_MAX;
messages[3]->when = messages[1]->when + 1 + randint(2);
snprintf(messages[3]->text, sizeof(messages[3]->text),
"smtp/cleanup[%d]: %08lX: message-id=<%08lx@junkmail.spam>",
pid, mid, mid2);
pid = (pid + 1 + randint(5)) % PID_MAX;
messages[4]->when = messages[3]->when + randint(1);
snprintf(messages[4]->text, sizeof(messages[4]->text),
"smtp/qmgr[%d]: %08lX: from=<%.*s@junkmail.spam>, size=%d, nrcpt=1 (queue active)",
pid, mid, fromlen, from, randint(6000));
messages[5]->when = messages[4]->when + 2 + randint(2);
snprintf(messages[5]->text, sizeof(messages[5]->text),
"smtp/qmgr[%d]: %08lX: removed",
pid, mid);
messages[6]->when = messages[4]->when + randint(1);
snprintf(messages[6]->text, sizeof(messages[6]->text),
"smtp/deliver(%s): msgid=<%08lx@junkmail.spam>: saved to INBOX",
to, mid2);
pid = (pid + 1 + randint(5)) % PID_MAX;
messages[7]->when = messages[4]->when + randint(1);
snprintf(messages[7]->text, sizeof(messages[7]->text),
"smtp/local[%d]: %08lX: to <%s@dirtbags.net>, relay=local, dsn=2.0.0, status=sent (delivered to command /usr/bin/deliver)",
pid, mid, to);
enqueue_messages(messages, 8);
}
}
break;
case 21 ... 30:
/* ssh */
break;
default:
/* HTTP */
if (-1 != get_many_messages(messages, 1)) {
messages[0]->when = start;
snprintf(messages[0]->text, sizeof(messages[0]->text),
"httpd[%d]: %d.%d.%d.%d\t-\tdirtbags.net\t80\tGET\t%s\t-\tHTTP/1.1\t200\t%d\t-\tMozilla/5.0",
pid,
randint(256), randint(256),
randint(256), randint(256),
url(), randint(4000) + 378);
enqueue_messages(messages, 1);
}
break;
}
}
{
struct timespec t = { 1, 0 };
nanosleep(&t, NULL);
}
}
return 0;
}

View File

@ -1 +0,0 @@
../../../src/token.c

View File

@ -1 +0,0 @@
../../../src/token.h

View File

@ -1 +0,0 @@
logger

View File

@ -1 +0,0 @@
S゙*郢シ緩ミ7<EFBE90>k<13>

View File

@ -1 +0,0 @@
™כְ־אֹם[½ָµ<C2B5> 

View File

@ -1 +0,0 @@
logger

View File

@ -1 +0,0 @@
S゙*郢シ緩ミ7<EFBE90>k<13>

View File

@ -1 +0,0 @@
™כְ־אֹם[½ָµ<C2B5> 

View File

@ -1 +0,0 @@
logger

View File

@ -1 +0,0 @@
S゙*郢シ緩ミ7<EFBE90>k<13>

View File

@ -1 +0,0 @@
™כְ־אֹם[½ָµ<C2B5> 

52
packages/lxc/lxc.mk Normal file
View File

@ -0,0 +1,52 @@
LXC_PKGDIR = $(TARGET)/lxc
LXC_BUILDDIR = $(BUILD)/lxc
LXC_VERSION = 0.7.5
LXC_TAR = $(CACHE)/lxc-$(LXC_VERSION).tar.gz
LXC_URL = http://lxc.sourceforge.net/download/lxc/lxc-$(LXC_VERSION).tar.gz
LXC_SRCDIR = $(LXC_BUILDDIR)/lxc-$(LXC_VERSION)
LXC_COMMANDS = attach cgroup checkpoint console execute freeze
LXC_COMMANDS += info init kill monitor restart start stop
LXC_COMMANDS += unfreeze unshare wait
LXC_PROGRAMS = $(addprefix $(LXC_SRCDIR)/src/lxc/lxc-, $(LXC_COMMANDS))
# Prevents automake from mangling cross-compiled binary names
LXC_CC_HOST := $(shell $(CC) -v 2>&1 | awk '/Target:/{print $$2}')
LXC_CONF_OPT := --host=i386-unknown-linux-uclibc --program-transform-name=
lxc-install: lxc-build
$(LXC_TAR):
@ mkdir -p $(@D)
wget -O $@ $(LXC_URL)
lxc-source: $(LXC_BUILDDIR)/source
$(LXC_BUILDDIR)/source: $(LXC_TAR)
mkdir -p $(LXC_BUILDDIR)
zcat $(LXC_TAR) | (cd $(LXC_BUILDDIR) && tar xf -)
cp packages/lxc/utmp.c $(LXC_SRCDIR)/src/lxc/
touch $@
lxc-build: $(LXC_BUILDDIR)/built
$(LXC_BUILDDIR)/built: $(LXC_BUILDDIR)/source libcap-build
cd $(LXC_SRCDIR) && CFLAGS="$(LIBCAP_CFLAGS)" LDFLAGS="$(LIBCAP_LDFLAGS) -Xlinker -rpath -Xlinker /opt/lxc/lib" ./configure $(CONFIG_XCOMPILE_FLAGS)
$(MAKE) -C $(LXC_SRCDIR)
touch $@
lxc-install: lxc-build
mkdir -p $(LXC_PKGDIR)/lib
cp $(LXC_SRCDIR)/src/lxc/liblxc.so $(LXC_PKGDIR)/lib/liblxc.so.0
cp $(LIBCAP_SRCDIR)/libcap/libcap.so.* $(LXC_PKGDIR)/lib
mkdir -p $(LXC_PKGDIR)/bin
cp $(LXC_PROGRAMS) $(LXC_PKGDIR)/bin
# $(call COPYTREE, packages/lxc/service, $(LXC_PKGDIR)/service)
lxc-clean:
rm -rf $(LXC_BUILDDIR)
LIBCAP_PKGDIR = $(TARGET)/libcap

11
packages/lxc/utmp.c Normal file
View File

@ -0,0 +1,11 @@
/* Detecting runlevels from utmp is straight up bullshit, you.
1. runit doesn't have run levels
2. dbtl doesn't write utmp
3. even if it did, it doesn't have the glibc functions this code
wants
*/
int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
struct lxc_handler *handler) {
return 0;
}

View File

@ -45,13 +45,9 @@ esac
# Compute hash of team name; they'll use this for everything in the
# contest instead of their team name, which makes stuff much easier on
# me since all team hashes are in the set /[0-9a-f]{8}/.
hash=$(echo "not a nonce:::$1" | md5sum | cut -b 1-8)
hash=$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | cut -b 1-8)
echo "$1" > $base/teams/names/$hash
echo "$color" > $base/teams/colors/$hash
echo "Registered with hash: $hash"
# Create encrypted listing of teams
ls $base/teams/names | KEY="Too much cheese." arc4 > $www/teams.txt.$$
mv $www/teams.txt.$$ $www/teams.txt

View File

@ -1,4 +1,4 @@
#! /usr/bin/awk -f
#! /bin/awk -f
##
##

View File

@ -1,27 +1,28 @@
MCP_PKGDIR = $(TARGET)/mcp
MCP_BUILDDIR = $(BUILD)/mcp
MCP_FNORD_VERSION = 1.10
MCP_FNORD_TARBALL = fnord-$(MCP_FNORD_VERSION).tar.bz2
MCP_FNORD_TARCACHE = $(CACHE)/$(MCP_FNORD_TARBALL)
MCP_FNORD_URL = http://www.fefe.de/fnord/$(MCP_FNORD_TARBALL)
MCP_FNORD_SRCDIR = $(MCP_BUILDDIR)/fnord-$(MCP_FNORD_VERSION)
$(MCP_FNORD_TARCACHE):
@ mkdir -p $(@D)
wget -O $@ $(MCP_FNORD_URL)
##
## XXX: clean up fnord like router.mk
##
FNORD_CACHE = $(CACHE)/fnord.git
FNORD_BUILDDIR = $(MCP_BUILDDIR)/fnord
FNORD_URL = http://woozle.org/~neale/projects/fnord
$(FNORD_CACHE):
git clone --bare $(FNORD_URL) $@
mcp-source: $(MCP_BUILDDIR)/source
$(MCP_BUILDDIR)/source: $(MCP_FNORD_TARCACHE)
$(MCP_BUILDDIR)/source: $(FNORD_CACHE)
mkdir -p $(@D)
bzcat $< | (cd $(@D) && tar xf -)
(cd $(@D)/fnord-$(MCP_FNORD_VERSION) && patch -p 1) < packages/mcp/fnord.patch
git clone $(FNORD_CACHE) $(@D)/fnord
touch $@
mcp-build: $(MCP_BUILDDIR)/build
$(MCP_BUILDDIR)/build: $(MCP_BUILDDIR)/source
$(MAKE) -C packages/mcp/src build
$(MAKE) -C $(MCP_BUILDDIR)/fnord-$(MCP_FNORD_VERSION) DIET= CC=$(CC) fnord-cgi
$(MAKE) -C $(MCP_BUILDDIR)/fnord DIET= CC=$(CC) fnord-cgi
mcp-install: $(MCP_BUILDDIR)/build
@ -31,12 +32,10 @@ mcp-install: $(MCP_BUILDDIR)/build
cp packages/mcp/src/pointscli $(MCP_PKGDIR)/bin/
cp packages/mcp/src/puzzles.cgi $(MCP_PKGDIR)/bin/
cp $(MCP_BUILDDIR)/fnord-$(MCP_FNORD_VERSION)/fnord-cgi $(MCP_PKGDIR)/bin/
cp $(MCP_BUILDDIR)/fnord/fnord-cgi $(MCP_PKGDIR)/bin/
$(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service)
$(call COPYTREE, packages/mcp/tokend.keys, $(MCP_PKGDIR)/tokend.keys)
$(call COPYTREE, packages/mcp/www, $(MCP_PKGDIR)/www)
cp packages/mcp/src/puzzler.cgi $(MCP_PKGDIR)/www/
cp packages/mcp/src/claim.cgi $(MCP_PKGDIR)/www/

View File

@ -0,0 +1 @@
fd84:b410:3441::2/64

View File

@ -2,11 +2,13 @@
exec 2>&1
ip addr add 10.0.0.2/16 label eth0:mcp dev eth0
install -d /var/www
# Bring up address
IP=$(cat ip.txt)
ip addr add $IP dev eth0
ip monitor | grep -q $IP
# Link in puzzles and web pages
install -d /var/www
for d in /opt/*; do
if [ -d $d/puzzles ]; then
ln -sf $d/puzzles /var/www/$(basename $d)
@ -16,8 +18,4 @@ for d in /opt/*; do
fi
done
mkdir -p sites
cd sites
ln -sf /var/www default
exec tcpsvd -u ctf 10.0.0.2 80 /opt/mcp/bin/fnord-cgi
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/fnord-cgi /var/www

View File

@ -1,28 +1,14 @@
#! /bin/sh
# First argument is seconds between running everything
period=${1:-60}
NEWPOINTS=/var/lib/ctf/points.new
fn=$2/$3
POINTS=/var/lib/ctf/points.log
SCOREBOARD=/var/www/scoreboard.html
if ! [ -f $SCOREBOARD ]; then
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD
cat $fn >> $POINTS || break
rm $fn
# Render scoreboard
if [ $POINTS -nt $SCOREBOARD ]; then
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD.new && mv $SCOREBOARD.new $SCOREBOARD
fi
while true; do
# Collect any new points
for fn in $NEWPOINTS/*; do
[ -f $fn ] || continue
cat $fn >> $POINTS || break
rm $fn
done
# Render scoreboard
if [ $POINTS -nt $SCOREBOARD ]; then
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD.new && mv $SCOREBOARD.new $SCOREBOARD
fi
sleep $period
done

View File

@ -1,13 +1,52 @@
#! /bin/sh
#! /bin/sh -e
exec 2>&1
install -o ctf -m 0755 -d /var/lib/ctf/points.new
install -d /var/lib/ctf
# Create CTF and nobody users
touch /etc/group /etc/passwd
addgroup -g 65534 nogroup || true
adduser -D -S -h /var/lib/ctf -H ctf || true
adduser -D -g nogroup -u 65534 -h /tmp -H nobody || true
# Set up base directories
NEWDIR=/var/lib/ctf/points.new
install -d /var/www
install -d /var/lib/ctf
install -o ctf -m 0755 -d $NEWDIR
install -o ctf -m 0755 -d /var/lib/ctf/points.tmp
# Make tokens database now, this is as good a time as any
TOKENS=/var/lib/ctf/tokens.db
for fn in $TOKENS /opt/*/tokens.txt; do
[ -f "$fn" ] || continue
cat $fn
done | sort | uniq > $TOKENS.new
mv $TOKENS.new $TOKENS
# Create some files
CLAIM=/var/lib/ctf/claim.db
touch $CLAIM
chown ctf $CLAIM
touch /var/lib/ctf/points.log
# Re-populate teams list for tanks
ls $base/teams/names | KEY="Too much cheese." /opt/mcp/bin/arc4 > $www/teams.txt.$$
mv $www/teams.txt.$$ $www/teams.txt
# Generate preliminary scoreboard
if ! [ -f /var/www/scoreboard.html ]; then
/opt/mcp/bin/scoreboard < /dev/null > /var/www/scoreboard.html
fi
exec ./pointsd
if [ -x /sbin/inotifyd ]; then
exec /sbin/inotifyd ./pointsd $NEWDIR:y
fi
# Simulate inotifyd
cd $NEWDIR
while true; do
for fn in *; do
[ -f "$fn" ] || continue
./pointsd m $NEWDIR $fn
done
sleep 7
done

View File

@ -2,9 +2,10 @@
exec 2>&1
DB=/var/lib/ctf/puzzles.db
install -d /var/www
mkdir -p /var/www
# Install truncates files
DB=/var/lib/ctf/puzzles.db
touch $DB
chown ctf $DB

View File

@ -1,3 +0,0 @@
#! /bin/sh
exec svlogd -tt $PWD

View File

@ -1,20 +0,0 @@
#! /bin/sh
exec 2>&1
ip addr add 10.0.0.2/16 label eth0:mcp dev eth0
DB=/var/lib/ctf/tokens.db
if [ ! -f $DB ]; then
# Append any package-provided tokens
cat /opt/*/tokens.txt >$DB 2>/dev/null
chown ctf $DB
fi
for fn in /var/lib/ctf/tokens.db /var/lib/ctf/claim.db; do
touch $fn
chown ctf $fn
done
exec tcpsvd -u ctf 0 1 /opt/mcp/bin/in.tokend

View File

@ -19,8 +19,8 @@
<a href="scoring.html">About scoring</a>
</li>
<li>
<a href="irc://10.0.0.2/ctf"
title="IRC on 10.0.0.2, channel #ctf">Contest chat</a>
<a href="irc://[fd84:b410:3441::6]/ctf"
title="IRC on fd84:b410:3441::6, channel #ctf">Contest chat</a>
carries important announcements, and sometimes clues and
puzzles.
</li>
@ -42,16 +42,14 @@
<h2>Rules</h2>
<ul>
<li>
No ARP-level attacks: this includes IP spoofing.
</li>
<li>
No DoS attacks.
</li>
<li>
Do not attack machines outside the contest network
(10.<i>x</i>.<i>x</i>.<i>x</i>). Low ports (under 1024) do not
run contest categories.
Contest servers lie within <samp>fd84:b410:3441::/112</samp>.
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>.
Low ports (under 1024) do not run contest categories, don't
waste your time.
</li>
<li>
Consider the contest network hostile. It is up to you to

View File

@ -0,0 +1,19 @@
MULTICASTER_PKGDIR = $(TARGET)/multicaster
multicaster-install: multicaster-build
mkdir -p $(MULTICASTER_PKGDIR)
cp packages/multicaster/tokens.txt $(MULTICASTER_PKGDIR)
$(call COPYTREE, packages/multicaster/service, $(MULTICASTER_PKGDIR)/service)
mkdir -p $(MULTICASTER_PKGDIR)/bin/
$(MAKE) -C packages/multicaster/src install DESTDIR=$(CURDIR)/$(MULTICASTER_PKGDIR)
multicaster-clean:
rm -rf $(MULTICASTER_PKGDIR)
$(MAKE) -C packages/multicaster/src clean
multicaster-build:
$(MAKE) -C packages/multicaster/src build
PACKAGES += multicaster

View File

@ -0,0 +1 @@
fd84:b410:3441::4e11/64

View File

@ -0,0 +1,8 @@
#! /bin/sh -e
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt

View File

@ -0,0 +1,11 @@
CFLAGS = -Wall -Werror
TARGETS = multicaster
all: build
build: $(TARGETS)
install: $(TARGETS)
install -m 0755 $(TARGETS) $(DESTDIR)/bin
clean:
rm -f *.o $(TARGETS)

View File

@ -0,0 +1,121 @@
/* multicast_client.c
* Adopted from tmouse's client/server example code
* found at http://cboard.cprogramming.com/showthread.php?t=67469
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h> /* for printf() and fprintf() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <time.h> /* for timestamps */
#include <unistd.h>
void DieWithError(const char* errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(10);
}
int main(int argc, char* argv[])
{
int sock; /* Socket */
char* multicastIP; /* Arg: IP Multicast Address */
char* multicastPort; /* Arg: Port */
struct addrinfo * multicastAddr = {0}; /* Multicast Address */
struct addrinfo * localAddr; /* Local address to bind to */
struct addrinfo hints = { 0 }; /* Hints for name lookup */
if ( argc != 3 )
{
fprintf(stderr,"Usage: %s <Multicast IP> <Multicast Port>\n", argv[0]);
exit(10);
}
multicastIP = argv[1]; /* First arg: Multicast IP address */
multicastPort = argv[2]; /* Second arg: Multicast port */
/* Resolve the multicast group address */
hints.ai_family = PF_INET6;
hints.ai_flags = AI_NUMERICHOST;
if ( getaddrinfo(multicastIP, NULL, &hints, &multicastAddr) != 0 ) DieWithError("getaddrinfo() failed");
/* Get a local address with the same family as our multicast group */
hints.ai_family = multicastAddr->ai_family;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; /* Return an address we can bind to */
if ( getaddrinfo(NULL, multicastPort, &hints, &localAddr) != 0 )
{
DieWithError("getaddrinfo() failed");
}
/* Create socket for receiving datagrams */
if ( (sock = socket(localAddr->ai_family, localAddr->ai_socktype, 0)) == -1 )
{
DieWithError("socket() failed");
}
const int trueValue = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &trueValue, sizeof(trueValue));
#ifdef __APPLE__
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const void *) &trueValue, sizeof(trueValue));
#endif
/* Bind to the multicast port */
if ( bind(sock, localAddr->ai_addr, localAddr->ai_addrlen) != 0 )
{
DieWithError("bind() failed");
}
/* Join the multicast group. */
if ((multicastAddr->ai_family == PF_INET6)&&(multicastAddr->ai_addrlen == sizeof(struct sockaddr_in6)))
{
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(multicastAddr->ai_addr);
struct ipv6_mreq multicastRequest; /* Multicast address join structure */
/* Specify the multicast group */
memcpy(&multicastRequest.ipv6mr_multiaddr, &((struct sockaddr_in6*)(multicastAddr->ai_addr))->sin6_addr, sizeof(multicastRequest.ipv6mr_multiaddr));
printf("scope_id: %d\n", addr->sin6_scope_id);
/* Accept multicast from any interface */
multicastRequest.ipv6mr_interface = addr->sin6_scope_id;
/* Join the multicast address */
if ( setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*) &multicastRequest, sizeof(multicastRequest)) != 0 ) DieWithError("setsockopt(IPV6_JOIN_GROUP) failed");
}
else DieWithError("Not IPv6");
freeaddrinfo(localAddr);
freeaddrinfo(multicastAddr);
for (;;) /* Run forever */
{
char recvString[500]; /* Buffer for received string */
int recvStringLen; /* Length of received string */
struct sockaddr_in6 from;
socklen_t fromlen = sizeof(from);
char sendString[] = "Token: banana\n";
char errorString[] = "That is not correct! Try again!\n";
/* Receive a single datagram from the server */
if ((recvStringLen = recvfrom(sock, recvString, sizeof(recvString) - 1, 0, (struct sockaddr *)&from, &fromlen)) < 0) DieWithError("recvfrom() failed");
recvString[recvStringLen] = '\0';
if(strcmp(recvString, "hello")==0) {
printf("Correct!!\n");
// printf("Token: banana\n");
sendto(sock, sendString, sizeof(sendString) - 1, 0, (struct sockaddr *)&from, fromlen);
} else {
// printf("That isn't correct! Try again!\n");
sendto(sock, errorString, sizeof(errorString) - 1, 0, (struct sockaddr *)&from, fromlen);
}
/* Print the received string */
printf("Received string [%s]\n", recvString);
}
/* NOT REACHED */
close(sock);
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,71 @@
/* multicast_server.c
* Adapted from tmouse's IPv6 client/server example code
* found at http://cboard.cprogramming.com/showthread.php?t=67469
*/
#include <stdio.h> /* for fprintf() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h> /* for atoi() and exit() */
#include <unistd.h>
#include <string.h>
static void DieWithError(const char* errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(10);
}
int main(int argc, char *argv[])
{
int sock; /* Socket */
char* multicastIP; /* Arg: IP Multicast address */
char* multicastPort; /* Arg: Server port */
char* sendString; /* Arg: String to multicast */
size_t sendStringLen; /* Length of string to multicast */
struct addrinfo * multicastAddr; /* Multicast address */
struct addrinfo hints = { 0 }; /* Hints for name lookup */
if ( argc != 4 )
{
fprintf(stderr, "Usage: %s <Multicast Address> <Port> <Send String>\n", argv[0]);
exit(10);
}
multicastIP = argv[1]; /* First arg: multicast IP address */
multicastPort = argv[2]; /* Second arg: multicast port */
sendString = argv[3]; /* Third arg: String to multicast */
sendStringLen = strlen(sendString); /* Find length of sendString */
/* Resolve destination address for multicast datagrams */
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(multicastIP, multicastPort, &hints, &multicastAddr) != 0) DieWithError("getaddrinfo() failed");
/* Create socket for sending multicast datagrams */
if ((sock = socket(multicastAddr->ai_family, multicastAddr->ai_socktype, 0)) == -1) DieWithError("socket() failed");
int hops = 5;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) != 0) DieWithError("setsockopt(MULTICAST_HOPS) failed");
for (;;) /* Run forever */
{
int sendLen = sendto(sock, sendString, sendStringLen, 0, multicastAddr->ai_addr, multicastAddr->ai_addrlen);
if (sendLen == sendStringLen )
{
printf("Sent [%s] (%i bytes) to %s, port %s\n", sendString, sendLen, multicastIP, multicastPort);
}
else
{
DieWithError("sendto() sent a different number of bytes than expected");
}
sleep(1); /* Multicast sendString in datagram to clients every second */
}
/* NOT REACHED */
freeaddrinfo(multicastAddr);
close(sock);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More