Example #1
0
 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)));
 }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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 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);
 }
 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));
 }
Example #7
0
        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")));
            }
        }