New ctf python module

This commit is contained in:
Neale Pickett 2009-10-05 13:33:20 -06:00
parent d925cdcc39
commit cb7ce0d84d
25 changed files with 127 additions and 102 deletions

View File

@ -1,12 +1,14 @@
DESTDIR = target DESTDIR = target
PYCDIR = $(DESTDIR)/usr/lib/python3.1/site-packages
CTFDIR = $(DESTDIR)/usr/lib/ctf CTFDIR = $(DESTDIR)/usr/lib/ctf
WWWDIR = $(DESTDIR)/usr/lib/www WWWDIR = $(DESTDIR)/usr/lib/www
FAKE = fakeroot -s fake -i fake FAKE = fakeroot -s fake -i fake
INSTALL = $(FAKE) install INSTALL = $(FAKE) install
PYC = config.pyc points.pyc teams.pyc PYC = __init__.pyc
PYC += config.pyc points.pyc teams.pyc
PYC += register.pyc scoreboard.pyc puzzler.pyc PYC += register.pyc scoreboard.pyc puzzler.pyc
PYC += flagd.pyc pointsd.pyc pointscli.pyc PYC += flagd.pyc pointsd.pyc pointscli.pyc
PYC += histogram.pyc PYC += histogram.pyc
@ -19,9 +21,11 @@ target: $(PYC)
$(INSTALL) -d $(DESTDIR)/var/lib/ctf/disabled $(INSTALL) -d $(DESTDIR)/var/lib/ctf/disabled
touch $(DESTDIR)/var/lib/ctf/disabled/survey touch $(DESTDIR)/var/lib/ctf/disabled/survey
$(INSTALL) -d $(CTFDIR) $(INSTALL) -d $(PYCDIR)/ctf
$(INSTALL) $(PYC) $(CTFDIR) $(INSTALL) $(PYC) $(PYCDIR)/ctf
$(INSTALL) ctfd.py $(CTFDIR)
$(INSTALL) -d $(DESTDIR)/usr/sbin
$(INSTALL) ctfd.py $(DESTDIR)/usr/sbin
$(INSTALL) -d $(WWWDIR) $(INSTALL) -d $(WWWDIR)
$(INSTALL) index.html intro.html ctf.css grunge.png $(WWWDIR) $(INSTALL) index.html intro.html ctf.css grunge.png $(WWWDIR)
@ -36,6 +40,7 @@ target: $(PYC)
rm -rf $(WWWDIR)/puzzler rm -rf $(WWWDIR)/puzzler
$(INSTALL) -d $(WWWDIR)/puzzler $(INSTALL) -d $(WWWDIR)/puzzler
$(INSTALL) -d $(CTFDIR)
./mkpuzzles.py --htmldir=$(WWWDIR)/puzzler --keyfile=$(CTFDIR)/puzzler.keys ./mkpuzzles.py --htmldir=$(WWWDIR)/puzzler --keyfile=$(CTFDIR)/puzzler.keys
ctf.tce: target ctf.tce: target
@ -45,5 +50,8 @@ clean:
rm -rf target rm -rf target
rm -f fake ctf.tce $(PYC) rm -f fake ctf.tce $(PYC)
%.pyc: %.py ctf/%.pyc: ctf/%.py
python3 -c 'import $*' python3 -c 'from ctf import $(notdir $*)'
%.pyc: ctf/%.pyc
cp $< $@

33
ctf/__init__.py Executable file
View File

@ -0,0 +1,33 @@
#! /usr/bin/env python3
import asynchat
import asyncore
import socket
class Flagger(asynchat.async_chat):
"""Connection to flagd"""
def __init__(self, addr, auth):
asynchat.async_chat.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((addr, 6668))
self.push(auth + b'\n')
self.flag = None
def handle_read(self):
msg = self.recv(4096)
raise ValueError("Flagger died: %r" % msg)
def handle_error(self):
# If we lose the connection to flagd, nobody can score any
# points. Terminate everything.
asyncore.close_all()
asynchat.async_chat.handle_error(self)
def set_flag(self, team):
if team:
eteam = team.encode('utf-8')
else:
eteam = b''
self.push(eteam + b'\n')
self.flag = team

View File

@ -8,11 +8,11 @@ import time
import hmac import hmac
import optparse import optparse
import os import os
import points
import pointscli
import teams
import config
import traceback import traceback
from . import teams
from . import points
from . import pointscli
from . import config
key = b'My First Shared Secret (tm)' key = b'My First Shared Secret (tm)'
def hexdigest(data): def hexdigest(data):
@ -21,7 +21,7 @@ def hexdigest(data):
flags_dir = config.get('global', 'flags_dir') flags_dir = config.get('global', 'flags_dir')
class Submitter(asyncore.dispatcher): class Submitter(asyncore.dispatcher):
def __init__(self, host='', port=6667): def __init__(self, host='127.0.0.1', port=6667):
asyncore.dispatcher.__init__(self) asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
self.connect((host, port)) self.connect((host, port))
@ -82,7 +82,7 @@ class Submitter(asyncore.dispatcher):
class Listener(asyncore.dispatcher): class Listener(asyncore.dispatcher):
def __init__(self, connection_factory, host='localhost', port=6668): def __init__(self, connection_factory, host='', port=6668):
asyncore.dispatcher.__init__(self) asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() self.set_reuse_addr()

View File

@ -6,8 +6,9 @@ import asynchat
import socket import socket
import traceback import traceback
import time import time
import teams
from errno import EPIPE from errno import EPIPE
from . import teams
from . import Flagger
# Heartbeat frequency (in seconds) # Heartbeat frequency (in seconds)
@ -38,35 +39,6 @@ class Listener(asyncore.dispatcher):
return True return True
class Flagger(asynchat.async_chat):
"""Connection to flagd"""
def __init__(self, addr, auth):
asynchat.async_chat.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect(addr)
self.push(auth + b'\n')
self.flag = None
def handle_read(self):
msg = self.recv(4096)
raise ValueError("Flagger died: %r" % msg)
def handle_error(self):
# If we lose the connection to flagd, nobody can score any
# points. Terminate everything.
asyncore.close_all()
asynchat.async_chat.handle_error(self)
def set_flag(self, team):
if team:
eteam = team.encode('utf-8')
else:
eteam = b''
self.push(eteam + b'\n')
self.flag = team
class Manager: class Manager:
"""Contest manager. """Contest manager.

View File

@ -1,11 +1,11 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import points
import time import time
import os import os
import tempfile import tempfile
import teams from . import points
import config from . import teams
from . import config
pngout = config.datafile('histogram.png') pngout = config.datafile('histogram.png')

View File

@ -4,9 +4,9 @@ import socket
import hmac import hmac
import struct import struct
import io import io
import teams
import config
import os import os
from . import teams
from . import config
## ##
## Authentication ## Authentication

View File

@ -2,9 +2,9 @@
import optparse import optparse
import select import select
import points
import socket import socket
import time import time
from . import points
def makesock(host): def makesock(host):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

View File

@ -3,10 +3,11 @@
import asyncore import asyncore
import socket import socket
import struct import struct
import points
import time import time
from . import points
from . import config
house = 'dirtbags' house = config.get('global', 'house_team')
class MyHandler(asyncore.dispatcher): class MyHandler(asyncore.dispatcher):
def __init__(self, port=6667): def __init__(self, port=6667):

View File

@ -7,9 +7,9 @@ import re
import sys import sys
import http.cookies import http.cookies
from urllib.parse import quote, unquote from urllib.parse import quote, unquote
import config from . import config
import pointscli from . import pointscli
import teams from . import teams
datafile = config.datafile('puzzler.dat') datafile = config.datafile('puzzler.dat')
keysfile = config.get('puzzler', 'keys_file') keysfile = config.get('puzzler', 'keys_file')

View File

@ -2,10 +2,10 @@
import cgitb; cgitb.enable() import cgitb; cgitb.enable()
import cgi import cgi
import teams
import fcntl import fcntl
import string import string
import config from . import teams
from . import config
def main(): def main():
print('Content-type: text/html') print('Content-type: text/html')

View File

@ -2,10 +2,10 @@
import cgitb; cgitb.enable() import cgitb; cgitb.enable()
import os import os
import config
import teams
import points
import sys import sys
from . import config
from . import teams
from . import points
flags_dir = config.get('global', 'flags_dir') flags_dir = config.get('global', 'flags_dir')
house_team = config.get('global', 'house_team') house_team = config.get('global', 'house_team')

View File

@ -2,9 +2,9 @@
import fcntl import fcntl
import time import time
import config
import os import os
from urllib.parse import quote, unquote from urllib.parse import quote, unquote
from . import config
house = config.get('global', 'house_team') house = config.get('global', 'house_team')
passwdfn = config.get('global', 'passwd') passwdfn = config.get('global', 'passwd')

View File

@ -8,8 +8,8 @@ kevin.tce: target
target: kevin.py irc.pyc run log.run target: kevin.py irc.pyc run log.run
$(INSTALL) -d target/usr/lib/ctf $(INSTALL) -d target/usr/lib/ctf/kevin
$(INSTALL) kevin.py irc.py target/usr/lib/ctf $(INSTALL) kevin.py irc.py target/usr/lib/ctf/kevin
$(INSTALL) --owner=100 -d target/var/lib/ctf/kevin/tokens $(INSTALL) --owner=100 -d target/var/lib/ctf/kevin/tokens

1
kevin/ctf Symbolic link
View File

@ -0,0 +1 @@
../ctf

View File

@ -7,38 +7,10 @@ import asynchat
import socket import socket
import asyncore import asyncore
from urllib.parse import quote_plus as quote from urllib.parse import quote_plus as quote
from ctf import Flagger
nobody = '\002[nobody]\002' nobody = '\002[nobody]\002'
class Flagger(asynchat.async_chat):
"""Connection to flagd"""
def __init__(self, addr, auth):
asynchat.async_chat.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((addr, 6668))
self.push(auth + b'\n')
self.flag = None
def handle_read(self):
msg = self.recv(4096)
raise ValueError("Flagger died: %r" % msg)
def handle_error(self):
# If we lose the connection to flagd, nobody can score any
# points. Terminate everything.
asyncore.close_all()
asynchat.async_chat.handle_error(self)
def set_flag(self, team):
if team:
eteam = team.encode('utf-8')
else:
eteam = b''
self.push(eteam + b'\n')
self.flag = team
class Kevin(irc.Bot): class Kevin(irc.Bot):
def __init__(self, host, flagger, tokens, victims): def __init__(self, host, flagger, tokens, victims):
irc.Bot.__init__(self, host, irc.Bot.__init__(self, host,

View File

@ -2,4 +2,4 @@
[ -f /var/lib/ctf/disabled/kevin ] && exit 0 [ -f /var/lib/ctf/disabled/kevin ] && exit 0
exec envuidgid ctf /usr/lib/ctf/kevin.py --victims=/var/lib/ctf/kevin/victims.txt --tokens=/var/lib/ctf/kevin/tokens exec envuidgid ctf /usr/lib/ctf/kevin/kevin.py --victims=/var/lib/ctf/kevin/victims.txt --tokens=/var/lib/ctf/kevin/tokens

View File

@ -1,7 +1,4 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import cgitb; cgitb.enable() from ctf import puzzler
import sys
sys.path.insert(0, '/usr/lib/ctf')
import puzzler
puzzler.main() puzzler.main()

View File

@ -0,0 +1 @@
all: in.fingerd

View File

@ -0,0 +1,38 @@
#include <stdio.h>
int
main(int argc, char *argv)
{
char user[256];
char path[512];
char *data;
FILE *f;
size_t count;
int i;
if (NULL == gets(user)) {
return 0;
}
for (data = user; *data; data += 1) {
if ('\r' == *data) {
*data = 0;
}
}
if (0 == user[0]) {
printf("Nobody's home.\n");
return 0;
}
sprintf(path, "/home/%s/.plan", user);
f = fopen(path, "r");
if (NULL == f) {
printf("No such user.\n");
return 0;
}
data = path;
while (count = fread(data, sizeof(*data), 1, f)) {
fwrite(data, count, 1, stdout);
}
return 0;
}

3
pwnables/fingerd/run Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
exec tcpsvd 0 79 /usr/sbin/in.fingerd

3
pwnables/tftpd/run Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
exec udpsvd 0 69 tftpd /var/lib/tftp

View File

@ -1,6 +1,4 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import sys from ctf import register
sys.path.insert(0, '/usr/lib/ctf')
import register
register.main() register.main()

View File

@ -1,4 +1,4 @@
#! /bin/sh #! /bin/sh
exec envuidgid ctf /usr/lib/ctf/ctfd.py 2>&1 exec envuidgid ctf /usr/sbin/ctfd.py 2>&1

View File

@ -1,6 +1,4 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import sys from ctf import scoreboard
sys.path.insert(0, '/usr/lib/ctf')
import scoreboard
scoreboard.main() scoreboard.main()