Via dit forum kwam ik er achter dat de Nefit Easy XMPP gebruikt om met de Bosch backend (Nefit is van Bosch) te babbelen.
De iOS applicatie gebruikt dat protocol ook, en aangezien het verkeer daarvan redelijk makkelijk af te luisteren is (ik heb XMPPloit gebruikt) heb ik geprobeerd om te kijken of het mogelijk is een eigen client te maken.
Vooralsnog is dat nog niet gelukt, ik loop al vast bij de authenticatie. Bij deze een beschrijving van wat ik geprobeerd heb, misschien dat anderen er iets mee kunnen.
De app gebruikt SASL DIGEST-MD5 authenticatie om zich bij de server aan te melden. De challenge/response data ziet er vrij standaard uit, alhoewel er een aantal velden gebruikt worden die niet in voornoemde pagina staan, en ook wordt een veld soms wel, soms niet gequote. Ik weet niet of dat laatste iets uitmaakt.
Na enige handshaking stuurt de server een challenge naar de client (een base64-encoded string, die ik voor de duidelijkheid even formatteer hieronder):
De client stuurt een response:
Daar loop ik al spaak. Waar het bij de response om gaat is het "response" veld, die moet je berekenen aan de hand van het volgende algoritme:
Voor de volledigheid de (Node) code, voor de liefhebber. Ik heb al allerlei mogelijkheden uitgeprobeerd maar ik krijg de juiste token niet uit m'n code.
EDIT 25 december 2015
Na "bekijken" van de Android app blijkt dat "password" ook een prefix moet krijgen:
Zodra ik die gebruik wordt het token goed berekend! Volgende stap is om het bereken van het token met node-xmpp-client werkend te krijgen zodat die zich kan authenticeren bij de backend.
EDIT 26 december 2015
Het decrypten van de berichten die de server terugstuurt heb ik inmiddels ook werkend. De berichten zijn met AES-256/ECB/NoPadding versleuteld, de sleutel wordt gegenereerd aan de hand van o.a. de "access key" (die is toegewezen aan het apparaat, staat op de verpakking) en het wachtwoord dat je zelf bij de eerste keer moet opgeven. Zodra ik de code heb opgeschoond zal ik 'em ergens online zetten.
De iOS applicatie gebruikt dat protocol ook, en aangezien het verkeer daarvan redelijk makkelijk af te luisteren is (ik heb XMPPloit gebruikt) heb ik geprobeerd om te kijken of het mogelijk is een eigen client te maken.
Vooralsnog is dat nog niet gelukt, ik loop al vast bij de authenticatie. Bij deze een beschrijving van wat ik geprobeerd heb, misschien dat anderen er iets mee kunnen.
De app gebruikt SASL DIGEST-MD5 authenticatie om zich bij de server aan te melden. De challenge/response data ziet er vrij standaard uit, alhoewel er een aantal velden gebruikt worden die niet in voornoemde pagina staan, en ook wordt een veld soms wel, soms niet gequote. Ik weet niet of dat laatste iets uitmaakt.
Na enige handshaking stuurt de server een challenge naar de client (een base64-encoded string, die ik voor de duidelijkheid even formatteer hieronder):
code:
1
2
3
4
5
| realm="wa2-mz36-qrmzh6.bosch.de", nonce="KofKm91UCIVDZQwrugeZueNdaF61rIPiM6u/r8PE", qop="auth", charset=utf-8, algorithm=md5-sess |
De client stuurt een response:
code:
1
2
3
4
5
6
7
8
9
| username="rrccontact_SERIENUMMER", realm="wa2-mz36-qrmzh6.bosch.de", nonce="KofKm91UCIVDZQwrugeZueNdaF61rIPiM6u/r8PE", cnonce="047FFB47-C3EF-40C9-A805-017FA9BC956C", nc=00000001, qop=auth, digest-uri="xmpp/wa2-mz36-qrmzh6.bosch.de", response=9d046be53fd44bc7495f13985349dfaf, charset=utf-8 |
Daar loop ik al spaak. Waar het bij de response om gaat is het "response" veld, die moet je berekenen aan de hand van het volgende algoritme:
- Create a string of the form "username:realm:password". Call this string X.
- Compute the 16 octet MD5 hash of X. Call the result Y.
- Create a string of the form "Y:nonce:cnonce:authzid". Call this string A1.
- Create a string of the form "AUTHENTICATE:digest-uri". Call this string A2.
- Compute the 32 hex digit MD5 hash of A1. Call the result HA1.
- Compute the 32 hex digit MD5 hash of A2. Call the result HA2.
- Create a string of the form "HA1:nonce:nc:cnonce:qop:HA2". Call this string KD.
- Compute the 32 hex digit MD5 hash of KD. Call the result Z.
Voor de volledigheid de (Node) code, voor de liefhebber. Ik heb al allerlei mogelijkheden uitgeprobeerd maar ik krijg de juiste token niet uit m'n code.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| const crypto = require('crypto') const MD5 = (s, encoding) => { return crypto .createHash('md5') .update(s) .digest(encoding || 'binary'); }; const MD5H = (s) => MD5(s, 'hex'); const username = 'rrccontact_' + SERIENUMMER'; const password = 'PASSWORD'; const realm = 'wa2-mz36-qrmzh6.bosch.de'; const nonce = 'KofKm91UCIVDZQwrugeZueNdaF61rIPiM6u/r8PE'; const cnonce = '047FFB47-C3EF-40C9-A805-017FA9BC956C'; const digestUri = 'xmpp/wa2-mz36-qrmzh6.bosch.de'; const nc = '00000001'; const qop = 'auth'; const X = [ username, realm, password ].join(':'); const Y = MD5(X); const A1 = [ Y, nonce, cnonce ].join(':'); // no authzid const A2 = [ 'AUTHENTICATE', digestUri ].join(':'); const HA1 = MD5H(A1); const HA2 = MD5H(A2); const KD = [ HA1, nonce, nc, cnonce, qop, HA2 ].join(':'); const Z = MD5H(KD); console.log('token', Z); |
EDIT 25 december 2015
Na "bekijken" van de Android app blijkt dat "password" ook een prefix moet krijgen:
code:
1
| const password = 'Ct7ZR03b_' + PASSWORD; |
Zodra ik die gebruik wordt het token goed berekend! Volgende stap is om het bereken van het token met node-xmpp-client werkend te krijgen zodat die zich kan authenticeren bij de backend.
EDIT 26 december 2015
Het decrypten van de berichten die de server terugstuurt heb ik inmiddels ook werkend. De berichten zijn met AES-256/ECB/NoPadding versleuteld, de sleutel wordt gegenereerd aan de hand van o.a. de "access key" (die is toegewezen aan het apparaat, staat op de verpakking) en het wachtwoord dat je zelf bij de eerste keer moet opgeven. Zodra ik de code heb opgeschoond zal ik 'em ergens online zetten.
[ Voor 10% gewijzigd door brightvalve op 26-12-2015 14:34 ]