Beispiel #1
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            //Read configs
            int checkInterval = Int32.Parse(_conf.GetSection("SignService")["CheckIntervalSeconds"]);

            _l.Debug($"Signing Service started; will check for new entries each {checkInterval} seconds.");

            while (!stoppingToken.IsCancellationRequested)
            {
                var signItems = _asvc.getItemsToBeSigned();
                foreach (var ac in signItems)
                {
                    _l.Debug($"Fetched item {ac.UniqueKey} for signing.");
                    ac.Status  = ApiActivity.ApiStatus.Signing;
                    ac.Message = "Signing..";
                    _asvc.addUpdateApiActivity(ac);
                    if (signFile(ac))
                    {
                        ac.Status = ApiActivity.ApiStatus.Ready;
                        // ac.Message already filled by output parser
                        _asvc.addUpdateApiActivity(ac);
                        _l.Information(ac.ToString());
                    }
                    else
                    {
                        // ac.Message Error already filled by output parser
                        ac.Status = ApiActivity.ApiStatus.Error;
                        _asvc.addUpdateApiActivity(ac);
                        _l.Error(ac.ToString());
                    }
                }



                await Task.Delay(1000 *checkInterval, stoppingToken);
            }
        }
Beispiel #2
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            //Read configs
            var strCheckInterval = _conf.GetValue <string>("AnalyseService:CheckIntervalSeconds");

            _l.Information($"chekinterval {strCheckInterval}");
            int checkInterval = 15;

            try
            {
                checkInterval = System.Int32.Parse(strCheckInterval);
            }
            catch (Exception e)
            {
                _l.Error(e.Message);
            }

            // Read secrets
            JObject secretsConfig = JObject.Parse(File.ReadAllText(@"secrets.json")); //secrets.json file not checked in. .gitignore
            var     vtApiKey      = (string)secretsConfig["ApiKeys"]["VirusTotal"];

            // Init analyserPlugins
            VirusTotal vt = new VirusTotal(vtApiKey);

            vt.UseTLS = true;



            _l.Debug($"Analyse Service started; will check for new entries each {checkInterval} seconds.");

            while (!stoppingToken.IsCancellationRequested)
            {
                var analyseItems = _asvc.getItemsToBeAnalysed();
                foreach (var ac in analyseItems)
                {
                    _l.Debug($"Fetched item {ac.UniqueKey} for analysing.");
                    ac.Status  = ApiActivity.ApiStatus.Analysing;
                    ac.Message = "Analysing";
                    _asvc.addUpdateApiActivity(ac);
                    //prepare filestream
                    using (Stream fs = File.OpenRead(ac.SystemOfficeFilename))
                    {
                        // new Analyser Service start e.g. VirusTotal
                        ac.Message = $"Checking Virustotal for known file {ac.UserOfficeFilename}. This can take up to 5 Min...";
                        _asvc.addUpdateApiActivity(ac);
                        _l.Information(ac.Message);

                        // first check if file already known to VT
                        var fileReport = await vt.GetFileReportAsync(fs);

                        _l.Information($"File Report requested for Resource {fileReport.Resource}");


                        if (fileReport.ResponseCode == VirusTotalNet.ResponseCodes.FileReportResponseCode.Queued)
                        {
                            // file already submitted but still scanned -> not scanning again
                            _l.Information($"File {ac.UserOfficeFilename} already submitted. Not scanning again. Resetting result to {ApiActivity.ApiStatus.QueuedAnalysis}");
                            ac.Status = ApiActivity.ApiStatus.QueuedAnalysis;
                            _asvc.addUpdateApiActivity(ac);
                        }



                        if (fileReport.ResponseCode == VirusTotalNet.ResponseCodes.FileReportResponseCode.NotPresent)
                        {
                            ScanResult scanResult = null;
                            // reset stream, otherwise it's posted from last position :(
                            fs.Seek(0, SeekOrigin.Begin);
                            //not known to VT -> start new scan
                            ac.Message = "File not know to VT yet. Starting Scan...";
                            _asvc.addUpdateApiActivity(ac);
                            _l.Information(ac.Message);
                            scanResult = await vt.ScanFileAsync(fs, ac.SystemOfficeFilename);

                            if (scanResult.ResponseCode == VirusTotalNet.ResponseCodes.ScanFileResponseCode.Queued)
                            {
                                // set to result queued to be picked up by loop next time; then Results should be already known
                                // and can be retrieved.
                                ac.Message = $"File Queued for Analysis in VirusTotal with ScanID {scanResult.ScanId}.";
                                ac.Status  = ApiActivity.ApiStatus.QueuedAnalysis;
                                _asvc.addUpdateApiActivity(ac);
                                _l.Information(ac.Message + $"Resetting result to {ApiActivity.ApiStatus.QueuedAnalysis}");
                            }
                        }
                        if (fileReport.ResponseCode == VirusTotalNet.ResponseCodes.FileReportResponseCode.Present)
                        {
                            //Filereport here, check
                            _l.Information($"Filereport retrieved successfully. Checking if file file clean..");

                            // how many positives are OK?
                            int maxPositives = Int32.Parse(_conf["AnalyseService:SecurityPlugins:Virustotal:MaxPositives"]);

                            if (fileReport.Positives < maxPositives)
                            {
                                //file clean
                                ac.Message = $"File scanned by VT: File has {fileReport.Positives} of max {maxPositives} Positives. File clean! Queued for Signing";
                                ac.Status  = ApiActivity.ApiStatus.QueuedSigning; //send to signing service
                                _asvc.addUpdateApiActivity(ac);
                                _l.Information(ac.Message);
                            }
                            else
                            {
                                //file infected
                                ac.Message = $"File scanned by VT: File has {fileReport.Positives} of max {maxPositives} Positives. File infected!! Cancel Signing";
                                ac.Status  = ApiActivity.ApiStatus.Error;
                                _asvc.addUpdateApiActivity(ac);
                                _l.Warning(ac.Message);
                            }
                        }
                    }
                }



                await Task.Delay(1000 *checkInterval, stoppingToken);
            }
        }
Beispiel #3
0
        public IActionResult CheckOfficeFile(IFormFile officeFile)
        {
            ApiActivity ac = new ApiActivity();

            ac.ClientIPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
            ac.Operation       = ApiActivity.ApiOperation.Verify;
            ac.Message         = $"Check Office File started";
            ac.Status          = ApiActivity.ApiStatus.Verifying;
            ac.StatusUrl       = GHelper.generateUrl(GHelper.UrlType.StatusUrl, ac, _httpctx);
            ac.DownloadUrl     = GHelper.generateUrl(GHelper.UrlType.DownloadUrl, ac, _httpctx);
            _asvc.addUpdateApiActivity(ac);


            if (officeFile != null)
            {
                ac.UserOfficeFilename = officeFile.FileName;
                //check valid file extension
                _l.Debug("Checking for valid file extensions...");
                string officeFileExt = Path.GetExtension(officeFile.FileName.ToLowerInvariant());
                if (!GHelper.fileHasAllowedExtension(GHelper.ExtensionType.OfficeFile, officeFileExt))
                {
                    ac.Message = $"Office File extension {officeFileExt} not valid!";
                    ac.Status  = ApiActivity.ApiStatus.Error;
                    _asvc.addUpdateApiActivity(ac);
                    _l.Error(ac.Message);
                    return(Content(ac.getWebresult()));
                }


                // check magic number file types
                _l.Debug("Checking for magic number of file...");
                if (!(GHelper.fileHasValidFormat(GHelper.ExtensionType.OfficeFile, officeFile.OpenReadStream())))
                {
                    ac.Message = $"Office File {officeFile.FileName} not a valid office file!";
                    ac.Status  = ApiActivity.ApiStatus.Error;
                    _asvc.addUpdateApiActivity(ac);
                    _l.Error(ac.Message);
                    return(Content(ac.getWebresult()));
                }

                //save office file
                string uniFilenameOfficeFile    = GHelper.createUniqueFileName(officeFile.FileName);
                string systemFolderOfficeFile   = GHelper.getOfficeFilesSystemDir(_webHostEnv, _conf);
                string systemFileNameOfficeFile = Path.Combine(systemFolderOfficeFile, uniFilenameOfficeFile);
                ac.SystemOfficeFilename = systemFileNameOfficeFile;

                // create dir if not exist
                System.IO.Directory.CreateDirectory(systemFolderOfficeFile);
                _l.Debug($"Saving file to {systemFileNameOfficeFile}");
                using (var fileStream = new FileStream(systemFileNameOfficeFile, FileMode.Create))
                {
                    officeFile.CopyTo(fileStream);
                }



                //verify file


                // prepare run
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = _webHostEnv.ContentRootPath + @"\lib\signtool.exe";
                psi.RedirectStandardError  = true;
                psi.RedirectStandardOutput = true;
                psi.UseShellExecute        = false;
                //use quoted filename otherwise systempath is revealed in error message!!
                psi.Arguments = $"verify /pa /debug /v \"{systemFileNameOfficeFile}\"";
                _l.Debug($"Executing {psi.FileName} {psi.Arguments}...");

                // execute run
                StringBuilder stdOut = new StringBuilder();
                StringBuilder stdErr = new StringBuilder();
                Process       p      = new Process();
                p.StartInfo = psi;
                p.Start();

                while (!p.StandardOutput.EndOfStream)
                {
                    stdOut.AppendLine(p.StandardOutput.ReadLine());
                }
                while (!p.StandardError.EndOfStream)
                {
                    stdErr.AppendLine(p.StandardError.ReadLine());
                }
                p.WaitForExit();
                _l.Debug("Process exited. Parsing...");

                // parse result
                ac = SignToolOutputParser.parseSignToolOutput(SignToolOutputParser.SignToolOperation.Verify, ac, stdOut.ToString(), stdErr.ToString());
                _l.Debug($"Parsed result = {ac.ToString()}");
                _l.Debug($"Deleting file {systemFileNameOfficeFile}");
                // delete after verify
                System.IO.File.Delete(Path.Combine(systemFileNameOfficeFile));


                _asvc.addUpdateApiActivity(ac);

                return(Content(ac.getWebresult()));
            }
            else
            {
                var message = ("No Files submitted for Verifying!");
                _l.Warning(message);
                ac.Operation = ApiActivity.ApiOperation.Verify;
                ac.Status    = ApiActivity.ApiStatus.Error;
                ac.Message   = message;
                return(Content(ac.getWebresult()));
            }
        }