/// <summary> /// Finds all references (not including aliases) in a script for the given symbol /// </summary> /// <param name="scriptAst">The abstract syntax tree of the given script</param> /// <param name="foundSymbol">The symbol that we are looking for referneces of</param> /// <param name="needsAliases">If this reference search needs aliases. /// This should always be false and used for occurence requests</param> /// <returns>A collection of SymbolReference objects that are refrences to the symbolRefrence /// not including aliases</returns> public static IEnumerable <SymbolReference> FindReferencesOfSymbol( ScriptBlockAst scriptAst, SymbolReference foundSymbol, bool needsAliases) { FindReferencesVisitor referencesVisitor = new FindReferencesVisitor(foundSymbol); scriptAst.Visit(referencesVisitor); return(referencesVisitor.FoundReferences); }
public void ParamAndStatement() { ScriptBlockAst scriptBlockAst = ParseInput("{ param ([string]$s) Get-ChildItem }"). EndBlock. Statements[0]. PipelineElements[0]. Expression. ScriptBlock; Assert.AreEqual(1, scriptBlockAst.ParamBlock.Parameters.Count); Assert.AreEqual(1, scriptBlockAst.EndBlock.Statements.Count); }
public void Empty() { ScriptBlockAst scriptBlockAst = ParseInput("{}"). EndBlock. Statements[0]. PipelineElements[0]. Expression. ScriptBlock; Assert.AreEqual(0, scriptBlockAst.ParamBlock.Parameters.Count); Assert.AreEqual(0, scriptBlockAst.EndBlock.Statements.Count); }
public void SemicolonTerminatedTest() { ScriptBlockAst scriptBlockAst = ParseInput("Get-ChildItem;"); Assert.IsNull(scriptBlockAst.ParamBlock); Assert.IsNull(scriptBlockAst.BeginBlock); Assert.IsNull(scriptBlockAst.ProcessBlock); Assert.IsNull(scriptBlockAst.DynamicParamBlock); Assert.IsNull(scriptBlockAst.Parent); Assert.AreEqual(1, scriptBlockAst.EndBlock.Statements.Count); }
public void SemicolonOnly() { ScriptBlockAst scriptBlockAst = ParseInput(";"); Assert.IsNull(scriptBlockAst.ParamBlock); Assert.IsNull(scriptBlockAst.BeginBlock); Assert.IsNull(scriptBlockAst.ProcessBlock); Assert.IsNull(scriptBlockAst.DynamicParamBlock); Assert.IsNull(scriptBlockAst.Parent); CollectionAssert.IsEmpty(scriptBlockAst.EndBlock.Statements); }
/// <summary> /// Detects variables retrieved by usage of Get-Variable and remove those /// variables from the entries in <paramref name="assignmentsDictionary_OrdinalIgnoreCase"/>. /// </summary> /// <param name="scriptBlockAst"></param> /// <param name="assignmentsDictionary_OrdinalIgnoreCase"></param> private void AnalyzeGetVariableCommands( ScriptBlockAst scriptBlockAst, Dictionary <string, AssignmentStatementAst> assignmentsDictionary_OrdinalIgnoreCase) { var getVariableCmdletNamesAndAliases = Helper.Instance.CmdletNameAndAliases("Get-Variable"); IEnumerable <Ast> getVariableCommandAsts = scriptBlockAst.FindAll(testAst => testAst is CommandAst commandAst && getVariableCmdletNamesAndAliases.Contains(commandAst.GetCommandName(), StringComparer.OrdinalIgnoreCase), true); foreach (CommandAst getVariableCommandAst in getVariableCommandAsts) { var commandElements = getVariableCommandAst.CommandElements.ToList(); // The following extracts the variable name(s) only in the simplest possible usage of Get-Variable. // Usage of a named parameter and an array of variables is accounted for though. if (commandElements.Count < 2 || commandElements.Count > 3) { continue; } var commandElementAstOfVariableName = commandElements[commandElements.Count - 1]; if (commandElements.Count == 3) { if (!(commandElements[1] is CommandParameterAst commandParameterAst)) { continue; } // Check if the named parameter -Name is used (PowerShell does not need the full // parameter name and there is no other parameter of Get-Variable starting with n). if (!commandParameterAst.ParameterName.StartsWith("n", StringComparison.OrdinalIgnoreCase)) { continue; } } if (commandElementAstOfVariableName is StringConstantExpressionAst constantExpressionAst) { assignmentsDictionary_OrdinalIgnoreCase.Remove(constantExpressionAst.Value); continue; } if (!(commandElementAstOfVariableName is ArrayLiteralAst arrayLiteralAst)) { continue; } foreach (var expressionAst in arrayLiteralAst.Elements) { if (expressionAst is StringConstantExpressionAst constantExpressionAstOfArray) { assignmentsDictionary_OrdinalIgnoreCase.Remove(constantExpressionAstOfArray.Value); } } } }
public static Tuple <Ast, Token[], IScriptPosition> MapStringInputToParsedInput(string input, int cursorIndex) { Token[] tokenArray; ParseError[] errorArray; if (cursorIndex > input.Length) { throw PSTraceSource.NewArgumentException("cursorIndex"); } ScriptBlockAst ast = Parser.ParseInput(input, out tokenArray, out errorArray); IScriptPosition position = ((InternalScriptPosition)ast.Extent.StartScriptPosition).CloneWithNewOffset(cursorIndex); return(Tuple.Create <Ast, Token[], IScriptPosition>(ast, tokenArray, position)); }
public void GlobalSetup() { _currentAst = s_scriptBlocksDict[FunctionsToCompile]; // Run it once to get the C# code jitted. // The first call to this takes relatively too long, which makes the BDN's heuristic incorrectly // believe that there is no need to run many ops in each interation. However, the subsequent runs // of this method is much faster than the first run, and this causes 'MinIterationTime' warnings // to our benchmarks and make the benchmark results not reliable. // Calling this method once in 'GlobalSetup' is a workaround. // See https://github.com/dotnet/BenchmarkDotNet/issues/837#issuecomment-828600157 CompileFunction(); }
public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst) { var statements = new List <Node>(); foreach (var statement in scriptBlockAst.EndBlock.Statements) { statements.Add(VisitSyntaxNode(statement)); } _currentNode = new Block(statements); return(AstVisitAction.SkipChildren); }
internal ScriptBlockAst GetScriptBlockAst() { var scriptContents = ScriptContents; if (_scriptBlock == null) { this.ScriptBlock = ScriptBlock.TryGetCachedScriptBlock(_path, scriptContents); } if (_scriptBlock != null) { return((ScriptBlockAst)_scriptBlock.Ast); } if (_scriptBlockAst == null) { ParseError[] errors; Parser parser = new Parser(); // If we are in ConstrainedLanguage mode but the defining language mode is FullLanguage, then we need // to parse the script contents in FullLanguage mode context. Otherwise we will get bogus parsing errors // such as "Configuration or Class keyword not allowed". var context = LocalPipeline.GetExecutionContextFromTLS(); if (context != null && context.LanguageMode == PSLanguageMode.ConstrainedLanguage && DefiningLanguageMode == PSLanguageMode.FullLanguage) { context.LanguageMode = PSLanguageMode.FullLanguage; try { _scriptBlockAst = parser.Parse(_path, ScriptContents, null, out errors, ParseMode.Default); } finally { context.LanguageMode = PSLanguageMode.ConstrainedLanguage; } } else { _scriptBlockAst = parser.Parse(_path, ScriptContents, null, out errors, ParseMode.Default); } if (errors.Length == 0) { this.ScriptBlock = new ScriptBlock(_scriptBlockAst, isFilter: false); ScriptBlock.CacheScriptBlock(_scriptBlock.Clone(), _path, scriptContents); } } return(_scriptBlockAst); }
public override IEnumerable <IPathNode> ResolvePath(CodeOwls.PowerShell.Provider.PathNodeProcessors.IProviderContext providerContext, string path) { if (null == _script) { var script = Regex.Replace(path, @"^(.+?\.ps1).*$", "$1"); _script = script; Token[] _tokens; ParseError[] _errors; _ast = Parser.ParseFile(_script, out _tokens, out _errors); } path = path.Replace(_script, String.Empty); return(base.ResolvePath(providerContext, path)); }
/// <summary> /// Format a powershell script. /// </summary> /// <param name="scriptDefinition">A string representing a powershell script.</param> /// <param name="settings">Settings to be used for formatting</param> /// <param name="range">The range in which formatting should take place.</param> /// <param name="cmdlet">The cmdlet object that calls this method.</param> /// <returns></returns> public static string Format <TCmdlet>( string scriptDefinition, Settings settings, Range range, TCmdlet cmdlet) where TCmdlet : PSCmdlet, IOutputWriter { // todo implement notnull attribute for such a check ValidateNotNull(scriptDefinition, "scriptDefinition"); ValidateNotNull(settings, "settings"); ValidateNotNull(cmdlet, "cmdlet"); Helper.Instance = new Helper(cmdlet.SessionState.InvokeCommand, cmdlet); Helper.Instance.Initialize(); var ruleOrder = new string[] { "PSPlaceCloseBrace", "PSPlaceOpenBrace", "PSUseConsistentWhitespace", "PSUseConsistentIndentation", "PSAlignAssignmentStatement", "PSUseCorrectCasing", "PSAvoidUsingCmdletAliases", "PSAvoidUsingDoubleQuotesForConstantString", }; var text = new EditableText(scriptDefinition); ScriptBlockAst scriptAst = null; Token[] scriptTokens = null; bool skipParsing = false; foreach (var rule in ruleOrder) { if (!settings.RuleArguments.ContainsKey(rule)) { continue; } var currentSettings = GetCurrentSettings(settings, rule); ScriptAnalyzer.Instance.UpdateSettings(currentSettings); ScriptAnalyzer.Instance.Initialize(cmdlet, null, null, null, null, true, SuppressionPreference.Omit); text = ScriptAnalyzer.Instance.Fix(text, range, skipParsing, out Range updatedRange, out bool fixesWereApplied, ref scriptAst, ref scriptTokens, skipVariableAnalysis: true); skipParsing = !fixesWereApplied; range = updatedRange; } return(text.ToString()); }
/// <summary> /// Finds all references (not including aliases) in a script for the given symbol /// </summary> /// <param name="scriptAst">The abstract syntax tree of the given script</param> /// <param name="foundSymbol">The symbol that we are looking for referneces of</param> /// <param name="needsAliases">If this reference search needs aliases. /// This should always be false and used for occurence requests</param> /// <returns>A collection of SymbolReference objects that are refrences to the symbolRefrence /// not including aliases</returns> public static IEnumerable <SymbolReference> FindReferencesOfSymbol( ScriptBlockAst scriptAst, SymbolReference foundSymbol, bool needsAliases) { FindReferencesVisitor referencesVisitor = new FindReferencesVisitor(foundSymbol); scriptAst.Visit(referencesVisitor); FindReferencesVisitor2 declarationVisitor2 = new FindReferencesVisitor2(foundSymbol); scriptAst.Visit(declarationVisitor2); return(referencesVisitor.FoundReferences.Concat(declarationVisitor2.FoundReferences).ToList()); }
private async Task LaunchScriptAsync(string scriptToLaunch) { // Is this an untitled script? if (ScriptFile.IsUntitledPath(scriptToLaunch)) { ScriptFile untitledScript = _workspaceService.GetFile(scriptToLaunch); if (BreakpointApiUtils.SupportsBreakpointApis) { // Parse untitled files with their `Untitled:` URI as the file name which will cache the URI & contents within the PowerShell parser. // By doing this, we light up the ability to debug Untitled files with breakpoints. // This is only possible via the direct usage of the breakpoint APIs in PowerShell because // Set-PSBreakpoint validates that paths are actually on the filesystem. ScriptBlockAst ast = Parser.ParseInput(untitledScript.Contents, untitledScript.DocumentUri, out Token[] tokens, out ParseError[] errors);
/// <summary> /// Attempt to find whether a function has SupportsShouldProcess set based on its AST. /// </summary> /// <param name="functionInfo">The function info object referring to the function.</param> /// <param name="hasShouldProcessSet">True if SupportsShouldProcess is set, false if not. Value is not valid if this method returns false.</param> /// <returns>True if a value for SupportsShouldProcess was found, false otherwise.</returns> private bool TryGetShouldProcessValueFromAst(FunctionInfo functionInfo, out bool hasShouldProcessSet) { // Get the body of the function ScriptBlockAst functionBodyAst = (ScriptBlockAst)functionInfo.ScriptBlock.Ast.Find(ast => ast is ScriptBlockAst, searchNestedScriptBlocks: false); // Go through attributes on the parameter block, since this is where [CmdletBinding()] will be foreach (AttributeAst attributeAst in functionBodyAst.ParamBlock.Attributes) { // We're looking for [CmdletBinding()] if (!attributeAst.TypeName.FullName.Equals("CmdletBinding", StringComparison.OrdinalIgnoreCase)) { continue; } foreach (NamedAttributeArgumentAst namedArgumentAst in attributeAst.NamedArguments) { // We want [CmdletBinding(SupportsShouldProcess)] if (!namedArgumentAst.ArgumentName.Equals("SupportsShouldProcess", StringComparison.OrdinalIgnoreCase)) { continue; } // [CmdletBinding(SupportsShouldProcess)] is the same as [CmdletBinding(SupportsShouldProcess = $true)] if (namedArgumentAst.ExpressionOmitted) { hasShouldProcessSet = true; return(true); } // Otherwise try to get the value assigned to the parameter, and assume false if value cannot be determined try { hasShouldProcessSet = LanguagePrimitives.IsTrue( Helper.GetSafeValueFromExpressionAst( namedArgumentAst.Argument)); } catch { hasShouldProcessSet = false; } return(true); } } hasShouldProcessSet = false; return(false); }
public void AstParser() { ScriptBlockAst sb = System.Management.Automation.Language.Parser.ParseInput(sampleScript, out tokens, out ParseError[] errors); // AST type list https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.language?view=powershellsdk-1.1.0 IEnumerable <Ast> astnodeList = sb.FindAll(delegate(Ast t) { return(true); } , true); foreach (var astnode in astnodeList) { asttypeList.Add(astnode.GetType().ToString()); } }
public static void MeasureCommandInjection(string ScriptBlock) { Token[] token; ParseError[] error; ScriptBlockAst ScriptBlockAst = Parser.ParseInput(ScriptBlock, out token, out error); Func <Ast, bool> predicate = delegate(Ast ast) { var derpVar = new VariableExpressionAst(ast.Extent, "Derp", splatted: false); CommandAst targetAst = new CommandAst(ast.Extent, new[] { derpVar }, TokenKind.Unknown, Enumerable.Empty <RedirectionAst>()); if (targetAst != null) { if (targetAst.CommandElements[0].Extent.Text.In(false, new List <string> { "cmd", "powershell" })) { var commandInvoked = targetAst.CommandElements[1]; for (int parameterPosition = 1; parameterPosition < targetAst.CommandElements.Count; parameterPosition++) { if (targetAst.CommandElements[parameterPosition].Extent.Text.In(false, new List <string> { "/c", "/k", "command", "-c", "-enc" })) { commandInvoked = targetAst.CommandElements[parameterPosition + 1]; break; } } if (commandInvoked is ExpandableStringExpressionAst) { return(true); } } } return(false); }; var foundNode = ScriptBlockAst.Find(predicate, true); if (foundNode != null) { Console.WriteLine("[+] Possible injection vulnerability found"); Console.WriteLine(String.Format(@"Possible command injection risk via calling cmd.exe or powershell.exe. Untrusted input can cause arbitrary commands to be run. Input should be provided as variable input directly (such as 'cmd /c ping $destination', rather than within an expandable string. The PowerShell.AddCommand().AddParameter() APIs should be used instead. RuleName = InjectionRisk.CommandInjection Severity = Warning", foundNode.Extent)); } }
public static FunctionDefinitionAst Update( this FunctionDefinitionAst ast, string name = null, ScriptBlockAst body = null, IEnumerable <ParameterAst> parameters = null, bool?isFilter = null, bool?isWorkflow = null) { return(new FunctionDefinitionAst( ast.Extent, isFilter ?? ast.IsFilter, isWorkflow ?? ast.IsWorkflow, name ?? ast.Name, parameters?.CloneAll() ?? ast.Parameters?.CloneAll(), body.Clone() ?? ast.Body.Clone())); }
public virtual ScriptBlockAst VisitScriptBlock(ScriptBlockAst scriptBlockAst) { var attributes = scriptBlockAst.Attributes.Count == 0 ? null : scriptBlockAst.Attributes.RewriteAll(this, SyntaxKind.Attribute); return(new ScriptBlockAst( scriptBlockAst.Extent, scriptBlockAst.UsingStatements?.RewriteAll(this, SyntaxKind.UsingStatement), attributes, scriptBlockAst.ParamBlock?.Rewrite(this, SyntaxKind.ParamBlock), scriptBlockAst.BeginBlock?.Rewrite(this, SyntaxKind.NamedBlock), scriptBlockAst.ProcessBlock?.Rewrite(this, SyntaxKind.NamedBlock), scriptBlockAst.EndBlock?.Rewrite(this, SyntaxKind.NamedBlock), scriptBlockAst.DynamicParamBlock?.Rewrite(this, SyntaxKind.NamedBlock))); }
public System.Object VisitFunctionDefinition(System.Management.Automation.Language.FunctionDefinitionAst functionDefinitionAst) { IScriptExtent mappedExtent = MapExtent(functionDefinitionAst.Extent); LinkedList <ParameterAst> mappedParameters = new LinkedList <ParameterAst>(); if (functionDefinitionAst.Parameters != null) { foreach (ParameterAst p in functionDefinitionAst.Parameters) { mappedParameters.AddLast((ParameterAst)VisitParameter(p)); } } ScriptBlockAst mappedBody = (ScriptBlockAst)VisitScriptBlock(functionDefinitionAst.Body); return(new FunctionDefinitionAst(mappedExtent, functionDefinitionAst.IsFilter, functionDefinitionAst.IsWorkflow, functionDefinitionAst.Name, mappedParameters, mappedBody)); }
public void ValidateSyntax(Script script, ClaimsPrincipal user) { Token[] token = null; ParseError[] errors = null; ScriptBlockAst result = Parser.ParseInput(script.Code, out token, out errors); if (errors != null && errors.Length > 0) { string msg = string.Concat(Environment.NewLine, errors.Select(error => error.Message)); auditLogic.LogOpsError(user, script.Name, EventCategory.JobError, msg); throw new System.Exception("Error while parsing script"); } }
public static void MeasureForeachObjectInjection(string ScriptBlock) { Token[] token; ParseError[] error; ScriptBlockAst ScriptBlockAst = Parser.ParseInput(ScriptBlock, out token, out error); Func <Ast, bool> predicate = delegate(Ast ast) { var derpVar = new VariableExpressionAst(ast.Extent, "Derp", splatted: false); CommandAst targetAst = new CommandAst(ast.Extent, new[] { derpVar }, TokenKind.Unknown, Enumerable.Empty <RedirectionAst>()); if (targetAst != null) { if (targetAst.CommandElements[0].Extent.Text.In(false, new List <string> { "foreach", "%" })) { var memberInvoked = targetAst.CommandElements[1]; for (int parameterPosition = 1; parameterPosition < targetAst.CommandElements.Count; parameterPosition++) { if (targetAst.CommandElements[parameterPosition].Extent.Text.In(false, new List <string> { "process", "membername" })) { memberInvoked = targetAst.CommandElements[parameterPosition + 1]; break; } } if (memberInvoked is ConstantExpressionAst && memberInvoked is ScriptBlockExpressionAst) { return(true); } } } return(false); }; var foundNode = ScriptBlockAst.Find(predicate, true); if (foundNode != null) { Console.WriteLine("[+] Possible injection vulnerability found"); Console.WriteLine(String.Format(@"Possible property access injection via Foreach-Object. Untrusted input can cause arbitrary properties /methods to be accessed: RuleName = InjectionRisk.ForeachObjectInjection Severity = Warning", foundNode.Extent)); } }
private ScriptBlock GetScriptBlockFromFile(string filePath) { if (WildcardPattern.ContainsWildcardCharacters(filePath)) { throw new ArgumentException(Properties.Resources.ResourceManager.GetString("FilePathWildcards")); } if (!filePath.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(Properties.Resources.ResourceManager.GetString("FilePathExt")); } string resolvedPath = null; if (_rs.SessionStateProxy.Path != null) { ProviderInfo provider = null; resolvedPath = _rs.SessionStateProxy.Path.GetResolvedProviderPathFromPSPath(filePath, out provider).FirstOrDefault(); } else { resolvedPath = filePath; } if (!string.IsNullOrEmpty(resolvedPath)) { Token[] tokens; ParseError[] errors; ScriptBlockAst scriptBlockAst = Parser.ParseFile(resolvedPath, out tokens, out errors); if (scriptBlockAst != null && errors.Length == 0) { return(scriptBlockAst.GetScriptBlock()); } foreach (var error in errors) { this.Error.Add( new ErrorRecord( new ParseException(error.Message), "ThreadJobError", ErrorCategory.InvalidData, this)); } } return(null); }
public static ConfigurationParseResult ParseConfiguration(string path) { // Get the resolved script path. This will throw an exception if the file is not found. string fullPath = Path.GetFullPath(path); Token[] tokens; ParseError[] errors; // Parse the script into an AST, capturing parse errors. Note - even with errors, the // file may still successfully define one or more configurations. ScriptBlockAst ast = Parser.ParseFile(fullPath, out tokens, out errors); List <string> requiredModules = GetRequiredModulesFromAst(ast).Distinct().ToList(); return(new ConfigurationParseResult() { Path = fullPath, Errors = errors, RequiredModules = requiredModules, }); }
public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst) { if (!AstContainsPosition(scriptBlockAst)) { return(AstVisitAction.SkipChildren); } // If the scriptblock is closed and we're on the closing brace // then we're not *in* that scriptblock if (scriptBlockAst.Extent.Text.EndsWith("}") && scriptBlockAst.Extent.EndLineNumber == _position.LineNumber && scriptBlockAst.Extent.EndColumnNumber == _position.ColumnNumber) { return(AstVisitAction.SkipChildren); } _astAtPosition = scriptBlockAst; return(AstVisitAction.Continue); }
//public static void MeasureAddType(string ScriptBlock) //{ // Token[] token; // ParseError[] error; // ScriptBlockAst ScriptBlockAst = Parser.ParseInput(ScriptBlock, out token, out error); // // Func<Ast, bool> predicate = delegate (Ast ast) // { // var derpVar = new VariableExpressionAst(ast.Extent, "Derp", splatted: false); // CommandAst targetAst = new CommandAst(ast.Extent, new[] { derpVar }, TokenKind.Unknown, Enumerable.Empty<RedirectionAst>()); // if (targetAst.CommandElements[0].Extent.Text == "Add-Type") // { // var addTypeParameters = StaticParameterBinder.BindCommand(targetAst); // var typeDefinitionParameter = addTypeParameters.BoundParameters.TypeDefinition; // if (typeDefinitionParameter.ConstantValue) // { // if (addTypeParameters.BoundParameters.TypeDefinition.ValueSystem.Management.Automation.Language.VariableExpressionAst) // { // var variableName = addTypeParameters.BoundParameters.TypeDefinition.Value.VariablePath.UserPath; // var constantAssignmentForVariable = ScriptBlockAst.FindAll(tempvar => tempvar is Ast, true); // if (assignmentAst && assignmentAst.Left.VariablePath.UserPath == variableName && assignmentAst.Right.ExpressionSystem.Management.Automation.Language.ConstantExpressionAst) // { // return true; // } // if (constantAssignmentForVariable != null) // { // return false; // } // else // { // return true; // } // } // return true; // } // } // return false; // }; // // var foundNode = ScriptBlockAst.Find(predicate, true); // if (foundNode != null) // { // Console.WriteLine("[+] Possible injection vulnerability found"); // Console.WriteLine(String.Format(@"Possible code injection risk via the Add-Type cmdlet. Untrusted input can cause arbitrary Win32 code to be run.. //RuleName = InjectionRisk.AddType //Severity = Warning", foundNode.Extent // )); // } //} public static void MeasureDangerousMethod(string ScriptBlock) { Token[] token; ParseError[] error; ScriptBlockAst ScriptBlockAst = Parser.ParseInput(ScriptBlock, out token, out error); Func <Ast, bool> predicate = delegate(Ast ast) { var derpVar = new VariableExpressionAst(ast.Extent, "Derp", splatted: false); var derpVar2 = new StringConstantExpressionAst(ast.Extent, "derbvar2", StringConstantType.BareWord); InvokeMemberExpressionAst targetAst = new InvokeMemberExpressionAst(ast.Extent, derpVar, derpVar2, Enumerable.Empty <ExpressionAst>(), false); if (targetAst != null) { if (targetAst.Member.Extent.Text.In(false, new List <string> { "invokescript", "createnestedpipeline", "addscript", "newscriptblock", "expandstring" })) { return(true); } if (targetAst.Member.Extent.Text.In(false, new List <string> { "create" }) && targetAst.Expression.Extent.Text.In(false, new List <string> { "scriptblock" })) { return(true); } } return(false); }; var foundNode = ScriptBlockAst.Find(predicate, true); if (foundNode != null) { Console.WriteLine("[+] Possible injection vulnerability found"); Console.WriteLine(String.Format(@"Possible script injection risk via the a dangerous method. Untrusted input can cause arbitrary PowerShell expressions to be run. The PowerShell.AddCommand().AddParameter() APIs should be used instead. RuleName = {1} Severity = Warning", foundNode.Extent, foundNode.Extent.Text) ); } }
internal ScriptBlock ParseScriptBlock(string script, string fileName, bool interactiveCommand) { ParseError[] errorArray; ScriptBlockAst ast = this.EngineNewParser.Parse(fileName, script, null, out errorArray); if (interactiveCommand) { this.EngineNewParser.SetPreviousFirstLastToken(this._context); } if (!errorArray.Any <ParseError>()) { return(new ScriptBlock(ast, false)); } if (errorArray[0].IncompleteInput) { throw new IncompleteParseException(errorArray[0].Message, errorArray[0].ErrorId); } throw new ParseException(errorArray); }
} // end InvokeWithContext internal static ScriptBlockAst LoadScript(string file) { Token[] tokens; ParseError[] errors; ScriptBlockAst ast = Parser.ParseFile(file, out tokens, out errors); if (0 != errors.Length) { var pe = new ParseException(errors); try { throw pe; } catch (ParseException) { } // give it a stack. throw new DbgProviderException(Util.Sprintf("Error(s) parsing file: {0}.", file), "LoadScriptFailure_ParseErrors", ErrorCategory.ParserError, pe, file); } return(ast); } // end LoadScript
private PSClassInfo ConvertToClassInfo(PSModuleInfo module, ScriptBlockAst ast, TypeDefinitionAst statement) { PSClassInfo classInfo = new PSClassInfo(statement.Name); Dbg.Assert(statement.Name != null, "statement should have a name."); classInfo.Module = module; Collection <PSClassMemberInfo> properties = new Collection <PSClassMemberInfo>(); foreach (var member in statement.Members) { PropertyMemberAst propAst = member as PropertyMemberAst; if (propAst != null) { Dbg.Assert(propAst.Name != null, "PropName cannot be null"); Dbg.Assert(propAst.PropertyType != null, "PropertyType cannot be null"); Dbg.Assert(propAst.PropertyType.TypeName != null, "Property TypeName cannot be null"); Dbg.Assert(propAst.Extent != null, "Property Extent cannot be null"); Dbg.Assert(propAst.Extent.Text != null, "Property ExtentText cannot be null"); PSClassMemberInfo classProperty = new PSClassMemberInfo(propAst.Name, propAst.PropertyType.TypeName.FullName, propAst.Extent.Text); properties.Add(classProperty); } } classInfo.UpdateMembers(properties); string mamlHelpFile = null; if (ast.GetHelpContent() != null) { mamlHelpFile = ast.GetHelpContent().MamlHelpFile; } if (!String.IsNullOrEmpty(mamlHelpFile)) { classInfo.HelpFile = mamlHelpFile; } return(classInfo); }
public static ScriptBlockAst Update( this ScriptBlockAst ast, IEnumerable <UsingStatementAst> usingStatements = null, IEnumerable <AttributeAst> attributes = null, ParamBlockAst paramBlock = null, NamedBlockAst beginBlock = null, NamedBlockAst processBlock = null, NamedBlockAst endBlock = null, NamedBlockAst dynamicParamBlock = null) { return(new ScriptBlockAst( ast.Extent, usingStatements?.CloneAll() ?? ast.UsingStatements?.CloneAll(), attributes?.CloneAll() ?? ast.Attributes?.CloneAll(), paramBlock?.Clone() ?? ast.ParamBlock?.Clone(), beginBlock?.Clone() ?? ast.BeginBlock?.Clone(), processBlock?.Clone() ?? ast.ProcessBlock?.Clone(), endBlock?.Clone() ?? ast.EndBlock?.Clone(), dynamicParamBlock?.Clone() ?? ast.DynamicParamBlock?.Clone())); }