Hi guys, I've developed a virus scanning program using php. Well, it seems my program worked fine--- it can detected the infected files. The problem is how can I make the program to delete the infected files. It seems when I tried to developed the coding, it didn't work. Below is the code;

<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$debug = true;
file_scan("http://localhost/", $defs, true);
$extensions = Array();
$extensions[] = 'htm';
$extensions[] = 'html';
$extensions[] = 'txt';
$extensions[] = 'php';
$extensions[] = 'hp4';
$extensions[] = 'hp5';
//$extensions[] = '.pl';



// CODE BEGINS here

// declare variables
$report = '';

// output html headers
renderhead();

// set counters
$dircount = 0;
$filecount = 0;
$infected = 0;

// load virus defs
if (!check_defs('virus.def'))
	trigger_error("Virus.def vulnerable to overwrite, please change permissions", E_USER_ERROR);
$defs = load_defs('virus.def', $debug);

// scan specified root for specified defs
file_scan($path, $defs, $debug);

// output summary
echo '<h1>Scan Completed</h2>';
echo '<div id=summary>';
echo '<p><strong>Scanned folders:</strong> ' . $dircount . '</p>';
echo '<p><strong>Scanned files:</strong> ' . $filecount . '</p>';
echo '<p class=r><strong>Infected files:</strong> ' . $infected . '</p>';
echo '</div>';

// output full report
echo $report;


function file_scan($folder, $defs, $debug = true) {
	// hunts files/folders recursively for scannable items
	global $dircount, $report;
	$dircount++;
	if ($debug)
		$report .= '<p class="d">Scanning folder ...</p>';
	if ($d = @dir($folder)) {
		while (false !== ($entry = $d->read())) {
			$isdir = @is_dir($folder.'/'.$entry);
			if (!$isdir and $entry!='.' and $entry!='..') {
				virus_check($folder.'/'.$entry,$defs,$debug);
			} elseif ($isdir  and $entry!='.' and $entry!='..') {
				file_scan($folder.'/'.$entry,$defs,$debug);
			}
		}
		$d->close();
	}
}

function virus_check($file, $defs, $debug = true) {
	global $filecount, $infected, $report, $extensions;

	// find scannable files
	$scannable = 0;
	foreach ($extensions as $ext) {
		if (substr($file,-3)==$ext)
			$scannable = 1;
	}

	// compare against defs
	if ($scannable) {
		// affectable formats
		$filecount++;
		$data = file($file);
		$data = implode('\r\n', $data);
		$clean = 1;
		foreach ($defs as $virus) {
			if (strpos($data, $virus[1])) {
				// file matches virus defs
				$report .= '<p class="r">Infected: ' . $file . ' (' . $virus[0] . ')</p>';
				$infected++;
				$clean = 0;
			}
		}
		if (($debug)&&($clean))
			$report .= '<p class="g">Clean: ' . $file . '</p>';
	}
}

function load_defs($file, $debug = true) {
	// reads tab-delimited defs file
	$defs = file($file);
	$counter = 0;
	$counttop = sizeof($defs);
	while ($counter < $counttop) {
		$defs[$counter] = explode('	', $defs[$counter]);
		$counter++;
	}
	if ($debug)
		echo '<p>Loaded ' . sizeof($defs) . ' malicious codes definitions</p>';
	return $defs;
}

function check_defs($file) {
	// check for >755 perms on virus defs
	clearstatcache();
	$perms = substr(decoct(fileperms($file)),-2);
	if ($perms > 55)
		return false;
	else
		return true;
}

function renderhead() {
?>

<html>
<head>
<title>Virus scan</title>
<style type="text/css">
h1 {
	font-family: arial;
}

p {
	font-family: arial;
	padding: 0;
	margin: 0;
	font-size: 10px;
}

.g {
	color: #009900;
}

.r {
	color: #990000;
	font-weight: bold;
}

.d {
	color: #ccc;
}

#summary {
	border: #333 solid 1px;
	background: #f0efca;
	padding: 10px;
	margin: 10px;
}

#summary p {
	font-size: 12px;
}
</style>
</head>

<body>
<?php
}
?>
<p class="d">&nbsp;</p>
</body>
</html>

So guys can you helped enhance my coding? I mean the program can delete the infected files. Thanks in advanced.

Hi, Actually i have a chat system, i want to add your virus scanner when user upload file during chat. can you tell me how i can integrate it. below i send my code in which i want to add virus scan testing

<?
//include_once("./virus.php");
if (empty($current_user->id)) {
  die();
}

$_window_title.=' '.PCPIN_WINDOW_TITLE_SEPARATOR.' '.$l->g('upload_file');

_pcpin_loadClass('message'); $msg=new PCPIN_Message($session);

if (empty($profile_user_id) || $current_user->is_admin!=='y') {
  $profile_user_id=$current_user->id;
}

if (!isset($f_target) || !is_scalar($f_target)) {
  $f_target='/dev/null';
}
// Validate uploaded file
if (isset($f_submitted)) {
  $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
} else {
  $upload_status=null;
}
$binaryfile_id=0;
$width=0;
$height=0;
$filename='';

if (!empty($f_data) && is_array($f_data) && isset($f_data['error']) && isset($f_data['tmp_name']) && isset($f_data['size'])) {
  $filename=$f_data['name'];
  
/*$file=$filename;
$scan=file_scan($file, $defs, $debug = true);
*/
  $upload_status=array('code'=>10, 'message'=>$l->g('error'));
  if ($f_data['error']==UPLOAD_ERR_NO_FILE || $f_data['error']==UPLOAD_ERR_OK && empty($f_data['size'])) {
    // No file was uploaded or file is empty
    $upload_status=array('code'=>-1, 'message'=>$l->g('file_upload_error'));
  } elseif ($f_data['error']!=UPLOAD_ERR_OK) {
    // File upload error
    $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
  } /*elseif ($scan==0){
      //virus scan check.
	  $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
	  exit();
	}*/ else {  

    switch ($f_target) {

      case 'avatar': // New Avatar
        // Check avatars number limit
        _pcpin_loadClass('avatar'); $avatar=new PCPIN_Avatar($session);
        $avatar->_db_getList('COUNT', 'user_id = '.$profile_user_id);
        if ($avatar->_db_list_count>=$session->_conf_all['avatars_max_count']) {
          // Limit reached
          $upload_status=array('code'=>10, 'message'=>str_replace('[NUMBER]', $session->_conf_all['avatars_max_count'], $l->g('avatars_limit_reached')));
        } else {
          // Check image data
          $img_data=null;
          switch (PCPIN_Image::checkImage($img_data,
                                          $f_data['tmp_name'],
                                          $session->_conf_all['avatar_image_types'],
                                          $session->_conf_all['avatar_max_width'],
                                          $session->_conf_all['avatar_max_height'],
                                          $session->_conf_all['avatar_max_filesize'],
                                          false)) {

            case  PCPIN_IMAGE_CHECK_OK: // Image OK
              $upload_status=array('code'=>0, 'message'=>$l->g('avatar_uploaded'));
            break;

            case PCPIN_IMAGE_CHECK_ERROR_FILE: // File does not exists / not readable
              $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
            break;

            case PCPIN_IMAGE_CHECK_ERROR_MIME: // MIME not allowed
            case PCPIN_IMAGE_CHECK_ERROR_NOT_IMAGE: // File is not an image or has incompatible format
              $upload_status=array('code'=>200, 'message'=>$l->g('image_type_not_allowed'));
            break;

            case PCPIN_IMAGE_CHECK_ERROR_WIDTH: // Image width larger than allowed
            case PCPIN_IMAGE_CHECK_ERROR_HEIGHT: // Image height larger than allowed
              $upload_status=array('code'=>300, 'message'=>str_replace('[WIDTH]', $session->_conf_all['avatar_max_width'], str_replace('[HEIGHT]', $session->_conf_all['avatar_max_height'], $l->g('image_too_large'))));
            break;

            case PCPIN_IMAGE_CHECK_ERROR_FILESIZE: // Image file size larger than allowed
              $upload_status=array('code'=>400, 'message'=>str_replace('[SIZE]', $session->_conf_all['avatar_max_filesize'], $l->g('file_too_large')));
            break;

          }
        }
        if ($upload_status['code']===0) {
          // Image OK
          $width=$img_data['width'];
          $height=$img_data['height'];
          _pcpin_loadClass('binaryfile'); $binaryfile=new PCPIN_BinaryFile($session);
          if ($binaryfile->newBinaryFile(file_get_contents($f_data['tmp_name']), $img_data['mime'], $width, $height, 'log')) {
            if (!empty($binaryfile->id)) {
              $binaryfile_id=$binaryfile->id;
              $avatar->addAvatar($binaryfile->id, $profile_user_id);
            }
          }
          $msg->addMessage(1010, 'n', 0, '', $session->_s_room_id, 0, $profile_user_id);
        }
      break;

      case 'avatar_gallery_image': // New Avatar for Gallery
        if ($current_user->is_admin!=='y') {
          break;
        }
        // Check image data
        $img_data=null;
        switch (PCPIN_Image::checkImage($img_data,
                                        $f_data['tmp_name'],
                                        $session->_conf_all['avatar_image_types'],
                                        $session->_conf_all['avatar_max_width'],
                                        $session->_conf_all['avatar_max_height'],
                                        $session->_conf_all['avatar_max_filesize'],
                                        false)) {

          case  PCPIN_IMAGE_CHECK_OK: // Image OK
            $upload_status=array('code'=>0, 'message'=>$l->g('avatar_uploaded'));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_FILE: // File does not exists / not readable
            $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_MIME: // MIME not allowed
          case PCPIN_IMAGE_CHECK_ERROR_NOT_IMAGE: // File is not an image or has incompatible format
            $upload_status=array('code'=>200, 'message'=>$l->g('image_type_not_allowed'));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_WIDTH: // Image width larger than allowed
          case PCPIN_IMAGE_CHECK_ERROR_HEIGHT: // Image height larger than allowed
            $upload_status=array('code'=>300, 'message'=>str_replace('[WIDTH]', $session->_conf_all['avatar_max_width'], str_replace('[HEIGHT]', $session->_conf_all['avatar_max_height'], $l->g('image_too_large'))));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_FILESIZE: // Image file size larger than allowed
            $upload_status=array('code'=>400, 'message'=>str_replace('[SIZE]', $session->_conf_all['avatar_max_filesize'], $l->g('file_too_large')));
          break;

        }
        if ($upload_status['code']===0) {
          // Image OK
          $width=$img_data['width'];
          $height=$img_data['height'];
          _pcpin_loadClass('binaryfile'); $binaryfile=new PCPIN_BinaryFile($session);
          if ($binaryfile->newBinaryFile(file_get_contents($f_data['tmp_name']), $img_data['mime'], $width, $height, '')) {
            $binaryfile_id=$binaryfile->id;
            if (!empty($binaryfile->id)) {
              _pcpin_loadClass('tmpdata'); $tmpdata=new PCPIN_TmpData($session);
              $tmpdata->_db_deleteRowMultiCond(array('user_id'=>$current_user->id, 'type'=>4));
              $tmpdata->addRecord(4, $current_user->id, $binaryfile_id, $filename);
            }
          }
        }
      break;

      case 'language_file': // Language file
        if ($current_user->is_admin!=='y') {
          break;
        }
        $language_id=0;
        $l2=new PCPIN_Language($session);
        $import_status=$l2->importLanguage(file_get_contents($f_data['tmp_name']), $language_id);
        unset($l2);
        if ($import_status==0 && $language_id>0) {
          // Language imported
          $l->_db_getList('name,local_name', 'id = '.$language_id, 1);
          $upload_status=array('code'=>0, 'message'=>str_replace('[NAME]', $l->_db_list[0]['name'].' ('.$l->_db_list[0]['local_name'].')', $l->g('language_import_success')));
          $l->_db_freeList();
        } else {
          // Invalid language file
          switch ($import_status) {

            case 10 :
            default  :
              $upload_status=array('code'=>1000, 'message'=>$l->g('invalid_language_file'));
            break;

            case 100 :
              $l->_db_getList('name', 'id = '.$language_id, 1);
              $upload_status=array('code'=>1000, 'message'=>str_replace('[NAME]', $l->_db_list[0]['name'], $l->g('language_already_exists')));
              $l->_db_freeList();
            break;

          }
        }
      break;

      case 'msg_attachment': // Message attachment
        $msg_attachments_limit=$session->_conf_all['msg_attachments_limit'];
        if (empty($session->_s_room_id)) {
          // User is not in room
          $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
        } elseif (!file_exists($f_data['tmp_name']) || !is_file($f_data['tmp_name']) || !is_readable($f_data['tmp_name'])) {
          // File upload error
          $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
        } elseif (filesize($f_data['tmp_name'])>$session->_conf_all['msg_attachments_maxsize']*1024) {
          // File too large
          $upload_status=array('code'=>400, 'message'=>str_replace('[SIZE]', $session->_conf_all['msg_attachments_maxsize']*1024, $l->g('file_too_large')));
        } else {
          // Check attachments limit
          _pcpin_loadClass('tmpdata'); $tmpdata=new PCPIN_TmpData($session);
          $tmpdata->_db_getList('COUNT', 'type = 3', 'user_id = '.$session->_s_user_id);
          if ($tmpdata->_db_list_count>=$msg_attachments_limit) {
            // Max attachments limit reached
            $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
          } else {
            $upload_status=array('code'=>0, 'message'=>'OK');
          }
        }
        if ($upload_status['code']===0) {
          // Get MIME type
          $mime_type=$f_data['type']; // TODO: detect real MIME type
          _pcpin_loadClass('binaryfile'); $binaryfile=new PCPIN_BinaryFile($session);
          if ($binaryfile->newBinaryFile(file_get_contents($f_data['tmp_name']), $mime_type, 0, 0, 'room|'.$session->_s_room_id)) {
            $binaryfile_id=$binaryfile->id;
            if (!empty($binaryfile->id)) {
              _pcpin_loadClass('tmpdata'); $tmpdata=new PCPIN_TmpData($session);
              $tmpdata->addRecord(3, $current_user->id, $binaryfile_id, $filename);
            }
          }
        }
      break;

      case 'room_image': // New room image
        // Room image will be saved into tmpdata table
        // Check image data
        $img_data=null;
        switch (PCPIN_Image::checkImage($img_data,
                                        $f_data['tmp_name'],
                                        $session->_conf_all['room_img_image_types'],
                                        $session->_conf_all['room_img_max_width'],
                                        $session->_conf_all['room_img_max_height'],
                                        $session->_conf_all['room_img_max_filesize'],
                                        false)) {

          case  PCPIN_IMAGE_CHECK_OK: // Image OK
            $upload_status=array('code'=>0, 'message'=>'OK');
          break;

          case PCPIN_IMAGE_CHECK_ERROR_FILE: // File does not exists / not readable
            $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_MIME: // MIME not allowed
          case PCPIN_IMAGE_CHECK_ERROR_NOT_IMAGE: // File is not an image or has incompatible format
            $upload_status=array('code'=>200, 'message'=>$l->g('image_type_not_allowed'));
            break;

          case PCPIN_IMAGE_CHECK_ERROR_WIDTH: // Image width larger than allowed
          case PCPIN_IMAGE_CHECK_ERROR_HEIGHT: // Image height larger than allowed
            $upload_status=array('code'=>300, 'message'=>str_replace('[WIDTH]', $session->_conf_all['room_img_max_width'], str_replace('[HEIGHT]', $session->_conf_all['room_img_max_height'], $l->g('image_too_large'))));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_FILESIZE: // Image file size larger than allowed
            $upload_status=array('code'=>400, 'message'=>str_replace('[SIZE]', $session->_conf_all['room_img_max_filesize'], $l->g('file_too_large')));
          break;

        }
        if ($upload_status['code']===0) {
          // Image OK
          $width=$img_data['width'];
          $height=$img_data['height'];
          _pcpin_loadClass('binaryfile'); $binaryfile=new PCPIN_BinaryFile($session);
          if ($binaryfile->newBinaryFile(file_get_contents($f_data['tmp_name']), $img_data['mime'], $width, $height, 'log')) {
            $binaryfile_id=$binaryfile->id;
            if (!empty($binaryfile->id)) {
              _pcpin_loadClass('tmpdata'); $tmpdata=new PCPIN_TmpData($session);
              $tmpdata->deleteUserRecords($current_user->id, 1);
              $tmpdata->addRecord(1, $current_user->id, $binaryfile_id, $filename);
            }
          }
        }
      break;

      case 'smilie_image': // New smilie image
        if ($current_user->is_admin!=='y') {
          break;
        }
        // Smilie image will be saved into tmpdata table
        // Check image data
        $img_data=null;
        switch (PCPIN_Image::checkImage($img_data,
                                        $f_data['tmp_name'],
                                        '',
                                        0,
                                        0,
                                        0,
                                        false)) {

          case  PCPIN_IMAGE_CHECK_OK: // Image OK
            $upload_status=array('code'=>0, 'message'=>'OK');
          break;

          case PCPIN_IMAGE_CHECK_ERROR_FILE: // File does not exists / not readable
            $upload_status=array('code'=>100, 'message'=>$l->g('file_upload_error'));
          break;

          case PCPIN_IMAGE_CHECK_ERROR_MIME: // MIME not allowed
          case PCPIN_IMAGE_CHECK_ERROR_NOT_IMAGE: // File is not an image or has incompatible format
            $upload_status=array('code'=>200, 'message'=>$l->g('image_type_not_allowed'));
          break;

        }
        if ($upload_status['code']===0) {
          // Image OK
          $width=$img_data['width'];
          $height=$img_data['height'];
          _pcpin_loadClass('binaryfile'); $binaryfile=new PCPIN_BinaryFile($session);
          if ($binaryfile->newBinaryFile(file_get_contents($f_data['tmp_name']), $img_data['mime'], $width, $height, '')) {
            $binaryfile_id=$binaryfile->id;
            if (!empty($binaryfile->id)) {
              _pcpin_loadClass('tmpdata'); $tmpdata=new PCPIN_TmpData($session);
              $tmpdata->_db_deleteRowMultiCond(array('user_id'=>$current_user->id, 'type'=>2));
              $tmpdata->addRecord(2, $current_user->id, $binaryfile_id, $filename);
            }
          }
        }
      break;

    }
  }
}

_pcpin_loadClass('pcpintpl'); $tpl=new PcpinTpl();
$tpl->setBasedir('./tpl');
$tpl->readTemplatesFromFile('./file_upload.tpl');

// JS files
$_js_files[]='./js/file_upload.js';

if (!empty($upload_status)) {
  $message=str_replace('\'', '\\\'', htmlspecialchars($upload_status['message']));
  $message=str_replace("\n", '\\n', str_replace("\r", '\\r', $message));
  $_body_onload[]='parseUploadResponse('.$upload_status['code'].', \''.$message.'\', '.$binaryfile_id.', '.$width.', '.$height.', \''.str_replace('\'', '\\\'', $filename).'\')';
} else {
  $_body_onload[]='initUploadForm(\''.$f_target.'\')';
}

// Add global vars to template
foreach ($global_tpl_vars as $key=>$val) {
  $tpl->addGlobalVar($key, htmlspecialchars($val));
}

// Add language expressions to template
foreach ($tpl->tpl_vars_plain as $var) {
  if (0===strpos($var, 'LNG_')) {
    $var=strtolower($var);
    $tpl->addGlobalVar($var, htmlspecialchars($l->g(substr($var, 4))));
  }
}

$tpl->addVar('main', 'profile_user_id', htmlspecialchars($profile_user_id));
?>

Hi,

In PHP if you want to delete a file you can use the unlink function.

$file = 'path_to/test_file.txt';
unlink( $file );

Of course there might be permission issues with certain system files ???

Hope it helps

Hi,

In PHP if you want to delete a file you can use the unlink function.

$file = 'path_to/test_file.txt';
unlink( $file );

Of course there might be permission issues with certain system files ???

Hope it helps

actually sir, I used your code for virus scanning but i don't have any defination filewhich mentioned in your code. So can you send me that file . my email id is <EMAIL SNIPPED>

thanks in advance.

actually sir, I used your code for virus scanning but i don't have any defination filewhich mentioned in your code. So can you send me that file . my email id is <EMAIL SNIPPED>

thanks in advance.

I did not write the PHP Virus scan, that would be this guy: chaom79

I'm just trying to help if I can, but would be very interested in how well it works and what kind of virus activity it detects and handles ???

I did not write the PHP Virus scan, that would be this guy: chaom79

I'm just trying to help if I can, but would be very interested in how well it works and what kind of virus activity it detects and handles ???

this code is work if you have a virus defination file with it and dynamically pass the folder name which you want to scan at running time.

Thats why i am asking if someone have virus defination file then plz post here so we can check the code is working or not.

This article has been dead for over six months. Start a new discussion instead.