Chevereto ≤ 1.1.4 Free, ≤ 3.13.5 Core, Multiple vulnerabilities

The legendary two-keyboard hacker (I love stock photos)

This disclosure has been waiting to be let out for some time now. Some of these I first stumbled on many years ago but didn’t have the time or energy to give it any more thought. Well now I have both time, energy, and motivation to report and write about all the stuff I’ve found (including new findings since I’m currently on a “review roll”).

Downgrade attack — ≤ 1.1.4 Free, ≤ 3.13.5 Core

CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19652

Github: https://github.com/jra89/CVE-2019-19652

An admin user can instruct the updater script to downgrade to another version instead of upgrade, reintroducing previous flaws. Due to the lack of a CSRF token this attack can also be used in a CSRF attack, meaning an admin user can be tricked into performing this action.

GET /update/?action=download&version=3.13.4 HTTP/1.1
Host: 192.168.0.88
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Referer: http://192.168.0.88/dashboard/settings/external-services
Cookie: PHPSESSID=47s523u1s4m67g0vaheldg4s31; KEEP_LOGIN=I8G%3A65983a8df3bcb482e2571a6e771c89600221f615208d39aee8bf6663b88aef732c7783e202410a7ae4c3ad2205c96baeddb841b912325b359ec79528638807efbff73a017c6d719aa0cab0d6a5814d98a671c17d457479371228c590e215f7e8bc7bfcb820142106%3A1575658473
Upgrade-Insecure-Requests: 1

Missing cookie flags — ≤ 1.1.4 Free, ≤ 3.13.5 Core

CVE:

Photo by Lisa Fotios from Pexels

Basically the session cookie was missing needed flags to keep the session safe from certain attacks. The HttpOnly flag makes sure that the browser wont allow scripts to access the cookie, thus protection it from cross-site scripting attacks (XSS). The Secure flag tells the browser to only send the cookie over a secure (HTTPS) channel; meaning without it, if there are resources loaded within the same domain that go over a clear text protocol like HTTP (maybe the site loads images like this), the cookie would be sent in clear text. Anyone listening on said clear text protocol, could then fetch the cookie and munch it. The SameSite flag tells the browser to not send the cookie in cross-site requests. All of the flags were missing, however. And yes I copy/pasted this text from another article I wrote, since it’s the exact same problem.

Cross-site scripting — ≤ 1.1.4 Free, ≤ 3.13.5 Core

CVE:

Github:

Two cross-site scripting vulnerabilities. One requires that you have an admin account, and the other one simply requires a regular user account. The first one will reflect on the whole site, and the second one only on the user’s profile page. But both can be used to steal session cookies, redirect, or potentially hijack the browser.

In the first case, a user can manipulate a meta tag on the profile page to execute script. In the example below I manipulate the tag to redirect the user.

And the moment the user enters the profile page, they will be redirected. So, manipulate a tag; which will be stored until someone removes it. Then post an image that will attract people to go to your profile, like cute alpacas.

test is the name of the profile, and further down is the redirect to Google

The second finding that needs admin access will be reflected on different parts of the site, so the way to inject differs depending on where you want it to run. But if you wanted it to be injected into the title tag of the whole site then one would change the site name in the admin settings to something like the example below.

Chevereto</title>Chevt<img src=x onerror=alert(document.cookie)><title>

Which would then execute everywhere once the site loads.

Information disclosure — ≤ 3.13.5 Core

CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19653

Github: https://github.com/jra89/CVE-2019-19653

Chevereto has a bulk importer that will import images from a folder and add to the system. There are process and error logs for this function that can be viewed by anyone, which might reveal system information. Because the importer jobs start with id 1 and then just increments, it’s simple to enumerate and extract logs.

/app/importer/jobs/9/process.txt
/app/importer/jobs/9/errors.txt

Denial of service — ≤ 3.13.5

CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19654

Github: https://github.com/jra89/CVE-2019-19654

The above mentioned bulk importer will ask you to input the full path of the folder to import. The importer will remove files and folders once it’s finishes, as long as it has write access to it. So say you were to enter the path of the Chevereto installation instead? It would self-destruct, and the site would stop working.

In the importer logs you can see some of the process, although I think this file is removed as well.

1575660328 - [Thread #1] ...Removing directory /var/www/html/app/importer/jobs/9 (rmdir)
1575660328 - [Thread #1] Unable to remove /var/www/html/app/importer/jobs/9
1575660328 - [Thread #1] ...Removing directory /var/www/html/app/importer/jobs (rmdir)
1575660328 - [Thread #1] Unable to remove /var/www/html/app/importer/jobs
1575660328 - [Thread #1] ...Removing directory /var/www/html/app/importer (rmdir)
1575660328 - [Thread #1] Unable to remove /var/www/html/app/importer
1575660328 - [Thread #1] ...Removing file /var/www/html/app/.htaccess (unlink)
1575660328 - [Thread #1] ...Removing file /var/www/html/app/install/installer.php (unlink)
1575660328 - [Thread #1] ...Removing file /var/www/html/app/install/template/updated.php (unlink)

When I tested this I had to write a script that would quickly restore the site again since I wanted to do it a few times to make sure I got all the data.

Brute force protection bypass — ≤ 1.1.4 Free, ≤ 3.13.5

CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19633

Github: https://github.com/jra89/CVE-2019-19633

Chevereto has built in protection against brute force attacks, which will ban any offending IP that fails to login to an account more than 25 times. The function that is used to identify the IP of the offender uses a few different methods to do so. Two of these methods, that are the prioritized ones, will take the IP from the HTTP headers (Client-IP and X-Forwarded-For). There’s a point behind this, which is usually to get the correct IP if the server is behind a load balancer or proxy. These headers can be manipulated by the client and can sometimes be used to trick the application that the client has a different IP. By doing this one can trick the application that the client has one IP the first 25 requests, and another IP the next 25 requests; successfully bypassing the brute force protection.

An example would be, the first 25 requests

POST /login HTTP/1.1
Host: 192.168.0.88
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 85
Origin: http://192.168.0.88
DNT: 1
Connection: close
Referer: http://192.168.0.88/login
X-Forwarded-For: 8.8.8.228, 8.8.8.88
Cookie: PHPSESSID=16dal7t7fmdbd86ahjkp8qo43a
Upgrade-Insecure-Requests: 1

login-subject=admin&password=test&auth_token=fb22558fc0f068d3cfb9ca98b413c8d0adbbc205

And then the second wave you would just change the X-Forwarded-For header to something else.

POST /login HTTP/1.1
Host: 192.168.0.88
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 85
Origin: http://192.168.0.88
DNT: 1
Connection: close
Referer: http://192.168.0.88/login
X-Forwarded-For: 8.8.8.229, 8.8.8.88
Cookie: PHPSESSID=16dal7t7fmdbd86ahjkp8qo43a
Upgrade-Insecure-Requests: 1

login-subject=admin&password=test&auth_token=fb22558fc0f068d3cfb9ca98b413c8d0adbbc205

Remote Code Execution — ≤ 1.1.4 Free, ≤ 3.13.4 Core

CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19511

Github: https://github.com/jra89/CVE-2019-19511

I wanted to save this one for last, since this is the one I’ve been sitting on the longest. Noticed it many years ago but for some reason I just decided to leave it, most likely due to a very busy period in my life. This attack also results in a denial of service attack if you don’t happen to know the exact credentials in the settings.php file before the attack, since the exploit will overwrite the file. It should also be noted that there’s another function in the Chevereto admin function that allows one to execute code; by design. The function is meant to let an admin edit arbitrary PHP files in a certain folder. So as long as that feature is there and can’t be disabled then this exploit is not as interesting as I first thought.

To exploit this you would need to compromise an admin account and then send a manipulated request to the install script and tell it to finish the installation an write the settings.php file. The data sent to the install script can be manipulated to include PHP code that will then be written to the settings.php file and executed. I wrote a script that exploits this to drop a backdoor in another folder, and then cleanup the settings.php file again after that. It will still put the site in a denial of service state since the settings wont be correct anymore, and you will also need the settings you overwrite with to actually be correct since the install script connects to the database to verify that it actually works. This is a trivial problem though, and there are services out there that can be used for free to get a remote database or two. Medium.com messes up the script if I try to post it here, but it’s available in the Github repository if you’re interested.

That’s it for now

The contact I had at Chevereto was very good and he was open minded about the findings I had. We had a good discussion and he requested some extended time to fix the issues. The findings were reported between August and December (since I only review sometimes when I have free time, they were a bit spread out over the months) and so we agreed on 90 days plus extension before anything was disclosed. Since the report time differed between the findings, there was also the option to extend it even further into 2020. In the end we agreed on the 4th of January for the disclosure, and I decided to publish today due to some other stuff that came up this weekend.

The latest release as of me writing this is v3.13.5 and the next one coming up is v3.14.0, and can both be checked out at their website at https://chevereto.com/

Update 2020–01–11: It turns out that I forgot to make the Github repositories public. This has now been fixed.

I program, hack, and write odd stories. I currently work for an IT-security company called Defensify.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store