+2

open_basedir on ajeniti V is not working properly

JL Griffin 5 years ago updated by Amirhossein Nobandegani 5 years ago 11
I seem to have an issue with openbasedir restrictions not being in effect. yesterday one of my clients workpress installs got hacked, and overnight every php file in the entire /srv directory for all clients has:

<?php eval(gzinflate(base64_decode('<A bunch of code here>')));?>

in the interest of security and formatting i removed the code after the decode statement.

It seems that they managed to upload a php script which allowed them to edit files and upload files to that directory and it seems they were able to hit files that were outside that web directory as well:

based on this post: http://support.ajenti.org/topic/430340-open_basedir-for-ajenti-v-web-sites/ i know that ajenti SHOULD have properly implimented open_basedir so is there something ive missed here? while i wait for a reply ill be sanitizing a thousand php files by hand -_-
additional info: if this were just a wordpress hack id disable the clients site and alert the client of the hack and after they have fixed it id unsuspend it, but in this case i need to find out how the hack escaped the wordpress directory and hit other php documents. several site designs have nothing more than a common menu file (a site with all .php extensions and the nav menu is in menu.html and php has an include statement to include menu.html.). no vulnerabilities, still got hit. looking for some info here. where can i start looking??
Anything? Anyone? i really need to get this sorted. i spent hours sanitizing all the files and by this morning everything has been reinfected! can someone give me something/anything to work with? can i pay for support? something??
+1
In the websites section of ajenti -v you have PHP FastCGI section built?

If so, you put in, according to your file structure for PHP .ini values - like: open_basedir = /srv/http/0002:/tmp
wow. i didnt even catch that. this seems like ahorrible design flaw that the correct value isnt already inserted upon site creation! if you use this for hosting your clients arent going to know that they need to do this, as mine didnt! for such a security focused panel, why would we leave such a huge potential for error? thank you Wrrrr
Ok well ill throw this up for anyone who is interested. i used 2 scripts to fix this:

firstly i made a list of infected files using this:

find /srv -name "*.php" -exec grep -li "eval(gzinflate" {} \; >> results.txt
Then after unsucessfully using sed for a while i just used this php script which you should run using php5-cli

<?php

// vim (or your favorite editor) a file from results.txt and copy the entire string of bad code including 
// the <?php \>? brackets exactly as the line appears and place it in the finewhat variable.
 
// Make sure $findWhat won't match any code you actually want!!! Any line that matches will be deleted.
$findWhat = '<?php your-infection-code ?>';
$listOfFiles = "results.txt";
$infectionCounter = 0;
try {
    $cleanLog = fopen('cleanLog.txt', 'a+');
    $infectedFileList = fopen($listOfFiles, 'r');
    if ($infectedFileList !== FALSE) {
        while ($file = rtrim(fgets($infectedFileList))) {
            $possibleInfectedFile = fopen($file, 'r');
            $tmpFile = fopen($file . '.tmp', 'w+');
            if ($possibleInfectedFile !== FALSE && $tmpFile !== FALSE) {
                while ($lineToCheck = fgets($possibleInfectedFile)) {
                    if (strpos($lineToCheck, $findWhat) === FALSE) {
                        fwrite($tmpFile, $lineToCheck);
                    } else {
                        $infectionCounter++;
                    }
                }
                fclose($possibleInfectedFile);
                fclose($tmpFile);
                unlink($file);
                rename($file . '.tmp', $file);
                fwrite($cleanLog, $file . " was cleaned\n");
            } else {
                echo $file . ' was skipped' . "\n";
            }
        }
        fclose($cleanLog);
        fclose($infectedFileList);
        echo "Number of infections found: " . $infectionCounter;
    }
} catch (Exception $e) {
    echo $e->getMessage();
    die("\nAn Unknown exception occured!");
}
?>
you should run the first command again after the php script as more than one version of the gzinflatecode may exist on the server and if that is the case repeat the php script placing the next infection string into the findWhat variable.

i did not write this php script myself, i found it online though i dont recall where (probably stack overflow tbh) but whoever the originator was is briliant, as it works great.

+1
I think Eugene (re)wrote it so that a value of "none" is to be inserted: open_basedir = none (which is better than empty) but for a set up like mine with many WordPress installs the folder location is the preferred solution. This is discussed elsewhere in here, Eugeny github and probably stackexchange too.

The FastCGI is not invoked automatically because sites that are not php based will require parameters for node.js, Python etc... I follow the WordPress procedures prescribed by Ajenti by Myles here on a WordsRack Nginx hardened set up.
I know fastCGI isnt enabled by deafult, but when you do create it in the websites panel, a lot of stuff is auto inserted, including apparently, open_basedir = none. agreed none is better than blank, but based on how fluid the rest of the panel is at inserting the proper values, one would think by default that the parameter would be set
 
open_basedir = /srv/webroot/of/this/site

it only makes sense, ESPECIALLY with ajenti V. V is designed for hosting. hosting means clients with accounts, those clients wont know better. Heck, I'm the admin and i didn't catch this. it seems unreasonable to allow those clients who don't know, to compromise the security of the rest of the server, including the clients who DO know. is there a value set up stopping open_basedir form leaving the /srv directory at least? if not, you are asking for a whole server to be compromised. anyone with fs access can do just about anything...

Great Links Wrrr, will give them a thorough read through tonight.
Based on the above it would be for the PHP .ini values in the FastCGI of the content section:

open_basedir = /srv/webroot/of/this/site:/tmp;

any way i can have that auto injected at FCGI generation? some mod i can make to the panel itself?

+1
in the latest version of ajenti, ajenti v , add default value for open base direction
in the webistes section >> content tab >> php fast cgi >> php >> open_basedir = none;
in the php tab you can enter your php setting for your sites , by default the value of open basedir is none
and its ok, and dont have security problem

but if you need configure it , with your addithional setting , feel free and use it

please clean your meta,
yum clean metadata
and install latest version of rpm
wget http://repo.ajenti.org/ajenti-repo-1.0-1.noarch.rpm 
rpm -i ajenti-repo-1.0-1.noarch.rpm
then update your system
yum update
yum upgrade
sorry for my english, be happy