如何使用charlesproxy检查websocket流量以用于iOS模拟器/设备

问题描述 投票:30回答:3

我想检查通过网络套接字的网络流量,我无法控制网络代码,因为这是一个二进制库,我没有源代码,所以我不能在网络部分做任何日志/断点码。

我已经尝试使用最新版本的CharlesProxy声称能够嗅探网页框,但是当我尝试使用网页框时,我甚至没有在我的iPhone调用的端点列表中提到网址。

Version 3.11 release notes

我已经验证CharlesProxy配置正确,因为即使在SSL下我也可以检查非websocket流量。

所以我的问题是:有没有人找到一个解决方案来检查通过CharlesProxy通过websockets的流量?

注意:使用iOS9时,我禁用了ATS

谢谢!

ios sockets websocket charles-proxy cfnetwork
3个回答
22
投票

我终于找到了答案。

Charles 3.11.2与WebSocket完美配合。

我使用socketIO,所以我已经看到在协商阶段发送的http请求,但我错过了websockets流量。

最初,socketIO尝试使用轮询,然后切换到使用websockets。

当您转到具有以下状态的请求时,可以看到websocket流量:“发送请求正文”,这实际上是wss:// request。

您甚至可以为此类流量设置专用标签。其余的消息将出现在那里。

enter image description here

PS1。确保您已正确连接到插座,然后它出现在Charles中。 PS2。我建议使用socketIO,这对于像websockets这样的全双工流量来说是一个很好的增强。


3
投票

更新:显然socket.io-client-swift v15.1.0现在正确支持SOCKS代理。我还没有尝试过,但这意味着不再需要对红蜘蛛进行这些手动编辑。


接受的答案似乎不适用于iOS设备上的Socket.IO。

最新版本的Socket.IO-Client-Swift(撰写本文时为15.0.0)在iOS / OS X上使用Starscream作为WebSockets。

好消息是,红蜘蛛支持SOCKS代理:

  1. Socket.IO不公开Starscream websocket或提供任何API来启用SOCKS代理行为。
  2. 内置于Starscream中的SOCKS代理使用OS SOCKS代理设置,这些设置很麻烦(至少对于iOS)。

如果我得到一些时间,我可能会建议PR更彻底地解决这个问题,但鉴于它需要同时使用Starscream和Socket.IO-Client-Swift,这并不完全是直截了当的。

为了临时调试目的(这是查尔斯的用例),最简单的方法是编辑WebSocket.swift文件作为Starscream的一部分,并替换此代码:

if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

使用此代码:

let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, CFNetworkCopySystemProxySettings()!.takeRetainedValue()) as! [String: Any]
let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let ip = socksConfig["HTTPSProxy"]
let proxySocksConfig = ["SOCKSProxy": ip, "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

这将确保默认情况下启用SOCKS代理,并将通过Charles路由所有websockets流量。

然后,您需要确保在iOS中配置HTTP代理设置(因为相同的IP将用于HTTP和SOCKS),在Charles中启用SOCKS代理,并且端口与上面代码中的端口匹配(默认情况下) 8889)。


1
投票

谢谢你非常有帮助的回答Jonathan Ellis!我正在使用Pusher,这很棒!

但是,我发现socksConfig并不总是包含有效数据,但是当我从那里取出IP时,它不起作用或者会崩溃应用程序。因为我们从那里获得的唯一东西是localhost IP我刚刚在WebSocket.swift中替换了以下内容

if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

有了这个:

let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let proxySocksConfig = ["SOCKSProxy": "127.0.0.1", "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

然后如你所述在Charles中启用socks代理。

再次感谢!

© www.soinside.com 2019 - 2024. All rights reserved.