JaveWeb中常见的信息泄漏——DWR类测试地址

  • A+

关于DWR

  DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站。

图片.png

  DWR主要包括两部分:

  • 在服务器上运行的Servlet来处理请求并把结果返回浏览器
  • 运行在浏览器上的Javascript,可以发送请求,并动态改变页面。

  DWR会根据你的Java类动态的生成Javascript代码,并负责数据的传递和转换。

  这种Java和Javascript之间的远程调用会让DWR用户感觉像是曾经习惯使用的RMI或SOAP的RPC机制。而且这一过程还不需要额外的浏览器插件。

具体实现

  要使用dwr需要进行简单的配置,主要是web.xml和dwr.xml这两个配置文件。

  首先是web.xml,最简单的只需要配置dwr对应的servlet映射即可:

xml
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

  然后提供了额外的参数进行相关配置,例如若想跨域支持可以在对应的<servlet>节点配置如下参数:

```xml
<!-- Enables remoting -->

allowScriptTagRemoting
true

crossDomainSessionSecurity
false

allowGetForSafariButMakeForgeryEasier
true

```

  其他的一些可选参数:

| 属性名称 | 作用 |
| ------------------------ | -------------------------------------------------- |
| jsonpEnabled | 设置为true时直接JSONP |
| debug | 设置为true时可以启用debug模式,可访问dwr的测试页面 |
| scriptSessionTimeout | 设置scriptSessions的超时时间 |
| maxWaitingThreads | 最大线程等待数 |
| maxCallCount | 最大调用数量 |
| maxHitsPerSecond | 最大访问量/每秒 |
| classes | 设定需要注解的域对象以及业务实现类 |
| activeReverseAjaxEnabled | 设置为true时启用轮询和长连接 |
| maxWaitAfterWrite | 设置长连接的时间 |
| ...... | ...... |

  可以根据实际需要增加对应的属性。

  配置好了对应的servlet映射以后,就是dwr.xml了,其是DWR的标准配置文件,默认情况下你要将其放到WEB-INF根目录下。例如一个简单的案例:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd">
<dwr>
<allow>
<create javascript="dwrtest" creator="new" scope="application"><!-- application -->
<param name="class" value="com.test.dwrtest"></param>
</create>
</allow>
</dwr>

  相关标签的含义:

  • allow:allow部分定义了哪些class能被DWR创建和转换以供全局过滤器使用。
  • create:任何我们想要被js执行的Java类都需要在此标签创建。
  • convert:将类转换成js对象。这样js可以以对象的方式处理参数。

  同样的可以使用注解的方式进行代替。例如@RemoteMethod对应dwr.xml文件中的create标签,用于创建DWR所提供的远程方法。

  dwr.xml配置文件可以有一个或者多个,都需要在web.xml文件中声明

  完成上述配置后,这样在js调用层我们可以通过/dwr/interface/dwrtest.js的dwrtest变量调用我们编写的函数(findByUserId)了:

html
<script type='text/javascript' src='/dwr/interface/dwrtest.js'></script>
function findByUserId(){
var userId = getQueryString("name");
$("#userName").html(userId);
dwrtest.findByUserId(userId);
......
}

  到此简单的dwr实现就完成了,可以根据实际的业务需要进行调整拓展。

  dwr的request数据包格式也比较看辨认,例如下面的例子:

```
POST /DwrProject/dwr/call/plaincall/dwrtest.findByUserId.dwr HTTP/1.1
Host: ip:port
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: /
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/plain
Content-Length: 227
Cookie: JSESSIONID=F0DE72C197AFEF273E84AC3686F4F8C7; DWRSESSIONID=7viforTWTj$BVBJSxv99$V*hVgn
Connection: close

callCount=1
windowName=
c0-scriptName=dwrtest
c0-methodName=findByUserId
c0-id=0
c0-param0=number:1
batchId=1
instanceId=0
page=%2FDwrProject%2Fdwr%2Ftest%2Fdwrtest
scriptSessionId=7viforTWTj$BVBJSxv99$VhVgn/YsBVgn-XOm0BUHfr
```

类测试地址泄漏

  前面提到一个debug属性,当设置为true时可以启用debug模式,可访问dwr的测试页面:

xml
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>

  一般来说在实际开发时,开发喜欢直接拿现有的demo进行修改,那么如果dwr配置中配置了debug参数且设置为true时,就会导致类测试地址泄漏的问题,相关路径:

/dwr/index.html

  访问效果如下:

图片.png

  点击进去就是对应的接口测试页面了,填写对应参数的值,点击Execute即可发送对应的请求进行debug:

图片.png

  当debug属性设置为true时,相关的测试页面是可以直接未授权访问的,相应的会带来一系列的安全问题。很多开发人员使用DWR框架开发时经常前后端不分,例如DWR直接调用数据库信息把用户登陆逻辑直接放到了前端来做。结合类测试地址泄漏,可以达到很多意想不到的效果。

  最常见的就是未授权访问,通过对应的api接口可以读取敏感信息,进行业务操作等。例如WooYun库里的案例,直接通过Execute即可获取敏感信息:

图片.png

  除此之外,一些常见的漏洞也可能涉及:

  • SQL注入
  • 任意文件上传/下载
  • .......

  因为类测试地址泄漏是直接暴露在相关web路径下的。所有人均可以访问查看。通过这一点即可获取项目上所有的接口信息。那么结合实际业务,直接测试即可。

修复建议

  在生产环境上需将DWR配置的debug属性注释掉(关闭debug模式)。

参考资料

http://directwebremoting.org/dwr/documentation/?hmsr=aladdin1e5

相关推荐: Linux提权命令总结

=== 操作系统 === 发行类型、发行版本 ``` cat /etc/issue cat /etc/*-release cat /etc/lsb-release cat /etc/redhat-release uname -n   //hostname主机名…