[PHP] SSO lukt me niet in MSNP15

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Cake Masher

Cake Masher

27/07/2011 16:38:24
Quote Anchor link
Beste,

Het volgende gaat over MSNP15, niet iedereen zal zich hier waarschijnlijk in verdiept hebben. Maar ik hoop toch dat iemand me hier veder mee kan helpen.

Wat ik nu probeer, is om een script te maken dat inlogt op een MSN account.
Dit is me veder gelukt met de vorige MSN Protocol versies waar geen SSO vereist was.
Nu probeer ik een login te maken die op de nieuwere msn protocollen werkt.

Het probleem zit hem bij mij in de SSO (Singel Sign On). De verbinding met de MSN servers en de daarop komende commands heb ik geen problemen mee.
Maar zodra de SSO komt zit ik in de knoei.

Er moet van alles gebeuren om een SSO response te creëren. Nu snapte ik daar zelf niet zo veel meer van, dus ben op internet gaan zoeken naar mensen die 't wel voor elkaar hebben gekregen met PHP. Die heb ik gevonden, namelijk 1 vaarvan ik de bron niet meer weet, en de MSN class die hier te vinden is 'http://code.google.com/p/phpmsnclass'.

Ik heb de functies die die class gebruikt gekopieerd en in mijn script geplakt. Maar ik krijg als response terug '[Sock 0] << 911 7' wat inhoud dat de ticket of iets dergelijks onjuist is. Ik heb de test's uitgevoerd die onderaan op de volgende pagina staan 'http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO'.
De results daarvan zijn gewoon 't zelfde. Maar het werkt gewoon niet. Die class waar ik de funcites vandaan gekopieërd hebt werkt wel gewoon.

Ik hoop dat iemand me kan helpen.
Hieronder volgt de code die ik gebruik om de SSO response te genereren:


Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
<?php

// Het volgende is dus gekopieërd uit de al eerder genoemde class !!

    function get_passport_ticket($user, $pass, $policy, $url = '')
    {

        $password = htmlspecialchars($pass);

        if ($url === '')
            $passport_url = 'https://login.live.com/RST.srf';
        else
            $passport_url = $url;

        $XML = '<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
          xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
          xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
          xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc"
          xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">
<Header>
  <ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">
    <ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>
    <ps:BinaryVersion>4</ps:BinaryVersion>
    <ps:UIVersion>1</ps:UIVersion>
    <ps:Cookies></ps:Cookies>
    <ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>
  </ps:AuthInfo>
  <wsse:Security>
    <wsse:UsernameToken Id="user">
      <wsse:Username>'
.$user.'</wsse:Username>
      <wsse:Password>'
.htmlspecialchars ($password).'</wsse:Password>
    </wsse:UsernameToken>
  </wsse:Security>
</Header>
<Body>
  <ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">
    <wst:RequestSecurityToken Id="RST0">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>http://Passport.NET/tb</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST1">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>messengerclear.live.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="'
.$policy.'"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST2">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>messenger.msn.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="?id=507"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST3">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>contacts.msn.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST4">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>messengersecure.live.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="MBI_SSL"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST5">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>spaces.live.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
    <wst:RequestSecurityToken Id="RST6">
      <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
          <wsa:Address>storage.msn.com</wsa:Address>
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      <wsse:PolicyReference URI="MBI"></wsse:PolicyReference>
    </wst:RequestSecurityToken>
  </ps:RequestMultipleSecurityTokens>
</Body>
</Envelope>'
;
//<?
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $passport_url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);
        $data = curl_exec($curl);
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);

        if ($http_code != 200) {
            if (strpos($data, '<faultcode>psf:Redirect</faultcode>') === false) {
                echo "*** Can't get passport ticket! http code = $http_code";
                return false;
            }

            preg_match("#<psf\:redirectUrl>(.*)</psf\:redirectUrl>#", $data, $matches);
            if (count($matches) == 0) {
                echo "*** redirect, but can't get redirect URL!";
                return false;
            }

            $redirect_url = $matches[1];
            if ($redirect_url == $passport_url) {
                echo "*** redirect, but redirect to same URL!";
                return false;
            }

            echo "*** redirect to $redirect_url";
            return get_passport_ticket($user, $pass, $policy, $redirect_url);
        }


        if (strpos($data, '<faultcode>psf:Redirect</faultcode>') !== false) {
            preg_match("#<psf\:redirectUrl>(.*)</psf\:redirectUrl>#", $data, $matches);
            if (count($matches) != 0) {
                $redirect_url = $matches[1];
                if ($redirect_url == $passport_url) {
                    echo "*** redirect, but redirect to same URL!";
                    return false;
                }

                echo "*** redirect to $redirect_url";
            return get_passport_ticket($user, $pass, $policy, $redirect_url);
            }
        }


        preg_match("#".
                   "<wsse\:BinarySecurityToken Id=\"Compact1\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "<wst\:BinarySecret>(.*)</wst\:BinarySecret>(.*)".
                   "<wsse\:BinarySecurityToken Id=\"PPToken2\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "<wsse\:BinarySecurityToken Id=\"Compact3\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "<wsse\:BinarySecurityToken Id=\"Compact4\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "<wsse\:BinarySecurityToken Id=\"Compact5\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "<wsse\:BinarySecurityToken Id=\"Compact6\">(.*)</wsse\:BinarySecurityToken>(.*)".
                   "#",
                   $data, $matches);

        // no ticket found!
        if (count($matches) == 0) {

            preg_match("#".
                       "<wsse\:BinarySecurityToken Id=\"Compact1\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "<wst\:BinarySecret>(.*)</wst\:BinarySecret>(.*)".
                       "<wsse\:BinarySecurityToken Id=\"Compact2\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "<wsse\:BinarySecurityToken Id=\"Compact3\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "<wsse\:BinarySecurityToken Id=\"Compact4\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "<wsse\:BinarySecurityToken Id=\"Compact5\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "<wsse\:BinarySecurityToken Id=\"Compact6\">(.*)</wsse\:BinarySecurityToken>(.*)".
                       "#",
                       $data, $matches);
            if (count($matches) == 0) {
                echo "*** Can't get passport ticket!";
                return false;
            }
        }


        $aTickets = array(
                    'ticket' => html_entity_decode($matches[1]),
                    'secret' => html_entity_decode($matches[3]),
                    'web_ticket' => html_entity_decode($matches[5]),
                    'contact_ticket' => html_entity_decode($matches[7]),
                    'oim_ticket' => html_entity_decode($matches[9]),
                    'space_ticket' => html_entity_decode($matches[11]),
                    'storage_ticket' => html_entity_decode($matches[13])
                    );

                      
        return $aTickets;
    }



  
    function
mhash_sha1($data, $key)
    {

        if (extension_loaded("mhash"))
            return mhash(MHASH_SHA1, $data, $key);

        // RFC 2104 HMAC implementation for php. Hacked by Lance Rushing
        $b = 64;
        if (strlen($key) > $b)
            $key = pack("H*", sha1($key));
        $key = str_pad($key, $b, chr(0x00));
        $ipad = str_pad("", $b, chr(0x36));
        $opad = str_pad("", $b, chr(0x5c));
        $k_ipad = $key ^ $ipad ;
        $k_opad = $key ^ $opad;

        $sha1_value = sha1($k_opad . pack("H*", sha1($k_ipad . $data)));

        $hash_data = '';
        $str = join('',explode('\x', $sha1_value));
        $len = strlen($str);
        for ($i = 0; $i < $len; $i += 2)
            $hash_data .= chr(hexdec(substr($str, $i, 2)));
        return $hash_data;
    }

    function
derive_key($key, $magic)
    {


        $hash1 = mhash_sha1($magic, $key);
        $hash2 = mhash_sha1($hash1.$magic, $key);
        $hash3 = mhash_sha1($hash1, $key);
        $hash4 = mhash_sha1($hash3.$magic, $key);
        return $hash2.substr($hash4, 0, 4);
    }

    function
generateLoginBLOB($key, $challenge)
    {

        $key1 = base64_decode($key);
        $key2 = derive_key($key1, 'WS-SecureConversationSESSION KEY HASH');
        $key3 = derive_key($key1, 'WS-SecureConversationSESSION KEY ENCRYPTION');

        // get hash of challenge using key2
        $hash = mhash_sha1($challenge, $key2);

        // get 8 bytes random data
        $iv = substr(base64_encode(rand(1000,9999).rand(1000,9999)), 2, 8);
        $iv = "\x00\x00\x00\x00\x00\x00\x00\x00";


        $cipher = mcrypt_cbc(MCRYPT_3DES, $key3, $challenge."\x08\x08\x08\x08\x08\x08\x08\x08", MCRYPT_ENCRYPT, $iv);

        $blob = pack('LLLLLLL', 28, 1, 0x6603, 0x8004, 8, 20, 72);
        $blob .= $iv;
        $blob .= $hash;
        $blob .= $cipher;

        return base64_encode($blob);
    }

    
    





// Zo handel ik de SSO request, daarnaast word in de functie send het volgende gedaan:
// 1) [n] word veranderd door de juist TRID, hierbij word alleen de eerste [n] veranderd word eventueel de [n] die in $login_code of dergelijks staat niks mee gedaan.
// 2) er word \r\n aan het einde toegevoegd.
// 3) Het geheel word naar de juiste socket gestuurd.


// $data is wat er ontvangen is van de MSN Server.



@list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce,) = @explode(' ', $data);
$tickets        = get_passport_ticket ($email, $pass, $policy);
$login_code        = generateLoginBlob ($tickets['secret'], $nonce);
                                
                                
send ("USR [n] SSO S " . $tickets['ticket'] . " " . $login_code);



?>
Gewijzigd op 27/07/2011 16:41:01 door Cake Masher
 
PHP hulp

PHP hulp

19/04/2024 10:16:43
 
Cake Masher

Cake Masher

29/07/2011 17:00:13
Quote Anchor link
Het is me nog steeds niet gelukt.
Ik heb geprobeerd om de class te gebruiken in mijn script, dus ik include de class en roep de functies van die class aan. De output daarvan werkt ook niet.
Wat me opvalt is dat de $login_code altijd bij mij eindigde met '=='. Bij de class eindigde dit altijd met '='. Nu is 't base64 en zou dat kunnen kloppen, maar ik vond 't gewoon raar. Ik krijg dus ook == terug als ik de class aanroep via mijn script.
Veder zit er niks raars in 't script van mij, hij doet gewoon precies 't zelfde wat de class ook doet, en verstuurd de boel ook het zelfde zoals de class het doet. Er zijn veder geen aanpassingen. Maar toch werkt 't niet.

Veder heb ik de hele class stap voor stap na gekeken wat die nou precies allemaal stuurd. Mijn script stuurt dus precies 't zelfde, tot de SSO. De SSO is dus elke keer verschillend en worden ook random bytes aangemaakt.

Kan iemand me helpen? Ik snap er niks meer van.

p.s. Ik wil die class niet gebruiken, ik wil m'n eige script maken maar zou eventueel de functies van de class wel willen kopiëren om veder te komen. (zoals ik nu dus ook al gedaan heb).
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.