Skip to content

Commit d91fc55

Browse files
authored
Merge pull request #1 from zaproxy/master
pulling in changes
2 parents 6bd9e8f + 87ad393 commit d91fc55

125 files changed

Lines changed: 5972 additions & 1314 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
* text=auto
2+
3+
*.conf text
4+
*.gradle text
5+
*.gradle.kts text
6+
*.java text
7+
*.js text
8+
*.md text
9+
*.properties text
10+
*.py text
11+
*.txt text
12+
*.zest text
13+
*.zst text
14+
15+
*.bat text eol=crlf
16+
*.sh text eol=lf
17+
gradlew text eol=lf
18+
19+
*.jar binary

.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Gradle
2+
#-------
3+
.gradle
4+
/build
5+
/buildSrc/build
6+
7+
# IDEA
8+
# ----
9+
.idea
10+
.shelf
11+
/*.iml
12+
/*.ipr
13+
/*.iws
14+
/buildSrc/*.iml
15+
/buildSrc/*.ipr
16+
/buildSrc/*.iws
17+
/buildSrc/out
18+
/out
19+
20+
# Eclipse
21+
# -------
22+
*.pydevproject
23+
.metadata
24+
tmp/
25+
*.tmp
26+
*.bak
27+
*.swp
28+
*~.nib
29+
local.properties
30+
.loadpath
31+
*.classpath
32+
*.project
33+
*.settings
34+
/bin
35+
RemoteSystemsTempFiles/
36+
.externalToolBuilders/
37+
*.launch
38+
.cproject
39+
.buildpath
40+
41+
# NetBeans
42+
# --------
43+
.nb-gradle
44+
.nb-gradle-properties

.project

Lines changed: 0 additions & 11 deletions
This file was deleted.

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: java
2+
sudo: false
3+
4+
jdk:
5+
- openjdk8
6+
- openjdk11
7+
8+
before_cache:
9+
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
10+
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
11+
cache:
12+
directories:
13+
- $HOME/.gradle/caches/
14+
- $HOME/.gradle/wrapper/

active/TestInsecureHTTPVerbs.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
Note that new active scripts will initially be disabled
3+
Right click the script in the Scripts tree and select "enable"
4+
"""
5+
6+
"""
7+
Active Scan Python script to test if the webserver has potentially insecure http methods enabled
8+
Author: http://renouncedthoughts.wordpress.com
9+
10+
11+
Tested to work with some of the online vulnerable applications like:
12+
http://zero.webappsecurity.com
13+
http://testaspnet.vulnweb.com
14+
http://testfire.net/
15+
http://crackme.cenzic.com
16+
17+
and other apps from https://www.owasp.org/index.php/OWASP_Vulnerable_Web_Applications_Directory_Project#tab=On-Line_apps
18+
19+
For some reasons, the order of the array insecureverbs could throw a java.net.SocketTimeoutException, for example with some proxies when TRACE is called just after DELETE
20+
If you encounter such issues, try to change the order on the following line
21+
"""
22+
23+
insecureverbs=["HEAD", "TRACE", "OPTIONS", "PUT", "DELETE", "CONNECT", "DEBUG", "MOVE", "SEARCH", "PATCH", "MKCOL", "COPY", "LOCK", "UNLOCK", "ARBIT", "XXXX", "12AB"]
24+
acceptedhttpstatuscodesforinsecureverbs=[301, 302, 404, 405, 403, 400, 501] # if we get a response code that is not a part of this array, then flag as potentially vulnerable
25+
activevulnerabilitytitle='Potentially Insecure HTTP Verb allowed'
26+
activevulnerabilityfulldescription='Some of the HTTP methods can potentially pose a security risk for a web application, as they allow an attacker to modify the files stored on the web server and, in some scenarios, steal the credentials of legitimate users.' + 'Insecure configuration can possibly lead to web server compromise and website defacement. ' + 'If an application needs one or more of the potentially insecure HTTP methods, such as for REST Web Services (which may require PUT or DELETE), it is important to check that their usage is properly limited to trusted users and safe conditions. ' + 'http://security.stackexchange.com/questions/21413/how-to-exploit-http-methods.'
27+
activevulnerabilitysolution = 'Configure the web server to allow insecure methods like DELETE and PUT only for the relevant resources. ' + 'If your application does not need HTTP methods other than GET and POST, consider disabling the unused HTTP methods.'
28+
printdebugmessages = True
29+
#printdebugmessages= False
30+
31+
def PrintAlerts(sas, msg, uri, insecureverb, responsestatuscode, responsestatusmessage):
32+
attackevidence = 'VERB: \t' + insecureverb + '\t-- HTTP STATUS CODE: '+ str(responsestatuscode) +' -- \tMESSAGE: ' + responsestatusmessage + '\t\t-- POTENTIALLY VULNERABLE: YES\n'
33+
if printdebugmessages:
34+
print (attackevidence)
35+
sas.raiseAlert(1, 2, activevulnerabilitytitle, activevulnerabilityfulldescription, uri, 'HTTP VERB', 'ZAP sent an HTTP request with method - ' + insecureverb, '', activevulnerabilitysolution, attackevidence, 0, 0, msg);
36+
37+
38+
def ProcessAndPrintAlert(sas, msg, uri, insecureverb):
39+
if not msg.getResponseHeader().getStatusCode() in acceptedhttpstatuscodesforinsecureverbs:
40+
PrintAlerts(sas, msg, uri, insecureverb, msg.getResponseHeader().getStatusCode(), msg.getResponseHeader().getReasonPhrase())
41+
42+
43+
def PrepareHttpRequest(msg, insecureverb):
44+
msg.mutateHttpMethod(insecureverb)
45+
if insecureverb == "POST" or insecureverb == "PUT":
46+
msg.setRequestBody("bodytext")
47+
msg.getRequestHeader().setContentLength(msg.getRequestBody().length());
48+
if printdebugmessages:
49+
print('After mutating resulting HTTP VERB: -- \t' + msg.getRequestHeader().getMethod() + '\n')
50+
51+
52+
def TestTheURIForInsecureVerbs(sas, msg, uri, insecureverbs):
53+
for insecureverb in insecureverbs:
54+
try:
55+
if printdebugmessages:
56+
print ('Testing Initiated for the HTTP VERB: -- \t' + insecureverb + '\n')
57+
msg = msg.cloneRequest();
58+
PrepareHttpRequest(msg, insecureverb)
59+
sas.sendAndReceive(msg, False)
60+
if printdebugmessages:
61+
print('VERB: \t' + insecureverb + '\t-- STATUS: '+ str(msg.getResponseHeader().getStatusCode()) +' -- \tMESSAGE: ' + msg.getResponseHeader().getReasonPhrase() + '\n')
62+
ProcessAndPrintAlert(sas, msg, uri, insecureverb)
63+
except Exception, e:
64+
print('ERROR For: ' + insecureverb + 'Detail: ' + e.message + '\n')
65+
66+
67+
def scanNode(sas, msg):
68+
url = msg.getRequestHeader().getURI().toString()
69+
if printdebugmessages:
70+
print('Active scan script called for url = ' + url + '\n')
71+
print('Testing for insecure verbs against a list of accepted http response status codes for the url = ' + url + '\n')
72+
TestTheURIForInsecureVerbs(sas, msg, url, insecureverbs)
73+
74+
75+
def scan(sas, msg, param, value):
76+
pass

active/User defined attacks.js

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
// An example active scan rule script which uses a set of attack payloads and a set of regexes
2+
// in order to find potential issues.
3+
// Replace or extend the attacks and evidence regexes with you own values.
4+
5+
// Note that new active scripts will initially be disabled
6+
// Right click the script in the Scripts tree and select "enable"
7+
8+
// Replace or extend these with your own attacks
9+
// put the attacks you most want to run higher, unless you disable the attack strength check
10+
var attacks = [
11+
'<>"\'%;)(&+',
12+
'\'',
13+
'\' --',
14+
'|',
15+
'!',
16+
'?',
17+
'/',
18+
'//',
19+
'//*',
20+
'(',
21+
')',
22+
'*|',
23+
'*/*',
24+
'{',
25+
'}',
26+
]
27+
28+
// Replace or extend these with your own evidence - regexes that indicate potential issues
29+
// The default ones are a subset of https://github.com/fuzzdb-project/fuzzdb/blob/master/regex/errors.txt
30+
var evidence = [
31+
"A syntax error has occurred",
32+
"Active Server Pages error",
33+
"ADODB.Field error",
34+
"An illegal character has been found in the statement",
35+
"An unexpected token .* was found",
36+
"ASP\.NET is configured to show verbose error messages",
37+
"ASP\.NET_SessionId",
38+
"Custom Error Message",
39+
"database error",
40+
"DB2 Driver",
41+
"DB2 Error",
42+
"DB2 ODBC",
43+
"detected an internal error",
44+
"Error converting data type varchar to numeric",
45+
"Error Diagnostic Information",
46+
"Error Report",
47+
"Fatal error",
48+
"Incorrect syntax near",
49+
"Index of",
50+
"Internal Server Error",
51+
"Invalid Path Character",
52+
"Invalid procedure call or argument",
53+
"invalid query",
54+
"Invision Power Board Database Error",
55+
"is not allowed to access",
56+
"JDBC Driver",
57+
"JDBC Error",
58+
"JDBC MySQL",
59+
"JDBC Oracle",
60+
"JDBC SQL",
61+
"Microsoft OLE DB Provider for ODBC Drivers",
62+
"Microsoft VBScript compilation error",
63+
"Microsoft VBScript error",
64+
"MySQL Driver",
65+
"mysql error",
66+
"MySQL Error",
67+
"mySQL error with query",
68+
"MySQL ODBC",
69+
"ODBC DB2",
70+
"ODBC Driver",
71+
"ODBC Error",
72+
"ODBC Microsoft Access",
73+
"ODBC Oracle",
74+
"ODBC SQL",
75+
"OLE/DB provider returned message",
76+
"on line",
77+
"on MySQL result index",
78+
"Oracle DB2",
79+
"Oracle Driver",
80+
"Oracle Error",
81+
"Oracle ODBC",
82+
"Parent Directory",
83+
"PHP Error",
84+
"PHP Parse error",
85+
"PHP Warning",
86+
"PostgreSQL query failed",
87+
"server object error",
88+
"SQL command not properly ended",
89+
"SQL Server Driver",
90+
"SQLException",
91+
"supplied argument is not a valid",
92+
"Syntax error in query expression",
93+
"The error occurred in",
94+
"The script whose uid is",
95+
"Type mismatch",
96+
"Unable to jump to row",
97+
"Unclosed quotation mark before the character string",
98+
"unexpected end of SQL command",
99+
"unexpected error",
100+
"Unterminated string constant",
101+
"Warning: mysql_query",
102+
"Warning: pg_connect",
103+
"You have an error in your SQL syntax near",
104+
]
105+
106+
/**
107+
* Scans a "node", i.e. an individual entry in the Sites Tree.
108+
* The scanNode function will typically be called once for every page.
109+
*
110+
* @param as - the ActiveScan parent object that will do all the core interface tasks
111+
* (i.e.: sending and receiving messages, providing access to Strength and Threshold settings,
112+
* raising alerts, etc.). This is an ScriptsActiveScanner object.
113+
* @param msg - the HTTP Message being scanned. This is an HttpMessage object.
114+
*/
115+
function scanNode(as, msg) {
116+
// Do nothing here - this script just attacks parameters rather than nodes
117+
}
118+
119+
/**
120+
* Scans a specific parameter in an HTTP message.
121+
* The scan function will typically be called for every parameter in every URL and Form for every page.
122+
*
123+
* @param as - the ActiveScan parent object that will do all the core interface tasks
124+
* (i.e.: sending and receiving messages, providing access to Strength and Threshold settings,
125+
* raising alerts, etc.). This is an ScriptsActiveScanner object.
126+
* @param msg - the HTTP Message being scanned. This is an HttpMessage object.
127+
* @param {string} param - the name of the parameter being manipulated for this test/scan.
128+
* @param {string} value - the original parameter value.
129+
*/
130+
function scan(as, msg, param, value) {
131+
// Debugging can be done using print like this
132+
//print('scan called for url=' + msg.getRequestHeader().getURI().toString() +
133+
// ' param=' + param + ' value=' + value);
134+
135+
var max_attacks = attacks.length // No limit for the "INSANE" level ;)
136+
137+
if (as.getAttackStrength() == "LOW") {
138+
max_attacks = 6
139+
} else if (as.getAttackStrength() == "MEDIUM") {
140+
max_attacks = 12
141+
} else if (as.getAttackStrength() == "HIGH") {
142+
max_attacks = 24
143+
}
144+
145+
for (var i in attacks) {
146+
// Dont exceed recommended number of attacks for strength
147+
// feel free to disable this locally ;)
148+
if (i > max_attacks) {
149+
return
150+
}
151+
// Copy requests before reusing them
152+
msg = msg.cloneRequest();
153+
154+
// setParam (message, parameterName, newValue)
155+
as.setParam(msg, param, attacks[i]);
156+
157+
// sendAndReceive(msg, followRedirect, handleAntiCSRFtoken)
158+
as.sendAndReceive(msg, false, false);
159+
160+
// Add any generic checks here, eg
161+
var code = msg.getResponseHeader().getStatusCode()
162+
if (code >= 500 && code < 600) {
163+
raiseAlert(as, msg, param, attacks[i], code)
164+
// Only raise one alert per param
165+
return
166+
}
167+
168+
var body = msg.getResponseBody().toString()
169+
var re = new RegExp(evidence.join("|"), "i")
170+
var found = body.match(re)
171+
if (found) { // Change to a test which detects the vulnerability
172+
raiseAlert(as, msg, param, attacks[i], found)
173+
// Only raise one alert per param
174+
return
175+
}
176+
177+
// Check if the scan was stopped before performing lengthy tasks
178+
if (as.isStop()) {
179+
return
180+
}
181+
}
182+
}
183+
184+
function raiseAlert(as, msg, param, attack, evidence) {
185+
// Replace with more suitable information
186+
// raiseAlert(risk, int confidence, String name, String description, String uri,
187+
// String param, String attack, String otherInfo, String solution, String evidence,
188+
// int cweId, int wascId, HttpMessage msg)
189+
// risk: 0: info, 1: low, 2: medium, 3: high
190+
// confidence: 0: falsePositive, 1: low, 2: medium, 3: high, 4: confirmed
191+
as.raiseAlert(1, 1, 'Active Vulnerability Title', 'Full description',
192+
msg.getRequestHeader().getURI().toString(),
193+
param, attack, 'Any other info', 'The solution ', evidence, 0, 0, msg);
194+
}
195+

0 commit comments

Comments
 (0)