###############################################################################
# Protocol for CTF #
###############################################################################
Information regarding the protocol: It is mandatory to hand in a protocol. It is
the basis for the grading of the lab of the lecture. Therefore, start writing
the protocol timely!
Hints:
* Describe all flaws you have found in the services.
* Also explain how you fixed these flaws.
* If you found flaws but did not make it to fix them, describe the
vulnerabilities and what has to be done in order to fix them.
* There may be flaws or bad configurations at different locations. If you find
them, document them, regardless whether they are exploitable or not.
* Document your creative offense/defense ideas/approaches. Is is important to
describe them, regardless whether they have been implemented or not. e.g.:
automated attacks, exploiting vulnerabilities in service A to get flags from
service B, ...
* Document the attacks made by you. If an attack was not successful, this should
be documented nevertheless as you could still get points for it. In this case,
precisely describe your approach and the errors occurred.
* If you want to attach additional files such as source code, screenshots, etc,
refer to them (filename) and hand them in together with this protocol as an
archive (zip, tar, etc).
* More information about the grading can also be found in tuwel in the document
about CTF information and rules in the section about the CTF.
###############################################################################
# Team
###############################################################################
Teamname: (L) Password Lost Team-ID: 24
-------------------------------------------------------------------------------
Matriculation number, first name, last name
-------------------------------------------------------------------------------
1: 00000000, redacted
2: 00000000, redacted
3: 00000000, redacted
-------------------------------------------------------------------------------
###############################################################################
# Notes on attached source code
###############################################################################
We've written a Python script to automate exploitation and flag submission. It
takes lists of exploits and IP addresses, and runs them every 15 minutes. It
also submits the flags and stores the results in a JSON file, so we could easily
view the status in a frontend.
The individual exploit scripts are in the `/exploits` directory.
###############################################################################
# Service NetterGuestbook
###############################################################################
-------------------------------------------------------------------------------
1) Description of the service
-------------------------------------------------------------------------------
This website allows to store notes and list them later on. It has a
functionality to store private notes, which are stored behind a password.
Furthermore, one can use a "Print posts" function to render the notes as a pdf
file.
-------------------------------------------------------------------------------
2) Found vulnerabilities and solutions
-------------------------------------------------------------------------------
When printing the entries, the execute_query endpoint takes all messages and
places them inside the printout.text file. This is done with the function
`f.write(render_template('printout.tex',data=result).encode())` which populates
the placeholders `{{post[1]}}` and `{{post[4]}}` in the latex file.
The message, which is stored in `post[4]`, is user controlled. Therefore a user
can enter arbitrary latex commands. These later on get executed with
`os.system(f"cd /tmp; pdflatex {f.name}")`.
To fix the latex injection, we've added this sanitization:
```python
def sanitize_latex(val):
if isinstance(val, str):
return val.replace('\\', '')
return val
# ...
result = [sanitize_latex(entry) for entry in result]
```
This removes all `\` before passing it into the latex file, and thus prevents
inserting latex commands.
A further issue is, that custom SQL commands are possible. While this by itself
is not a vulnerability as they should be protected, it increases the attack
surfaces. In our case, we were able to obtain the secret, which allows
circumventing the protection and executing the SQL query.
With the secret, one can create a valid security hash for arbitrary SQL queries.
These queries can then be submitted via the API to retrieve all posts.
-------------------------------------------------------------------------------
3) Attacks on this service
-------------------------------------------------------------------------------
The exploit script is attached as `exploits/guestbook.py`.
We first create a message with following content:
```latex
\end{verbatim}
\input{/app/secret}
\begin{verbatim}
```
The we print the document as pdf, which includes this message. Because of the
latex injection described above, this gets inserted into `printout.tex`. There
it closes the `\begin{verbatim}` command, executes `\input{/app/secret}` which
inserts the secret into the pdf, and then opens verbatim again. So, by parsing
the text, we know the secret.
With the secret, we can use the `compute_security_hash` method to compute a
signature for the query `SELECT * FROM post`. We then use the `/execute_query`
endpoint to execute this query with our (valid) generated signature. This yields
all messages, including the flags.
###############################################################################
# Service NetterMaps
###############################################################################
-------------------------------------------------------------------------------
1) Description of the service
-------------------------------------------------------------------------------
This website displays a map with interesting locations. The user can click on
any point to add a new marker, which gets displayed there. For private markers,
a cookie is stored in the browser, which is used to retrieve them later on.
-------------------------------------------------------------------------------
2) Found vulnerabilities and solutions
-------------------------------------------------------------------------------
In the db.php file, the SQL queries are concatenated with the query parameters.
For instance, take the line:
```php
pg_query($db, "SELECT * FROM (SELECT * FROM markers WHERE owner = '".$_GET["mepoc"]."' ORDER BY cdate DESC LIMIT 100) x UNION SELECT * FROM (SELECT * FROM markers WHERE rvisible = 1 ORDER BY cdate DESC LIMIT 100) x;");
```
Here we use the `mepoc` query parameter from the URL, and directly insert it
into the SQL. This parameter is user controlled and could contain SQL commands.
To fix it, one should replace all occurrences of pq_query with pg_prepare and
pg_execute (see https://www.php.net/manual/en/function.pg-prepare.php).
For instance:
```php
// $result = pg_query($db, "DELETE FROM markers WHERE owner = '".$_GET["mepoc"]."' AND cref = '".$_GET["cref"]."';");
$query = pg_prepare($db, "query2", 'DELETE FROM markers WHERE owner = $1 AND cref = $2');
$result = pg_execute($db, "query", array($_GET["mepoc"], $_GET["cref"]));
```
This safely inserts the values as data into the query, and prevents that it
could be interpreted as code.
Another issue, is that the application stores the password and username in the
source file (and the password is not randomly created).
-------------------------------------------------------------------------------
3) Attacks on this service
-------------------------------------------------------------------------------
The exploit script is attached as `exploits/maps.py`.
To use the SQL injection, one needs to escape from the quotes in the SQL query.
The mepoc variable is padded inside `'` qoutes, therefore we can use these to
end the string and start with our commands.
To get all markers, we use `?mepoc=abc'OR'1'='1`. Because of the OR clause this
always evalutes to true. The resulting SQL query is:
```php
pg_query($db, "SELECT * FROM (SELECT * FROM markers WHERE owner = 'abc' OR '1' = '1' ORDER BY cdate DESC LIMIT 100) x UNION SELECT * FROM (SELECT * FROM markers WHERE rvisible = 1 ORDER BY cdate DESC LIMIT 100) x;");
```
The response includes all markers, and therefore also the ones with the flags.
###############################################################################
# Service NetterMusic
###############################################################################
-------------------------------------------------------------------------------
1) Description of the service
-------------------------------------------------------------------------------
The NetterMusic service allows users to create playlists of their favorite songs
in the netterverse by submitting YouTube URLs. After creation a user can view
the playlist, play random songs and also delete the playlist. All of the above
actions require the user to be authorized via username and password.
-------------------------------------------------------------------------------
2) Found vulnerabilities and solutions
-------------------------------------------------------------------------------
However, in the `exec.php` file of the NetterMusic service the admin has an
default password set. More specific, the username `admin` and the admin password
`NETTERMUSIC_ADMIN_PW_PLACEHOLDER` is used and allows to successfully
authenticate in the service. If the above mentioned credentials are used on the
`https://10.10.40.124:9000/` page and then just the `Do it!` butten is pressed,
all the available tracks are displayed. This also includes all the flags as they
are specified as the "YouTube" links e.g.
```
ID = 1
TRACKS (separated by the | character) = 04062022063209UTCXXARNZWBQPJD79F
```
To prevent this exploit, one can change the default password to a new password
and therefore make it impossible for other teams to access the flags. It can be
done by simply changing the `$admin_password` in the `exec.php` file to a new
randomly created password.
-------------------------------------------------------------------------------
3) Attacks on this service
-------------------------------------------------------------------------------
The exploit works as follows:
1. First we connect to the corresponding services of the other teams by
accessing `https://{ip}:9000//exec.php'`
2. Secondly, we provide the above mentioned credentials in the request body
```json
params = {
"username":"admin",
"password":"NETTERMUSIC_ADMIN_PW_PLACEHOLDER",
"specifier":""
}
```
3. And finally we send the request using `requests.post`.
The whole exploit code can be found in `runner/exploits/nettermusic.py`.
###############################################################################
# Service NetterNotes
###############################################################################
-------------------------------------------------------------------------------
1) Description of the service
-------------------------------------------------------------------------------
NetterNotes is a simple note taking service. Users can create (public) unlocked
notes, (private) - secured via a password - locked notes and also search for
notes.
-------------------------------------------------------------------------------
2) Found vulnerabilities and solutions
-------------------------------------------------------------------------------
There are several vulnerabilities in NetterNotes:
1. The /search/ endpoint is vulnerable to information disclosure; by using e.g.
"a" as search query also locked notes (and thus flags) are returned. To
retrieve all possible flags one has to search for "F", "l", "a", "g"; because
without the patch the title (= "Flag") and the message (i.e., some flag
containing UTC) must both include the searched letter.
2. The /locked endpoint uses unsafe eval, which allows to circumvent the
password protection.
Our patches are as follows:
- For 1., we change `SELECT * FROM notes WHERE locked = 0 AND title LIKE ? OR
message LIKE ?` to `SELECT * FROM notes WHERE locked = 0 AND (title LIKE ? OR
message LIKE ?)` to respect the order of evaluation of SQL correctly.
- For 2., we removed the `else:; my_password_provided = eval(password); if
my_password_provided == my_password_hashed:; notes.append(entry)` part to
avoid using `eval` if the password doesn't match.
-------------------------------------------------------------------------------
3) Attacks on this service
-------------------------------------------------------------------------------
Our exploit works as follows:
- Retrieve all titles of stored (and locked) notes via endpoint /.
- For 1. we simply query the /search/ endpoint with data={"search": "a"} to
retrieve all flags using the information disclosure vulnerability.
- For 2. we use either "entry['note_password']" or "my_hashed_password" as
password to retrieve the note without knowing the password.
Its code is given in `runner/exploits/netternotes.py`.
###############################################################################
# Service NetterPizza
###############################################################################
-------------------------------------------------------------------------------
1) Description of the service
-------------------------------------------------------------------------------
NetterPizza is a service where users can register themselves, order pizza and
also view their order history. After being registered a user can oder up to 3
pizzas and view the corresponding order histories.
-------------------------------------------------------------------------------
2) Found vulnerabilities and solutions
-------------------------------------------------------------------------------
Although we were not able to fully exploit the service, we encountered some
weird behaviours. Namely, after registering an `admin` user and viewing the
order history of this user, the history also contained the data of another user
(`test` user). Unfortunately, time has passed too quickly and we were not able
to fully reproduce this behaviour with other users to eventually retrieve the
flag.
However, we developed some *Offensive* and *Defensive* measures which are
described in more detailed in the following section.
-------------------------------------------------------------------------------
3) Attacks on this service
-------------------------------------------------------------------------------
We had multiple approaches to attack this service:
1. Offensive: As the source code of the given service was obfuscated with the
`netterpizza/src/backend/.../.mylang.h` definitions, we first decoded the
given source file using a custom python script:
```python
import sys
esoteric ={
"FLOOP" : "for",
"LOOP" : "do",
"AS_LONG" : "while",
"CONSTANT" : "const",
"NUMBER" : "int",
"CHARACTER" : "char",
"STRING" : "char *",
"POINTER" : "*",
"NOTHING" : "void",
"LOGIC" : "bool",
"TIME" : "time_t",
"EQUAL_TO" : "==",
"NOT_EQUAL" : "!=",
"SMALLERTHAN" : "<=",
"GREATERTHAN" : ">=",
"POINT" : "->",
"GREATER" : ">",
"SMALLER" : "<",
"OPTYPE" : "",
"IS" : "if",
"OTHERWISE" : "else",
"ALTERNATE" : "switch",
"OPTION" : "case",
"STOPHERE" : "break",
"NOOPTION" : "default",
"GIVEBACK" : "return",
"END" : "exit",
"LIE" : "false",
"TRUTH" : "true",
"CB_" : "{",
"_CB" : "}",
"RB_" : "(",
"_RB" : ")",
"SB_" : "[",
"_SB" : "]",
"_EI" : ";",
"EQUALS": "=",
"OTHERWifE": "else",
"GET": "#include "
}
# Replace strings
with open(sys.argv[1], 'rt') as fin:
with open(sys.argv[1]+"_fixed.c", 'wt') as fout:
for line in fin:
for x, y in esoteric.items():
line = line.replace(x, y)
fout.write(line)
```
This python script uses the given definitions and replaces them by the correct
`C` language keywords. This allowed us to better understand the given sourcecode
and obtain some insights.
2. Defensive: We configured
[mod_dumpio](https://httpd.apache.org/docs/2.4/mod/mod_dumpio.html) to
monitor attacks from other teams on this service and eventually figure out
how these attacks work. Therefore, we added `DumpIOInput On;DumpIOOutput
On;LogLevel dumpio:trace7` the `netterpizza/src/site`, and `a2enmod dump_io
&& a2dismod -f deflate` to the `Dockerfile`. Disabling `deflate` was
necessary, because otherwise the dumped responses would have been zipped.
Unfortunately, we could not completely decipher the attacks we received.
However, it had something to do with the `possible problem with user dir: %s`
error message and that somehow the flag was written into another user's
`userdata` file.
###############################################################################
# Comments
#
# Any comments related to the CTF. This part is not used for the evaluation.
# Feedback helps us to improve this event for next semester.
#
###############################################################################
TODO