malicious code on 1st line of all files

Selection_050

If you somehow came to this post searching for solution about that pesky malicious code which inserts some poorly encrypted php code on the first line on all(in some cases only a few) of your php files, then you somehow came to the correct page. Why only somehow? Maybe because as of posting time I still can not determine which particular script is causing the insertion of the malicious codes. I know the malicious code varies from site to site and it’s done on different ways. Whatever it is, they seem successful at it or not so, because when they add that pesky code chances are the site will halt and thus their code will fail to execute so they are not really that smart afterall.

Ok so enough of the rantings, i’ve written a quick php code to remove the pesky malicious code on the  first line added to all of your php files.

The code is below, just use it, edit it or do whatever you like with it as long as it helps you and make you happy. 🙂

<?php
# This code get rids of the pesky malicious codes which add to the first lines on all of your php files in a directory

###### Configuration ######

/* we are getting ftp info because some malicious codes are written
   using the active ftp account of your website. We need this access
   so we can set pemissions to the infected files via that FTP User permission */
$ftp_host = 'ftp.host.com';
$ftp_user = 'ftpuser';
$ftp_password = 'secretpassword';

/* This is the path that is shown on your ftp. usually it is /public_html/path/to/this/file.php but
   it differs on many servers. add it without the trailing slash
*/
$ftpPathToThisFile = '/public_html/my/wordpress/path';

/* place any substring of the malicious code below */
$traces = 'ZKw9W9Lj2pZSO6zqvfd6hsiTHsbM1328eXiKHEX64NzfyuLkVo7kZZ/YsSW0LaXp'; 

/* if there are any subdirectories you wish to exclude
   place it inside the array below comma separated.
   example: $excludedDir = array( 'path/to/excluded/dir', 'path/to/excluded/another/dir' ); */
$excludedDir = array();

###########################

/* function I found in this page -> http://www.webmaster-talk.com/php-forum/41811-list-files-in-directory-sub-directories.html#post202723 
	It basically list files of the specified directory including it's subdirectories
*/
function ListFiles($dir) {
	global $excludedDir;
	if( in_array( $dir, $excludedDir ) ) return;

    if($dh = opendir($dir)) {

        $files = Array();
        $inner_files = Array();

        while($file = readdir($dh)) {
            if($file != "." && $file != ".." && $file[0] != '.') {
                if(is_dir($dir . "/" . $file)) {
                    $inner_files = ListFiles($dir . "/" . $file);
                    if(is_array($inner_files)) $files = array_merge($files, $inner_files); 
                } else {
					if( strstr( $file, '.php' ) !== false && strstr( $file, '.infected' ) === false  )
                    	array_push($files, $dir . "/" . $file);
                }
            }
        }

        closedir($dh);
        return $files;
    }
}

/*
	This is the clean function I created. First it stores the whole php file line by line in to a variable.
	Then it checks if the traces can be seen on the firstline. If the trace is found it creates a backup
	of the file to a relative folder named "all-infected-files". The created backup ends with a .infected extension.
	It then rewrites the whole file without the infected first line.
*/
function cleanFile( $file, $traces ){
	global $conn_id, $docRootDifference, $ftpPathToThisFile;
	$fc = file( $file );
	if( strstr( $fc[0], $traces ) !== false ){

		$ftpFile = str_replace( $docRootDifference, '', $file );

		if( is_writable( $ftpFile ) || ftp_chmod($conn_id, 0777, $ftpFile ) !== false ){
				//lets make a backup first		
				$backupFile = str_replace( $ftpPathToThisFile, $ftpPathToThisFile.'/all-infected-files',$file ).'.infected';
				$path = pathinfo( $backupFile );

				if( !file_exists( $path['dirname'] ) ){
					$backupFileFtp = str_replace( $docRootDifference,'',$path['dirname'] );
					if( ftp_mkdir_recusive($conn_id, $backupFileFtp ) )
						ftp_chmod($conn_id, 0777, $backupFileFtp );
					else
						echo 'Error Creating backup: '.$backupFileFtp;

				}
			if( file_exists( $backupFile ) || copy( $file, $backupFile ) ){
				$posStart = strpos( $fc[0], '?>' );
				 $fc[0] = substr( $fc[0], $posStart + 2 );
				$fp = fopen( $file, 'w+' );
				fwrite( $fp, implode( '', $fc ) );
				fclose( $fp );
				return 1;
			}
		}
		else
			echo 'Cannot ftp_chmod: '.$ftpFile."<br />\n";
	}
	unset( $fc );
	return 0;
}

/* some useful function i found on this page -> http://www.php.net/manual/en/function.ftp-mkdir.php#108505
   i added the ftp_chmod so the dir is set to 777 automatically.
   Basically it creates the path and it's parent paths
*/
function ftp_mkdir_recusive($con_id,$path){
        $parts = explode("/",$path);
        $return = true;
        $fullpath = "";
        foreach($parts as $part){
                if(empty($part)){
                        $fullpath .= "/";
                        continue;
                }
                $fullpath .= $part."/";
                if(@ftp_chdir($con_id, $fullpath)){
                   ftp_chdir($con_id, $fullpath);
                }else{
                        if(@ftp_mkdir($con_id, $part)){
								ftp_chmod($con_id, 0777, $part);
                                ftp_chdir($con_id, $part);
                        }else{
                                $return = false;
                        }
                }
        }
        return $return;
}

/* let's get the server path relative to where you put this script */
$scriptPathInfo = pathinfo( $_SERVER['SCRIPT_FILENAME'] );
$scriptPath = $scriptPathInfo['dirname'];

/* login with the ftp credentials configured above */
$conn_id = ftp_connect( $ftp_host );
$login_result = ftp_login( $conn_id, $ftp_user, $ftp_password );

/* get the difference between the ftp path and the server path */
$docRootDifference = str_replace( $ftpPathToThisFile, '',$scriptPath  );

/* get all files relative to where you put this script, then cycle to
   each one of them. run cleanFile function to each file. if an infection
   is found and it is cleaned it will be outputted to screen.
*/
foreach (ListFiles( $scriptPath ) as $key=>$file){
  	if( cleanFile( $file, @$traces ) )
   		echo 'Cleaned: '.$file.'<br />'."\n";
} 

/* close the ftp session */
ftp_close($conn_id);
?>

Or save this file here and just change the extension to .php.

The  code is pretty self explanatory, i’ve added some helpful(i think) code comments. Just edit the configuration section, remember it does not run out of the box, the configuration is important in order for the code to run successful. About the $trace variable, if you are confused on what to put in there, just get any part of the malicious code string, any length will do, but the longer the better.

So i hoped i somehow have helped you with your ordeal as I know how you feel. This very blog you are reading is attacked and I do not know if it was caused by some plugin i used or perhaps the author of this template mistakenly thought that i removed his link on the footer which i certainly did not. I have also used this script initially when my client have some problems with some of his sites not loading and when he checked he saw that all files have some malicious codes inserted on the first line.

One thought on “malicious code on 1st line of all files

Leave a Reply

Your email address will not be published. Required fields are marked *