如何使用iOS模拟器/设备的charlesproxy检查WebSocket流量

ar7v8xwq  于 2023-02-17  发布在  iOS
关注(0)|答案(5)|浏览(543)

我想检查通过web套接字的网络流量,我无法控制网络代码,因为这是一个二进制库,我没有源代码,所以我无法在代码的网络部分执行任何日志/断点
我试过使用最新版本的CharlesProxy,它声称能够嗅探websocket,但是当我尝试使用websocket的url和apis时,从我的iPhone调用的端点列表中甚至没有提到。

我已经验证了CharlesProxy配置正确,因为即使在SSL下,我也能够检查非websocket流量。
所以我的问题是:有没有人找到一个解决方案来检查流量通过网络套接字与CharlesProxy?

  • 注意:我在使用iOS9时禁用了ATS *

谢谢!

kyvafyod

kyvafyod1#

我终于找到了答案。

Charles 3.11.2与WebSocket完美配合。

我使用socketIO,所以我已经看到了协商阶段发送的http请求,但是我错过了websockets流量。
一开始,socketIO尝试使用 polling,然后切换到使用 websockets
当您转到状态为的请求时,WebSocket流量可见:* “发送请求正文”*,实际上是 wss:// 请求。
你甚至有一个专门的标签来处理这类流量。其余的消息都会出现在那里。

PS1。确保您正确连接到插座,然后它出现在查尔斯。
我建议使用socketIO,这是一个伟大的增强全双工流量,如网络套接字。

k0pti3hp

k0pti3hp2#

    • 2022年6月更新:**虽然socket. io-client-swift有一个enableSOCKSProxy的API,但似乎 Redis v4实际上已经删除了对SOCKS代理的内置支持,所以这个选项实际上没有做任何事情!

所以看起来我们又回到了手工修补 Redis 来启用SOCKS代理。
简单回顾一下:我们已经从 Redis 支持SOCKS代理,但socket. io-client-swift没有API来启用它,到现在socket. io-client-swift有API来启用SOCKS代理, Redis 不再支持。🤣🙄.

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

可接受的答案似乎不适用于iOS设备上的Socket. IO。
IO-Client-Swift的最新版本(撰写本文时为15.0.0)在iOS/OS X上使用Starscream作为WebSockets。
好消息是 Redis 支持SOCKS代理:

  1. IO不公开 Redis 网络套接字,也不提供任何API来启用SOCKS代理行为。
    1.内置在 Redis 中的SOCKS代理使用了OS SOCKS代理设置,设置起来很麻烦(至少对于iOS来说)。
    如果我有时间,我可能会建议公关更彻底地解决这个问题,但考虑到这需要 Redis 和Socket. IO-Client-Swift的工作,这并不完全是直截了当的。
    出于临时调试的目的(这是Charles的用例!),最简单的方法是将WebSocket.swift文件作为 Redis 的一部分进行编辑,并替换以下代码:
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代理设置(因为HTTP和SOCKS将使用相同的IP),在Charles中启用了SOCKS代理,并且端口与上面代码中的端口匹配(默认为8889)。

lyr7nygr

lyr7nygr3#

谢谢你非常非常有帮助的回答乔纳森埃利斯!我正在使用推送器,这工作得很好!
然而,我发现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代理。
再次感谢!

rpppsulh

rpppsulh4#

找到了变通解决方案:我试了一下,虽然iOS模拟器遵循系统的HTTP代理设置,但是WebSocket没有遵循,Socks5代理设置也没有遵循,但是我们可以在Charles中使用Reverse Proxies来强制模拟器使用,在Charles中点击Proxy -> Reverse Proxies,设置一个本地地址作为你的WebSocket服务器的透明代理,然后在new WebSocket(<address>)中使用该地址(在ReactNative的情况下),然后您可以看到WebSocket连接出现在Charles中

z9zf31ra

z9zf31ra5#

还有一个变种

var rd: InputStream
var wr: OutputStream
let dict: NSDictionary = [
    StreamSOCKSProxyConfiguration.hostKey.rawValue : <ip>,
    StreamSOCKSProxyConfiguration.portKey.rawValue : <port>
]
rd.setProperty(dict, forKey: Stream.PropertyKey.socksProxyConfigurationKey)
wr.setProperty(dict, forKey: Stream.PropertyKey.socksProxyConfigurationKey)

let proxyDict = CFNetworkCopySystemProxySettings()
let prop = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
rd.setProperty(prop, forKey: Stream.PropertyKey(rawValue: kCFStreamPropertySOCKSProxy as String as String))
wr.setProperty(prop, forKey: Stream.PropertyKey(rawValue: kCFStreamPropertySOCKSProxy as String as String))

CharlesProxy设置

Proxy -> Proxy Settings... -> Proxies -> Enable SOCKS Proxy

也可以使用websocket-tester检查/查看套接字连接

相关问题