1
+ import powershell
2
+ import semmle.code.powershell.dataflow.TaintTracking
3
+ import semmle.code.powershell.dataflow.DataFlow
4
+ import semmle.code.powershell.ApiGraphs
5
+ import semmle.code.powershell.dataflow.flowsources.FlowSources
6
+
7
+ abstract class InjectionSink extends DataFlow:: Node {
8
+ abstract string getSinkType ( ) ;
9
+ }
10
+
11
+ class InvokeExpressionCall extends InjectionSink {
12
+ InvokeExpressionCall ( ) {
13
+ exists ( CmdCall c |
14
+ this .asExpr ( ) .getExpr ( ) = c .getAnArgument ( ) and
15
+ c .getName ( ) = [ "Invoke-Expression" , "iex" , "Add-Type" ] )
16
+ }
17
+ override string getSinkType ( ) {
18
+ result = "call to Invoke-Expression"
19
+ }
20
+ }
21
+
22
+ class InvokeScriptSink extends InjectionSink {
23
+ InvokeScriptSink ( ) {
24
+ exists ( API:: Node call |
25
+ API:: getTopLevelMember ( "executioncontext" ) .getMember ( "invokecommand" ) .getMethod ( "invokescript" ) = call and
26
+ this = call .getArgument ( _) .asSink ( )
27
+ )
28
+ }
29
+ override string getSinkType ( ) {
30
+ result = "call to InvokeScript"
31
+ }
32
+ }
33
+
34
+ class CreateNestedPipelineSink extends InjectionSink {
35
+ CreateNestedPipelineSink ( ) {
36
+ exists ( API:: Node call |
37
+ API:: getTopLevelMember ( "host" ) .getMember ( "runspace" ) .getMethod ( "createnestedpipeline" ) = call and
38
+ this = call .getArgument ( _) .asSink ( )
39
+ )
40
+ }
41
+ override string getSinkType ( ) {
42
+ result = "call to CreateNestedPipeline"
43
+ }
44
+ }
45
+
46
+ class AddScriptInvokeSink extends InjectionSink {
47
+ AddScriptInvokeSink ( ) {
48
+ exists ( InvokeMemberExpr ie |
49
+ this .asExpr ( ) .getExpr ( ) = ie .getAnArgument ( ) and
50
+ ie .getName ( ) = "AddScript" and
51
+ ie .getQualifier ( ) .( InvokeMemberExpr ) .getName ( ) = "Create" and
52
+ ie .getQualifier ( ) .getAChild ( ) .toString ( ) = "PowerShell" and
53
+ ie .getParent ( ) .( InvokeMemberExpr ) .getName ( ) = "Invoke"
54
+ )
55
+ }
56
+ override string getSinkType ( ) {
57
+ result = "call to AddScript"
58
+ }
59
+ }
60
+
61
+ class PowershellSink extends InjectionSink {
62
+ PowershellSink ( ) {
63
+ exists ( CmdCall c |
64
+ c .getName ( ) = "powershell" |
65
+ (
66
+ this .asExpr ( ) .getExpr ( ) = c .getArgument ( 1 ) and
67
+ c .getArgument ( 0 ) .getValue ( ) .toString ( ) = "-command"
68
+ ) or
69
+ (
70
+ this .asExpr ( ) .getExpr ( ) = c .getArgument ( 0 )
71
+ )
72
+ )
73
+ }
74
+ override string getSinkType ( ) {
75
+ result = "call to Powershell"
76
+ }
77
+ }
78
+
79
+ class CmdSink extends InjectionSink {
80
+ CmdSink ( ) {
81
+ exists ( CmdCall c |
82
+ this .asExpr ( ) .getExpr ( ) = c .getArgument ( 1 ) and
83
+ c .getName ( ) = "cmd" and
84
+ c .getArgument ( 0 ) .getValue ( ) .toString ( ) = "/c"
85
+ )
86
+ }
87
+ override string getSinkType ( ) {
88
+ result = "call to Cmd"
89
+ }
90
+ }
91
+
92
+ class ForEachObjectSink extends InjectionSink {
93
+ ForEachObjectSink ( ) {
94
+ exists ( CmdCall c |
95
+ this .asExpr ( ) .getExpr ( ) = c .getAnArgument ( ) and
96
+ c .getName ( ) = "Foreach-Object"
97
+ )
98
+ }
99
+ override string getSinkType ( ) {
100
+ result = "call to ForEach-Object"
101
+ }
102
+ }
103
+
104
+ class InvokeSink extends InjectionSink {
105
+ InvokeSink ( ) {
106
+ exists ( InvokeMemberExpr ie |
107
+ this .asExpr ( ) .getExpr ( ) = ie .getCallee ( ) or
108
+ this .asExpr ( ) .getExpr ( ) = ie .getQualifier ( ) .getAChild * ( )
109
+ )
110
+ }
111
+ override string getSinkType ( ) {
112
+ result = "call to Invoke"
113
+ }
114
+ }
115
+
116
+ class CreateScriptBlockSink extends InjectionSink {
117
+ CreateScriptBlockSink ( ) {
118
+ exists ( InvokeMemberExpr ie |
119
+ this .asExpr ( ) .getExpr ( ) = ie .getAnArgument ( ) and
120
+ ie .getName ( ) = "Create" and
121
+ ie .getQualifier ( ) .toString ( ) = "ScriptBlock"
122
+ )
123
+ }
124
+ override string getSinkType ( ) {
125
+ result = "call to CreateScriptBlock"
126
+ }
127
+ }
128
+
129
+ class NewScriptBlockSink extends InjectionSink {
130
+ NewScriptBlockSink ( ) {
131
+ exists ( API:: Node call |
132
+ API:: getTopLevelMember ( "executioncontext" ) .getMember ( "invokecommand" ) .getMethod ( "newscriptblock" ) = call and
133
+ this = call .getArgument ( _) .asSink ( )
134
+ )
135
+ }
136
+ override string getSinkType ( ) {
137
+ result = "call to NewScriptBlock"
138
+ }
139
+ }
140
+
141
+ class ExpandStringSink extends InjectionSink {
142
+ ExpandStringSink ( ) {
143
+ exists ( API:: Node call | this = call .getArgument ( _) .asSink ( ) |
144
+ API:: getTopLevelMember ( "executioncontext" ) .getMember ( "invokecommand" ) .getMethod ( "expandstring" ) = call or
145
+ API:: getTopLevelMember ( "executioncontext" ) .getMember ( "sessionstate" ) .getMember ( "invokecommand" ) .getMethod ( "expandstring" ) = call
146
+
147
+ )
148
+ }
149
+ override string getSinkType ( ) {
150
+ result = "call to ExpandString"
151
+ }
152
+ }
0 commit comments