Пример #1
0
        private void ParseAndAnalyze(string php, IVulnerabilityStorage storage)
        {
            FunctionsHandler fh = new FunctionsHandler(Config.FuncSpecSettings);

            fh.LoadJsonSpecifications();

            var extractedFuncs = PHPParseUtils.ParseAndIterate <ClassAndFunctionExtractor>(php, Config.PHPSettings.PHPParserPath).Functions;

            fh.CustomFunctions.AddRange(extractedFuncs);

            var cfg = PHPParseUtils.ParseAndIterate <CFGCreator>(php, Config.PHPSettings.PHPParserPath).Graph;

            var incResolver = new IncludeResolver(new List <File>());
            var fileStack   = new Stack <File>();

            fileStack.Push(new File()
            {
                FullPath = @"C:\TestFile.txt"
            });
            var condAnalyser = new ConditionTaintAnalyser(AnalysisScope.File, incResolver, fileStack, fh);

            var funcMock      = new Mock <Func <ImmutableVariableStorage, IIncludeResolver, AnalysisScope, AnalysisStacks, ImmutableVariableStorage> >();
            var blockAnalyzer = new TaintBlockAnalyzer(storage, incResolver,
                                                       AnalysisScope.File, funcMock.Object, new AnalysisStacks(fileStack), new FunctionAndMethodAnalyzerFactory(), fh);
            var immutableInitialTaint = new DefaultTaintProvider().GetTaint();
            var cfgTaintAnalysis      = new TaintAnalysis(blockAnalyzer, condAnalyser, immutableInitialTaint);
            var taintAnalysis         = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new QueueWorklist());

            taintAnalysis.Analyze(cfg);
        }
Пример #2
0
        /// <summary>
        /// Analyses a custom function in for security issues, with the currenctly known taint for actual parameters.
        /// </summary>
        /// <returns>A TainSets for the custom function that is being analyzed</returns>
        /// <param name="customFunction">Custom function object to perform the analysis on</param>
        /// <param name="varStorage">The currently known variable storage (this is to included because of superglobals, globals etc.)</param>
        /// <param name="paramActualVals">Parameter actual values</param>
        /// <param name="resolver">File inclusion resolver</param>
        /// <param name="includeStack">Currently known includes</param>
        /// <param name="functionCalls">Currently known function calls</param>
        internal ExpressionInfo AnalyseCustomFunction(Function customFunction, ImmutableVariableStorage varStorage, IVulnerabilityStorage vulnerabilityStorage,
                                                      IList <ExpressionInfo> paramActualVals, IIncludeResolver resolver, AnalysisStacks stacks)
        {
            var stmts = customFunction.AstNode.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Stmts).FirstChild;

            var traverser  = new XmlTraverser();
            var cfgcreator = new CFGCreator();

            traverser.AddVisitor(cfgcreator);
            traverser.Traverse(stmts);

            var cfgPruner = new CFGPruner();

            cfgPruner.Prune(cfgcreator.Graph);

            var initialTaint = varStorage.ToMutable();

            initialTaint.SuperGlobals.Clear();
            initialTaint.SuperGlobals.AddRange(varStorage.SuperGlobals);
            initialTaint.LocalVariables.Clear();
            initialTaint.LocalAccessibleGlobals.Clear();

            for (int i = 1; i <= paramActualVals.Count; i++)
            {
                var paramFormal = customFunction.Parameters.FirstOrDefault(x => x.Key.Item1 == i);
                if (paramFormal.Value == null)
                {
                    continue;
                }
                var @var = new Variable(paramFormal.Value.Name, VariableScope.Function)
                {
                    Info = paramActualVals[i - 1].ValueInfo
                };
                initialTaint.LocalVariables.Add(paramFormal.Value.Name, @var);
            }

            var blockAnalyzer = new TaintBlockAnalyzer(vulnerabilityStorage, resolver, AnalysisScope.Function, fileAnalyzer, stacks, subroutineAnalyzerFactory, _funcHandler);

            blockAnalyzer.AnalysisExtensions.AddRange(AnalysisExtensions);
            var condAnalyser     = new ConditionTaintAnalyser(AnalysisScope.Function, resolver, stacks.IncludeStack, _funcHandler);
            var cfgTaintAnalysis = new TaintAnalysis(blockAnalyzer, condAnalyser, ImmutableVariableStorage.CreateFromMutable(initialTaint));
            //var taintAnalysis = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new QueueWorklist());
            var taintAnalysis = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new ReversePostOrderWorkList(cfgcreator.Graph));

            taintAnalysis.Analyze(cfgcreator.Graph);

            var exprInfoAll = new ExpressionInfo();

            foreach (ExpressionInfo exprInfo in blockAnalyzer.ReturnInfos)
            {
                exprInfoAll = exprInfoAll.Merge(exprInfo);
            }

            return(exprInfoAll);
        }
Пример #3
0
        public void IfElseVarDefTest()
        {
            const string php = @"<?php
                                 if(true)
                                 {
	                                 $var = 1;
                                 }
                                 else
                                 {
	                                 $var = 2;
                                 }
                                 $var = 3;";

            var cfgCreator = ParseAndBuildCFG(php);
            var reachDef   = new ReachingDefinitionAnalysis();
            var analysis   = new CFGTraverser(new ForwardTraversal(), reachDef, new QueueWorklist());

            analysis.Analyze(cfgCreator.Graph);

            var inLineNumbers = new List <int>()
            {
                4, 8
            };
            var outLineNumbers = new List <int>()
            {
                4, 8, 10
            };

            foreach (var block in reachDef.ReachingSetDictionary)
            {
                if (block.Key.AstEntryNode != null && block.Key.AstEntryNode.Name == "node:Expr_Assign")
                {
                    if (block.Value.DefinedInVars.Any())
                    {
                        int ins = AstNode.GetStartLine(block.Value.DefinedInVars.Values.First().Info.Block.AstEntryNode);
                        inLineNumbers.RemoveAll(x => ins == x);
                    }
                    if (block.Value.DefinedOutVars.Any())
                    {
                        int outs = AstNode.GetStartLine(block.Value.DefinedOutVars.Values.First().Info.Block.AstEntryNode);
                        outLineNumbers.RemoveAll(x => x == outs);
                    }
                }
            }

            Assert.IsTrue(inLineNumbers.IsEmpty(), "The InLineNumbers are incorrect!");
            Assert.IsTrue(outLineNumbers.IsEmpty(), "The OutLineNumbers are incorrect!");
        }
Пример #4
0
        private void AssertNoOfVulnsInMultipleCodeFiles(Tuple <string, string>[] codeFiles, int numberOfVulns)
        {
            FunctionsHandler fh = new FunctionsHandler(Config.FuncSpecSettings);

            fh.LoadJsonSpecifications();

            var vulnStorage = new Mock <IVulnerabilityStorage>();

            var parsedFiles = codeFiles.Select(code => new File(PHPParseUtils.ParsePHPCode(code.Item2, Config.PHPSettings.PHPParserPath))
            {
                FullPath = code.Item1,
                CFG      = PHPParseUtils.ParseAndIterate <CFGCreator>(code.Item2, Config.PHPSettings.PHPParserPath).Graph
            }).ToArray();

            Func <ImmutableVariableStorage, IIncludeResolver, AnalysisScope, AnalysisStacks, ImmutableVariableStorage> fileTaintAnalyzer = null;

            fileTaintAnalyzer = (varStorage, inclResolver, scope, stacks) =>
            {
                Preconditions.NotNull(varStorage, "varStorage");
                Preconditions.NotNull(inclResolver, "inclResolver");
                var fileToAnalyze = stacks.IncludeStack.Peek();
                var blockAnalyzer = new TaintBlockAnalyzer(vulnStorage.Object, inclResolver,
                                                           scope, fileTaintAnalyzer, stacks, new FunctionAndMethodAnalyzerFactory(), fh);
                var condAnalyser     = new ConditionTaintAnalyser(scope, inclResolver, stacks.IncludeStack, fh);
                var cfgTaintAnalysis = new PHPAnalysis.Analysis.CFG.TaintAnalysis(blockAnalyzer, condAnalyser, varStorage);
                var analyzer         = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new ReversePostOrderWorkList(fileToAnalyze.CFG));

                analyzer.Analyze(fileToAnalyze.CFG);
                return(cfgTaintAnalysis.Taints[fileToAnalyze.CFG.Vertices.Single(block => block.IsLeaf)].Out[EdgeType.Normal]);
            };

            foreach (var file in parsedFiles)
            {
                var inclusionResolver = new IncludeResolver(parsedFiles);
                var fileStack         = new Stack <File>();
                fileStack.Push(file);
                var immutableInitialTaint = new DefaultTaintProvider().GetTaint();

                var stacks = new AnalysisStacks(fileStack);
                fileTaintAnalyzer(immutableInitialTaint, inclusionResolver, AnalysisScope.File, stacks);
            }

            vulnStorage.Verify(x => x.AddVulnerability(It.IsAny <IVulnerabilityInfo>()), Times.Exactly(numberOfVulns));
        }
Пример #5
0
        private static void Analyze(Arguments arguments, Config configuration)
        {
            Console.WriteLine("Parsing project at: " + arguments.Target);
            Console.WriteLine();

            foreach (var analysisStartingListener in _components.AnalysisStartingListeners)
            {
                // TODO - This should probably be a proper event - same goes for EndingEvent (this will also remove the loop(s)).
                analysisStartingListener.AnalysisStarting(null, new AnalysisStartingEventArgs(configuration, arguments));
            }

            var stopwatch = Stopwatch.StartNew();

            Console.WriteLine("Building ASTs..");
            ParseResult parseResult = ParseTarget(arguments, configuration);

            Console.WriteLine(" - AST build for {0} files ({1} failed)..", parseResult.ParsedFiles.Count, parseResult.FilesThatFailedToParse.Count);
            Console.WriteLine("Traversing ASTs..");

            var filesCollection      = new List <File>();
            var runningVulnReporter  = new CompositeVulneribilityReporter(_components.VulnerabilityReporters);
            var vulnerabilityStorage = new ReportingVulnerabilityStorage(runningVulnReporter, _funcHandler);

            var progrssIndicator = ProgressIndicatorFactory.CreateProgressIndicator(parseResult.ParsedFiles.Count());

            foreach (var parsedFile in parseResult.ParsedFiles)
            {
                progrssIndicator.Step();

                var file = BuildFileCFGAndExtractFileInformation(parsedFile);
                filesCollection.Add(file);
            }

            var subroutineAnalyzerFactory = new FunctionAndMethodAnalyzerFactory {
                UseSummaries = arguments.UseFunctionSummaries
            };
            Func <ImmutableVariableStorage, IIncludeResolver, AnalysisScope, AnalysisStacks,
                  ImmutableVariableStorage> fileTaintAnalyzer = null;

            fileTaintAnalyzer = (varStorage, inclResolver, scope, stacks) =>
            {
                Preconditions.NotNull(varStorage, "varStorage");
                Preconditions.NotNull(inclResolver, "inclResolver");

                var blockAnalyzer = new TaintBlockAnalyzer(vulnerabilityStorage, inclResolver, scope, fileTaintAnalyzer, stacks, subroutineAnalyzerFactory, _funcHandler);
                blockAnalyzer.AnalysisExtensions.AddRange(_components.BlockAnalyzers);
                var condAnalyser     = new ConditionTaintAnalyser(scope, inclResolver, stacks.IncludeStack, _funcHandler);
                var cfgTaintAnalysis = new TaintAnalysis(blockAnalyzer, condAnalyser, varStorage);
                var fileToAnalyze    = stacks.IncludeStack.Peek();
                var analyzer         = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new ReversePostOrderWorkList(fileToAnalyze.CFG));
                //var analyzer = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new QueueWorklist());
                analyzer.Analyze(fileToAnalyze.CFG);
                return(cfgTaintAnalysis.Taints[fileToAnalyze.CFG.Vertices.Single(block => block.IsLeaf)].Out[EdgeType.Normal]);
            };

            foreach (var file in filesCollection)
            {
                Console.WriteLine(Environment.NewLine + "=============================");
                Console.WriteLine("Analyzing {0}..", file.FullPath);
                var initialTaint      = GetDefaultTaint();
                var inclusionResolver = new IncludeResolver(filesCollection);

                var stacks = new AnalysisStacks(file);
                fileTaintAnalyzer(initialTaint, inclusionResolver, AnalysisScope.File, stacks);
            }

            Console.WriteLine("Scanned {0}/{1} subroutines. ", _funcHandler.ScannedFunctions.Count, _funcHandler.CustomFunctions.Count, _funcHandler);

            if (arguments.ScanAllSubroutines)
            {
                Console.WriteLine("Scanning remaining subroutines..");
                ScanUnscannedSubroutines(filesCollection, fileTaintAnalyzer, subroutineAnalyzerFactory, vulnerabilityStorage);
            }

            vulnerabilityStorage.CheckForStoredVulnerabilities();
            //parseResult.ParsedFiles.Values.First().Save(@"C:\Users\Kenneth\Documents\Uni\TestScript\current\parsedFile");

            stopwatch.Stop();

            foreach (var analysisEndedListener in _components.AnalysisEndedListeners)
            {
                analysisEndedListener.AnalysisEnding(null, new AnalysisEndedEventArgs(stopwatch.Elapsed));
            }

            Console.WriteLine("Time spent: " + stopwatch.Elapsed);
            Console.WriteLine("Found {0} vulnerabilities.", runningVulnReporter.NumberOfReportedVulnerabilities);
        }