forked from zaproxy/community-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Telerik Using Poor Crypto.js
175 lines (138 loc) · 5.12 KB
/
Telerik Using Poor Crypto.js
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
// This community script will check if a request is made to the Telerik
// DialogHandler using poor cryptography (CVE-2017-9248)
// (c) 2017 Harrison Neal
// http://www.apache.org/licenses/LICENSE-2.0
function scan(ps, msg, src) {
var alertRisk = org.parosproxy.paros.core.scanner.Alert.RISK_HIGH;
var alertTitle = "Telerik UI for ASP.NET AJAX CVE-2017-9248 Cryptographic Weakness";
var alertDesc = "A request has been made that appears to conform to poor cryptography used by Telerik UI for ASP.NET AJAX prior to v2017.2.621. An attacker could manipulate the value of the dp parameter to possibly learn the machine key and upload arbitrary files, which could then lead to the compromise of ASP.NET ViewStates and arbitrary code execution respectively. CVE-2017-9248 has a CVSSv3 score of 9.8. ";
var alertSolution = "See http://www.telerik.com/support/kb/aspnet-ajax/details/cryptographic-weakness for update/mitigation guidance."
var cweId = 327;
var wascId = 0;
var url = msg.getRequestHeader().getURI().toString();
var param = "dp";
var dp = null;
for (var iterator = msg.getUrlParams().iterator(); iterator.hasNext();) {
var urlParam = iterator.next();
if (urlParam.getName() == param) {
dp = urlParam.getValue();
break;
}
}
if (dp == null) {
return;
}
if (!org.apache.commons.codec.binary.Base64.isBase64(dp)) {
return;
}
var dpBytes = org.apache.commons.codec.binary.Base64.decodeBase64(dp);
if (dpBytes.length < 48) {
return;
}
for (var dpByteIdx = 0; dpByteIdx < dpBytes.length; dpByteIdx++) {
if (!(dpBytes[dpByteIdx] >= 0 && dpBytes[dpByteIdx] <= 127)) {
return;
}
}
var foundComma = 0;
var foundSemicolon = 0;
for (var blockStart = 0; blockStart < 48; blockStart += 4) {
var keyPossibilities1 = new Array(4);
var thisBlockAppearsValid = 0;
for (var keyIdx = 0; keyIdx < 4; keyIdx++) {
keyPossibilities1[keyIdx] = new Array(96);
for (var possibleIdx = 0; possibleIdx < 96; possibleIdx++) {
keyPossibilities1[keyIdx][possibleIdx] = 1;
}
for (dpByteIdx = blockStart + keyIdx; dpByteIdx < dpBytes.length; dpByteIdx += 48) {
for (possibleIdx = 0; possibleIdx < 96; possibleIdx++) {
var ctx = dpBytes[dpByteIdx];
var key = possibleIdx + 32;
var xor = ctx ^ key;
var chr = String.fromCharCode(xor);
if (!org.apache.commons.codec.binary.Base64.isBase64(chr)) {
keyPossibilities1[keyIdx][possibleIdx] = 0;
}
}
}
}
var keyPossibilities2 = new Array();
for (var key0Idx = 0; key0Idx < 96; key0Idx++) {
if (keyPossibilities1[0][key0Idx] == 0) {
continue;
}
for (var key1Idx = 0; key1Idx < 96; key1Idx++) {
if (keyPossibilities1[1][key1Idx] == 0) {
continue;
}
for (var key2Idx = 0; key2Idx < 96; key2Idx++) {
if (keyPossibilities1[2][key2Idx] == 0) {
continue;
}
for (var key3Idx = 0; key3Idx < 96; key3Idx++) {
if (keyPossibilities1[3][key3Idx] == 0) {
continue;
}
keyPossibilities2.push([key0Idx + 32, key1Idx + 32, key2Idx + 32, key3Idx + 32]);
}
}
}
}
for (possibleIdx = 0; possibleIdx < keyPossibilities2.length; possibleIdx++) {
var thisKeyValidSoFar = 1;
var thisKeyFoundComma = 0;
var thisKeyFoundSemicolon = 0;
for (var blockOffset = 0; blockOffset + blockStart + 4 <= dpBytes.length; blockOffset += 48) {
var ptBase64 = "";
for (var byteIdx = 0; byteIdx < 4; byteIdx++) {
ctx = dpBytes[blockOffset + blockStart + byteIdx];
key = keyPossibilities2[possibleIdx][byteIdx];
xor = ctx ^ key;
chr = String.fromCharCode(xor);
ptBase64 += chr;
}
var pt = org.apache.commons.codec.binary.Base64.decodeBase64(ptBase64);
for (byteIdx = 0; byteIdx < pt.length; byteIdx++) {
if (!(pt[byteIdx] >= 32 && pt[byteIdx] <= 127)) {
thisKeyValidSoFar = 0;
break;
}
if (pt[byteIdx] == 44) {
thisKeyFoundComma = 1;
}
if (pt[byteIdx] == 59) {
thisKeyFoundSemicolon = 1;
}
}
if (thisKeyValidSoFar == 0) {
break;
}
}
if (thisKeyValidSoFar == 1) {
thisBlockAppearsValid = 1;
if (thisKeyFoundComma == 1) {
foundComma = 1;
}
if (thisKeyFoundSemicolon == 1) {
foundSemicolon = 1;
}
}
}
if (thisBlockAppearsValid == 0) {
return;
}
}
if (foundComma == 0 || foundSemicolon == 0) {
return;
}
var alertReliability = null;
if (url.contains("DialogHandler.aspx")) {
alertReliability = org.parosproxy.paros.core.scanner.Alert.CONFIDENCE_HIGH;
alertDesc += "The URI strongly suggests this is a Telerik.Web.UI.DialogHandler instance; confidence is HIGH.";
} else {
alertReliability = org.parosproxy.paros.core.scanner.Alert.CONFIDENCE_MEDIUM;
alertDesc += "The URI is not typical for a Telerik.Web.UI.DialogHandler instance, so it may have been changed (e.g., in web.config), or this may be a false positive; confidence is MEDIUM.";
}
alertDesc = alertDesc.split(" ").join(java.lang.System.getProperty("line.separator"));
ps.raiseAlert(alertRisk, alertReliability, alertTitle, alertDesc, url, param, '', '', alertSolution, '', cweId, wascId, msg);
}