private bool HasBeenMoved(ScanAlertCollection scanAlerts, string filename) { return(scanAlerts .Any(x => x.Trace.Calls .Any(y => y.Name == "move_uploaded_file" && y.ParameterValues.Count > 1 && y.ParameterValues[1] == filename))); }
private void TestUploadedFile(PhpVHTester tester, ScanAlertCollection alerts, string filename) { Assert.IsTrue(HasBeenMoved(alerts, filename), _fileNotMoved, filename); var shellFile = Path.Combine(tester.TestDirectory.FullName, filename); Assert.IsTrue(File.Exists(shellFile), _fileNotUploaded, shellFile); var shellFileText = File.ReadAllText(shellFile); var isValidShellFile = shellFileText.Contains("system") || shellFileText.Contains("AddType"); Assert.IsTrue(isValidShellFile, _invalidUpload); }
public ScanAlertCollection LoadAlerts() { var reports = GetTestReports(); Assert.AreEqual( reports.Count(), 1, "More than one report for {0} found", Name); var report = reports.First(); var reportFiles = report.GetFiles(); var pxmlFile = reportFiles.FirstOrDefault(x => x.Extension == ".pxml"); Assert.IsNotNull(pxmlFile, _noPxml); return(ScanAlertCollection.Load(pxmlFile.FullName)); }
public void OpenFile(string SourceFile) { SelectedTab = -1; if (SourceFile == null) { var dialog = new OpenFileDialog() { Filter = "Report Files (*.rxml Files)|*.rxml|Vuln Files (*.pxml)|*.pxml|All|*.*" }; if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } SourceFile = dialog.FileName; } var info = new FileInfo(SourceFile); ReportDir = info.Directory.FullName; if (info.Extension == ".rxml") { var reportFiles = ReportFile.Load(SourceFile); Func <string, string> getFilePath = x => info.DirectoryName + "\\" + new FileInfo(x).Name; var staticAnalysisReport = reportFiles .SingleOrDefault(x => x.Name == "Static analysis"); if (staticAnalysisReport != null) { var alerts = StaticAnalysisFileAlertCollection .Load(getFilePath(staticAnalysisReport.Filename)) .SelectMany(x => x.Alerts.Select(y => new { x.Filename, Alert = y, })) .OrderBy(x => x.Alert.Name); if (alerts.Any()) { StaticAnalysisVisibility = Visibility.Visible; StaticAnalysisAlerts = alerts; } } var vulnReport = reportFiles .SingleOrDefault(x => new FileInfo(x.Filename).Extension == ".pxml"); if (vulnReport != null) { VulnerabilityTabVisibility = Visibility.Visible; SelectedTab = 0; var alerts = ScanAlertCollection.Load(getFilePath(vulnReport.Filename)); if (alerts == null) { return; } CreateAlertViewModels(alerts); } else { VulnerabilityTabVisibility = Visibility.Collapsed; } var inputMap = reportFiles .SingleOrDefault(x => x.Name == "Input Map Report"); if (inputMap != null) { var inputMapFile = inputMap.Filename; InputTable = ApplicationMap .FromXml(getFilePath(inputMapFile)).Pages .ToDictionary( x => string.Format( "{0} ({1})", x.Page, x.SuperglobalNameCollectionTable.Sum(y => y.Value.Count())), x => new Dictionary <string, List <object> >() { { "GET", x.Get.Select(y => (object)(new { Key = y })).ToList() }, { "POST", x.Post.Select(y => (object)(new { Key = y })).ToList() }, { "REQUEST", x.Request.Select(y => (object)(new { Key = y })).ToList() }, { "Files", x.Files.Select(y => (object)(new { Key = y })).ToList() }, { "Cookies", x.Cookie.Select(y => (object)(new { Key = y })).ToList() } } .Where(y => y.Value.Any()) .ToDictionary( y => string.Format("{0} ({1})", y.Key, y.Value.Count()), y => y.Value)); InputMapVisibility = Visibility.Visible; if (SelectedTab == -1) { SelectedTab = 1; } } var coverageReport = reportFiles .SingleOrDefault(x => x.Name == "Annotation"); if (coverageReport != null) { CoverageVisibility = Visibility.Visible; if (SelectedTab == -1) { SelectedTab = 2; } var annotationFile = Path.Combine(info.DirectoryName, coverageReport.Filename); var pluginTable = PluginAnnotationTable.Load(annotationFile); CoverageTables = pluginTable.Items .Select(x => new CodeCoverageCalculator(x).CalculateCoverage(false)) .ToArray(); } else { CoverageVisibility = Visibility.Collapsed; } if (SelectedTab != -1) { DynamicAnalysisVisibility = Visibility.Visible; SelectedRootTab = 0; } else { SelectedRootTab = 1; } } else { var alerts = ScanAlertCollection.Load(SourceFile); if (alerts == null) { return; } DynamicAnalysisVisibility = Visibility.Visible; SelectedRootTab = 0; VulnerabilityTabVisibility = Visibility.Visible; InputMapVisibility = Visibility.Collapsed; CoverageVisibility = Visibility.Collapsed; SelectedTab = 0; CreateAlertViewModels(alerts); } }
private bool HasBeenMoved(ScanAlertCollection scanAlerts, string filename) { return scanAlerts .Any(x => x.Trace.Calls .Any(y => y.Name == "move_uploaded_file" && y.ParameterValues.Count > 1 && y.ParameterValues[1] == filename)); }
static void ScanDirectory(DirectoryInfo AppDirectory, string RelativeAppPath) { var ignoreExtensions = new[] { "png", "jpg", "jpeg", "gif", "ico", "js", "css", }; var urlDictionary = CreateUrlDictionary(RelativeAppPath, AppDirectory); var urlCollections = new[] { urlDictionary.Select(x => x.Key).ToList(), new List<string>() }; var traceTable = new TraceTable(); var report = new StringBuilder(); var coverageReport = new StringBuilder(); var map = new ApplicationMap(); var alerts = new ScanAlertCollection(); int requestCount = 0; MessageDumper messageDumper = null; if (Config.DumpMessages) { messageDumper = new MessageDumper(_reportWriter.ReportPath.FullName); } for (int urlCollectionIndex = 0; urlCollectionIndex < 2; urlCollectionIndex++) foreach (ScanPluginBase plugin in Config.ScanPlugins) { if (Config.CodeCoverageReport > 0) { ScanMetrics.Default.Annotator.Reset(); ScanMetrics.Default.Annotator.AnnotationTable = ScanMetrics.Default.PluginAnnotations[plugin.ToString()]; } if (!urlCollections[urlCollectionIndex].Any()) continue; ScannerCli.DisplayScanPlugin(plugin); foreach (var remotePath in urlCollections[urlCollectionIndex]) { ScannerCli.DisplayResourcePath(remotePath); IEnumerable<IEnumerable<TracedFunctionCall>> calls = null; if (urlCollectionIndex == 0) { var key = urlDictionary[remotePath]; if (Program.PageFieldTable.ContainsKey(key)) calls = Program.PageFieldTable[key] .Select(x => x.Value.Select(y => new TracedFunctionCall() { Name = x.Key, ParameterValues = new List<string>() { y } })); } for (int i = 0; i < plugin.ModeCount; i++) { foreach (var useStaticAnalysisInputs in new[] { false, true }) { var trace = new FileTrace(); if (useStaticAnalysisInputs && calls != null) { if (!calls.Any(x => x.Any())) continue; foreach (var c in calls) trace.Calls.AddRange(c); } bool discoveredVars = true; while (discoveredVars) { var traceFile = new FileInfo(TraceFileName); IOHelper.TryAction(traceFile.Delete); var client = new TcpClient() { ReceiveTimeout = Config.Timeout, SendTimeout = Config.Timeout }; while (!client.Connected) try { client.Connect(Config.Server, Config.Port); } catch (SocketException ex) { ScannerCli.DisplayError(ex.Message); Thread.Sleep(5000); } client.LingerState = new LingerOption(true, 0); HttpResponse resp = null; string req, respString = ""; using (var stream = client.GetStream()) { req = plugin.BuildRequest(i, remotePath, trace); if (Config.DumpMessages) { messageDumper.Dump(req, requestCount, MessageType.Request); } var stopwatch = new Stopwatch(); stopwatch.Start(); stream.WriteString(req); try { var sgs = trace.Calls .Superglobals() .Select(x => new { x.Name, Value = x.ParameterValues.Count > 0 ? x.ParameterValues[0] : null }) .Distinct(); var discoveredVarCount = sgs.Count(); var reader = new HttpResponseReader(stream); resp = reader.Read(); stopwatch.Stop(); respString = resp.CompleteResponse; ScannerCli.DisplayResponse( resp, i, discoveredVarCount, stopwatch.ElapsedMilliseconds, resp.CompleteResponse.Length); } catch (SocketException) { ScannerCli.DisplayResponseError(respString); } catch (IOException) { ScannerCli.DisplayResponseError(respString); } } if (urlCollectionIndex == 0 && resp != null) { var abs = "http://" + Config.Server + remotePath; var urls = new UriScraper() { Regex = new Regex(@"[/.]" + Config.Server + @"($|/)", RegexOptions.IgnoreCase | RegexOptions.Compiled), } .Parse(resp.Body, abs) .Select(x => new Uri(x).LocalPath); foreach (var url in urls) { if (!ignoreExtensions.Any(x => url.ToLower().EndsWith("." + x)) && !urlCollections[0].Contains(url) && !urlCollections[1].Contains(url)) { urlCollections[1].Add(url); ScannerCli.DisplayDiscoveredUrl(url); } } } client.Close(); if (Config.DumpMessages) { messageDumper.Dump(respString, requestCount, MessageType.Response); } requestCount++; traceFile = new FileInfo(TraceFileName); FileTrace newTrace = null; IOHelper.TryAction(() => { if (traceFile.Exists) using (var reader = traceFile.OpenText()) newTrace = FileTrace.Parse(reader); }); if (newTrace == null) { newTrace = new FileTrace(); } newTrace.Request = req; newTrace.Response = respString; newTrace.File = remotePath; var alert = plugin.ScanTrace(newTrace); if (alert != null) { if (Config.BeepOnAlert) Console.Beep(); ScannerCli.DisplayAlert(alert); alerts.Add(alert); report.Append(alert.ToString()); } discoveredVars = false; foreach (TracedFunctionCall c in newTrace.Calls .Superglobals() .Where(x => x.ParameterValues.Any())) { var oldCalls = trace.Calls.Where(x => x.Name == c.Name && x.ParameterValues.SequenceEqual(c.ParameterValues)); if (!oldCalls.Any()) { discoveredVars = true; break; } } var orphanedInputs = trace.Calls .Superglobals() .Where(x => !newTrace.Calls .Any(y => x.Name == y.Name && x.ParameterValues .SequenceEqual(y.ParameterValues))) .ToArray(); newTrace.Calls.AddRange(orphanedInputs); trace = newTrace; } var superglobals = trace.Calls.Superglobals(); map.AddTrace(trace); if (Config.DiscoveryReport) { if (!traceTable.ContainsKey(plugin)) { traceTable.Add(plugin, new Dictionary<int, Dictionary<string, FileTrace>>()); } if (!traceTable[plugin].ContainsKey(i)) { traceTable[plugin].Add(i, new Dictionary<string, FileTrace>()); } if (!traceTable[plugin][i].ContainsKey(trace.File)) { traceTable[plugin][i].Add(trace.File, trace); } else { traceTable[plugin][i][trace.File] = trace; } } } } } if (Config.CodeCoverageReport > 0 && urlCollectionIndex == 0) { Cli.WriteLine("Calculating code coverage..."); CodeCoverageTable coverage = null; IOHelper.TryAction(() => { var calculator = new CodeCoverageCalculator( ScanMetrics.Default.Annotator.AnnotationFile, ScanMetrics.Default.PluginAnnotations[plugin.ToString()]); coverage = calculator.CalculateCoverage(); }); coverage.Plugin = plugin.ToString(); coverageReport.AppendLine(coverage.ToString() + "\r\n"); } Cli.WriteLine(); } _reportWriter.Write("Vulnerability Report", report.ToString()); _reportWriter.Write("Input Map Report", map.ToXml(), "xml"); if (alerts.Any()) { _reportWriter.Write("Vulnerability Report", alerts.ToXml(), "pxml"); } if (Config.DiscoveryReport) { _reportWriter.Write("Scan Overview Report", DiscoveryReport.Create(traceTable)); } if (Config.CodeCoverageReport > 0) { _reportWriter.Write("Code Coverage Report", coverageReport.ToString()); var annotationXml = ScanMetrics.Default.PluginAnnotations.ToXml(); var annotationFile = _reportWriter.Write( "Annotation", annotationXml, "axml"); Cli.WriteLine(); var commenter = new CoverageCommenter(ScanMetrics.Default.PluginAnnotations); commenter.LoadTable(annotationFile); commenter.WriteCommentedFiles(_reportWriter.ReportPath.FullName); _reportWriter.ReportFiles.Add( new ReportFile( "Coverage Comments", Path.Combine("Code Coverage", "index.html"))); } }