Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically running ClamAV's clamscan on file uploads with PHP

Stack,

I want to scan each file that gets uploaded via my php upload script with clam anti-virus's clamscan tool. I think I've got a good script written but I wanted to run it past you guys.

So assuming that the file I'm sending to this php upload script is named "uploadedfile" does the following code make sense?

<?php

$safe_path = escapeshellarg('/tmp/' . $_FILES['uploadedfile']['tmp_name']);
$command = 'clamscan ' . $safe_path;
$out = '';
$int = -1;
exec($command, $out, $int);

if ($int == 0) {
   // all good, code goes here uploads file as normal IE move to
permanent directory etc;
} else {
   unlink('/tmp/' . $_FILES['uploadedfile']['tmp_name']);
header(Location: http://www.domain.com/uploadform.php?error=your-file-was-infected-pal);
}

?>

Also, will clamscan find php shells as well as traditional good old malware?

Thanks!

Update - found the answer

I answered my own question but don't have the reputation to officially do so. Here is the anser:

For those who come after. I've tested this script using the EICAR test virus file http://eicar.org/86-0-Intended-use.html and after a few tweaks it works. The return variable $int is what tells you whether or not the file is safe or not. If $int is 0, no virus was found, if $int is 1, a virus was found. However, there are some changes that I had to make the script work (I updated the $safe_path variable to be correct), here is the working script:

<?php

$safe_path = escapeshellarg($_FILES['uploadedfile']['tmp_name']);
$command = 'clamscan ' . $safe_path;
$out = '';
$int = -1;
exec($command, $out, $int);

if ($int == 0) {
   // all good, code goes here uploads file as normal IE move to
permanent directory etc;
} else {
  //whatever you need to do if a virus is found.
}

?>
like image 295
billmalarky Avatar asked Oct 04 '11 13:10

billmalarky


3 Answers

I had a lot of trouble with permissions when trying to run this with clamdscan. I found a solution for the permissions problem here: https://wiki.archlinux.org/index.php/ClamAV

This changed this line:

$command = 'clamscan ' . $safe_path;

to:

$command = 'clamdscan  --fdpass ' . $safe_path;

Seemed to successfully pass a good file and flag an EICAR file.

like image 55
Chrono Avatar answered Nov 11 '22 13:11

Chrono


Note that if your server runs a clamav daemon (clamd) it may be possible to use clamdscan instead of clamscan as proposed, this usage is faster since use virus signatures already loaded by clamd.

like image 32
acesso Avatar answered Nov 11 '22 13:11

acesso


Just be careful. If your clamscan becomes outdated you'll get feedback in the output:

It will look like this:

LibClamAV Warning: ***********************************************************
LibClamAV Warning: ***  This version of the ClamAV engine is outdated.     ***
LibClamAV Warning: *** DON'T PANIC! Read http://www.clamav.net/support/faq ***
LibClamAV Warning: ***********************************************************

Also depending on the version of clamscan the "result" might look like this (and you'll need to parse it accordingly):

[filename]: OK

----------- SCAN SUMMARY -----------
Known viruses: x
Engine version: x.x.x
Scanned directories: 0
Scanned files: 1
Infected files: 0
Data scanned: x.xx MB
Data read: x.xx MB (ratio 0.00:1)
Time: x.xx sec (0 m x s)
like image 21
Tom Avatar answered Nov 11 '22 12:11

Tom