Example #1
0
        public static void ScanUploads(Config config, TeknikEntities db)
        {
            Output(string.Format("[{0}] Started Virus Scan.", DateTime.Now));
            List<Upload> uploads = db.Uploads.ToList();

            // Initialize ClamAV
            ClamClient clam = new ClamClient(config.UploadConfig.ClamServer, config.UploadConfig.ClamPort);
            clam.MaxStreamSize = config.UploadConfig.MaxUploadSize;

            int totalCount = uploads.Count();
            int totalScans = 0;
            int totalClean = 0;
            int totalViruses = 0;
            foreach (Upload upload in uploads)
            {
                totalScans++;
                string subDir = upload.FileName[0].ToString();
                string filePath = Path.Combine(config.UploadConfig.UploadDirectory, subDir, upload.FileName);
                if (File.Exists(filePath))
                {
                    // Read in the file
                    byte[] data = File.ReadAllBytes(filePath);
                    // If the IV is set, and Key is set, then decrypt it
                    if (!string.IsNullOrEmpty(upload.Key) && !string.IsNullOrEmpty(upload.IV))
                    {
                        // Decrypt the data
                        data = AES.Decrypt(data, upload.Key, upload.IV);
                    }

                    // We have the data, let's scan it
                    ClamScanResult scanResult = clam.SendAndScanFile(data);

                    switch (scanResult.Result)
                    {
                        case ClamScanResults.Clean:
                            totalClean++;
                            string cleanMsg = string.Format("[{0}] Clean Scan: {1}/{2} Scanned | {3} - {4}", DateTime.Now, totalScans, totalCount, upload.Url, upload.FileName);
                            Output(cleanMsg);
                            break;
                        case ClamScanResults.VirusDetected:
                            totalViruses++;
                            string msg = string.Format("[{0}] Virus Detected: {1} - {2} - {3}", DateTime.Now, upload.Url, upload.FileName, scanResult.InfectedFiles.First().VirusName);
                            File.AppendAllLines(virusFile, new List<string> { msg });
                            Output(msg);
                            // Delete from the DB
                            db.Uploads.Remove(upload);
                            db.SaveChanges();

                            // Delete the File
                            if (File.Exists(filePath))
                            {
                                File.Delete(filePath);
                            }
                            break;
                        case ClamScanResults.Error:
                            string errorMsg = string.Format("[{0}] Scan Error: {1}", DateTime.Now, scanResult.RawResult);
                            File.AppendAllLines(errorFile, new List<string> { errorMsg });
                            Output(errorMsg);
                            break;
                        case ClamScanResults.Unknown:
                            string unkMsg = string.Format("[{0}] Unknown Scan Result: {1}", DateTime.Now, scanResult.RawResult);
                            File.AppendAllLines(errorFile, new List<string> { unkMsg });
                            Output(unkMsg);
                            break;
                    }
                }
            }

            if (totalViruses > 0)
            {
                // Add to transparency report if any were found
                Takedown report = db.Takedowns.Create();
                report.Requester = TAKEDOWN_REPORTER;
                report.RequesterContact = config.SupportEmail;
                report.DateRequested = DateTime.Now;
                report.Reason = "Malware Found";
                report.ActionTaken = string.Format("{0} Uploads removed", totalViruses);
                report.DateActionTaken = DateTime.Now;
                db.Takedowns.Add(report);
                db.SaveChanges();
            }

            Output(string.Format("Scanning Complete.  {0} Scanned | {1} Viruses Found | {2} Total Files", totalScans, totalViruses, totalCount));
        }
 /// <summary>
 /// Scans your data stream for virus
 /// </summary>
 /// <param name="stream">The stream you want to check</param>
 public ScanResult ScanStream(Stream stream)
 {
     var clam = new ClamClient("localhost", 3310);
     return MapScanResult(clam.SendAndScanFile(stream));
 }
Example #3
0
        public ActionResult Upload(string fileType, string fileExt, string iv, int keySize, int blockSize, bool encrypt, bool saveKey, HttpPostedFileWrapper data, string key = null)
        {
            try
            {
                if (Config.UploadConfig.UploadEnabled)
                {
                    if (data.ContentLength <= Config.UploadConfig.MaxUploadSize)
                    {
                        // convert file to bytes
                        byte[] fileData = null;
                        int contentLength = data.ContentLength;
                        using (var binaryReader = new BinaryReader(data.InputStream))
                        {
                            fileData = binaryReader.ReadBytes(data.ContentLength);
                        }

                        // Scan the file to detect a virus
                        if (Config.UploadConfig.VirusScanEnable)
                        {
                            byte[] scanData = fileData;
                            // If it was encrypted client side, decrypt it
                            if (!encrypt && key != null)
                            {
                                // If the IV is set, and Key is set, then decrypt it
                                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(iv))
                                {
                                    // Decrypt the data
                                    scanData = AES.Decrypt(scanData, key, iv);
                                }
                            }
                            ClamClient clam = new ClamClient(Config.UploadConfig.ClamServer, Config.UploadConfig.ClamPort);
                            clam.MaxStreamSize = Config.UploadConfig.MaxUploadSize;
                            ClamScanResult scanResult = clam.SendAndScanFile(scanData);

                            switch (scanResult.Result)
                            {
                                case ClamScanResults.Clean:
                                    break;
                                case ClamScanResults.VirusDetected:
                                    return Json(new { error = new { message = string.Format("Virus Detected: {0}. As per our <a href=\"{1}\">Terms of Service</a>, Viruses are not permited.", scanResult.InfectedFiles.First().VirusName, Url.SubRouteUrl("tos", "TOS.Index")) } });
                                case ClamScanResults.Error:
                                    return Json(new { error = new { message = string.Format("Error scanning the file upload for viruses.  {0}", scanResult.RawResult) } });
                                case ClamScanResults.Unknown:
                                    return Json(new { error = new { message = string.Format("Unknown result while scanning the file upload for viruses.  {0}", scanResult.RawResult) } });
                            }
                        }

                        // if they want us to encrypt it, we do so here
                        if (encrypt)
                        {
                            // Generate key and iv if empty
                            if (string.IsNullOrEmpty(key))
                            {
                                key = Utility.RandomString(keySize / 8);
                            }

                            fileData = AES.Encrypt(fileData, key, iv);
                            if (fileData == null || fileData.Length <= 0)
                            {
                                return Json(new { error = new { message = "Unable to encrypt file" } });
                            }
                        }
                        Models.Upload upload = Uploader.SaveFile(db, Config, fileData, fileType, contentLength, fileExt, iv, (saveKey) ? key : null, keySize, blockSize);
                        if (upload != null)
                        {
                            if (User.Identity.IsAuthenticated)
                            {
                                Users.Models.User user = UserHelper.GetUser(db, User.Identity.Name);
                                if (user != null)
                                {
                                    upload.UserId = user.UserId;
                                    db.Entry(upload).State = EntityState.Modified;
                                    db.SaveChanges();
                                }
                            }
                            return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("u", "Upload.Download", new { file = upload.Url }), key = key } }, "text/plain");
                        }
                        return Json(new { error = new { message = "Unable to upload file" } });
                    }
                    else
                    {
                        return Json(new { error = new { message = "File Too Large" } });
                    }
                }
                return Json(new { error = new { message = "Uploads are disabled" } });
            }
            catch (Exception ex)
            {
                return Json(new { error = new { message = "Exception while uploading file: " + ex.GetFullMessage(true) } });
            }
        }
 /// <summary>
 /// Scans some bytes for virus
 /// </summary>
 /// <param name="data">byte data to scan</param>
 public ScanResult ScanBytes(byte[] data)
 {
     var clam = new ClamClient("localhost", 3310);
     return MapScanResult(clam.SendAndScanFile(data));
 }
Example #5
0
        public ActionResult Upload(HttpPostedFileWrapper file, string contentType = null, bool encrypt = true, bool saveKey = true, string key = null, int keySize = 0, string iv = null, int blockSize = 0, bool genDeletionKey = false, bool doNotTrack = false)
        {
            try
            {
                ViewBag.Title = "Upload";
                if (file != null)
                {
                    if (file.ContentLength <= Config.UploadConfig.MaxUploadSize)
                    {
                        // convert file to bytes
                        byte[] fileData = null;
                        string fileExt = Path.GetExtension(file.FileName);
                        int contentLength = file.ContentLength;
                        using (var binaryReader = new BinaryReader(file.InputStream))
                        {
                            fileData = binaryReader.ReadBytes(file.ContentLength);
                        }

                        // Scan the file to detect a virus
                        if (Config.UploadConfig.VirusScanEnable)
                        {
                            byte[] scanData = fileData;
                            // If it was encrypted client side, decrypt it
                            if (!encrypt && key != null)
                            {
                                // If the IV is set, and Key is set, then decrypt it
                                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(iv))
                                {
                                    // Decrypt the data
                                    scanData = AES.Decrypt(scanData, key, iv);
                                }
                            }
                            ClamClient clam = new ClamClient(Config.UploadConfig.ClamServer, Config.UploadConfig.ClamPort);
                            clam.MaxStreamSize = Config.UploadConfig.MaxUploadSize;
                            ClamScanResult scanResult = clam.SendAndScanFile(scanData);

                            switch (scanResult.Result)
                            {
                                case ClamScanResults.Clean:
                                    break;
                                case ClamScanResults.VirusDetected:
                                    return Json(new { error = new { message = string.Format("Virus Detected: {0}. As per our <a href=\"{1}\">Terms of Service</a>, Viruses are not permited.", scanResult.InfectedFiles.First().VirusName, Url.SubRouteUrl("tos", "TOS.Index")) } });
                                case ClamScanResults.Error:
                                    break;
                                case ClamScanResults.Unknown:
                                    break;
                            }
                        }

                        // Need to grab the contentType if it's empty
                        if (string.IsNullOrEmpty(contentType))
                        {
                            contentType = (string.IsNullOrEmpty(file.ContentType)) ? "application/octet-stream" : file.ContentType;
                        }

                        // Initialize the key size and block size if empty
                        if (keySize <= 0)
                            keySize = Config.UploadConfig.KeySize;
                        if (blockSize <= 0)
                            blockSize = Config.UploadConfig.BlockSize;

                        byte[] data = null;
                        // If they want us to encrypt the file first, do that here
                        if (encrypt)
                        {
                            // Generate key and iv if empty
                            if (string.IsNullOrEmpty(key))
                            {
                                key = Utility.RandomString(keySize / 8);
                            }
                            if (string.IsNullOrEmpty(iv))
                            {
                                iv = Utility.RandomString(blockSize / 8);
                            }

                            data = AES.Encrypt(fileData, key, iv);
                            if (data == null || data.Length <= 0)
                            {
                                return Json(new { error = new { message = "Unable to encrypt file" } });
                            }
                        }

                        // Save the file data
                        Upload.Models.Upload upload = Uploader.SaveFile(db, Config, (encrypt) ? data : fileData, contentType, contentLength, fileExt, iv, (saveKey) ? key : null, keySize, blockSize);

                        if (upload != null)
                        {
                            // Generate delete key if asked to
                            if (genDeletionKey)
                            {
                                string delKey = Utility.RandomString(Config.UploadConfig.DeleteKeyLength);
                                upload.DeleteKey = delKey;
                                db.Entry(upload).State = EntityState.Modified;
                                db.SaveChanges();
                            }

                            // Pull all the information together 
                            string fullUrl = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url });
                            var returnData = new
                            {
                                url = (saveKey || string.IsNullOrEmpty(key)) ? fullUrl : fullUrl + "#" + key,
                                fileName = upload.Url,
                                contentType = contentType,
                                contentLength = contentLength,
                                key = key,
                                keySize = keySize,
                                iv = iv,
                                blockSize = blockSize,
                                deletionKey = upload.DeleteKey

                            };
                            return Json(new { result = returnData });
                        }
                        return Json(new { error = new { message = "Unable to save file" } });
                    }
                    else
                    {
                        return Json(new { error = new { message = "File Too Large" } });
                    }
                }

                return Json(new { error = new { message = "Invalid Upload Request" } });
            }
            catch(Exception ex)
            {
                return Json(new { error = new { message = "Exception: " + ex.Message } });
            }
        }