【Web实战】HTTP-请求解析过程

目录

0x00 前言

0x01 "畸形scheme"HTTP请求

0x02 其他


0x00 前言

Reactor Netty HttpClient 是 Reactor Netty 框架提供的一个用于进行异步 HTTP 请求的客户端库。它基于 Reactor 框架,采用响应式编程模型,允许以非阻塞的方式执行 HTTP 请求和处理响应。

image.png

通过引入对应的依赖,即可通过使用Reactor Netty从HttpClient获取目标的响应报文:

image.png

下面是一个具体的例子,首先创建了一个 HttpClient 对象,通过Reactor Netty 的链式调用 API 来构建我们的请求,发起了一个 GET 请求访问了target并打印对应响应的内容,完成了整个请求与响应处理过程:

HttpClient httpClient = HttpClient.create().wiretap(true);
httpClient.get().uri(target).responseContent().aggregate().asString().doOnSuccess(s -> {
    System.out.println("s1=" + s);
}).block();

上述代码串联了多个Reactor Netty的方法,下面是简单的说明:

  • httpClient.get().uri(target):通过httpClient创建了一个HTTP GET请求,并指定了请访问的目标URL。
  • .responseContent():调用.responseContent()方法,会获取到一个表示HTTP响应内容(响应体)的Flux\<ByteBuf>,其中Flux是Reactor中的一种反应式数据类型,表示异步流。异步处理响应体的数据信息。
  • .aggregate():因为HTTP响应的内容通常会被分成多个字节块,该方法用于将它们进行整合。
  • .asString():调用该方法将ByteBuf内容解码为字符串方便后续的处理。
  • doOnSuccess(s -> { System.out.println("s1=" + s);}):使用.doOnSuccess()方法注册一个回调函数,当HTTP响应成功完成时,执行这个函数将HTTP响应的内容打印到控制台中。
  • .block():阻塞当前线程以等待HTTP响应的完成。.block()方法会触发实际的HTTP请求发送和响应处理,然后等待直到HTTP请求完成,并且只有在响应成功时才会解除阻塞。

当然除了block以外,还可以通过类似subscribe获取响应报文。

0x01 "畸形scheme"HTTP请求

以GET请求为例,下面对reactor netty httpclient请求解析过程进行简单的分析:

在 Reactor Netty 框架中,MonoHttpConnect是一个用于表示 HTTP 连接的 Mono 类型。它代表了一个异步的 HTTP 请求,并返回一个 Mono 类型的结果。通过调用 subscribe 方法,可以触发实际的 HTTP 请求,并通过订阅者来处理响应结果:

image.png

首先这里会实例化HttpClientConnect,这里会调用uriEndpointFactory.createUriEndpoint创建 UriEndpoint,UriEndpoint是一个用于表示网络请求的目标地址的类。它封装了 URI 的相关信息,包括协议、主机名、端口号、路径等。reactor.netty.http.client.UriEndpointFactory#createUriEndpoint方法根据传入的参数,创建一个 UriEndpoint 对象,并返回该对象:

image.png

可以看到,在createUriEndpoint方法中,主要是通过正则匹配的方式获取URI 的相关信息:

image.png

创建完HttpClientHandler后,会通过配置对象(_config)来设置一些参数:

image.png

这里会调用resolverInternal方法用于获取地址解析器组。它负责将主机名解析为一个或多个 IP 地址,以便 HttpClient 可以与目标服务器建立连接:

image.png

实际调用的是其父类ClientTransportConfig的方法:

image.png

这里会create一系列的组件:

image.png

例如创建ConnectionProvider用来管理连接池,Builer这里硬编码传入对应的name为http,后续会创建一组连接并存储在连接池中。 当需要进行网络通信时,可以从连接池中获取一个连接并使用它来发送请求:

image.png

又例如PooledConnectionProvider,这个在后面会用到:

image.png

调用完后,此时会调用_config.httpConnectionProvider().acquire从 HTTP 连接提供者中获取一个可用的连接。以便进行 HTTP 请求:

image.png

查看具体的过程,这里最终会调用PooledConnectionProvider的acquire方法:

image.png

image.png

reactor.netty.resources.PooledConnectionProvider的作用是提供连接池管理功能。在使用 Reactor Netty 进行网络通信时,可以通过 PooledConnectionProvider 来管理和复用连接,以提高性能和资源利用率,这里会调用 acquire 方法获取一个可用的连接,以便进行网络通信。获取到的连接可以用于发送请求、接收响应等操作,如果连接池中没有可用的连接,它可能会创建一个新的连接:

image.png

从对应的调试信息可以知道,这里创建的是http client pool,结合前面解析请求target的过程,这里name的值并不是从请求target的schema获取的,是从前面Builer里硬编码获取的:

image.png

后面是HttpClientOperations的处理,也没有对schema进行相应检查操作,那么这里有没有可能reactor netty httpclient可以以任意符合正则匹配的schema进行请求呢?

image.png

验证下前面的猜想:

image.png

正常情况下,通过reactor netty httpclient请求http://127.0.0.1:8080/health正常返回:

image.png

将scheme替换成任意字符,可以发现依旧能正常请求并返回:

image.png

查看reactor netty httpclient的日志,确实没有考虑用户输入的协议,在PooledConnectionProvider创建了新的http client pool,同时也没有发现关于schema的检查:

image.png

image.png

结合前面请求target解析的正则:

image.png

image.png

scheme还支持下划线匹配,所以类似anyt____hing的schema同样能正常请求:

image.png

0x02 其他

WebClient是从Spring WebFlux 5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。 它的响应式编程的基于Reactor的。 WebClient中提供了标准Http请求方式对应的get、post、put、delete等方法,可以用来发起相应的请求。

通过引入如下依赖即可使用WebClient:

image.png

从依赖关系可以看到,实际上spring-boot-starter-webflux也是基于reactor-netty-http来发起相应的请求的:

image.png

下面的代码是一个简单的WebClient请求示例。可以通过WebClient.create()创建一个WebClient的实例,然后选择调用方式get,在uri()指定需要请求的路径,然后调用retrieve()发起请求并获得响应,bodyToMono(String.class)用来指定请求结果需要处理为String:

WebClient webClient = WebClient.builder().build();
String response = webClient.get().uri(url).retrieve().bodyToMono(String.class).block();
return response;

简单看下WebClient的处理过程,首先会在org.springframework.web.util.UriComponentsBuilder#fromUriString方法处理需要请求的目标:

image.png

可以看到这里也是通过正则的方式进行匹配:

image.png

若未匹配相关信息,会抛出throw new IllegalArgumentException("[" + uri + "] is not a valid URI");异常,否则进行进一步的封装,同时这里对scheme和host进行了一定的合法性检查:

image.png

但是并没有强制校验scheme是否是http/https,所以同样的当尝试请求anything://127.0.0.1:8080/health,WebClient同样也是能正常解析并正常返回:

image.png

可以看到结合reactor netty httpclient解析过程中的一些处理方式,可以构造类似上述任意协议的“畸形”的请求样式,在某种情况下可以绕过现有ssrf的一些安全防护措施。开发人员应该避免将不受信任且未经验证的数据从 HTTP 请求传递给reactor netty httpclient,避免不必要的绕过导致ssrf风险。

原文链接:https://forum.butian.net/share/2557

免费领取安全学习资料包!

渗透工具

技术文档、书籍

 

面试题

帮助你在面试中脱颖而出

视频

基础到进阶

环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等

 

应急响应笔记

学习路线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值