在某次攻防演练过程中遇到一个 ActiveMQ ,看到历史漏洞ActiveMQ漏洞总结中描述了一个物理路径泄漏漏洞
很好奇,对其进行分析及复现
通过 PUT
方式传入不存在的路径 通过报错 会响应相应的路径信息
POC PUT /fileserver/%08/..%08/script%3E/.%08/%08
debug 过程
对 org.eclipse.jetty.server.Response#sendError
进行断点
sc 是状态码, sendError 方法 有两个重载方法, 是否传入 message ,未传入的话根据 状态码进行获取。
调用 org.eclipse.jetty.server.handler.ErrorHandler
处理
非GET/POST/HEAD
调用
this.complete()
` this._connection.completeResponse();`
setResponse 会 对 this._reason
进行赋值
在调用 org.eclipse.jetty.http.HttpGenerator#completeHeader
将 状态码及 this._reason
加入 this._header
中进行输出
可以看到,对输出也没有进行编码转义。
GET/POST/HEAD
ErrorHandler 对 GET 方法处理
org.eclipse.jetty.server.handler.ErrorHandler
HandlerErrorPage 实际上也会输出reason
fileserver 应用对 GET 方法处理
fileserver 应用在 web.xml 上一次注册了两个filter ,一个 servlet
按照处理顺序依次是
- FilenameGuardFilter
- RestFilter
- DefaultServlet
PUT 方法时会在 Restfilter 报错,抛出异常,由 servletHandler 处理, response.sendError(500, ((Throwable)th).getMessage());
fileserver 应用 的 RestFilter 不处理 Get 请求
else if (httpRequest.getMethod().equals("GET")) {
if (this.checkGet(httpRequest, httpResponse)) {
chain.doFilter(httpRequest, httpResponse);
}
兜底 DefaultServlet 在处理 get 请求时
会直接输出 404 ,而不输出 报错原因
response.sendError(404);
无应用时对 get 方法处理
在无webapp的情况下,对于不存在路径 由 org.eclipse.jetty.server.handler.DefaultHandler#handle
处理请求,不存在也会直接 404
response.sendError(404);
修复
org.eclipse.jetty.servlet.ServletHandler#doHandle
在输出错误的response 时,不再输出错误原因
5.10.0 与 5.11.1 diff
总结
该漏洞以其说是 ActiveMQ 的漏洞,不如说是 Jetty 的报错信息泄漏
影响版本:主要是 Jetty 版本,需要为 7 Jetty(7.6.9.v20130131)
报错这种重要信息可不能随便输出。