public void CFGCreator_RootAndExitIsStmtFunction(string phpcode) { var extract = ParseAndExtract(phpcode); foreach (var func in extract.Functions) { var ast = func.AstNode; var traverser = new XmlTraverser(); var cfgcreator = new CFGCreator(); traverser.AddVisitor(cfgcreator); traverser.Traverse(ast); var graph = cfgcreator.Graph; //Root assertions Assert.IsTrue(graph.Vertices.First().IsRoot, "first node was not the root node"); Assert.IsTrue(graph.Vertices.First().IsSpecialBlock, "first node was not marked as IsSpecialBlock"); graph.AssertInEdges(graph.Vertices.First(), 0, "Entry node - in edges"); graph.AssertOutEdges(graph.Vertices.First(), 1, "Entry node - out edges"); Assert.AreEqual(AstConstants.Nodes.Stmt_Function, graph.Vertices.First().ToString()); //Leaf assertions Assert.IsTrue(graph.Vertices.ElementAt(1).IsSpecialBlock, "The element at position 1 was not marked with IsSpecialBlock"); Assert.AreEqual(true, graph.Vertices.ElementAt(1).IsLeaf, "The element at position 1 was not marked with IsLeaf"); graph.AssertOutEdges(graph.Vertices.ElementAt(1), 0, "Exit node - out edges"); } }
public void CFGCreator_RootAndExitIsClousure(string phpCode) { var extract = ParseAndExtract(phpCode); foreach (var closure in extract.Closures) { var ast = closure.AstNode; var traverser = new XmlTraverser(); var cfgcreator = new CFGCreator(); traverser.AddVisitor(cfgcreator); traverser.Traverse(ast); var graph = cfgcreator.Graph; //Root Assert.IsTrue(graph.Vertices.First().IsRoot, "the first vertix is not the root node"); Assert.IsTrue(graph.Vertices.First().IsSpecialBlock, "The first node was not marked with IsSpecialBlock"); graph.AssertInEdges(graph.Vertices.First(), 0, "Entry node contains in edges"); graph.AssertOutEdges(graph.Vertices.First(), 1, "Entry node did not have exactly one out edge"); Assert.AreEqual(AstConstants.Nodes.Expr_Closure, graph.Vertices.First().ToString(), "The root node was not a closure, and was expected to be a closure"); //Leaf Assert.IsTrue(graph.Vertices.ElementAt(1).IsLeaf, "The element at position one was not the exit block"); Assert.IsTrue(graph.Vertices.ElementAt(1).IsSpecialBlock, "The element at position one was not marked with IsSpecialBlock"); graph.AssertOutEdges(graph.Vertices.ElementAt(1), 0, "The exit block contained out edged"); Assert.AreEqual(AstConstants.Nodes.Expr_Closure, graph.Vertices.ElementAt(1).ToString()); } }
/// <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); blockAnalyzer.AnalysisExtensions.AddRange(AnalysisExtensions); var condAnalyser = new ConditionTaintAnalyser(AnalysisScope.Function, resolver, stacks.IncludeStack); 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; }
private static File BuildFileCFGAndExtractFileInformation(KeyValuePair<string, XmlDocument> parsedFile) { var traverser = new XmlTraverser (); var metricAnalyzer = new MetricVisitor (); var extractor = new ClassAndFunctionExtractor (); var printer = new ASTPrinter (Console.Out); var cfgcreator = new SuperCFGCreator (); traverser.AddVisitor (extractor); traverser.AddVisitor (metricAnalyzer); traverser.Traverse (parsedFile.Value.FirstChild.NextSibling); cfgcreator.Traverse (parsedFile.Value.FirstChild.NextSibling); var ctlPrep = new CFGCTLPreparation (); ctlPrep.AddSelfLoops (cfgcreator.Graph); File file = new File (parsedFile.Value) { CFG = cfgcreator.Graph, FullPath = parsedFile.Key, Interfaces = extractor.Interfaces.GroupBy (i => i.Name, i => i).ToDictionary (i => i.Key, i => i.ToList ()), Classes = extractor.Classes.GroupBy (c => c.Name, c => c).ToDictionary (c => c.Key, c => c.ToList ()), Closures = extractor.Closures.ToArray (), Functions = extractor.Functions.GroupBy (i => i.Name, i => i).ToDictionary (i => i.Key, i => i.ToList ()) }; return file; }
private static void ExtractFunctions(KeyValuePair<string, XmlDocument> parsedFile) { var traverser = new XmlTraverser (); var extractor = new ClassAndFunctionExtractor (); traverser.AddVisitor (extractor); traverser.Traverse (parsedFile.Value.FirstChild.NextSibling); FunctionsHandler.Instance.CustomFunctions.AddRange (extractor.Functions); foreach (var @class in extractor.Classes) { foreach (var method in @class.Methods) { //HACK: This is not a good way to handle this! Should we add a new derived function class called method that includes the class name //-||-: and make a special list for them in the function handler, or is this okay? method.Name = @class.Name + "->" + method.Name; FunctionsHandler.Instance.CustomFunctions.Add (method); } } }
private static void WPGotoAnalysis(Arguments arguments, Config configuration) { var v = Stopwatch.StartNew(); var folders = Directory.GetDirectories(@"G:\WP"); int counter = 0; var progress = new BikeGuyRidingAnimation(folders.Count()); var locker = new object(); Parallel.ForEach(folders, new ParallelOptions() { MaxDegreeOfParallelism = 7 }, folder => { int myNumber = Interlocked.Increment(ref counter); arguments.Target = Path.Combine(arguments.Target, folder); if (!Directory.Exists(arguments.Target)) return; var projectParser = new ProjectParser(arguments.Target, configuration.PHPSettings); ParseResult parseResult = projectParser.ParseProjectFiles(); foreach (var parsedFile in parseResult.ParsedFiles) { //Console.WriteLine("File: " + parsedFile.Key); var traverser = new XmlTraverser(); var metricVisitor = new MetricVisitor(); traverser.AddVisitor(metricVisitor); traverser.Traverse(parsedFile.Value); if (metricVisitor.Gotos > 0) { lock (locker) { System.IO.File.AppendAllLines(@"C:/pluginDLMessages.txt", new [] { "Goto found in " + parsedFile.Key}); } } } //Console.WriteLine(folder); if ((myNumber % 250) == 0) { Console.WriteLine(myNumber + " plugins scanned.."); } }); Console.WriteLine(v.Elapsed); Environment.Exit(1); }
private static File BuildFileCFGAndExtractFileInformation(KeyValuePair<string, XmlDocument> parsedFile) { var traverser = new XmlTraverser(); var metricAnalyzer = new MetricVisitor(); var extractor = new ClassAndFunctionExtractor(); var printer = new ASTPrinter(Console.Out); var cfgcreator = new CFGCreator(); traverser.AddVisitor(extractor); traverser.AddVisitor(metricAnalyzer); traverser.AddVisitor(cfgcreator); //traverser.AddVisitor(printer); traverser.AddVisitors(_components.AstVisitors.ToArray()); traverser.Traverse(parsedFile.Value.FirstChild.NextSibling); foreach (var function in extractor.Functions) { function.File = parsedFile.Key; } foreach (var closure in extractor.Closures) { closure.File = parsedFile.Key; } FunctionsHandler.Instance.CustomFunctions.AddRange(extractor.Functions); foreach (var @class in extractor.Classes) { @class.File = parsedFile.Key; foreach (var method in @class.Methods) { //HACK: This is not a good way to handle this! Should we add a new derived function class called method that includes the class name //-||-: and make a special list for them in the function handler, or is this okay? method.Name = @class.Name + "->" + method.Name; method.File = parsedFile.Key; FunctionsHandler.Instance.CustomFunctions.Add(method); } } //cfgcreator.Graph.VisualizeGraph("graph", Program.Configuration.GraphSettings); var cfgPruner = new CFGPruner(); cfgPruner.Prune(cfgcreator.Graph); //cfgcreator.Graph.VisualizeGraph("graph-pruned", Configuration.GraphSettings); File file = new File(parsedFile.Value) { CFG = cfgcreator.Graph, FullPath = parsedFile.Key, Interfaces = extractor.Interfaces.GroupBy(i => i.Name, i => i).ToDictionary(i => i.Key, i => i.ToList()), Classes = extractor.Classes.GroupBy(c => c.Name, c => c).ToDictionary(c => c.Key, c => c.ToList()), Closures = extractor.Closures.ToArray(), Functions = extractor.Functions.GroupBy(i => i.Name, i => i).ToDictionary(i => i.Key, i => i.ToList()) }; return file; }