今天给大家分享一个 Java 实现的代理抓包工具,亲测好用,我个人更是曾经用这个项目赚到了一点小钱,最近刚好也有一个项目可能会用到这个技术,就把它单独拎出来跟大家分享一下。
想必大家都知道 fiddler 吧?就是一款流行的抓包工具(如果不知道的话,可以留言求分享,后续也可以简单介绍一下)。
直接上项目链接:
https://github.com/bytesops/jProxy
jProxy 是一个 JAVA 编写的 HTTP 代理服务器类库,支持 HTTP、HTTPS、Websocket 协议,并且支持 MITM (中间人攻击),可以对 HTTP、HTTPS 协议的报文进行捕获和篡改。
关于中间人攻击,大家可以自己搜一下,HTTPS 劫持算其中的一个具体实现,直白点理解就是:你原本想和小花说“我爱你”,但是一天,小强带着假发来到你身边,冒充小花,你就把这句话告诉了小强,然后小强又带上面具冒充你,跟小花说了一句“我讨厌你”,然后,就没有然后了。
熟悉 fiddler 的都知道 fiddler 可以截获 https 的内容,本项目的价值区别于 fiddler 的点就是可以实现程序代码介入 http 请求的全过程,至于能做什么,大家可以自由想象,欢迎留言区互动。
为了把技术讲的清楚一点,还是从网上抄点干货吧(如有错误,大家赶紧指正)。
首先来回顾下 https 协议的 ssl 握手(看不懂的也可以跳过,不过建议好好看一下,面试很有用)
简单叙述下 ssl 握手,上面只是单向验证过程(大多我们访问网站都是单向的,除非一些银行网站或服务器之间会用到双向验证)
注意第 3 步非常关键,ssl 证书是采用信任链的方式来验证 ssl 证书是否有效,在计算机中都会内置好许多受信任的 CA 证书(见下图 电脑查找设置- 管理计算机证书 ),而只有受信任的 CA 证书签发的 ssl 证书来访问浏览器才会验证通过,不然就会提示证书不安全。
计算机内置的,我们大体上认为是权威的(不过也发生过 权威机构 证书泄露的事件),那么我们是不是可以伪造一个呢?现在有请小强。
我们可以借助 openssl 自签一个 ca 证书,并安装到自己的电脑里,并且选择信任它(相信小强是小花)。
注:如果为了快速验证上面的小项目,不必自己生成,可以直接使用项目里的 ca.crt 安装,下面了解即可,如遇到项目里的 ca 证书过期了,可以尝试自行生成,也可以留言,我来更新。
# key 的生成,生成 RSA 密钥,openssl 格式,2048位强度,ca.key 是密钥文件名
openssl genrsa -out ca.key 2048
# crt 的生成,通过-subj 选项可以自定义证书的相关信息
openssl req -sha256 -new -x509 -days 365 -key ca.key -out ca.crt \
-subj "/C=CN/ST=GD/L=SZ/O=byteops/OU=study/CN=jProxyRoot"
生成了 ca.crt 即 ca 证书,双击可以安装(优先安装项目里的,方便演示)
安装证书后,需要重启一下计算机,不然证书可能有缓存,浏览器不识别。 重启后,执行项目里的
HttpProxyServerApp.java
main函数,启动项目
/**
* 测试 main
*/
public class HttpProxyServerApp {
public static void main(String[] args) {
System.out.println("start proxy server");
HttpProxyServerConfig config = new HttpProxyServerConfig();
config.setHandleSsl(true);
new HttpProxyServer()
.serverConfig(config)
.proxyInterceptInitializer(new HttpProxyInterceptInitializer() {
@Override
public void init(HttpProxyInterceptPipeline pipeline) {
pipeline.addLast(new FullResponseIntercept() {
@Override
public boolean match(HttpRequest httpRequest, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) {
// 在匹配到百度首页时插入js
return HttpUtil.checkUrl(pipeline.getHttpRequest(), "^www.baidu.com$")
&& HttpUtil.isHtml(httpRequest, httpResponse);
}
@Override
public void handleResponse(HttpRequest httpRequest, FullHttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) {
// 打印匹配到的 host
String host = httpRequest.headers().get(HttpHeaderNames.HOST);
System.out.println(host);
// 修改响应头和响应体
httpResponse.headers().set("handle", "edit head");
httpResponse.content().writeBytes("<script>alert('hello jproxy')</script>".getBytes());
}
});
}
})
.start(9999);
}
}
启动项目后,需要开启代理才能拦截到请求(目前还做不到 fiddler 的自动,也欢迎大家提 PR 一起改进),代理开启也很简单,电脑网络配置,代理,手动配置代理(记得点保存哟):
打开浏览器,访问百度首页:
https://www.baidu.com
即会弹出:
F12 打开控制台,也可以刷新页面,可以看到 响应头 中多了一条记录:
本次的分享到此结束,希望对你有所帮助。
如果你对我分享的内容感兴趣,欢迎扫码关注公众号:新质程序猿,并设置星标,推送更实时哟!