Malicious user managed to upload a .php to my server available via apache

Hi everyone,

I recently experienced a security breach on my server where a user managed to upload a malicious PHP file with the passthru() function. This file allowed unauthorized SSH access by modifying the “known ssh keys” user’s file. Since the website runs under the same user context as the server, this led to serious vulnerabilities.

To address this issue, I’ve set up a temporary server with Cloudflare and I’m in the process of creating a new, more secure server.

While I’ve taken steps to prevent the direct upload of malicious files by checking file extensions and MIME types, I’m concerned that there may be other avenues for attackers to compromise the server.

  1. I plan to implement mod_security to enhance security. However, I’m worried about inadvertently blocking legitimate users, especially considering that Cloudflare IPs might be affected. How can I effectively block attackers while avoiding false positives? mod_security is for disabling the execution of .php files located in the storage folder (while I move everything to S3)

  2. Separating Web and SSH Users: I want to ensure that the user account used for hosting the website doesn’t have SSH access. However, I still need a separate user account for SSH access, as I currently don’t use any automated deployment methods like CI/CD. How can I achieve this separation of privileges within Virtualmin?

  3. User Jailing? Is it advisable to use jailkit to confine users within Virtualmin? I recall not seeing this option in the menu on the attacked server, I had the last version, but I’m wondering if it’s worth considering for added security.

  4. I’m considering restricting HTTP access to only Cloudflare IPs. However, I find FirewallD somewhat challenging to understand, and I’m not sure if it’s the best tool for this purpose. Should I invest time in learning FirewallD, or are there alternative tools better suited for this task? It’s intuitive for blocking or whitelisting. I was used to the router’s FW with source/dest/ip/port etc.

  5. Would it make sense to deploy a docker inside the virtual server for added security?

I appreciate any insights or advice on addressing these security concerns within the Virtualmin environment. Thank you!

Web user has no shell (/bin/false), additional admin user has a shell. As long as they share a group for web content, it should be possible to upload/edit web content.

But, this kind of attack isn’t prevented by this change. If a remote user can execute their own code via a web request, it’s already over.

Jail wouldn’t prevent this; the jailed user has access to their own home, so unless the attacker escalated out of the user account and into root or some other privileged user, a jail wouldn’t alter the attack or its results. Putting uploaded files outside of executable paths would prevent this specific attack, and is recommended for any app. An attacker can’t run a shell they’ve uploaded if they can’t cause uploaded code to run.

Docker is not a security tool. The same app deployed in the same way inside of a container (where an attacker has the ability to upload a file and execute it) would still make a variety of exploits possible.

Hi Joe, thanks a lot for the fast response.

  1. I agree that if a remote user can execute code in my server, its over. But, I case this ever happens again, I would like to contain the access as much as possible. I have created virtual domains and each one has a user and the webpage is located in the home user’s directory. So php fpm runs a the user, and the .ssh files are writable by the user. The user can ssh, and it has shell. You said “web user has no shell” you meant www-data?

  2. if the jailed user has access only to their home, I can delete the all files at home and redeploy the site in case something happens again, but I would be confident that the user was not able to plant any file somewhere else. At this point I don’t event remember if the virtualserver users have sudo enabled by default.

  3. I know docker is not a security tool, I thought it might contain a user that may gain access, in which case I can destroy and redeploy it without having to setup a new server, as I am doing now.

  4. regarding a WAF o firewall, any guides I can follow?

thanks again.

No, that user should never be used for anything in a Virtualmin environment. I mean the domain owner user that code executes as. (www-data would only be the user executing code in a Virtualmin virtual server if you have mod_php installed, which should never happen.)

You can already be confident of that. A user can’t put files outside of their home, unless you’ve altered permissions to allow them to do so. A jail is not what provides that. A jail is mostly aesthetic.

Unless the attacker escalated to root or some other privileged user, they couldn’t write elsewhere. Of course, if you have reason to believe they escalated privileges, then reinstalling is, in fact, the right course of action.

That’d be insane. That’s not the default, and I would strongly discourage anyone from ever granting website users sudo. That’d be wildly dangerous.

Ok, so I have checked and as you said, the user cannot run sudo without the password. So that was ok at least.

Is there any virtualmin compatible ImunifyAV or “antivirus” or anti rootkit that I can use and configure from within virtualmin?

I’m really sorry, I still can’t understand what you say about the www and the user.
I was running php as FPM (fcgi before that)
“Web user has no shell (/bin/false), additional admin user has a shell. As long as they share a group for web content, it should be possible to upload/edit web content.”"

Which one is the web user?

Every time I create a virtual domain, a new user is created. Apart from apache2 running as www-data, the php (via php-fpm) runs as the user owner of the site. So, each site has a their own home and the user for uploading and sshing is the same a the one the fpm runs with.
I was thinking that I might set php-fpm to run as a user with no shell, but that wouldnt matter if the user runs a command with passthru, exec or any of those functions. I even need proc_open for a script that compress uploaded images.

Thanks a lot again.

They shouldn’t be able to run sudo at all. (Anyone could probably run su if you have a root password set, and they had the root password. But, sudo should only be possible for someone with a user in sudoers or in sudo-capable group, which Virtualmin doesn’t do by default, and I would strong discourage configuring it to do so.

Then the domain owner user is the user running the PHP applications. By default, Virtualmin would give the domain owner user a name like virtualmin for a domain virtualmin.com, but that’s configurable. You need to look at the virtual server, as only you can know what your user names are.

“Administration username” is the domain owner user. Applications always run as that user in this domain (unless, again, mod_php is involved, or something else out of the ordinary).

Exactly. As I was saying, you’re already lost if a remote user can execute arbitrary code. Nothing you do with the shell, a jail, or anything else will prevent problems, if you’ve got a web app that can be exploited to run arbitrary code.

In case I wasn’t clear: I told you how to make the domain owner user not have a login shell (/bin/false or nologin or whatever, for shell), but I also explained that it can’t help with the exploit you had. (I said, “But, this kind of attack isn’t prevented by this change.”)

Have you installed Virtualmin by following the instructions here, or in some other way?

https://www.virtualmin.com/download/

Hi! I have followed the official guide. thanks.

Hi Joe

  1. Confirmed, the users are not in sudoers list. I even received an email letting me know the attempt to sudo.
  2. In my case, I change the name of the user for each virtual server, something like in your image example. No mod_php used. So yes, the site runs as the user owner of the virtual server.
  3. If I make the virtual server/domain user a user with no shell, I will not be able to ssh in for administration, etc. So I will give write permission to the webuser only to the cache/storage/etc and create another user for sshing, also restricted only to my personal office IP.

thanks for responding to all my messages.