web-dev-qa-db-fra.com

Comment inspecter le trafic websocket avec charlesproxy pour simulateur / appareils iOS

Je voudrais inspecter le trafic réseau passant par les sockets web , je n'ai aucun contrôle sur le code réseau car il s'agit d'une bibliothèque binaire pour laquelle je n'ai pas le code source, donc je ne peux pas faire de journal/point d'arrêt dans la partie réseau du code.

J'ai essayé d'utiliser la dernière version de CharlesProxy qui prétend être capable de flairer les websockets mais quand j'ai essayé l'url et les apis en utilisant des websockets n'étaient même pas mentionnés dans la liste des points de terminaison appelés depuis mon iPhone.

Version 3.11 release notes

J'ai vérifié que CharlesProxy est correctement configuré car je peux inspecter le trafic non Websocket même sous SSL.

Ma question est donc la suivante: quelqu'un a-t-il trouvé une solution pour inspecter le trafic passant par les sockets Web avec CharlesProxy?

Remarque: J'ai désactivé ATS lorsque j'utilise iOS9

Merci!

31
matanwrites

J'ai finalement trouvé la réponse.

Charles 3.11.2 fonctionne parfaitement avec WebSocket.

J'utilise socketIO , j'ai donc déjà vu des requêtes http envoyées pendant la phase de négociation, mais J'ai raté le trafic des websockets.

Au début, socketIO essaie d'utiliser polling puis passe à l'utilisation websockets.

Le trafic Websocket est visible lorsque vous accédez à la demande avec le statut: "Envoi du corps de la demande" qui est en fait wss: // demande.

Vous avez même un onglet dédié à ce type de trafic. Le reste des messages apparaîtra juste là.

enter image description here

PS1. Assurez-vous que vous êtes correctement connecté au socket, il apparaîtra dans Charles.
PS2. Je suggère que l'utilisation de socketIO soit une grande amélioration pour le trafic full-duplex comme les websockets.

22
klimat

MISE À JOUR: Apparemment socket.io-client-Swift v15.1.0 prend désormais correctement en charge le proxy SOCKS. Je ne l'ai pas encore essayé, mais cela signifierait que ces modifications manuelles de Starscream ne sont plus nécessaires.


La réponse acceptée ne semble pas fonctionner avec Socket.IO sur les appareils iOS.

La dernière version de Socket.IO-Client-Swift (15.0.0 au moment de la rédaction) utilise Starscream pour WebSockets sur iOS/OS X.

La bonne nouvelle est que Starscream prend en charge le proxy SOCKS cependant:

  1. Socket.IO n'expose pas la websocket de Starscream et ne fournit aucune API pour activer le comportement de proxy SOCKS.

  2. Le proxy SOCKS intégré à Starscream utilise les paramètres de proxy OS SOCKS qui sont lourds à configurer (au moins pour iOS).

Si j'obtiens un peu de temps, je pourrais proposer un RP pour résoudre ce problème de manière plus approfondie, mais étant donné qu'il nécessite un travail à la fois sur Starscream et Socket.IO-Client-Swift, ce n'est pas tout à fait simple.

Le moyen le plus simple de contourner cela à des fins de débogage temporaire (qui est le cas d'utilisation de Charles!), Est de modifier le WebSocket.Swift fichier dans le cadre de Starscream, et remplacez ce code:

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)
}

avec ce code:

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)

Cela garantira que le proxy SOCKS est activé par défaut et acheminera tout le trafic Websockets via Charles.

Vous devez ensuite vous assurer que les paramètres du proxy HTTP sont configurés dans iOS (car la même IP sera utilisée pour HTTP et SOCKS), le proxy SOCKS est activé dans Charles et que le port correspond au port dans le code ci-dessus (par défaut 8889).

3
Jonathan Ellis

Merci pour votre réponse très très utile Jonathan Ellis! J'utilise Pusher et cela a très bien fonctionné!

Cependant, j'ai trouvé que socksConfig ne contenait pas toujours des données valides et ne fonctionnait pas ou plantait l'application lorsque j'en retirais l'IP. Étant donné que la seule chose que nous obtenons à partir de là est l'IP localhost, je viens de remplacer ce qui suit dans 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)
}

avec ça:

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)

Et puis activé le proxy de chaussettes dans Charles comme vous l'avez décrit.

Merci encore!

1