From 9317595bc56ba917e9cccfe9006f21557ca9bd6d Mon Sep 17 00:00:00 2001 From: Manos Kirtas Date: Tue, 9 Jul 2019 18:21:10 +0300 Subject: [PATCH] [WS-Passive-Scan] Add Error Application Disclosure scan with regexp --- .../Application Error Scanner Regex.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 addOns/websocket/src/main/zapHomeFiles/scripts/templates/websocketpassive/Application Error Scanner Regex.js diff --git a/addOns/websocket/src/main/zapHomeFiles/scripts/templates/websocketpassive/Application Error Scanner Regex.js b/addOns/websocket/src/main/zapHomeFiles/scripts/templates/websocketpassive/Application Error Scanner Regex.js new file mode 100755 index 00000000000..388de86a7e4 --- /dev/null +++ b/addOns/websocket/src/main/zapHomeFiles/scripts/templates/websocketpassive/Application Error Scanner Regex.js @@ -0,0 +1,69 @@ +// * This Script analyzes incoming websocket messages for error messages with a set of regular expressions + +// * Based on org.zaproxy.zap.extension.pscanrules.ApplicationErrorScanner +// * Application error strings are equal to (characters '/' is escaped -> '//'): +// ** https://github.com/zaproxy/zap-extensions/blob/master/addOns/pscanrules/src/main/resources/org/zaproxy/zap/extension/pscanrules/resources/application_errors.xml + +// Author: Manos Kirtas (manolis.kirt@gmail.com) + +OPCODE_TEXT = 0x1; +RISK_MEDIUM = 2; +CONFIDENCE_MEDIUM = 2; + +patterns = ["(?i)Line\\s\\d+:\\sIncorrect\\ssyntax\\snear\\s'[^']*'", + "(?i)pg_query\\(\\)[:]*\\squery\\sfailed:\\serror:\\s", + "(?i)'[^']*'\\sis\\snull\\sor\\snot\\san\\sobject", + "(?i)ORA\\-\\d{4,5}:\\s", + "(?i)Microsoft\\sJET\\sDatabase\\sEngine\\s\\([^\\)]*\\)<br>Syntax\\serror(.*)\\sin\\squery\\sexpression\\s'.*\\.<br><b>.*,\\sline\\s\\d+</b><br>", + "(?i)<h2>\\s<i>Syntax\\serror\\s(\\([^\\)]*\\))?(in\\sstring)?\\sin\\squery\\sexpression\\s'[^\\.]*\\.</i>\\s</h2></span>", + "(?i)<font\\sface=\"Arial\"\\ssize=2>Syntax\\serror\\s(.*)?in\\squery\\sexpression\\s'(.*)\\.</font>", + "(?i)<b>Warning</b>:\\s\\spg_exec\\(\\)\\s\\[\\<a\\shref='function.pg\\-exec\\'\\>function\\.pg-exec\\</a>\\]\\:\\sQuery failed:\\sERROR:\\s\\ssyntax error at or near \\&quot\\;\\\\\\&quot; at character \\d+ in\\s<b>.*</b>", + "(?i)System\\.Data\\.OleDb\\.OleDbException\\:\\sSyntax\\serror\\s\\([^)]*?\\)\\sin\\squery\\sexpression\\s.*", + "(?i)System\\.Data\\.OleDb\\.OleDbException\\:\\sSyntax\\serror\\sin\\sstring\\sin\\squery\\sexpression\\s", + "<font style=\"COLOR: black; FONT: 8pt/11pt verdana\">\\s+(\\[Macromedia\\]\\[SQLServer\\sJDBC\\sDriver\\]\\[SQLServer\\]|Syntax\\serror\\sin\\sstring\\sin\\squery\\sexpression\\s)", + "(?i)The Error Occurred in <b>(.*): line.*<\/b><br>", + "(?i)The error occurred while processing.*Template: (.*) <br>.", + "(?i)The error occurred while processing.*in the template file (.*)\\.<\/p><br>", + "(?i)<span><H1>Server\\sError\\sin\\s'[^']*'\\sApplication\\.<hr\\swidth=100%\\ssize=1\\scolor=silver></H1>", + "(?i)<title>Invalid\\sfile\\sname\\sfor\\smonitoring:\\s'([^']*)'\\.\\sFile\\snames\\sfor\\smonitoring\\smust\\shave\\sabsolute\\spaths\\,\\sand\\sno\\swildcards\\.</title>", + "(?i)<b>(Warning|Fatal\\serror|Parse\\serror)</b>:\\s+.*?\\sin\\s<b>.*?</b>\\son\\sline\\s<b>\\d*?</b><br\\s/>", + "(?:Unknown database '.*?')|(?:No database selected)|(?:Table '.*?' doesn't exist)|(?:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.*?' at line .*?)", + "Exception report.*message.*description.*exception.*note.*", + "(?i)<head><title>JRun Servlet Error</title></head>", + "(?i)<h1>Servlet\\sError:\\s\\w+?</h1>", + "(?i)Servlet\\sError</title>"]; + +var errorPatterns = []; +patterns.forEach(function(pattern){ + errorPatterns.push(java.util.regex.Pattern.compile(pattern)); +}); + +function scan(helper,msg) { + + if(msg.opcode != OPCODE_TEXT || msg.isOutgoing){ + return; + } + var message = String(msg.getReadablePayload()); + + errorPatterns.forEach(function(pattern){ + var matcher = pattern.matcher(message); + while(matcher.find()){ + helper.newAlert() + .setRiskConfidence(RISK_MEDIUM, CONFIDENCE_MEDIUM) + .setName("Application Error Disclosure via WebSockets (regex-script)") + .setDescription("This payload contains an error/warning message that\ + may disclose sensitive information like the location of the file\ + that produced the unhandled exception. This information can be used\ + to launch further attacks against the web application.") + .setSolution("Review the error payloads which are piped directly to WebSockets.\ + Handle the related exceptions.\ + Consider implementing a mechanism to provide a unique\ + error reference/identifier to the client (browser) while logging the\ + details on the server side and not exposing them to the user.") + .setEvidence(String(matcher.group())) + .setCweId(209) // Information Exposure Through an Error Message + .setWascId(13) //Information Leakage + .raise(); + } + }); +}