7

I am trying to run an antivirus scan on an uploaded file in an ASP.Net web app. We are using Sophos so have access to their command line API sav32cli. In the code I use:

Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = @"-remove -nc " + SavedFile;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;

When stepping through the code, when attached to the w3wp process on dev server, the code just jumps from one line to the next seemingly doing nothing at all. When running from code on dev server, it performs as expected scanning file and deleting if it is seen as a virus.

The server is running IIS 8.0, and the app built in .Net Framework 4. I have changed the machine config to allow the process to run as SYSTEM account, in accordance to these instructions. https://support.microsoft.com/en-us/kb/317012#%2Fen-us%2Fkb%2F317012

<processModel  userName="SYSTEM" password="AutoGenerate" />

Is there something I'm missing? What is the best practice for this kind of implementation?

EDIT: When called, the Process returns an ExitCode of 2 (Error stopped execution), rather than the expected 0 (Scan worked, no viruses), or 3 (Scan worked, viruses found).

EDIT 2: As per comment below I changed the code to:

Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = @"-remove -nc " + SavedFile;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
StringBuilder output = new StringBuilder();

while (!proc.StandardOutput.EndOfStream)
{
    string line = proc.StandardOutput.ReadLine();
    output.AppendLine(line);
}
proc.WaitForExit();

int exitCode = proc.ExitCode;
ASPxMemo2.Text = exitCode.ToString() + Environment.NewLine + output.ToString();

output is always empty when run over IIS, but is populated correctly when running from code.

EDIT 3: Instead of looking at StandardOutput we looked at StandardError and it revealed this error:

Error initialising detection engine [0xa0040200] (Possible insufficient user Admin rights.)

For the time being we are going to move to another method of virus checking, but would still like to know a possible solution if anyone has it.

anothershrubery
  • 20,461
  • 14
  • 53
  • 98
  • 1
    _"the Process returns an ExitCode"_ - just [read the process's output](http://stackoverflow.com/questions/4291912/process-start-how-to-get-the-output)... – CodeCaster Oct 30 '15 at 14:31
  • The Process's output is blank when run via IIS, but is populated correctly when run from local code. – anothershrubery Oct 30 '15 at 16:12
  • 2
    The IIS user that you set will also need Admin rights to Sophos path. I'd recommend not using any of the IIS built in users and have a sysadmin create a service account which can be used for this task – Ian Oct 30 '15 at 17:02
  • First question: Is sophos supported in a service environment at all. Do they support this config? Anyway, you could write a small custom gateway Windows service running with sufficient rights that would work with this sophos exe. You could then communicate with this service from IIS using easier methods such as HTTP/REST/WCF/Remoting, etc. so w/o needing special rights between IIS and this service. – Simon Mourier Oct 30 '15 at 18:05
  • 1
    typically such kind of error can be solved by usage [Process Monitor](https://technet.microsoft.com/en-us/sysinternals/bb896645). It can trace all file/registry/process/network activity of `sav32cli.exe` process which you start. You will see which requests failed. Could you creates the traces? – Oleg Oct 30 '15 at 21:13
  • I was just about to add a comment to advice using the procmon.exe (process monitor from sysinternals) and seen Oleg's and upvoted. procmon.exe is a life saver when we face complex problems during app setups or third party library operations. Use it, and apply the filters: "process name is sav32cli.exe" and "result is not SUCCESS" and double click on the event reporting the failure and it will give you who the user is and what the path he is trying to access. – Oguz Ozgul Nov 01 '15 at 22:23
  • You can interactively debug, (and monitor with process tools) the whole issue _if_ you log in and run VS with a user which have the same permissions as your configured IIS / ASP.NET user. – g.pickardou Nov 05 '15 at 08:16

4 Answers4

1

You will need to make sure that the application pool that is running your .NET application inside IIS has execute permissions to your file

"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe"

You may also need to add this permission to the folder location where the file to be scanned is uploaded (c:\temp) for example

You may also need to have administrator privileges to run the anti virus scan since IIS8 does not run as an administrator. When you are debugging visual studio uses your current logged in windows user(unless you use runas) so this will explain why it would work when debugging.

Mallek
  • 122
  • 5
  • No - If it couldn't execute the process he wouldn't be getting error codes specific to that process. – nothingisnecessary Nov 05 '15 at 21:08
  • My answer is speaking of the actual scanning process and making sure the application when launched has enough permissions to complete the scan. If the anti virus did not have the permissions I would expect the return Error stopped execution from the antivirus application. The execute permission part is to clarify and help answer "What is the best practice for this kind of implementation?" – Mallek Nov 06 '15 at 15:08
0

Have you tried running your web process in elevated trust?

Configuring .NET Trust Levels in IIS 7

<system.web>
  <securityPolicy>
    <trustLevel name="Full" policyFile="internal"/>
  </securityPolicy>
</system.web>

ASP.NET Trust Levels and Policy Files

TombMedia
  • 1,962
  • 2
  • 22
  • 27
0

Most likely the permissions are not configured correctly on the content being scanned (the uploads folder) or the worker process user doesn't have the full permissions it needs to use Sophos. You know the executable itself is accessible by the worker process because you are getting exit codes and error messages that are specific to Sophos.

Because your process will delete files that are perceived as threats you need to grant the user running the process modify or full control permissions on the folders that store the uploaded files.

By default you could use the IIS_IUSRS group for ApplicationPoolIdentity processes, but you can verify (and modify) the user in IIS Manager > App Pools > Advanced.

This answer has more details

Community
  • 1
  • 1
nothingisnecessary
  • 6,099
  • 36
  • 60
0

Here are some ideas:

  1. Create the process using a different user with elevated privileges on the folder, see for reference start-a-net-process-as-a-different-user
  2. If the previous suggestion fails, login one time on the server using the credentials used in point 1. It will configure registry entries connected to the user profile, some programs requires it.
  3. Develop a simple .net service running on the server and monitoring the upload folder. The service has more probability running the Sophos scan succesfully. Here is a reference on service creation using .net.
  4. The service may also talk to your web page using DB/file system/ etc.. so the operation may seem synchronous.

These are my 4 cents :-)

Community
  • 1
  • 1
Matteo Conta
  • 1,423
  • 13
  • 17