TUMCTF 2016 – Writeups

From 2016-09-30 to 2016-10-02 we took part in the TUM-CTF organized by the team h4x0rpsch0rr from TU Munich. As usual in CTFs there were some challenges and if you
solved one correctly a special flag in form of a binary string appears from somewhere. This flag can be submitted in the web-interface and your team gets points.

The guys from TU Munich did a very good job with their CTF. Some of the challenges were not online at the beginning and only became available later. But there was no noticeable server downtime or
DoS-attacks on the infrastructure.

Our team the Ulm Security Sparrows scored 85th place of 435.

As usual, we make our solutions available to the CTF community and hope to inspire others to learn about IT security.


The Haggis challenge started with the following greeting:

Connecting to the port yielded some hex-code. There was also a file attached with the following content:

This was most probably the code running on the server. Let’s look at it step by step. There is a padding defined which takes a message as input and pads it such that its length is a multiple of 16 Bytes. If one byte is missing, it adds a one, if two bytes are missing it adds two twos. If three bytes are missing it adds three threes. And so on. If the message is already a multiple of 16 Bytes, it adds 16 16s to the end. So there is one whole block of padding at the end.

The function haggis takes a messages and computes some kind of CBC-MAC. It prepends the length of the message. This length fills one whole block. Then comes the message itself together with the padding to make the length a multiple of the block size of the cipher. All of this is encrypted with the AES-cipher in CBC mode. The key used is 0x10, the initialization vector is set to zero. This is not in the code, but it can be found in the documentation that this is the default.
The function haggis returns the last encrypted block. This block depends on all of the previous blocks because that is the way CBC works.

The code then chooses a random target, which is encoded in hex and printed. It waits for an incoming msg which is hex-decoded. If msg starts with the string ‘I solemnly swear that I am up to no good.\0′ and if haggis(m) yields the target then the flag is printed.

So our task is pretty clear: For a given target we need to find a msg where haggis(msg)==target and msg needs to start with ‘I solemnly swear that I am up to no good.\0′.

To solve this challenge, remember how CBC works. CBC splits the input in blocks $$P_i$$ of equal length and computes $$C_i=E(C_{i-1}\oplus P_i)$$, where $$\oplus$$ is the xor operator. $$C_0$$ by the way is the initialization vector.
We can decrypt a single block, since we know the key. It was just 0x10. To make things easier, we restrict some variables such that we have fewer choices to make. We know that our msg needs to start with ‘I solemnly swear that I am up to no good.\0′. Let us append ‘aaaaaa’ to make this a multiple of the block size. Next comes a block further referred to as mojo which we will choose in a very special way.
The final block consists of the padding. It is one block full of padding, so in Python it looks like this:
Then we already know the length of the whole plaintext, namely 64 Bytes which we can prepend. All in all, we get the arrangement shown in the image.

Graphical Explanation of our Forgery

Note the only part of the plaintext which is not fixed is the block containing the mojo. This mojo contains the whole magic of the forgery of the MAC. Regarding the ciphertext for the most part we do not care, except for the last block. This should be the target we receives from the server. So we can consider it as fixed.

How can we find a suitable mojo? We can trace the target backwards through the CBC. For sake of notation, let $$n$$ denote the last block, so $$C_n=target$$. We can decrypt $$C_n$$ such that we end up on top of the last block. Xoring with the padding yields $$C_{n-1}$$. If we decrypt $$C_{n-1}$$ with a single round of AES and xor it with $$C_{n-2}$$ then we get the mojo. But what is $$C_{n-2}$$? To compute this, we can start from the left hand side and encrypt with CBC. It happens to be the CBC encryption of the blocks up to then, i.e., the encryption of the string ‘I solemnly swear that I am up to no good.\0aaaaaa’. And that is already everything.

There were some programming issues with AES objects in CBC-mode being stateful, which we did not expect and was a source of confusion. We did not talk to the IP with Python, but instead copied the given target from Netcat into an ipython. There we computed the dehaggised target and copied it into our NetCat process.
This yielded the flag.

JOY of Painting

The challenge consisted only of a flac audio file. It was solved by loading the given file into the Sonic Visualiser and applying the feature Layer-Add Spectrogram. This shows the spectrum of the file. The time is as usual on the x-axis, and the y-axis denotes the frequency. We can clearly see the flag in the spectrum.

Joy of Painting flac file as a Spectrogram

Free as in Bavarian Beer

The challenge presented a todo list on a website, where one could add arbitrary entries that would be displayed on the main page.
From the URLs one could easily tell that this challenge was based on php.
A link to the source code was provided. The first lines of the source file were bloated with license terms. The real code was provided below that. Let’s analyze how it works, step by step:

Notice the foreach statement? Here, each todo-entry will be formatted to a string, so users can see their todo-entries. The form for submitting todo-entries is routed to the same script (href=”.”), so they really gave us all we need. Now, let’s check how todo-entries are processed and stored, after submission:

We learn that the value from the form ($_POST[‘text’]) is put into an array called $todos. After that, the array will be serialized and stored as a cookie like this:
$COOKIE['todos'] = md5($serialized_array) . $serialized_array (with . denoting string concatenation)

Finally, let’s look at how todo-entries are loaded:

If the cookie “todos” is set, the script creates two variables, like this: $h = $cookieval[0:32], $m = $cookieval[32:]
A md5 hash results in 32 characters, so $h contains md5($serialized_array). The serialized array itself is stored in $m.
After that, the script calculates the md5 of the serialized array from the cookie, to see if it matches $h. In case of a match, $todos is assigned the unserialized value of $m.

PHP serialization with user-supplied data can be very dangerous, because the type of the serialized data is arbitrary, which means that the user can supply any serialized php class to the unserialize function.
With php object serialization, whole instances of classes can be serialized. This means that every member of a class can be set to a concrete value, unless there are protections in place.
Furthermore, php classes can define so-called magic functions. These functions are invoked implicitly, if certain conditions are met – which makes them very interesting for exploiting deserialization of untrusted data.
For example, the magic function ‘__wakeup()’ will be called on an object directly after it has been unserialized.
This can lead to exploitable bugs, that allow attackers to craft a serialized payload that, once unserialized, can even lead to code-execution.
The exploitability of this depends on the classes that are available to the program and their methods. Keep in mind that while magic methods are helpful, such bugs can still be exploited without them.
In our case, we are lucky:

This class provides the magic function ‘__toString()’ which is called implicitly when a string representation of the object is needed.
Remembering the code that is handling the output of todo-entries, the exploitability was clear:

If we are able to sneak a GPLSourceBloater into the $todos array, this code will trigger the __toString() function. But just triggering this function is not enough.
If you look closely at the GPLSourceBloater source code, you will see that it will return the contents of two files: license.txt and a file defined by $this->source.
In the challenge description it was mentioned that the flag resides in flag.php – if we are able to point $this->source at flag.php and the __toString() function is
called in the todo-entries output code, we will be able to see the contents of the flag file.

Now, we have two possibilities: Read up on the serialization format and write the payload ourselves, or use the code they gave us, instantiate a class with the right variables set and serialize it straight away.
I chose to do the latter. The format of the cookie had to include the md5-sum of the serialized payload, but this can be done with php as well. I downloaded the file to my computer and added a few lines after the definition of GPLSourceBloater:

I used the last line to confirm that the vulnerability is triggered. Running this with the php-cli command resulted in the following:

Success! The warning shows that the code is trying to open license.txt and flag.php, which don’t exist on my computer – but the code is working. The first line shows the actual payload for the cookie.
After sneaking this into the cookie using burp, the flag was displayed on the list:
hxp{Are you glad that at least Java(TM) isn’t affected by serialization bugs?}

This writeup brought to you by Henning, Heiko and Ferdi (in order of challenges)

Posted in CTF, TUMCTF | Leave a comment

TUCTF 2016 – Writeups

Two weeks ago we had the pleasure to take part in the TU-CTF 2016 organized by ASCII Overflow. It was an entry-level Jeopardy CTF with challenges from different security areas including web, binary exploitation, crypto and even one network analysis challenge. After solving the security riddles a so called flag in the form of TUCTF{…} could be retrieved. Uploading it to the CTF website your team earned some points. The points to earn ranged from 10 to 500 per challenge.
The guys from University of Tulsa programmed their website to show only up to 50 registered teams, since they were not expecting to register more (as far as I understood conversations from IRC). There were some confusion during registration since it seemed we, with a team ID greater than 150, weren’t on the list. The worries got settled after the CTF began. ASCII Overflow delivered a bunch of creative challenges to keep us awake without service interruptions or considerable confusions about the setup. Looking back, this was one of the best organized CTFs(at least infrastructure wise) I took part in – stuff just worked. They pulled off an awesome event. Especially considering that the scoreboard prompts 435 team – nice job scaling ;-)
One of those teams were the Ulm Security Sparrows. A handful of people of the USS met in the Ulm University to take part in the CTF on Saturday. With some additional hours invested on Sunday we were able to collect 640 points.
This made us achieve the 118th place of 435 teams and place 54/162 among college teams.
We solved the following challenges and wanted to contribute our solutions to the CTF community. We hope to inspire and make others learn like we do reading their writeups. Enjoy.

• PWN 1-3
• Escape from Hell – Start Your Decent
• The Neverending Crypto Level 1-3
• Web 1,2,4
• Misc – The Nack

Continue reading

Posted in CTF, TUCTF | Leave a comment

TU-CTF This Weekend

The Ulm Security Sparrows invite all hackers, security interested students and all other creatures in the area of Ulm to join us solving riddles and breaking IT security challenges.

TU-CTF is an introductory CTF offering challenges the categories like reversing, web, crypto, exploitation and others.

The orga team ASCIIOverflow announced the event to start on Friday midnight and end after 48h on Sunday. We will gather in the O27/Linuxpool between 12 and 1pm on Saturday and decide when we show up on Sunday on sight. Night owls are of course welcomed to start the night before. Orga related information and CTF coordination is done through our CTF-mailinglist. If your not subscribed yet, it’s time to do so.

See you on Saturday!

Posted in CTF | Leave a comment

Cpt Security Sparrow’s App Shop – iCTF2015 Writeup

The last year’s iCTF organizers changed the format of the event regarding vulnerable services. This time the services to be exploited were not provided by Vigna and Team Shellphish but had to be submitted by the participating teams. Even though we had only a few weeks for preparations we were thrilled to face the challenge. Shortly after collecting some ideas we began hacking down the first prototype of our service. Over time the tinkering evolved to a solid service, ready to be broken by teams over the globe. Service specification provided by the guys from Santa Barbara offered two general possibilities to implement the services. It could have been a xinetd or a web based service. We made  the choice to implement a web application based on the Python microframework Flask and a corresponding Android app. The general idea was to force the attackers to deal with both, the web app and the Android app. The actual functionality, you probably already guessed by the name, is an app shop to provide next generation security software. Circumventing a small obstacle the attacker can gain access to a closed area on the website to download an interesting app. The app communicates with our website, to be precise a web service, implementing two factor authentication inspired by hard or in context of smartphones increasingly popular soft tokens. The difference between our InsecureID and competitors’ products is that we managed to create a solution which is not only secure but also easy to use ;-)

Web Application/Service

If you’re familiar with frameworks like Sinatra or alike you will feel at home with Flask. It’s a Python microwebframework in which methods can be equipped with a decorator to bind it to a certain URI and a request type. Consider the following code for user creation.

Continue reading

Posted in CTF, ICTF | 2 Comments

iCTF 2014 Write-Ups: Temperature, Guestbook and Traintrain

Even though USS’s team was small in size during iCTF 2014 (2015) it was pretty good at writing exploits. The Ulm Security Sparrows scored 4.771 points and achieved the 35th place of 87 teams (66 of them scored) at the iCTF2014-2015 . In the following we would like to contribute to the event and do our part to education by sharing some of our exploits in the following writeups, namely the services “Temperature”, “Guestbook” and “traintrain”.


Temperature provides a service to query and store temperature values for a supplied date and location. The service was executed directly from its python source code. It uses a plain text file (neverguess) to store its data. For adding new entries the service uses the command

where the placeholders are replaced by the user provided input which is assumed to be a date, location, and temperature value. Retrieving a value is done by executing

 again replacing the placeholders by the user provided input which is assumed to be a date and a location. The flag_id that is given to the exploit is a date and the sought after flag is the corresponding temperature value. One way to exploit this service is that one of the input data provided must be an expression that causes the corresponding command
grep %s to become a no op .

To patch this service the intended purpose of the retrieval command was reimplemented in python such that the corresponding temperature value is returned only if the user supplied date and location matches the date and location stored in the file.


The Guestbook web app (like the name suggests) enables the visitors to publish their messages. The first step was identifying the service. At the first glance one could find the corresponding Apache config residing inside /etc/apache2/sites-enabled/guestbook. Beside the port it strikes one’s eye the option “FollowSymlinks” is explicitly turned on. Little bit later more on that.
Like all other services guestbook resides in {/usr,/var}/ctf/guestbook. The first of them contains the cgi-bin folders with some Perl scripts along with guestbook.txt and a symbolic link to /var/ctf/data with it’s own guest-book.txt file. The later one contains not only the public messages but also the ones marked private (which are posted through a check mark in the web interface). Since the tokens were posted as private messages we just had to call the URL “http://$HOST:$PORT/guestbook/cgi-bin/data/guestbook.txt” and parse the response to get tokens. As simple as the exploitation was the fix:


Traintrain was another web app we managed to exploit. Although there are several good write ups out there we implemented our own solution and wanted to publish it. The reasons for the new implementation were a) it was fun and b) we noticed pretty late after digging through the service’s source that the service really didn’t change since last year (despite somebody on IRC/Mailinglist claimed otherwise).
Inside the web app you had to register an account and the log in with the new credentials. Afterwards you were redirected to the base URL. All saved data is stored inside an SQLite db file inside the service’s folder (/var/ctf/traintrain/traintrain.db). Inside the the database file one can noticed there’s also a “history” field aside to the user credentials. Every time you surfed on the traintrain website the URLs got saved there. The next step was to decompile the python bytecode of the service and dig through the source. SQL-code inside the history row of some users (already exploited by other teams) gave us the idea what to do. We didn’t have to look long to find that the SQLi was triggered in the “solutions” area of the site executing the following python code in the line 346 (depending on what decompiler you use) inside the function solution(self, form):

As for the SQL injection itself, we were able to utilize the code that was injected in our own service by other teams, in order to build our own SQLi. Since the flags were located in the users table and the username was used as flag ID, we simply added a complete printout of the users table to the output of the solutions, utilizing the UNION keyword.
To store the SQLi payload we had to URL-encode it:

This is hence in line 114 of the def history(self, session, path): function the visited path was URL-decoded before stored in the db:

Knowing all this we identified and replayed all the important requests to trigger the vulnerability with BurpSuite Proxy and then began to bake the Python exploit. Following brief description explains the steps have to be executed to get to the tokens:

  • Register with a self defined username, password and authorization-string
  • Login using username/password and parse out the session-id from response to attach it to all further requests
  • Fire up a request with the encoded SQLi inside the URL, which is stored in the history row afterwards
  • A request to the assignment page is needed since the value of the field “assignment” has to be extracted for the final request (why ever…)
  • Launch a POST-request to the solution-site with the “assignment” and a random “solution”-value attached in the body
  • SQLi is triggered. Now you just need to extract the values of the HTML-Table and save/return the desired one

The exploits and writeups were a joint work of matou, Viktor and winnie.

Posted in CTF, ICTF | Leave a comment

WebApp Testing Seminar

Die Security Sparrows laden euch herzlich ein am Seminar zum Thema WebApplication Testing mitzumachen. Wir werden Beispielapplikation unter die Luppe nehmen und mit den Mitteln von professionellen Penterstern nach Schwachstellen suchen und diese ausnutzen. Dies ist eine Hands-On Session in der wir bei jedem Themengebiet das Vorgehen erläutern, vorführen und danach die Teilnehmer selbst durchführen lassen.

Wann/Wo/Wie lange: Das Seminar findet am 29.01.2016 im Raum O27/341 um 16.15 Uhr statt. Da das Seminar von Fragen, Interaktion und von Übungen geprägt ist solltet ihr mindestens 2,5 Stunden einplannen.

Speaker: Ferdinand uns Sergej

Das grobe Agenda sieht folgendermaßen aus:

  • Allgemeines Vorgehen
  • Vorstellung des BurpSuite (Local Attack Proxy)
  • Injection Angriffe (XSS, SQLi, XXE, XPath)
  • Client Side Controls
  • Access Controls
  • Session Management
  • Optional/Wenn Zeit bleibt (Serialization Schwachstellen, SMTP und XPath Injection, …)
  • Gegenmaßnahmen
  • Checklisten/Literatur

Alle Übungen werden mit der dem Local Attack Proxy BurpSuite durchgeführt. Wir werden uns den HTTP-Verkehr zwischen Browser und Webserver anschauen.


Link zur Anmeldung wird über die ctf-Mailingliste/Vorlesungsforen geschickt.


Slides von der Veranstaltung: webapp_testing_29-01-2016

Posted in Seminar, TeamMeeting | Tagged | Leave a comment

WebApp-Testing Seminar

An diesem Freitag(12.12.2014) um 16.30 Uhr findet im Raum O27/341 das Seminar WebApp-Testing statt. Beachtet Infos in der Mailingliste um die sich für das Seminar entsprechend Vorbereiten (benötigte Tools vorinstallieren) zu können.



Posted in TeamMeeting, USS | Leave a comment

iCTF2014 und neuer Termin

Dieses Jahr wird leider kein iCTF mehr stattfinden, das Spektakel wurde auf den 27. März 2015 verschoben.

Trotzdem wollen wir wieder regelmäßig USS-Treffen veranstalten, der dafür gefundene Termin ist Freitag, 16 Uhr in O27/341.

Posted in ICTF, USS | Leave a comment

iCTF 2013

Der iCTF 2013 wird am Freitag, 6. Dezember 17 bis 2 Uhr CET (8 bis 17 Uhr PST) stattfinden. (Quelle: http://ictf.cs.ucsb.edu/)

Wir trainieren dafür an den nächsten Terminen unserer Treffen (28. Nov. und 5. Dez., je ab 18 Uhr im Raum O27/341). Unser lokales Netzwerk setzen wir dann auch am 5. Dezember auf. Kommt also an diesen Terminen möglichst zahlreich.

Posted in ICTF, USS | Leave a comment

Treffen Donnerstag

Diesen Donnerstag (24. 10.) wird es wieder ein USS-Treffen geben. Da das Semester wieder angefangen hat, versuchen wir in dieses Treffen ein Einstieg an zu bieten für neue Studierenden, die daran interesse haben bei uns mit zu machen.

Außerdem kann jeder sich auf unsere mailing-list einschreiben via den webinterface. Über diese Mailing List werden informationen über Treffen verschickt.

Posted in Allgemein, USS | Leave a comment