Пример #1
0
        public Window1()
        {
            InitializeComponent();

            DataContext = this;

            Config = new ScanConfig() { RunViewer = true };

            Loaded += new RoutedEventHandler(Window1_Loaded);
            Closing += new CancelEventHandler(Window1_Closing);

            var l = Assembly.GetExecutingAssembly().Location;

            _phpvhExe = new FileInfo(l).Directory + "\\phpvh.exe";
        }
Пример #2
0
        static void Main2(string[] args)
        {
            Cli.UseTrace    = true;
            Trace.AutoFlush = true;
            Trace.Listeners.Add(new ConsoleTraceListener());

            if (!args.Any(x => x == "-l"))
            {
                ScannerCli.RunAssistant();
            }

            ScannerCli.DisplayAppInfo();

            if (args.Length == 0)
            {
                ScannerCli.DisplayInstructions();

                Exit();
            }

            Config = ScanConfig.Parse(args);

            if (Config.TestMode)
            {
                RunSelfTest();
                return;
            }

            var versionTester = new PhpVersionTester(Config);

            versionTester.CheckVersion();
            Cli.WriteLine();

            ExeProbe.Copy();

            TraceFileName = Config.WebRoot + @"\trace.txt";

            foreach (string RelativeAppPath in Config.ApplicationPaths)
            {
                string filePath = Config.WebRoot + "\\" + RelativeAppPath.Replace('/', '\\');

                if (!Directory.Exists(filePath))
                {
                    ScannerCli.DisplayCriticalMessage("Application path {0} not found.", filePath);

                    Exit();
                }

                if (Config.Repair || new DirectoryInfo(filePath)
                    .GetFiles("*.phpvhbackup", SearchOption.AllDirectories)
                    .Any(x => x.Extension.ToLower() == ".phpvhbackup"))
                {
                    ScannerCli.DisplayPhaseName("Repair");
                    Cli.WriteLine();

                    new HookCollection().Unset(new DirectoryInfo(filePath));



                    if (Config.Repair)
                    {
                        continue;
                    }
                }

                _reportWriter = new ReportWriter(RelativeAppPath);

                Trace.Listeners.Clear();

                if (Config.LogConsole)
                {
                    Trace.Listeners.Add(new TextWriterTraceListener(_reportWriter.ReportPath + "\\scan.log"));
                }

                Trace.Listeners.Add(new ConsoleTraceListener());

                foreach (var plugin in Config.ScanPlugins)
                {
                    plugin.Initialize();
                }

                Program.PageFieldTable.Clear();

                Cli.WriteLine();
                ScannerCli.DisplayAppPath(RelativeAppPath);

                //////////////////////////////////////////////////////////////////////////
                // Static analysis
                ScannerCli.DisplayPhaseName("Static Analysis");

                var sae = new StaticAnalysis.StaticAnalysisEngine(Config);
                sae.FileScanned += (o, e) =>
                {
                    Cli.WriteLine(
                        "{0} [~{1}~{2}~R~]",
                        e.Item.Filename,
                        e.Item.Alerts.Any() ? ConsoleColor.Red : ConsoleColor.DarkGreen,
                        e.Item.Alerts.Length);

                    e.Item.Alerts.Iter(x => Cli.WriteLine("~Red~Potential Vulnerability: {0}~R~", x.Name));
                };
                var staticAnalysisAlerts = sae.ScanDirectory(filePath);

                if (staticAnalysisAlerts.Any())
                {
                    _reportWriter.Write("Static analysis", staticAnalysisAlerts.ToXml(), "xml");
                }

                Cli.WriteLine();
                Cli.WriteLine();

                // End Static analysis
                //////////////////////////////////////////////////////////////////////////

                if (!Config.StaticOnly)
                {
                    ScanMetrics.Default = new ScanMetrics();
                    ScanMetrics.Default.Annotator.AnnotationFile = new FileInfo(Config.WebRoot + "\\Annotation.txt");

                    #region Hooks
                    var hooks2    = new HookCollection(Hook.GetDefaults());
                    var sqlPlugin = new SqlScanPlugin(null);
                    sqlPlugin.Initialize();
                    hooks2.AddRange(sqlPlugin.Config.Functions.ToHooks());
                    #endregion

                    if (Config.HookSuperglobals)
                    {
                        hooks2.AddRange(Hook.GetSuperglobals());
                    }

                    if (_scan)
                    {
                        ScannerCli.DisplayPhaseName("Form scrape");

                        var urlDictionary = CreateUrlDictionary(RelativeAppPath, new DirectoryInfo(filePath));

                        foreach (var page in urlDictionary.Select(x => new
                        {
                            Relative = x.Key,
                            Url = "http://" + Config.Server + x.Key,
                        }))
                        {
                            var data    = WebClientHelper.DownloadData(page.Url);
                            var respStr = ASCIIEncoding.ASCII.GetString(data.Data);
                            var forms   = FormScraper.GetForms(respStr, page.Url);

                            if (forms.Any())
                            {
                                foreach (var f in forms)
                                {
                                    var action = new Uri(f.Action);
                                    if (!action.Host.Contains(Config.Server) ||
                                        !urlDictionary.ContainsKey(action.LocalPath))
                                    {
                                        continue;
                                    }

                                    var file = urlDictionary[action.LocalPath];

                                    if (!PageFieldTable.ContainsKey(file))
                                    {
                                        PageFieldTable.Add(file, new Dictionary <string, List <string> >());
                                    }

                                    var superglobal = "$_" + f.Method.ToUpper();

                                    if (!PageFieldTable[file].ContainsKey(superglobal))
                                    {
                                        PageFieldTable[file].Add(superglobal, new List <string>());
                                    }

                                    var newInputs = f.Inputs
                                                    .Select(x => x.Name ?? x.Type)
                                                    .Where(x => x != null && !PageFieldTable[file][superglobal].Contains(x));

                                    PageFieldTable[file][superglobal].AddRange(newInputs);
                                }
                            }

                            ScannerCli.DisplayScrapedUrl(page.Relative, forms);
                        }

                        Trace.WriteLine("");

                        if (_hook)
                        {
                            ScannerCli.DisplayPhaseName("Dynamic Analysis Initialization");
                            Cli.WriteLine();

                            hooks2.Set(new DirectoryInfo(filePath));
                            hooks2.CreateHandlerFile();
                            Cli.WriteLine();
                            Cli.WriteLine();

                            Program.Config.ScanPlugins
                            .Iter(x =>
                            {
                                var annotationTableClone    = ScanMetrics.Default.Annotator.AnnotationTable.Clone() as AnnotationTable;
                                annotationTableClone.Plugin = x.ToString();
                                ScanMetrics.Default.PluginAnnotations.Add(annotationTableClone);
                            });
                        }

                        ScannerCli.DisplayPhaseName("Dynamic Analysis");

                        ScanDirectory(new DirectoryInfo(filePath), RelativeAppPath);
                        Console.WriteLine();
                    }

                    ScannerCli.DisplayPhaseName("Dynamic Analysis Uninitialization");
                    Cli.WriteLine();
                    hooks2.DeleteHandlerFile();

                    File.Delete(TraceFileName);

                    foreach (var plugin in Config.ScanPlugins)
                    {
                        plugin.Uninitialize();
                    }

                    if (Config.Unhook)
                    {
                        hooks2.Unset(new DirectoryInfo(filePath));

                        Cli.WriteLine();
                        Cli.WriteLine();
                    }
                }

                var reportFiles = _reportWriter.WriteFilenames();
#if !MONO && !NET35
                if (_reportWriter.ReportFiles.Any() && Config.RunViewer)
                {
                    var viewerPath = Assembly.GetExecutingAssembly().Location.RemoveAtLastIndexOf('\\', 1) +
                                     @"PHPVHReportViewer.exe";

                    if (File.Exists(viewerPath))
                    {
                        System.Diagnostics.Process.Start(viewerPath, "\"" + reportFiles + "\"");
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Could not locate report viewer executable.",
                                                             "Error launching report viewer", System.Windows.Forms.MessageBoxButtons.OK,
                                                             System.Windows.Forms.MessageBoxIcon.Error);
                    }
                }
#endif
            }

            Trace.Listeners.Clear();
            Trace.Listeners.Add(new ConsoleTraceListener());
        }
Пример #3
0
 public PhpVersionTester(ScanConfig config)
 {
     _config = config;
 }
Пример #4
0
        public static ScanConfig Parse(string[] args)
        {
            var config = new ScanConfig();

            int argIndex = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "-s")
                {
                    if (args.Length == i + 1)
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("-s argument expects value");
                    }

                    config.Server = args[i + 1];
                    i++;

                    foreach (var a in config.ScanPlugins)
                    {
                        a.Server = config.Server;
                    }
                }
                else if (args[i] == "-static")
                {
                    config.StaticOnly = true;
                }
                else if (args[i] == "-t")
                {
                    int timeout = 0;
                    if (args.Length == i + 1 ||
                        !int.TryParse(args[i + 1], out timeout))
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("-t argument expects number value");
                    }

                    i++;
                    config.Timeout = timeout;
                }
                else if (args[i] == "-p")
                {
                    int port = 0;
                    if (args.Length == i + 1 ||
                        !int.TryParse(args[i + 1], out port))
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("-p argument expects number value");
                    }

                    i++;
                    config.Port = port;
                }
                else if (args[i] == "-l")
                {
                    config.LauncherUsed = true;
                }
                else if (args[i] == "-n")
                {
                    config.Unhook = false;
                }
                else if (args[i] == "-v")
                {
                    config.RunViewer = true;
                }
                else if (args[i] == "-d")
                {
                    config.DiscoveryReport = true;
                }
                else if (args[i] == "-c")
                {
                    config.CodeCoverageReport = 1;
                }
                else if (args[i] == "-c2")
                {
                    config.CodeCoverageReport = 2;
                }
                else if (args[i] == "-dump")
                {
                    config.DumpMessages = true;
                }
                else if (args[i] == "-b")
                {
                    config.BeepOnAlert = true;
                }
                else if (args[i] == "-log")
                {
                    config.LogConsole = true;
                }
                else if (args[i] == "-test")
                {
                    config.TestMode = true;
                }
                else if (args[i] == "-r")
                {
                    config.Repair = true;
                }
                //else if (args[i] == "-h")
                //    config.HookSuperglobals = true;
                else if (args[i] == "-l")
                {
                    // Nothing
                }
                else if (args[i] == "-m")
                {
                    if (args.Length == i + 1)
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("-m argument expects value");
                    }

                    var modes = args[i + 1];

                    i++;

                    foreach (var c in modes)
                    {
                        ScanPluginBase scan = null;

                        switch (c.ToString().ToLower()[0])
                        {
                            case 'c':
                                scan = new CommandScanPlugin(config.Server);
                                break;
                            case 'l':
                                try
                                {
                                    scan = new LocalFileInclusionScanPlugin(config.Server);
                                }
                                catch (UnauthorizedAccessException)
                                {
                                    ScannerCli.DisplayCriticalMessageAndExit("Error writing LFI test file. Ensure that " +
                                        "PHP Vulnerability Hunter has administrative privileges.");
                                }
                                break;
                            case 'f':
                                scan = new FileScanPlugin(config.Server);
                                break;
                            case 'p':
                                scan = new ArbitraryPhpScanPlugin(config.Server);
                                break;
                            case 's':
                                scan = new SqlScanPlugin(config.Server);
                                break;
                            case 'd':
                                scan = new DynamicScanPlugin(config.Server);
                                break;
                            case 'x':
                                scan = new XssScanPlugin(config.Server);
                                break;
                            case 'i':
                                scan = new FullPathDisclosureScanPlugin(config.Server);
                                break;
                            case 'r':
                                scan = new OpenRedirectScanPlugin(config.Server);
                                break;
                        }

                        if (scan == null)
                            ScannerCli.DisplayCriticalMessageAndExit("Invalid scan mode: " + c);

                        config.ScanPlugins.Add(scan);
                    }
                }
                else
                {
                    switch (argIndex)
                    {
                        case 0:
                            config.WebRoot = args[i];

                            if (!Directory.Exists(config.WebRoot))
                            {
                                ScannerCli.DisplayError(string.Format("Could not find directory {0}",
                                    config.WebRoot));

                                Environment.Exit(5);
                            }

                            break;
                        case 1:
                            if (args[i] == "*")
                            {
                                var dir = new DirectoryInfo(config.WebRoot);
                                config.ApplicationPaths = dir.GetDirectories()
                                    .Select(x => x.Name)
                                    .ToArray();
                            }
                            else
                                config.ApplicationPaths = args[i].Split(',');
                            break;
                    }

                    argIndex++;
                }
            }

            if (argIndex != 2)
                ScannerCli.DisplayCriticalMessageAndExit("Invalid argument count");

            // Validate user input

            if (!Directory.Exists(config.WebRoot))
                ScannerCli.DisplayCriticalMessageAndExit("Web root {0} not found.", config.WebRoot);

            if (config.ScanPlugins.Count == 0 && !config.Repair)
            {
                LocalFileInclusionScanPlugin lfi = null;

                try
                {
                    lfi = new LocalFileInclusionScanPlugin(config.Server);
                }
                catch (UnauthorizedAccessException)
                {
                    ScannerCli.DisplayCriticalMessageAndExit("Error writing LFI test file. Ensure that " +
                        "PHP Vulnerability Hunter has administrative privileges.");
                }

                config._ScanPlugins = new List<ScanPluginBase>()
                {
                    new CommandScanPlugin(config.Server),
                    new FileScanPlugin(config.Server),
                    lfi,
                    new ArbitraryPhpScanPlugin(config.Server),
                    new DynamicScanPlugin(config.Server),
                    new SqlScanPlugin(config.Server),
                    new XssScanPlugin(config.Server),
                    new OpenRedirectScanPlugin(config.Server),
                    new FullPathDisclosureScanPlugin(config.Server),
                };
            }

            return config;
        }
        public static ScanConfig Create(string[] args)
        {
            var config = new ScanConfig();

            int argIndex = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "-s")
                {
                    config.Server = args[i + 1];
                    i++;

                    foreach (var a in config.ScanPlugins)
                    {
                        a.Server = config.Server;
                    }
                }
                else if (args[i] == "-static")
                {
                    config.StaticOnly = true;
                }
                else if (args[i] == "-t")
                {
                    int timeout = 0;
                    if (args.Length == i + 1 ||
                        !int.TryParse(args[i + 1], out timeout))
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("Error parsing timeout");
                    }
                    i++;
                    config.Timeout = timeout;
                }
                else if (args[i] == "-p")
                {
                    int port;
                    if (!int.TryParse(args[i + 1], out port))
                    {
                        ScannerCli.DisplayCriticalMessageAndExit("Error parsing port");
                    }
                    i++;
                    config.Port = port;
                }
                else if (args[i] == "-l")
                {
                    config.LauncherUsed = true;
                }
                else if (args[i] == "-n")
                {
                    config.Unhook = false;
                }
                else if (args[i] == "-v")
                {
                    config.RunViewer = true;
                }
                else if (args[i] == "-d")
                {
                    config.DiscoveryReport = true;
                }
                else if (args[i] == "-c")
                {
                    config.CodeCoverageReport = 1;
                }
                else if (args[i] == "-c2")
                {
                    config.CodeCoverageReport = 2;
                }
                else if (args[i] == "-dump")
                {
                    config.DumpMessages = true;
                }
                else if (args[i] == "-b")
                {
                    config.BeepOnAlert = true;
                }
                else if (args[i] == "-log")
                {
                    config.LogConsole = true;
                }
                else if (args[i] == "-test")
                {
                    config.TestMode = true;
                }
                else if (args[i] == "-r")
                {
                    config.Repair = true;
                }
                //else if (args[i] == "-h")
                //    config.HookSuperglobals = true;
                else if (args[i] == "-l")
                {
                    // Nothing
                }
                else if (args[i] == "-m")
                {
                    var modes = args[i + 1];

                    i++;

                    foreach (var c in modes)
                    {
                        ScanPluginBase scan = null;

                        switch (c.ToString().ToLower()[0])
                        {
                        case 'c':
                            scan = new CommandScanPlugin(config.Server);
                            break;

                        case 'l':
                            try
                            {
                                scan = new LocalFileInclusionScanPlugin(config.Server);
                            }
                            catch (UnauthorizedAccessException)
                            {
                                ScannerCli.DisplayCriticalMessageAndExit("Error writing LFI test file. Ensure that " +
                                                                         "PHP Vulnerability Hunter has administrative privileges.");
                            }
                            break;

                        case 'f':
                            scan = new FileScanPlugin(config.Server);
                            break;

                        case 'p':
                            scan = new ArbitraryPhpScanPlugin(config.Server);
                            break;

                        case 's':
                            scan = new SqlScanPlugin(config.Server);
                            break;

                        case 'd':
                            scan = new DynamicScanPlugin(config.Server);
                            break;

                        case 'x':
                            scan = new XssScanPlugin(config.Server);
                            break;

                        case 'i':
                            scan = new FullPathDisclosureScanPlugin(config.Server);
                            break;

                        case 'r':
                            scan = new OpenRedirectScanPlugin(config.Server);
                            break;
                        }

                        if (scan == null)
                        {
                            ScannerCli.DisplayCriticalMessageAndExit("Invalid scan mode: " + c);
                        }

                        config.ScanPlugins.Add(scan);
                    }
                }
                else
                {
                    switch (argIndex)
                    {
                    case 0:
                        config.WebRoot = args[i];

                        if (!Directory.Exists(config.WebRoot))
                        {
                            ScannerCli.DisplayError(string.Format("Could not find directory {0}",
                                                                  config.WebRoot));

                            Environment.Exit(5);
                        }

                        break;

                    case 1:
                        if (args[i] == "*")
                        {
                            var dir = new DirectoryInfo(config.WebRoot);
                            config.ApplicationPaths = dir.GetDirectories()
                                                      .Select(x => x.Name)
                                                      .ToArray();
                        }
                        else
                        {
                            config.ApplicationPaths = args[i].Split(',');
                        }
                        break;
                    }

                    argIndex++;
                }
            }

            if (argIndex != 2)
            {
                ScannerCli.DisplayCriticalMessageAndExit("Invalid argument count");
            }

            // Validate user input

            if (!Directory.Exists(config.WebRoot))
            {
                ScannerCli.DisplayCriticalMessageAndExit("Web root {0} not found.", config.WebRoot);
            }

            if (config.ScanPlugins.Count == 0 && !config.Repair)
            {
                LocalFileInclusionScanPlugin lfi = null;

                try
                {
                    lfi = new LocalFileInclusionScanPlugin(config.Server);
                }
                catch (UnauthorizedAccessException)
                {
                    ScannerCli.DisplayCriticalMessageAndExit("Error writing LFI test file. Ensure that " +
                                                             "PHP Vulnerability Hunter has administrative privileges.");
                }

                config._ScanPlugins = new List <ScanPluginBase>()
                {
                    new CommandScanPlugin(config.Server),
                    new FileScanPlugin(config.Server),
                    lfi,
                    new ArbitraryPhpScanPlugin(config.Server),
                    new DynamicScanPlugin(config.Server),
                    new SqlScanPlugin(config.Server),
                    new XssScanPlugin(config.Server),
                    new OpenRedirectScanPlugin(config.Server),
                    new FullPathDisclosureScanPlugin(config.Server),
                };
            }

            return(config);
        }
Пример #6
0
 public PhpVersionTester(ScanConfig config)
 {
     _config = config;
 }
Пример #7
0
        static void Main2(string[] args)
        {
            Cli.UseTrace = true;
            Trace.AutoFlush = true;
            Trace.Listeners.Add(new ConsoleTraceListener());

            if (!args.Any(x => x == "-l"))
            {
                ScannerCli.RunAssistant();
            }

            ScannerCli.DisplayAppInfo();

            if (args.Length == 0)
            {
                ScannerCli.DisplayInstructions();

                Exit();
            }

            Config = ScanConfig.Parse(args);

            if (Config.TestMode)
            {
                RunSelfTest();
                return;
            }

            var versionTester = new PhpVersionTester(Config);
            versionTester.CheckVersion();
            Cli.WriteLine();

            ExeProbe.Copy();

            TraceFileName = Config.WebRoot + @"\trace.txt";

            foreach (string RelativeAppPath in Config.ApplicationPaths)
            {
                string filePath = Config.WebRoot + "\\" + RelativeAppPath.Replace('/', '\\');

                if (!Directory.Exists(filePath))
                {
                    ScannerCli.DisplayCriticalMessage("Application path {0} not found.", filePath);

                    Exit();
                }

                if (Config.Repair || new DirectoryInfo(filePath)
                    .GetFiles("*.phpvhbackup", SearchOption.AllDirectories)
                    .Any(x => x.Extension.ToLower() == ".phpvhbackup"))
                {
                    ScannerCli.DisplayPhaseName("Repair");
                    Cli.WriteLine();

                    new HookCollection().Unset(new DirectoryInfo(filePath));

                    if (Config.Repair)
                        continue;
                }

                _reportWriter = new ReportWriter(RelativeAppPath);

                Trace.Listeners.Clear();

                if (Config.LogConsole)
                    Trace.Listeners.Add(new TextWriterTraceListener(_reportWriter.ReportPath + "\\scan.log"));

                Trace.Listeners.Add(new ConsoleTraceListener());

                foreach (var plugin in Config.ScanPlugins)
                    plugin.Initialize();

                Program.PageFieldTable.Clear();

                Cli.WriteLine();
                ScannerCli.DisplayAppPath(RelativeAppPath);

                //////////////////////////////////////////////////////////////////////////
                // Static analysis
                ScannerCli.DisplayPhaseName("Static Analysis");

                var sae = new StaticAnalysis.StaticAnalysisEngine(Config);
                sae.FileScanned += (o, e) =>
                {
                    Cli.WriteLine(
                        "{0} [~{1}~{2}~R~]",
                        e.Item.Filename,
                        e.Item.Alerts.Any() ? ConsoleColor.Red : ConsoleColor.DarkGreen,
                        e.Item.Alerts.Length);

                    e.Item.Alerts.Iter(x => Cli.WriteLine("~Red~Potential Vulnerability: {0}~R~", x.Name));
                };
                var staticAnalysisAlerts = sae.ScanDirectory(filePath);

                if (staticAnalysisAlerts.Any())
                    _reportWriter.Write("Static analysis", staticAnalysisAlerts.ToXml(), "xml");

                Cli.WriteLine();
                Cli.WriteLine();

                // End Static analysis
                //////////////////////////////////////////////////////////////////////////

                if (!Config.StaticOnly)
                {
                    ScanMetrics.Default = new ScanMetrics();
                    ScanMetrics.Default.Annotator.AnnotationFile = new FileInfo(Config.WebRoot + "\\Annotation.txt");

                    #region Hooks
                    var hooks2 = new HookCollection(Hook.GetDefaults());
                    var sqlPlugin = new SqlScanPlugin(null);
                    sqlPlugin.Initialize();
                    hooks2.AddRange(sqlPlugin.Config.Functions.ToHooks());
                    #endregion

                    if (Config.HookSuperglobals)
                    {
                        hooks2.AddRange(Hook.GetSuperglobals());
                    }

                    if (_scan)
                    {
                        ScannerCli.DisplayPhaseName("Form scrape");

                        var urlDictionary = CreateUrlDictionary(RelativeAppPath, new DirectoryInfo(filePath));

                        foreach (var page in urlDictionary.Select(x => new
                        {
                            Relative = x.Key,
                            Url = "http://" + Config.Server + x.Key,
                        }))
                        {
                            var data = WebClientHelper.DownloadData(page.Url);
                            var respStr = ASCIIEncoding.ASCII.GetString(data.Data);
                            var forms = FormScraper.GetForms(respStr, page.Url);

                            if (forms.Any())
                            {
                                foreach (var f in forms)
                                {
                                    var action = new Uri(f.Action);
                                    if (!action.Host.Contains(Config.Server) ||
                                        !urlDictionary.ContainsKey(action.LocalPath))
                                        continue;

                                    var file = urlDictionary[action.LocalPath];

                                    if (!PageFieldTable.ContainsKey(file))
                                        PageFieldTable.Add(file, new Dictionary<string, List<string>>());

                                    var superglobal = "$_" + f.Method.ToUpper();

                                    if (!PageFieldTable[file].ContainsKey(superglobal))
                                        PageFieldTable[file].Add(superglobal, new List<string>());

                                    var newInputs = f.Inputs
                                        .Select(x => x.Name ?? x.Type)
                                        .Where(x => x != null && !PageFieldTable[file][superglobal].Contains(x));

                                    PageFieldTable[file][superglobal].AddRange(newInputs);
                                }
                            }

                            ScannerCli.DisplayScrapedUrl(page.Relative, forms);
                        }

                        Trace.WriteLine("");

                        if (_hook)
                        {
                            ScannerCli.DisplayPhaseName("Dynamic Analysis Initialization");
                            Cli.WriteLine();

                            hooks2.Set(new DirectoryInfo(filePath));
                            hooks2.CreateHandlerFile();
                            Cli.WriteLine();
                            Cli.WriteLine();

                            Program.Config.ScanPlugins
                                .Iter(x =>
                                {
                                    var annotationTableClone = ScanMetrics.Default.Annotator.AnnotationTable.Clone() as AnnotationTable;
                                    annotationTableClone.Plugin = x.ToString();
                                    ScanMetrics.Default.PluginAnnotations.Add(annotationTableClone);
                                });
                        }

                        ScannerCli.DisplayPhaseName("Dynamic Analysis");

                        ScanDirectory(new DirectoryInfo(filePath), RelativeAppPath);
                        Console.WriteLine();
                    }

                    ScannerCli.DisplayPhaseName("Dynamic Analysis Uninitialization");
                    Cli.WriteLine();
                    hooks2.DeleteHandlerFile();

                    File.Delete(TraceFileName);

                    foreach (var plugin in Config.ScanPlugins)
                        plugin.Uninitialize();

                    if (Config.Unhook)
                    {
                        hooks2.Unset(new DirectoryInfo(filePath));

                        Cli.WriteLine();
                        Cli.WriteLine();
                    }
                }

                var reportFiles = _reportWriter.WriteFilenames();
            #if !MONO && !NET35
                if (_reportWriter.ReportFiles.Any() && Config.RunViewer)
                {
                    var viewerPath = Assembly.GetExecutingAssembly().Location.RemoveAtLastIndexOf('\\', 1) +
                        @"PHPVHReportViewer.exe";

                    if (File.Exists(viewerPath))
                        System.Diagnostics.Process.Start(viewerPath, "\"" + reportFiles + "\"");
                    else
                        System.Windows.Forms.MessageBox.Show("Could not locate report viewer executable.",
                            "Error launching report viewer", System.Windows.Forms.MessageBoxButtons.OK,
                            System.Windows.Forms.MessageBoxIcon.Error);

                }
            #endif
            }

            Trace.Listeners.Clear();
            Trace.Listeners.Add(new ConsoleTraceListener());
        }