...

View Full Version : PHP Scanning Uploaded Files For Viruses



Coyote6
02-02-2010, 06:20 PM
Hi I am trying to find out how to scan my uploaded files for viruses. I have been searching for a bit and the only posts I have found are like 2007 posts that say to use clamav. The only problem is that is hadn't been updated for a while back in 2007 and now the website is some car loan page. I managed to find the files but noticed it is a UNIX file which would work at home but not at work where I'm using IIS running PHP. And what worries me is that it seems this php-clamavlib project is dead and not being updated. So is there a new one to use? Or how else would I do it? Thanks for any help.

angst
02-02-2010, 06:38 PM
you'll need to find a command line based virus scanner, then trigger it when a file has been uploaded. try a google search for "windows command line virus scanner"

http://www.google.ca/search?rlz=1C1CHNB_enCA329CA330&sourceid=chrome&ie=UTF-8&q=windows+command+line+virus+scanner

Coyote6
02-02-2010, 06:43 PM
Thanks... I will check with the guys in the IT to make sure which version of AV we are running here... So would you recommend doing the same for a UNIX system or something different.

angst
02-02-2010, 06:45 PM
it would be the same logic on any system. though as always, *nix systems likely make it run a little more smoothly. I don't have much experience executing command line programs on windowz/iis. but it should work.

Coyote6
02-02-2010, 06:52 PM
*nix systems likely make it run a little more smoothly.

That make's me smile...hahaha :D Yea, It takes about 3 to 4 times as long to write for windows and MsSQL as it does with a Unix/Linux system with MySQL. And then it never runs 100% as well as it should. :rolleyes: Thanks for the help.

angst
02-02-2010, 06:56 PM
lol,, yes.
good luck and please post back with your results. would be interesting to see how well it works.

thanks!

MattF
02-02-2010, 07:07 PM
And what worries me is that it seems this php-clamavlib project is dead and not being updated.

Try reading the actual ClamAV site. There are multiple ways you could scan with it.

http://www.clamav.net/

Coyote6
02-02-2010, 07:22 PM
Try reading the actual ClamAV site. There are multiple ways you could scan with it.

http://www.clamav.net/
I tried to read some of it but got kind of lost and wondered if it was the best way...

angst
02-02-2010, 07:25 PM
seems like a good option for *nix.

MattF
02-02-2010, 07:32 PM
and wondered if it was the best way...

I would say so. You could use either exec() and call clamscan from the script to scan the file(s), or connect via a TCP/unix socket and scan it directly.

MattF
02-02-2010, 07:37 PM
Info regarding sockets:

http://www.clamav.net/doc/latest/html/node26.html

Should be simple enough to connect and scan that way using fsockopen and such. There'll also be far less overhead doing it this way. Clamscan, (unlike clamdscan, which requires permissions on the files to be the Clam user or group, but can't remember which offhand), has to load the sig files each time it's called.

Coyote6
02-02-2010, 10:14 PM
Okay so I found a nice GUI interface to download ClamAV on my mac.

http://www.clamxav.com/index.php?page=dl

Pretty darn simple....

Next I downloaded the anti virus test file.

http://www.eicar.org/download/eicar.com.txt

Checked it and the scan worked. Came back saying it was a virus.

Now for the code... I'm not too knowledgeable with command line so hopefully you can help me out. Here is the code I am just testing. But it keeps coming back a virus even though I know the file is not... Do I have the wrong command line path or something.


$file = 'banner_6.jpg';
$dir = $path . 'Images/Common/';
$file_path = realpath ($dir . $file);
if (is_file($file_path)){
$safe_path = escapeshellarg($file_path);
$command = '/usr/bin/clamscan --stdout ' . $safe_path;
$out = '';
$int = -1;
exec($command, $out, $int);

if ($int == 0) {
$test = 'File is clean.';
}
// File is a virus.
else {
$test = 'File is a virus';
}
}
else {
$test = 'Not a file.';
}
echo $test;

Coyote6
02-02-2010, 10:25 PM
Put it in the wrong location.


$command = '/usr/local/clamXav/bin/clamscan --stdout ' . $safe_path;


Okay now that that is working... Matt you mentioned that you could call 'clamscan from the script to scan the file(s)'; Is this what you meant or something else cause this uses the exec command.

MattF
02-03-2010, 02:45 AM
That's what I meant. :) Clamscan scans with the privileges of the user calling it, so that's the one you want for exec. As I say though, that won't be the best option if the server is quite busy/loaded. Connecting directly to clamd via a socket would be preferable under those circumstances.

Coyote6
02-03-2010, 04:51 AM
Ya it runs kind of slow, so I will look into the socket in the morning. Thanks for the help guys.

Coyote6
02-03-2010, 07:59 PM
Okay I've been looking into sockets all morning... I learned how to check how many messages I have in my email account by using a pop server and a socket :D but I do not know how to open a socket for clamscan.

I also found a class for clamd that works with cakePHP...
http://www.jejik.com/articles/2009/07/scanning_files_with_clamav_from_cakephp/
http://svn.jejik.com/viewvc.cgi/cakephp/plugins/clamd/trunk/clamd.php?view=log
but that didn't help much on figuring out how to get the correct host info and anything past fsockopen...

I keep getting a unable to connect message... Stupid inexperience with sockets... ggrrrrrr... :mad: hehehehe

Does any one know an example of directly connecting to clamav using a socket without a class? Thanks.

Coyote6
02-04-2010, 04:09 AM
Okay so here is my conclusion after dealing with this for two days. I can't figure out how to go through sockets to connect to ClamAV but I moved the scan to next step and placed all of the files into a temp directory then scanned all of the files at once from there.



// Set the allowed types for reading and upload.
$types = array ('jpg', 'jpeg', 'txt');

// Start a variable.
$dir_files = array();

// If it is a directory add all the files.
if (is_dir ($dir)) {
// Open the directory.
if ($handle = opendir($dir)) {
// Read the file names of all the files available.
while (false !== ($file = readdir($handle))) {
// Make sure the file is not this directory or its parent and not the .DS_Store file.
if ($file != "." && $file != ".." && $file != '.DS_Store') {
// Get the file parts.
$file_parts = pathinfo($file);
// Make sure the extension is allowed.
if (in_array(strtolower ($file_parts['extension']),$types)) {
// Add the file to the array.
$dir_files[] = array ('original_name'=>$file, 'type'=>$file_parts['extension']);
}
}
}
// Close the handle.
closedir ($handle);
}
}

// If any files exist in the upload directory check them for viruses.
if (count ($dir_files) > 0) {
// Get the dir and prepare it for the command line.
$real_path = realpath ($dir);
$safe_path = escapeshellarg($real_path);
// Set the variables for the cmd.
$return = -1;
$out ='';
$cmd = '/usr/local/clamXav/bin/clamscan ' . $safe_path;
// Execute the cmd.
exec ($cmd, $out, $return);
// If a virus is found loop through each of the files and delete the virus, write the user a message, and add them to a db table.
if ($return != 0) {
// Loop through the files.
foreach ($dir_files as $k=>$v) {
// Get the dir and prepare it for the command line.
$real_path = realpath ($dir . $v['original_name']);
$safe_path = escapeshellarg($real_path);
// Reset the values.
$return = -1;
$out ='';
$cmd = '/usr/local/clamXav/bin/clamscan ' . $safe_path;
// Execute the command.
exec ($cmd, $out, $return);
// If the file is clean do nothing.
if ($return == 0){}
// If the file contains a virus remove it and add a note to the db.
else if ($return == 1) {
// Delete the file.
unlink ($dir . $v['original_name']);
// Unset the file from the records.
unset ($dir_files[$k]);
// Notify the user.
$message .= "The file {$v['original_name']} contained a known virus. It has been deleted from the server.<br />";
$message_class = 'error';
// Add the user who uploaded the file to the db and a time and date.
// Query the db to record who uploaded the file, not necessary but fun info to have.
}
else {
// Delete the file.
unlink ($dir . $v['original_name']);
// Unset the file from the records.
unset ($dir_files[$k]);
// Notify the user.
$message .= "The file {$v['original_name']} caused an unknown error and was removed from the server.<br />";
$message_class = 'minor_error';
}
}
}
}


Thanks for everyone who helped me with this.

MattF
02-04-2010, 05:35 PM
Are you trying to connect to Clam via a TCP socket, perchance? They are not enabled by default in the clamd.conf file. Defaults to unix sockets, if I recall.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum