利用java代码和web拦截器轻松实现一个app抓包工具

简介:     目前app测试时我们需要对接口数据进行抓包,对于app的抓包,我们可以使用很多现成的工具,比如fiddler、wireshark、charles等,基本上可以满足要求,但是对于一些定制化的需求,比如说:我们需要将抓包的数据进行篡改后再发送到服务器,或者对请求的数据新增标志字段以便定位问题,或者更多需要更改数据的需求,传统抓包工具已经很难实现,需要我们探索新的方式方法。

    目前app测试时我们需要对接口数据进行抓包,对于app的抓包,我们可以使用很多现成的工具,比如fiddler、wireshark、charles等,基本上可以满足要求,但是对于一些定制化的需求,比如说:我们需要将抓包的数据进行篡改后再发送到服务器,或者对请求的数据新增标志字段以便定位问题,或者更多需要更改数据的需求,传统抓包工具已经很难实现,需要我们探索新的方式方法。

    我们知道,一般的抓包工具都是使用代理的方式来截取请求,然后以ui的方式展现出来,我们本次也直接使用这种代理的方式来实现抓包,然后对抓取的包进行数据的重组和处理后再发送到原本请求的服务器获取结果返回给app即可。整个流程如下(此流程仅适用于http、https协议):



说明:代理服务器抓取到app到服务器之间的包,进行解包之后,对数据进行处理(更改或者新增)后再次进行数据封包,将封包后的数据发送到原服务器之后将数据返回给app即可,这期间我们在解包之后可以看到数据的具体信息。

   整个系统最核心的内容无疑为代理服务器,甚至有些人对数据的解包和封包和再次发送感觉实现起来很难。如果app的请求为http协议,其实我们可以使用现成的工具,最直接的就是将代理服务器伪装成一个web服务器,app发送给web服务器的数据可以直接被web服务器解包,之后可以使用httpclient再次模拟客户端做封包操作发送给app:

数据拦截:web拦截器

数据解包:servlet(request)

数据处理:自助java类

数据再封包和发送:httpclient

数据的接收:httpclient

数据返回app:servlet(response)


整个流程变为:


下面我们从代码层面来说明整个过程:

1.搭建一个web的服务器环境

2.写一个拦截器



3.代理服务器代码

packagecom.pingan.testcloud.units;

/**

* ClassName:LoginFilter

*

* @Description:过滤器,白名单里所有接口都要先经过此过滤器,白名单请在web.xml中设置

* @author dingjingjing058

* @date 2016年5月13日

*/

importjava.io.IOException;

importjava.io.PrintWriter;

importjava.net.URLDecoder;

importjava.net.URLEncoder;

importjava.util.ArrayList;

importjava.util.Enumeration;

importjava.util.HashMap;

importjava.util.List;

importjava.util.Map;

importjavax.servlet.Filter;

importjavax.servlet.FilterChain;

importjavax.servlet.FilterConfig;

importjavax.servlet.ServletException;

importjavax.servlet.ServletRequest;

importjavax.servlet.ServletResponse;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjavax.servlet.http.HttpSession;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importcom.pingan.testcloud.httphelper.BasicParameter;

import com.pingan.testcloud.httphelper.HttpClientHelper;

importcom.pingan.testcloud.httphelper.ResponseParameter;

public classLoginFilter implements Filter {

publicLogger logger = LoggerFactory.getLogger(this.getClass());

@Override

public void destroy() {

// TODO Auto-generated method stub

}

@SuppressWarnings("rawtypes")

@Override

public void doFilter(ServletRequest req,ServletResponse res, FilterChain chain)

throws IOException,ServletException {

HttpServletRequest request =(HttpServletRequest) req;

HttpServletResponse response =(HttpServletResponse) res;

request.setCharacterEncoding("UTF-8");

//获得用户请求的URI,并进行截取

String url= request.getRequestURI();

String[] path =url.split("/");

// System.out.println(path);

Enumerationenu=request.getParameterNames();

String paraString="";

while(enu.hasMoreElements()){

StringparaName=(String)enu.nextElement();

paraString=paraString+paraName+":"+request.getParameter(paraName)+"";

}

logger.info("用户请求地址为:"+url+"请求参数为:"+paraString);

if(ConfigReader.getWhiteListMap().get(path[path.length-1])==null){//如果不在白名单,则进行如下校验

String method=request.getMethod();

if(method.equals("POST"))

method="post";

elseif(method.equals("GET"))

method="get";

BasicParameter bp1 = newBasicParameter(url,"get","FILTER");

enu=request.getParameterNames();

while(enu.hasMoreElements()){

String paraName=(String)enu.nextElement();

bp1.addParamters(paraName,request.getParameter(paraName));

Enumerationen=request.getHeaderNames();

Map headers=newHashMap();

while(en.hasMoreElements()){

//取出信息名

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

//取出信息值

String value=request.getHeader(name);

headers.put(name, value);

}

bp1.setHeaders(headers);

}

List rps= new ArrayList();

try {

HttpClientHelper client=newHttpClientHelper(request.getServerName(),request.getServerPort(),"http");

client.addHttpRequest(bp1);

rps=client.run();

} catch (Exception e1) {

// TODO Auto-generatedcatch block

e1.printStackTrace();

}

for(Map.Entryen:rps.get(0).getHeaders().entrySet())

{

response.addHeader(en.getKey(),en.getValue());

}

response.setContentType("text/html");

response.setCharacterEncoding("UTF-8");

PrintWriter out =response.getWriter();

out.print(rps.get(0).getRespdata());

out.flush();

out.close();

//response.sendRedirect("./login.html");

//chain.doFilter(request,response);

//已经登陆,继续此次请求

}

else

{

//在白名单里,继续此次请求

chain.doFilter(request,response);

}

}

@Override

public void init(FilterConfig config)throws ServletException {

}

}


注意:

1.代码中使用了httpclient,具体代码封装请参加技术文档。

2.对于解包后的数据操作未做详细讲解,可以参考sevlet技术文档。


最后,对手机设置网络代理,代理指向web服务器的ip和端口,试试效果吧。

目录
相关文章
|
15天前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
3天前
|
Java API 数据处理
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
|
3天前
|
Java 数据安全/隐私保护
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
|
14天前
|
测试技术
基于LangChain手工测试用例转App自动化测试生成工具
在传统App自动化测试中,测试工程师需手动将功能测试用例转化为自动化用例。市面上多数产品通过录制操作生成测试用例,但可维护性差。本文探讨了利用大模型直接生成自动化测试用例的可能性,介绍了如何使用LangChain将功能测试用例转换为App自动化测试用例,大幅节省人力与资源。通过封装App底层工具并与大模型结合,记录执行步骤并生成自动化测试代码,最终实现高效自动化的测试流程。
27 4
|
23天前
|
XML JSON 安全
Web安全-代码注入
Web安全-代码注入
18 6
|
2月前
|
数据库 开发者 Java
数据战争:Hibernate的乐观与悲观锁之争,谁将主宰并发控制的王座?
【8月更文挑战第31天】在软件开发中,数据一致性至关重要,尤其是在多用户并发访问环境下。Hibernate 作为 Java 社区常用的 ORM 框架,提供了乐观锁和悲观锁机制来处理并发问题。乐观锁假设数据不易冲突,通过版本号字段 (`@Version`) 实现;悲观锁则假定数据易冲突,在读取时即加锁。选择哪种锁取决于具体场景:乐观锁适合读多写少的情况,减少锁开销;悲观锁适合写操作频繁的场景,避免数据冲突。正确应用这些机制可提升应用程序的健壮性和效率。
28 0
|
2月前
|
Java UED 自然语言处理
Struts 2 国际化竟有如此神奇魔力?快来揭开多语言支持的 Web 应用神秘面纱
【8月更文挑战第31天】在全球化背景下,Web应用需适应多种语言环境。Struts 2凭借其强大的国际化(i18n)支持,简化了多语言应用开发。通过不同语言的资源文件,它能自动匹配用户语言偏好,优化用户体验并扩展用户群。下面是一个示例:创建`messages.properties`(英语)与`messages_zh_CN.properties`(中文),并在Struts 2的Action类及JSP页面中调用`getText()`方法及Struts标签展示相应语言内容。此外,在struts.xml中指定资源文件,以确保框架正确加载对应语言包。通过这些步骤,开发者可以轻松实现应用的多语言支持。
51 0
|
2月前
|
Java 开发者 JavaScript
Struts 2 开发者的秘籍:隐藏的表单标签库功能,能否成为你下个项目的大杀器?
【8月更文挑战第31天】Struts 2表单标签库是提升Web页面交互体验的神器。它提供丰富的标签,如`<s:textfield>`和`<s:select>`,简化表单元素创建与管理,支持数据验证和动态选项展示。结合示例代码,如创建文本输入框并与Action类属性绑定,显著提升开发效率和用户体验。通过自定义按钮样式等功能,Struts 2表单标签库让开发者更专注于业务逻辑实现。
40 0
|
2月前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
37 0
|
2月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
76 0
下一篇
无影云桌面