使用Fiddler拦截Boost.Asio HTTP/S请求

Intercepting Boost.Asio HTTP/S request using Fiddler

本文关键字:请求 HTTP Asio Fiddler 拦截 Boost 使用      更新时间:2023-10-16

我正在使用Boost:Asio执行HTTP GET(使用中的示例http://www.boost.org/doc/libs/1_50_0/doc/html/boost_asio/example/http/client/async_client.cpp)

我没有在fiddler上看到我的请求(仅在WireShark上)我该怎么改?

Asio在套接字级别工作,不使用wininet,因此fiddler无法捕获其流量。

我一直在寻找解决方案,为了让fiddler与asio合作,你需要将其用作代理。要在fiddler中启用代理,请使用"工具"->"Telerik fiddler选项"->"连接"。

要将代理服务器与asio一起使用,您需要使用其IP地址+端口,而不是目标端口。然后在GET中,您需要提供完整的目的地uri,而不仅仅是路径。要获得更好的解释,请参阅此处:如何为boost::asio添加代理支持?

关于如何解决它,我也有类似的问题,所以我只是分享我的经验。据我所知,Asio在套接字级别工作,并不像@marcinj所指出的那样使用wininet,Fiddler在wininet上工作,但我们仍然可以通过使用Fiddler作为代理来做到这一点。

首先,解释为什么它在Boost:Asio上不起作用,就像在IE上解释流量一样

另请参阅如何在fiddler 中捕获套接字编程的发送和接收请求

Fiddler将自己作为HTTP代理服务器插入堆栈。它依赖于网络浏览器来识别PC上配置了代理并通过该代理进行发送。您的代码无法检测到要发送的代理,因此Fiddler将无法监控您的流量。

你有几个选择。

  1. 由于您拥有Windows,只需从使用直接套接字切换到使用WinInet HTTP API即可。它将为您进行自动代理检测,而无需考虑。如果需要,它也会进行代理身份验证。

  2. 或。使用Wireshark或NetMon来分析您的流量,而不是Fiddler。

我推荐#1,因为这意味着你的代码将在真正的代理服务器(通常在企业网络上找到)的存在下工作,Fiddler将只使用它。

我想还有第三种选择,你可以自动检测浏览器代理设置,然后创建一个到代理的套接字,使用HTTP proxy协议,等等……但这不是最好的做法。

第二,怎么做

有一个很好的例子是传递代理地址以创建基于Boost:asio的客户端,比如Socket(java.net.proxy)或Configure a PHP/cURL Application to Use Fiddler,或者客户端应用程序不是自己编写的,但如果您可以控制/配置客户端连接端点地址和端口,我们可以通过任何方式(将HTTP请求重新路由为HTTPS请求或将HTTPS请求重新路由作为HTTPS服务器的HTTPS请求)作为反向代理(需要一个参数),使Fiddler拦截HTTP流量。

默认情况下,Fiddler正在听8888。如果转到http://localhost:8888/在浏览器中,它会显示一个默认页面,如:

<!doctype html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Fiddler Echo Service</title></head><body style="font-family: arial,sans-serif;"><h1>Fiddler Echo Service</h1><br /><pre>GET / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
DNT: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _ga=GA9.1.123456789.1234567890
</pre>This page returned a <b>HTTP/200</b> response <br />Originating Process Information: <code>chrome:3628</code><br /><hr /><ul><li>To configure Fiddler as a reverse proxy instead of seeing this page, see <a href='http://fiddler2.com/r/?REVERSEPROXY'>Reverse Proxy Setup</a><li>You can download the <a href="FiddlerRoot.cer">FiddlerRoot certificate</a></ul></body></html>
  1. 如果目标服务器是HTTP服务器或目标服务器是HTTPS服务器,并且客户端根据您配置的地址支持HTTP,则只需在OnBeforeRequest中添加以下代码(在规则->自定义规则…Ctrl+R,FiddlerScript中),另请参阅修改请求或响应
//MessageBox.Show(oSession.fullUrl);
// string Session.fullUrl: Retrieves the complete URI, including protocol/scheme, in the form http://www.host.com/filepath?query.
//FiddlerObject.log("Session.fullUrl=" + oSession.fullUrl);
// string Session.url: Gets or sets the URL (without protocol) being requested from the server, in the form www.host.com/filepath?query."
//FiddlerObject.log("Session.url=" + oSession.url);
// string Session.PathAndQuery: Returns the path and query part of the URL. (For a CONNECT request, returns the host:port to be connected.)
//FiddlerObject.log("Session.PathAndQuery=" + oSession.PathAndQuery); // e.g. /filepath?query but host:port for a CONNECT request
// string Session.host: Gets/Sets the host to which this request is targeted. MAY include IPv6 literal brackets. MAY include a trailing port#.
// int Session.port: Returns the server port to which this request is targeted.
//FiddlerObject.log("Session.host=" + oSession.host + ", port=" + oSession.port);
// string Session.hostname: DNS Name of the host server (no port) targeted by this request. Will include IPv6-literal brackets for IPv6-literal addresses
//Gets/Sets the hostname to which this request is targeted; does NOT include any port# but will include IPv6-literal brackets for IPv6 literals.
FiddlerObject.log("Session: hostname=" + oSession.hostname +  ", oRequest.pipeClient.LocalPort=" + oSession.oRequest.pipeClient.LocalPort);

//bool Fiddler.Utilities.isLocalhostname(sHostnameWithoutPort))
// Determines if the specified Hostname is a either 'localhost' or an IPv4 or IPv6 loopback literal
// Returns true if True if the sHostname is 127.0.0.1, 'localhost', or ::1. Note that list is not complete.
// Run Fiddler on your machine, and then add this block of code and test it works on the your same machine:
// Use the `curl http://localhost:8888/get`command  or Using a browser, go to http://localhost:8888/get.
if (Utilities.isLocalhostname(oSession.hostname)) {
// By default, Fiddler is listening on 8888. Inspect what ports are being listened using proexp or netstat
// :: Lists the listening ports of a process with the specified image name including extension name(case-insensitive), fiddler.exe
// for /f "skip=1 tokens=2,9 delims=," %a in ('tasklist /fo csv /fi "IMAGENAME eq fiddler.exe" 2^>NUL') do (netstat -ano | findstr "PID LISTENING" | findstr "PID %a")
//oSession.host = "httpbin.org:443"; // oSession.oRequest.headers.UriScheme = "https";
oSession.fullUrl = "https://httpbin.org" + oSession.PathAndQuery;
}

您可以将使用实际url的预期响应与通过url localhost的上述响应进行比较,localhost连接将请求转发到实际url的Fiddler代理,即httpbin.org。

  1. 如果目标服务器是HTTPS服务器,但客户端不支持HTTP,则上述更改是不够的

使用命令curl -v https://localhost:8888/get(或浏览器),我们发现错误

* schannel: sent initial handshake data: sent 182 bytes
* schannel: SSL/TLS connection with localhost port 8888 (step 2/3)
* schannel: failed to receive handshake, need more data

检查Wireshark中的流量,我发现Fiddler在客户端发送第一个TLS请求(客户端你好)后没有执行任何HTTPS握手。

Fiddler输出日志:

18:28:44:5960 HTTPSLint>警告:ClientHello记录长508字节。某些服务器的ClientHello大于255字节时出现问题。https://github.com/ssllabs/research/wiki/Long-Handshake-Intolerance

要解决它,除了规则脚本之外,我们还需要做:

  1. 将Fiddler配置为反向代理服务器,它转发所有目标端口等于第二个参数的请求!侦听命令。单击"工具">"小提琴手选项">"连接"。确保选中"允许远程客户端连接"。它使fiddler能够响应HTTPS的SSL/TLS握手请求。此步骤是一个持久配置。

  2. 在HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2内创建一个名为ReverseProxyForPort的新DWORD。将DWORD设置为Fiddler将重新路由入站流量的本地端口(通常是标准HTTP服务器的端口80)。

:: reg query HKEY_CURRENT_USERSOFTWAREMicrosoftFiddler2 /v ReverseProxyForPort
reg add HKEY_CURRENT_USERSOFTWAREMicrosoftFiddler2 /v ReverseProxyForPort /t REG_DWORD /d 58080 /f && REM /f Force overwriting the existing registry entry without prompt to 58080
:: Deletes the registry key
:: REG DELETE HKEY_CURRENT_USERSOFTWAREMicrosoftFiddler2 /v ReverseProxyForPort  /f && REM /f Forces the deletion without prompt.
  1. 重新启动Fiddler,并在左下角的Fiddler的QuickExec框中键入!listen 443 ServerHostName,通过!listen *PORT [CERTHOSTNAME]*脚本命令启动侦听指定端口的代理服务器,其中ServerHostName是服务器的主机名;例如https://Fuzzle/您将使用fuzzle作为服务器名称

似乎没有必要在windows注册表(REGEDIT.exe)的HKEY_CURRENT_USERSOFTWAREMicrosoftFiddler2内创建一个名为ReverseProxyForPort的新DWORD

QuickExec-默认命令

!listen *PORT [CERTHOSTNAME]*

在另一个端口上设置一个额外的侦听器,可选地由HTTPS证书保护

!listen 8889
!listen 4443 localhost
!listen 444 secure.example.com

另请参见

  • 将Fiddler用作反向代理
  • WikiPedia反向代理
  • 代理服务器和反向代理服务器之间的区别?

    从用户的角度来看,当向代理服务器反向代理服务器发送请求时:

    • proxy-需要两个参数
      1)获取什么和2)使用中间代理服务器
    • 反向代理-需要一个参数
      1.)要得到什么反向代理在用户不知情的情况下从另一台服务器获取内容,返回结果,就好像它来自反向代理服务器pspi在4月13日5:47回答
  • 将Fiddler作为HTTPS服务器的反向代理运行
  • fiddler将https重定向到localhost

    static function OnBeforeRequest(oSession:Fiddler.Session) {}中使用的以下代码:

    if (oSession.HostnameIs("YYYY.azurewebsites.net")) oSession.host = "127.0.0.1:19703";
    
  • 将Fiddler作为HTTP到HTTPS反向代理运行

    Fiddler将入站请求从HTTP转换为HTTPS的最简单方法是在OnBeforeRequest中添加一些内容,如:

    if (oSession.HostnameIs("myhost") && (oSession.oRequest.pipeClient.LocalPort == 80)) {
    oSession.fullUrl = "https://" + oSession.url;
    }
    

    当然,这假设Fiddler被配置为在端口80上运行,端口80是HTTP的默认端口。您可以在任何您喜欢的端口上运行它(例如,如果端口80已经在使用中),但您需要更改客户端请求的URL中的端口,如果可以这样做,您可能可以将客户端更改为首先使用HTTPS URL。

  • 在WinHTTP中设置WinINet代理配置
  • MS-如何使用注册表文件配置客户端代理服务器设置
  • 配置Fiddler解密HTTPS流量