C# trigger antivirus to scan uploaded file

3.6k views Asked by At

I have a webapp where users can upload documents (pdf, jpeg, png, tiff, docx, etc.). The uploaded files are stored on SQL Server database within a VARBINARY(MAX) column. The webapp runs on a Windows Server 2016 server secured with McAfee Endpoint Security.

A security vulnerability has been noted where the uploaded files are not scanned by an antivirus for malicious content before being uploaded and stored server side.

In an attempt to mitigate this I have written the following code prior to the file being inserted to the database.

public byte[] WriteToSystemAndReadBack(string path, byte[] contents)
{
    try
    {
        // Write to file system
        Log.DebugFormat("Writing byte array to file system at path: {0}", path);
        File.WriteAllBytes(path, contents);
        Log.DebugFormat("Byte array successfully written at path: {0}. Thread sleeping for 5 seconds", path);

        // Wait
        Thread.Sleep(5000);

        // Read from file system
        Log.DebugFormat("Reading file from file system at path: {0}", path);
        byte[] fileReadFromFileSystem;

        using (var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            var buffer = new byte[s.Length];

            s.Read(buffer, 0, (int)s.Length);

            fileReadFromFileSystem = buffer;
        }
        Log.Debug("Successfully read file from file system at path: " + path);

        // Delete after to clean up
        var fileInfo = new FileInfo(path);
        fileInfo.Delete();

        return fileReadFromFileSystem;
    }
    catch (Exception ex)
    {
        Log.ErrorFormat("Potentially malicious file found at: {0}", path);
        Log.Error("An error has occurred while writing/reading file on the file system", ex);
        return null;
    }
}

The objective here is to write the file to the filesystem on the server and in the case of a malicious file it will be immediately quarantined by the Antivirus.

The behaviour I'm seeing is that a benign malicious file (EICAR) is not being quarantined in the duration when it is written to the filesystem on the server. However it is quarantined when I right click on the file in the duration before it is deleted. It behaves as if the file is fine until it is invoked in some way or shape.

I can consistently get the file to be quaratined by executing it using the following code:

var ps = Process.Start(path);
ps.Kill();

However I feel like this is a poor solution as it will use system resources for every uploaded file.

Any help would be appreciated.

  • Is there a mechanism to get the system Antivirus to trigger a scan on the uploaded file?
  • For McAfee specifically is there a command line based invocation that can be done to trigger a virus scan? McAfee has a right click context menu option for "Scan for threats" but I don't see how to invoke that from the command line.
1

There are 1 answers

1
Farrukh Saleem Sheikh On

you can use the free .NET Antivirus to scan files. please follow the blogpost to implement the Antivirus in .NET C#

https://farrukhsaleemsheikh.blogspot.com/2022/05/free-net-antivirus-to-scan-files.html

nClam nClam is a tiny library which helps you scan files or directories using a ClamAV server. It contains a simple API which encapsulates the communication with the ClamAV server as well as the parsing of its results. The library is licensed under the Apache License 2.0.

Dependencies ClamAV Server, also known as clamd. It is a free, open-source virus scanner. Win32 ports can be obtained here: http://oss.netfarm.it/clamav/ NuGet Package Install-Package nClam Directions Add the nuget package to your project. Create a nClam.ClamClient object, passing it the hostname (or IP address) and port of the ClamAV server. Scan! Code Example

using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using nClam;

class Program
{
    static async Task Main(string[] args)
    {
        var clam = new ClamClient("localhost", 3310);
        // or var clam = new ClamClient(IPAddress.Parse("127.0.0.1"), 3310);
        var scanResult = await clam.ScanFileOnServerAsync("C:\\test.txt");  //any file you would like!

        switch (scanResult.Result)
        {
            case ClamScanResults.Clean:
                Console.WriteLine("The file is clean!");
                break;
            case ClamScanResults.VirusDetected:
                Console.WriteLine("Virus Found!");
                Console.WriteLine("Virus name: {0}", scanResult.InfectedFiles.First().VirusName);
                break;
            case ClamScanResults.Error:
                Console.WriteLine("Woah an error occured! Error: {0}", scanResult.RawResult);
                break;
        }
        
    }
}

ClamAV Setup for Windows For directions on setting up ClamAV as a Windows Service, check out this blog post.

Test Application For more information about how to use nClam, you can look at the nClam.ConsoleTest project's Program.cs.