-
Notifications
You must be signed in to change notification settings - Fork 0
/
kotlin_external.kts
executable file
·195 lines (146 loc) · 6.25 KB
/
kotlin_external.kts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import org.apache.commons.httpclient.URI
import org.apache.log4j.LogManager
import org.parosproxy.paros.network.HttpHeader
import org.parosproxy.paros.network.HttpMessage
import org.parosproxy.paros.network.HttpRequestHeader
import org.zaproxy.zap.authentication.AuthenticationHelper
import org.zaproxy.zap.authentication.GenericAuthenticationCredentials
import org.zaproxy.zap.extension.script.ScriptVars
import java.io.InputStreamReader
import java.io.BufferedReader
import java.io.FileInputStream
import java.net.HttpCookie
// based on the template kotlin auth https://github.com/zaproxy/zap-extensions/blob/main/addOns/kotlin/src/main/zapHomeFiles/scripts/templates/authentication/Authentication%20default%20template.kts
val logger = LogManager.getLogger("external-script")
// This function is called before a scan is started and when the loggedOutIndicator is matched indicating re-authentication is needed.
fun authenticate(
helper: AuthenticationHelper,
paramsValues: Map<String, String>,
credentials: GenericAuthenticationCredentials
): HttpMessage {
var authFile = paramsValues["auth_script_file"]
val processBuilderPip = ProcessBuilder()
val processBuilder = ProcessBuilder()
// Build command to run script
// a new processBuilder should be created for each command
processBuilderPip.command("pip3", "install", "-r", "requirements.txt")
processBuilder.command("python3", authFile)
val testPath = paramsValues["test_path"]
var msg = helper.prepareMessage();
var requestUri = URI(testPath, false);
var requestMethod = HttpRequestHeader.GET
var requestHeader = HttpRequestHeader(requestMethod, requestUri, HttpHeader.HTTP11)
try {
logger.info("Starting special process")
val pipProcess: Process = processBuilderPip.start()
val process: Process = processBuilder.start()
val pipReader = BufferedReader(InputStreamReader(pipProcess.inputStream))
val reader = BufferedReader(InputStreamReader(process.inputStream))
val pipErrorReader = BufferedReader(InputStreamReader(pipProcess.errorStream))
val errorReader = BufferedReader(InputStreamReader(process.errorStream))
logger.info(pipReader.readText())
logger.info(reader.readText())
logger.info("waiting for processes")
val pipExitVal = pipProcess.waitFor()
val exitVal = process.waitFor()
logger.info("process finished")
if (exitVal == 0) {
if (paramsValues.containsKey("cookie_file")) {
val cookieFile = paramsValues["cookie_file"]
cookieFile?.let {
readAndInjectCookies(it, requestHeader)
}
}
if (paramsValues.containsKey("token_file")) {
val tokenFile = paramsValues["token_file"]
tokenFile?.let {
logger.info("This is the name of the token file $it}")
readAndInjectTokens(it, requestHeader)
}
}
} else {
logger.info("There was an issue processing the file")
logger.error(errorReader.readText())
}
} catch (e: Exception) {
logger.info(e.printStackTrace())
throw e
}
requestHeader.contentLength = msg.requestBody.length();
msg.requestHeader = requestHeader;
logger.info("Request Header ${msg.requestHeader}")
logger.info("Request Body ${msg.requestBody}")
helper.sendAndReceive(msg)
logger.info("Response Header ${msg.responseHeader}")
logger.info("Response Body ${msg.responseBody}")
return msg
}
fun readAndInjectAuth(file : String, type: String, requestHeader: HttpRequestHeader) {
val reader = FileInputStream(file).bufferedReader()
val iterator = reader.lines().iterator()
var i = 0;
while (iterator.hasNext()) {
val line = iterator.next()
logger.info(line)
readLineAndAddToken(line, type, requestHeader, i)
i++
}
}
fun readAndInjectCookies(file : String, requestHeader: HttpRequestHeader) {
readAndInjectAuth(file, "cookie", requestHeader )
}
fun readAndInjectTokens(file : String, requestHeader: HttpRequestHeader) {
readAndInjectAuth(file, "token", requestHeader )
}
fun readLineAndAddToken(line : String, type : String, httpRequestHeader: HttpRequestHeader, iterator: Int) {
val token = splitString(line)
token?.let {
addValueToScriptVar(it.first, it.second, type, iterator)
when (type) {
"token" -> addTokenToHeader(httpRequestHeader, it.first, it.second)
"cookie" -> addCookieToMessage(httpRequestHeader, HttpCookie(it.first, it.second))
}
}
}
fun splitString(line : String) : Pair<String, String>? {
line.split(":").let{
return Pair(it[0], it[1])
}
}
fun addValueToScriptVar(name : String, value: String, type : String, iterator: Int) {
ScriptVars.setGlobalVar("${type}Name$iterator", name)
ScriptVars.setGlobalVar("${type}Value$iterator", value)
}
fun addCookieToMessage(requestHeader: HttpRequestHeader, cookie: HttpCookie) {
val cookies = requestHeader.httpCookies
cookies?.removeIf {it.name == cookie.name}
cookies.add(cookie)
logger.info("Adding cookie ${cookie.name} with value ${cookie.value}")
requestHeader.setCookies(cookies)
}
fun addTokenToHeader(requestHeader: HttpRequestHeader, name : String, value : String) {
logger.info("Adding header $name with value $value")
requestHeader.setHeader(name, value)
}
// The required parameter names for your script, your script will throw an error if these are not supplied in the script.parameters configuration.
// getRequiredParamsNames
fun getRequiredParamsNames(): Array<String> {
return arrayOf("test_path", "auth_script_file")
}
// The required credential parameters, your script will throw an error if these are not supplied in the script.credentials configuration.
fun getCredentialsParamsNames(): Array<String> {
return arrayOf()
}
fun getOptionalParamsNames(): Array<String> {
return arrayOf("cookie_file")
}
fun getLoggedOutIndicator() : String {
return "DfE Sign-in"
}
// fun getLoggedInIndicator() : String {
// return "Access DfE services"
// }
// getLoggedInIndicator
fun getLoggedInIndicator(): String {
return "Access DfE services"
}