/// <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);
        }
Esempio n. 2
0
            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);
            }
Esempio n. 3
0
            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);
            }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
                    }
                }
            }
        }
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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));
        }
Esempio n. 12
0
        /// <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());
        }
Esempio n. 13
0
        /// <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);
Esempio n. 15
0
        /// <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());
            }
        }
Esempio n. 17
0
        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)));
        }
Esempio n. 20
0
    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));
    }
Esempio n. 21
0
        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");
            }
        }
Esempio n. 22
0
        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));
            }
        }
Esempio n. 23
0
        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,
            });
        }
Esempio n. 25
0
        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);
        }
Esempio n. 26
0
        //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)
                                  );
            }
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        }     // 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
Esempio n. 29
0
        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()));
 }