Wiki Qu'est-ce que captive.apple.com ?

2
2
sept.
2018

Qu'est-ce que captive.apple.com

captive.apple.com est un service de Health Check utilisé sur Android afin de connaître l'état de la connexion Wan (internet). Les smartphones/tablettes émettent de façon régulière des requêtes HTTP GET vers http://captive.apple.com/generate_204 tandis que ce dernier répond en affichant "Success " avec le code HTTP 204.
Si la machine n'arrive pas à récupérer cette valeur en joignant le site, le smartphone ou la tablette affichera un petit point d'exclamation sur l'écran d'accueil. Il annoncera aussi dans les notifications que la connexion internet n'est pas disponible.
A noter que d'autres logiciels peuvent utiliser d'autres adresses de health check.

Incidence sur la vie privée

La machine envoie un User-Agent complet avec la version de Dalvik, le modèle de la machine, la version d'Android et la version du Build. Bref, une emprune numérique qui peut éventuellement être facile à tracker.

Voici un exemple de ce que l'on peut voir grâce à netcat ( nc -l 127.0.0.1 8081 -v ). Les données sont bien entendu volontairement anonymisées :

root@testmachine:/# nc -l 127.0.0.1 8081 -v
Listening on [127.0.0.1] (family 0, port 8081)
Connection from [127.0.0.1] port 8081 [tcp/tproxy] accepted (family 2, sport 53078)
GET /generate_204 HTTP/1.1
Connection: Close
User-Agent: Dalvik/2.0.0 (Linux; U; Android 6.0; modèle_censuré Build/30.0.A.0.125)
Host: captive.apple.com
Accept-Encoding: gzip
X-Forwarded-For: 192.168.42.2

Mettre en place une alternative

Suivez ce tuto pour mettre en place un serveur DNS menteur : [Tuto/HowTo] Mettre en place un serveur DNS aux noms de domaines parametrable (Rogue DNS)
Dans les noms de domaines, renvoyez les adresses suivantes vers une adresse IP disponible sur votre réseau local (LAN).
captive.apple.com
connectivitycheck.gstatic.com
detectportal.firefox.com
Sur cette adresse IP Lan, utilisez un serveur web ou netcat afin de renvoyer un http 204 avec "Success" dans le contenu. Le plus simple étant d'utiliser ncat avec une commande du type :
ncat -c "echo 'HTTP/1.0 204 OK\n\n<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>'" -k -lp 80

Pour ce faire nous allons utiliser un script qui checkera le réseau et lancera ncat ou non :

  1. Téléchargez ce script de lancement, rendez-le exécutable puis rangez-le où vous souhaitez. Par défaut le script écoute sur 0.0.0.0:8081, éditez-le si besoin ;)
wget https://gitlab.com/voxdemonix/divers-script/raw/master/captive_alternative.bash && sudo chmod +x ./captive_alternative.bash
mv ./captive_alternative.bash /opt/scripts/
  • ncat et screen doivent être installé ( sudo apt-get install -y screen nmap )
  1. Éditez cron si possible avec un utilisateur disposant de peu de droit (root n'étant nécessaire que pour les ports les plus communs, situé sous les 1000 comme 80 et 443 entre autre)
crontab -e
  1. Et ajoutez la ligne suivante en l'adaptant éventuellement à vos envies :
@reboot     ( sleep 15 ; /opt/scripts/captive_alternative.bash )
*/10 * * * *    /opt/scripts/captive_alternative.bash
  • /opt/scripts/ => le chemin ou vous avez rangé le script

Si vous utilisez un Frontend Haproxy, voici la config Backend à insérer

backend fake_captive_portail
        mode http
        balance roundrobin
        cookie SERVERID insert indirect nocache
        server LocaleLoop 127.0.0.1:8081 cookie 127.0.0.1
  • # Analyse

    Posté par  . Évalué à 1 (+0/-0). Dernière modification le 05/09/18 à 15:47.

    Si quelqu'un dispose d'un peu de motivation et d'une passerelle permettant d'analyser le trafic réseau:
    J'aurais besoin d'infos (*1) afin de comprendre "pourquoi, lorsque le serveur captive.apple.com est sur le même LAN, avec Android 7 ou +, le smartphone renvoi vers une page de portail de connexion?".
    Ceci afin de terminer la procédure de mise en place d'une alternative.

    Merci ;)

    *1 au pire simplement un fichier .pcap contenant en brute les infos.

    • [^] # Re: Analyse

      Posté par  (site Web personnel) . Évalué à 3 (+0/-0). Dernière modification le 06/09/18 à 11:14.

      Pour mettre en place une alternative, ne vaut il mieux pas changer les réglages du téléphone que de rediriger via le DNS tous les services connus de détection de portail captif vers un serveur local ? Ici une doc plutôt bien fichue: https://android.stackexchange.com/questions/186993/captive-portal-parameters. Il y a le service Apple mentionné dans la page wiki, mais Google a aussi les siens ainsi que Qualcomm et plein d’autres.

      Suite à la lecture de cette page wiki, j’ai créé mon propre service et l’ai utilisé dans mon téléphone, c’est sûrement plus efficace que le contournement DNS.

      Par contre, mon service est accessible via une IP publique, je ne serais pas surpris qu’Android refuse explicitement les adresses privées, justement pour ne pas faire croire à l’utilisateur qu’il y a accès à Internet quand, en fait, ce n’est qu’une machine locale qui répond. Accepter une réponse locale serait à l’opposé exact de ce à quoi est censé servir la détection de portail captif.

      • [^] # Re: Analyse

        Posté par  . Évalué à 1 (+0/-0).

        Merci pour ton retour. 😉

        ne vaut il mieux pas changer les réglages du téléphone que de rediriger via le DNS tous les services connus de détection de portail captif vers un serveur local ?

        C'est plus propre a échelle personnelle, mais n'aura pas d'effet sur les invités.
        Dans le premier lien que tu partage: sont-ce des commandes a employer dans le terminal ?
        Quid après un reboot ?

        je ne serais pas surpris qu’Android refuse explicitement les adresses privées

        C'est le plus probable.

        • [^] # Re: Analyse

          Posté par  (site Web personnel) . Évalué à 3 (+0/-0). Dernière modification le 07/09/18 à 09:26.

          Après lecture du code d’Android (8.0.0_r4), je contredis mon intuition précédente : une réponse locale est acceptée.

          Par contre, pour qu’une réponse soit valide il faut qu’elle retourne un code HTTP 204 ou un code HTTP 200 à condition que le contenu soit vide. Or le serveur donné en exemple retourne 200 et un contenu HTML qui affiche « Success ». C’est donc la réponse du serveur local qui ne fonctionne pas.

          Il y a une exception à cela, c’est si la connection utilise un script PAC, auquel cas c’est l’adresse du proxy qui est testée, et s’il retourne un code 200, la réponse est valide.

          L’erreur ne doit donc pas être dans la configuration réseau, mais à la ligne 7 du script captive_alternative.bash.

          Je n’avais pas précisé ça dans ma réponse précédente, mais le service qui fonctionne chez moi est bien réglé pour retourner un code 204 (j’avais déjà un nginx sous la main et n’ai donc pas utilisé le script indiqué sur la page wiki).

          • [^] # Re: Analyse

            Posté par  . Évalué à 1 (+0/-0). Dernière modification le 07/09/18 à 13:23.

            L’erreur ne doit donc pas être dans la configuration réseau, mais à la ligne 7 du script captive_alternative.bash.

            Gros merci pour ton retour, l'erreur est corrigé.

            Pour l'anecdote, il est OBLIGATOIRE que le serveur puisse accepter les connexions en HTTP (sans S). (si vous utilisez HaProxy, vous pouvez déplacer les deux lignes de paramètres concernant la redirection http=>https depuis votre backend vers vos frontends)

            Il semble aussi fonctionner pour remplacer http://detectportal.firefox.com/success.txt

            j’avais déjà un nginx sous la main et n’ai donc pas utilisé le script indiqué sur la page wiki

            J'ai volontairement privilégié netcat vs apache2/nginx pour diminuer l'impact machine. (ainsi que la configuration)

            • [^] # Re: coquille

              Posté par  . Évalué à 1 (+0/-0). Dernière modification le 07/09/18 à 15:59.

              (si vous utilisez HaProxy, vous pouvez déplacer les deux lignes de paramètres concernant la redirection http=>https depuis votre backend vers vos frontends)

              Ptite erreur, c'est "depuis votre paragraphe backend vers vos paragraphes frontend".
              Un exemple sera fourni dans le wiki.

    • [^] # Re: Analyse

      Posté par  (site Web personnel) . Évalué à 1 (+0/-0).

      c'est une manière relativement simple et assez fiable de détecter un réseau wifi à portail: interroger un service connu externe et si l'adresse en réponse est une adresse du LAN c'est très probablement que le réseau demande une authentification Web

      • [^] # Re: Analyse

        Posté par  . Évalué à 1 (+0/-0).

        Non il demande juste un code HTTP 204, peu importe que l'IP soit publique ou privé. Idem pour firefox (qui produit pas mal de requêtes) avec detectportal.firefox.com.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.