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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' DetectCustomErrorsDisabled.vbs Script
' 版本3.1
'
' 此脚本将帮助检测填充预言机ASP.NET漏洞的易受攻击配置,该漏洞在MS公告2416728中记录。
'
' http://www.microsoft.com/technet/security/advisory/2416728.mspx
'
' 用法:
' cscript DetectCustomErrorsDisabled.vbs [RemoteServerName]
'
' 注意:此脚本使用文件系统和Shell对象,应以管理员身份运行
'
' 脚本通过枚举所有web.config并评估是否通过使用统一的ASP.NET应用程序自定义错误响应来缓解填充预言机漏洞的侧信道泄漏。
'
' 注意:在IIS 7服务器上,此脚本需要安装IIS6兼容模式。
'
' 更多信息:http://blogs.technet.com/b/srd/archive/2010/09/17/understanding-the-asp-net-vulnerability.aspx
'
' 版本历史:
' 1.0 - 初始版本
' 2.0 - 添加了对应用程序/站点根配置的额外检查
' 3.0 - 添加了XML解析和路径检查的错误验证
' 3.1 - 添加了对缺失根web.config的检查
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
OPTION EXPLICIT
ON ERROR RESUME NEXT
DIM strServer
DIM objWebService, objWebServer, objDir, objFileSys
DIM physicalPath, dir, xmlDoc, nodeList, node, ret
DIM configFile, configFilePath, configLine
DIM childNodes, ErrPage500, ErrPage404, errFound
DIM index, errCount
strServer = "localhost"
' 解析命令行输入
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
IF WScript.Arguments.Length=1 THEN
strServer = WScript.Arguments( 0 )
END IF
IF WScript.Arguments.Length>1 THEN
WScript.Echo "非法参数数量"
WScript.Echo "用法:cscript.exe DetectCustomErrorsDisabled.vbs [RemoteServerName]"
WScript.Quit( 1 )
END IF
' 初始化
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SET objFileSys = CreateObject("Scripting.FileSystemObject")
SET objWebService = GetObject( "IIS://" & strServer & "/W3SVC" )
IF Err <> 0 THEN
WScript.Echo "找不到IIS ADSI对象。请确保已安装IIS和IIS6管理兼容性。"
WScript.Quit (1)
END IF
SET xmlDoc = CreateObject("Microsoft.XMLDOM")
IF IsNull(objFileSys) THEN
WScript.Echo "创建FileSystemObject失败。请以管理员身份运行脚本。"
WScript.Quit (1)
END IF
IF IsNull(objWebService) THEN
WScript.Echo "连接到IIS ADSI提供程序失败。请确保已安装IIS6管理兼容性角色服务。"
WScript.Quit (1)
END IF
WScript.Echo("枚举可能具有自定义错误关闭的ASP.NET配置路径。")
WScript.Echo ("")
' 搜索Web服务器以查找不安全的配置
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
FindASPNetConfig(objWebService)
' 搜索Web服务器上所有可能的web.config文件路径
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB FindASPNetConfig(WebService)
FOR EACH objWebServer IN WebService
IF objWebserver.Class = "IIsWebServer" THEN
EnumDirectories(objWebServer)
END IF
NEXT
END SUB
' 递归遍历虚拟目录和Web目录
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB EnumDirectories(objDir)
DIM objSubDir
' 第一次调用来自IIsWebServer,因此我们可以跳过
FOR EACH objSubDir IN objDir
IF (objSubDir.Class = "IIsWebVirtualDir") THEN
GetPhysicalPaths(objSubDir)
EnumDirectories(objSubDir)
END IF
NEXT
END SUB
' 获取Web和虚拟目录的物理路径
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB GetPhysicalPaths(objDir)
physicalPath = objDir.Path
CALL EnumWebConfig(physicalPath,1)
END SUB
' 递归搜索web.config文件
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB EnumWebConfig(Path,IsRoot)
IF NOT objFileSys.FolderExists(Path) THEN
IF IsRoot THEN
WScript.Echo Path & ": ** 发现易受攻击的配置 **"
END IF
EXIT SUB
END IF
configFilePath = Path & "\web.config"
IF objFileSys.FileExists(configFilePath) THEN
CALL ProcessWebConfig(configFilePath,IsRoot)
ELSEIF IsRoot = 1 THEN
WScript.Echo Path & ": ** 发现易受攻击的配置 **"
END IF
FOR EACH dir IN objFileSys.GetFolder(Path).SubFolders
CALL EnumWebConfig(dir.Path,0)
NEXT
END SUB
' 跳过默认具有写入访问权限的已知身份
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB ProcessWebConfig(Path,IsRoot)
xmlDoc.async="false"
xmlDoc.load(Path)
errFound = 0
SET nodeList = xmlDoc.getElementsByTagName("customErrors")
IF IsRoot = 1 AND nodeList.length = 0 THEN
' 根web.config未设置defaultRedirect,因此此配置应具有启用了customErrors并存在defaultRedirect的customErrors部分。否则这是易受攻击的配置。
errFound = errFound + 1
ELSEIF IsRoot = 1 THEN
ret = CheckRootCustomErrorsSection(nodeList, Path)
errFound = errFound + ret
END IF
DIM count
FOR count=0 TO nodeList.length-1
ret = CheckCustomErrorsDisabled(nodeList.Item(count), Path)
errFound = errFound + ret
ret = CheckCustomErrorsAreHomogenous(nodeList.Item(count), Path)
errFound = errFound + ret
NEXT
IF errFound > 0 THEN
WScript.Echo Path & ": ** 发现易受攻击的配置 **"
ELSE
WScript.Echo Path & ": 正常"
END IF
END SUB
FUNCTION CheckRootCustomErrorsSection(xmlnodelist, path)
errCount = 0
FOR index=0 TO xmlnodeList.length-1
ret = CheckRootCustomErrorsDisabled(nodeList.Item(index), Path)
errCount = errCount + ret
NEXT
CheckRootCustomErrorsSection = errCount
END FUNCTION
FUNCTION CheckRootCustomErrorsDisabled(xmlnode, path)
IF StrComp (LCase(xmlnode.getAttribute("mode")), "off") = 0 THEN
CheckRootCustomErrorsDisabled = 1
EXIT FUNCTION
ELSEIF IsNull(xmlnode.getAttribute("defaultRedirect")) THEN
CheckRootCustomErrorsDisabled = 1
EXIT FUNCTION
ELSE
CheckRootCustomErrorsDisabled = 0
END IF
END FUNCTION
FUNCTION CheckCustomErrorsDisabled(xmlnode, path)
IF StrComp (LCase(xmlnode.getAttribute("mode")), "off") = 0 THEN
' 不安全配置
CheckCustomErrorsDisabled = 1
ELSE
CheckCustomErrorsDisabled = 0
END IF
END FUNCTION
FUNCTION CheckCustomErrorsAreHomogenous(xmlnode, path)
IF xmlnode.childNodes.length=0 AND len(xmlNode.getAttribute("defaultRedirect"))>0 THEN
CheckCustomErrorsAreHomogenous = 0
EXIT FUNCTION
END IF
SET childNodes = xmlnode.childNodes
ErrPage404 = ""
ErrPage500 = ""
DIM count
FOR count=0 TO childNodes.length-1
CALL GetErrorPage(childNodes.Item(count))
NEXT
IF StrComp(ErrPage404,"") = 0 AND StrComp(ErrPage500,"") = 0 AND IsNull(xmlNode.getAttribute("defaultRedirect")) THEN
' 在这种情况下缺少defaultRedirect将导致配置易受攻击
CheckCustomErrorsAreHomogenous = 1
EXIT FUNCTION
ELSEIF StrComp(ErrPage404,"") = 0 AND StrComp(ErrPage500,"") <> 0 AND StrComp(ErrPage500, xmlNode.getAttribute("defaultRedirect")) <> 0 THEN
CheckCustomErrorsAreHomogenous = 1
EXIT FUNCTION
ELSEIF StrComp(ErrPage500,"") = 0 AND StrComp(ErrPage404,"") <> 0 AND StrComp(ErrPage404, xmlNode.getAttribute("defaultRedirect")) <> 0 THEN
CheckCustomErrorsAreHomogenous = 1
EXIT FUNCTION
ELSEIF StrComp(ErrPage404, ErrPage500) <> 0 THEN
CheckCustomErrorsAreHomogenous = 1
EXIT FUNCTION
ELSE
CheckCustomErrorsAreHomogenous = 0
END IF
END FUNCTION
SUB GetErrorPage(xmlnode)
IF xmlnode.nodeType <> 1 THEN
EXIT SUB
ELSEIF IsNull(xmlnode.getAttribute("statusCode")) THEN
' 什么都不做
ELSEIF StrComp(xmlnode.getAttribute("statusCode"), "500") = 0 THEN
ErrPage500 = xmlnode.getAttribute("redirect")
ELSEIF StrComp(xmlnode.getAttribute("statusCode"), "404") = 0 THEN
ErrPage404 = xmlnode.getAttribute("redirect")
END IF
END SUB
|