private ExpressionInfo HandleGetOptions(FunctionCall call, IDictionary<uint, ExpressionInfo> argumentInfos, ExpressionInfo exprInfo) { XmlNode firstArgument; string optionsKeyValue; if (call.Arguments.TryGetValue(1, out firstArgument) && TryGetOptionKeyValue(firstArgument, argumentInfos[1], out optionsKeyValue)) { Func<TaintSets> taintFactory = () => new TaintSets(new SQLITaintSet(SQLITaint.SQL_ALL), new XSSTaintSet(XSSTaint.XSS_ALL)); var possibleStoredTaint = new StoredVulnInfo() { StorageOrigin = "Options", StorageName = optionsKeyValue, Taint = taintFactory(), ICantFeelIt = IsItInYet.NoImPullingOut }; var getOptionResult = new ExpressionInfo { ExpressionStoredTaint = possibleStoredTaint, ValueInfo = { PossibleStoredTaint = possibleStoredTaint, NestedVariablePossibleStoredDefaultTaintFactory = taintFactory, }, }; return getOptionResult; } return exprInfo; }
private ExpressionInfo HandleUpdateAddOptions(FunctionCall call, ExpressionInfo exprInfo, IVulnerabilityStorage storage, IDictionary<uint, ExpressionInfo> argumentInfos, AnalysisStacks analysisStacks) { XmlNode firstArgument; XmlNode secondArgument; string optionKeyValue; if (call.Arguments.TryGetValue(1, out firstArgument) && call.Arguments.TryGetValue(2, out secondArgument) && TryGetOptionKeyValue(firstArgument, argumentInfos[1], out optionKeyValue)) { foreach (var sqliTaintSet in argumentInfos.ElementAt(1).Value.ExpressionTaint.SqliTaint) { if (sqliTaintSet.TaintTag == SQLITaint.None) { continue; } string varName = (sqliTaintSet.InitialTaintedVariable ?? "???"); string message = "Stored SQLI found - Ingoing: " + varName + " on line: " + call.StartLine + " in file: " + analysisStacks.IncludeStack.Peek(); storage.AddPossibleStoredVulnerability(new StoredVulnerabilityInfo() { IncludeStack = analysisStacks.IncludeStack.ToImmutableStack(), CallStack = analysisStacks.CallStack.ToImmutableStack(), Message = message, VulnerabilityType = VulnType.SQL, PossibleStoredVuln = new StoredVulnInfo() { ICantFeelIt = IsItInYet.YesItsGoingIn, StorageName = optionKeyValue, StorageOrigin = "Options", Taint = new TaintSets(sqliTaintSet, new XSSTaintSet()) } }); } foreach (var xssTaintSet in argumentInfos.ElementAt(1).Value.ExpressionTaint.XssTaint) { if (xssTaintSet.TaintTag == XSSTaint.None) { continue; } string varName = (xssTaintSet.InitialTaintedVariable ?? "???"); string message = "Stored XSS found - Ingoing: " + varName + " on line: " + call.StartLine + " in file: " + analysisStacks.IncludeStack.Peek(); storage.AddPossibleStoredVulnerability(new StoredVulnerabilityInfo() { IncludeStack = analysisStacks.IncludeStack.ToImmutableStack(), CallStack = analysisStacks.CallStack.ToImmutableStack(), Message = message, VulnerabilityType = VulnType.XSS, PossibleStoredVuln = new StoredVulnInfo() { ICantFeelIt = IsItInYet.YesItsGoingIn, StorageName = optionKeyValue, StorageOrigin = "Options", Taint = new TaintSets(new SQLITaintSet(), xssTaintSet) } }); } } return exprInfo; }
/// <summary> /// Make sure that hardcoded callback functions are analyzed. /// </summary> private ExpressionInfo HandleHookCall(XmlNode node, ExpressionInfo exprInfo, IVariableStorage currentStorage, AnalysisStacks analysisStacks) { var functionCall = new FunctionCallExtractor().ExtractFunctionCall(node); var result = new ExpressionInfo(); foreach (var argument in functionCall.Arguments.Where(a => a.Value.LocalName == AstConstants.Nodes.Scalar_String)) { var stringValue = ScalarNode.GetStringValue(argument.Value); var functions = FunctionsHandler.Instance.LookupFunction(stringValue); if (functions.Any()) { //Console.WriteLine("FOUND " + functions.Count() + " functions with name: " + stringValue); var functionAnalyzer = this.FunctionMethodAnalyzerFactory(currentStorage); var call = new FunctionCall(stringValue, null, AstNode.GetStartLine(node), AstNode.GetEndLine(node)); if (analysisStacks.CallStack.Any(c => c.Name == call.Name)) { // Avoid recursive registrations. continue; } analysisStacks.CallStack.Push(call); var funcCallResult = functionAnalyzer.AnalyzeFunctionCall(call, new ExpressionInfo[0]); analysisStacks.CallStack.Pop(); result = result.Merge(funcCallResult); } // https://codex.wordpress.org/Function_Reference/add_submenu_page // If a method is called, it is called with: array( $this, 'function_name' ) or array( __CLASS__, 'function_name' ) } return result; }
private ExpressionInfo HandleOptionsCall(FunctionCall call, XmlNode node, ExpressionInfo exprInfo, IVariableStorage currentStorage, IVulnerabilityStorage storage, IDictionary<uint, ExpressionInfo> argumentInfos, AnalysisStacks analysisStacks) { if (_getOptionsFunctions.Contains(call.Name)) { return HandleGetOptions(call, argumentInfos, exprInfo); } else if (_updateOptionFunctions.Contains(call.Name) || _addOptionFunctions.Contains(call.Name)) { return HandleUpdateAddOptions(call, exprInfo, storage, argumentInfos, analysisStacks); } return exprInfo; }
private static void ScanUnscannedSubroutines(List<File> filesCollection, Func<ImmutableVariableStorage, IIncludeResolver, AnalysisScope, AnalysisStacks, ImmutableVariableStorage> fileTaintAnalyzer, FunctionAndMethodAnalyzerFactory subroutineAnalyzerFactory, ReportingVulnerabilityStorage vulnerabilityStorage) { var defaultTaint = new DefaultTaintProvider().GetTaint(); foreach (var file in filesCollection) { var analysisStacks = new AnalysisStacks(file); var analyser = new FunctionAndMethodAnalyzer(defaultTaint, new IncludeResolver(filesCollection), analysisStacks, new CustomFunctionHandler(fileTaintAnalyzer, subroutineAnalyzerFactory), vulnerabilityStorage); foreach (var function in file.Functions.SelectMany(f => f.Value).Except(FunctionsHandler.Instance.ScannedFunctions)) { var functionCall = new FunctionCall(function.Name, function.AstNode, 0, 0); analysisStacks.CallStack.Push(functionCall); analyser.AnalyzeFunctionCall(functionCall, new List<ExpressionInfo>()); } foreach (var @class in file.Classes.SelectMany(c => c.Value)) { foreach (var method in @class.Methods.Except(FunctionsHandler.Instance.ScannedFunctions)) { var methodCall = new MethodCall(method.Name, new [] { @class.Name }, method.AstNode, 0, 0); analysisStacks.CallStack.Push(methodCall); analyser.AnalyzeMethodCall(methodCall, new List<ExpressionInfo>()); } } } }