2011-02-11 33 views
1

我正在Python中實現MSNP15協議。我已經驗證過我的哈希和加密函數正在工作(或者至少,它們與我在網上找到的例子相匹配),但是我總是收到來自服務器的911錯誤。在Python中實現MSNP15 - 911錯誤,但所有票據都正確

感謝您的任何幫助。

Python代碼如下;

msntest.py:

import socket 
import httplib 
from encryption import GetSSOTicket 

username = "[email protected]" 
password = "password" 

def ReadAll(sock): 
    data = "" 
    while 1: 
     try: 
      r = sock.recv(4096) 
      data += r 
     except socket.timeout: 
      break 
    return data 


def SOAPRequest(xml): 
    url = "login.live.com" 
    con = httplib.HTTPSConnection(url) 

    headers = {"Host": "login.live.com", 
       "Accept": "text/plain"} 

    con.request("POST", "/RST.srf", xml, headers) 

    response = con.getresponse().read() 

    con.close() 

    return response 


def GetTicket(policy, nonce): 
    xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
    xml += "<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>"; 
    xml += "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">"; 
    xml += "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>"; 
    xml += "<ps:BinaryVersion>4</ps:BinaryVersion>"; 
    xml += "<ps:UIVersion>1</ps:UIVersion>"; 
    xml += "<ps:Cookies></ps:Cookies>"; 
    xml += "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>"; 
    xml += "</ps:AuthInfo>"; 
    xml += "<wsse:Security><wsse:UsernameToken Id=\"user\">"; 
    xml += "<wsse:Username>" + username + "</wsse:Username>"; 
    xml += "<wsse:Password>" + password + "</wsse:Password>"; 
    xml += "</wsse:UsernameToken></wsse:Security></Header><Body>"; 
    xml += "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">"; 
    xml += "<wst:RequestSecurityToken Id=\"RST0\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"; 
    xml += "<wsp:AppliesTo><wsa:EndpointReference><wsa:Address>http://Passport.NET/tb"; 
    xml += "</wsa:Address></wsa:EndpointReference></wsp:AppliesTo></wst:RequestSecurityToken>"; 
    xml += "<wst:RequestSecurityToken Id=\"RST1\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType><wsp:AppliesTo><wsa:EndpointReference>"; 
    xml += "<wsa:Address>messengerclear.live.com</wsa:Address></wsa:EndpointReference></wsp:AppliesTo>"; 
    xml += "<wsse:PolicyReference URI=\"" + policy + "\"></wsse:PolicyReference></wst:RequestSecurityToken>"; 
    xml += "<wst:RequestSecurityToken Id=\"RST2\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"; 
    xml += "<wsp:AppliesTo>"; 
    xml += "<wsa:EndpointReference>"; 
    xml += "<wsa:Address>contacts.msn.com</wsa:Address>"; 
    xml += "</wsa:EndpointReference>"; 
    xml += "</wsp:AppliesTo>"; 
    xml += "<wsse:PolicyReference URI=\"MBI\">"; 
    xml += "</wsse:PolicyReference>"; 
    xml += "</wst:RequestSecurityToken>"; 
    xml += "</ps:RequestMultipleSecurityTokens></Body></Envelope>"; 

    xmlDoc = SOAPRequest(xml) 

    start = xmlDoc.find("<wst:BinarySecret>")+len("<wst:BinarySecret>") 
    end = xmlDoc.find("</wst:BinarySecret>") 
    secret = xmlDoc[start:end] 

    print "secret:" 
    print secret 

    start = xmlDoc.find('<wsse:BinarySecurityToken Id="Compact1">')+len('<wsse:BinarySecurityToken Id="Compact1">') 
    end = xmlDoc.find("</wsse:BinarySecurityToken>") 
    ticket = xmlDoc[start:end].replace("&amp;", "&") 

    SSOTicket = GetSSOTicket(secret, nonce) 

    return ticket + " " + SSOTicket 



def LogIntoNS(): 
    address = ("64.4.61.219", 1863) 

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.connect(address) 
    s.settimeout(3) 

    s.send("VER 1 MSNP15 CVR0\r\n") 

    ReadAll(s) 

    s.send("CVR 2 0x0407 win 6.0 i386 MSNMSGR 8.5 MSMSGS " + username + "\r\n") 

    ReadAll(s) 

    s.send("USR 3 SSO I " + username + "\r\n") 

    recvbuf = ReadAll(s) 

    recvbuf = recvbuf[recvbuf.find("USR"):] 

    policy = recvbuf.split()[4] 

    print "policy:" 
    print policy 

    nonce = recvbuf.split()[5] 
    print "nonce:" 
    print nonce 

    ticket = GetTicket(policy, nonce) 

    print "ticket:" 
    print ticket 

    s.send("USR 4 SSO S " + ticket + "\r\n") 

    print "Sent" 

    print s.recv(4096) 


LogIntoNS() 

encryption.py:

import hashlib, hmac 
import base64 
import pyDes 


def Combine(a, b): 
    aBytes = bytes(a) 
    bBytes = bytes(b) 
    combinedBytes = aBytes + bBytes 
    return combinedBytes 


def DeriveKey(key, magic): 
    hash1 = hmac.new(key, magic, hashlib.sha1).digest() 

    combined = str(Combine(hash1, magic)) 
    hash2 = hmac.new(key, combined, hashlib.sha1).digest() 

    hash3 = hmac.new(key, hash1, hashlib.sha1).digest() 

    combined = str(Combine(hash3, magic)) 
    hash4 = hmac.new(key, combined, hashlib.sha1).digest() 

    retKey = str(Combine(hash2, hash4[:4])) 

    return retKey 

def GetBeginning(): 
    Beginning = [chr(0)]*28 

    # StructHeaderSize = 28 
    Beginning[0] = 0x1c 
    Beginning[1] = 0x00 
    Beginning[2] = 0x00 
    Beginning[3] = 0x00 

    # CryptMode = 1 
    Beginning[4] = 0x01 
    Beginning[5] = 0x00 
    Beginning[6] = 0x00 
    Beginning[7] = 0x00 

    # CipherType = 0x6603 
    Beginning[8] = 0x03 
    Beginning[9] = 0x66 
    Beginning[10] = 0x00 
    Beginning[11] = 0x00 

    # HashType = 0x8004 
    Beginning[12] = 0x04 
    Beginning[13] = 0x80 
    Beginning[14] = 0x00 
    Beginning[15] = 0x00 

    # IV length = 8 
    Beginning[16] = 0x08 
    Beginning[17] = 0x00 
    Beginning[18] = 0x00 
    Beginning[19] = 0x00 

    # hash length = 20 
    Beginning[20] = 0x14 
    Beginning[21] = 0x00 
    Beginning[22] = 0x00 
    Beginning[23] = 0x00 

    # cipher length = 72 
    Beginning[24] = 0x48 
    Beginning[25] = 0x00 
    Beginning[26] = 0x00 
    Beginning[27] = 0x00 

    asd = "".join([chr(x) for x in Beginning]) 

    return asd 


def GetSSOTicket(key, nonce): 
    key1 = base64.b64decode(key) 

    key2 = DeriveKey(key1, "WS-SecureConversationSESSION KEY HASH") 

    key3 = DeriveKey(key1, "WS-SecureConversationSESSION KEY ENCRYPTION") 

    nonceHash = hmac.new(key2, nonce, hashlib.sha1).digest() 

    iv = [chr(0)]*8 
    iv[0] = 0x75 
    iv[1] = 0x95 
    iv[2] = 0x85 
    iv[3] = 0x61 
    iv[4] = 0x38 
    iv[5] = 0x85 
    iv[6] = 0xEF 
    iv[7] = 0x5C 

    iv = "".join([chr(x) for x in iv]) 

    encryptor = pyDes.triple_des(key3, pyDes.CBC, iv) 

    restOfNonce = chr(0x08) * 8 
    fullNonce = Combine(nonce, restOfNonce) 


    output = encryptor.encrypt(fullNonce) 

    beginning = GetBeginning() 

    struc = beginning + iv + nonceHash + output 

    value = base64.b64encode(struc) 

    return value 
+0

我不能粘貼pyDes文件在這裏,因爲它太大了。它可以從這裏,但:http://twhiteman.netfirms.com/des.html – combatdave 2011-02-11 15:48:18

回答

1

修改您的msntest.py一點,現在它應該工作:

import socket 
import httplib 
from encryption import GetSSOTicket 
import re 
from xml.sax import saxutils 

username = "[email protected]" 
password = "password" 

def ReadAll(sock): 
    data = "" 
    while 1: 
     try: 
      r = sock.recv(4096) 
      data += r 
     except socket.timeout: 
      break 
    return data 


def SOAPRequest(xml): 
    url = "login.live.com" 
    con = httplib.HTTPSConnection(url) 

    headers = {"Host": "login.live.com", 
       "Accept": "text/plain"} 

    con.request("POST", "/RST.srf", xml, headers) 

    response = con.getresponse().read() 

    con.close() 

    return response 


def GetTicket(policy, nonce): 
    xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
    xml += "<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>"; 
    xml += "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">"; 
    xml += "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>"; 
    xml += "<ps:BinaryVersion>4</ps:BinaryVersion>"; 
    xml += "<ps:UIVersion>1</ps:UIVersion>"; 
    xml += "<ps:Cookies></ps:Cookies>"; 
    xml += "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>"; 
    xml += "</ps:AuthInfo>"; 
    xml += "<wsse:Security><wsse:UsernameToken Id=\"user\">"; 
    xml += "<wsse:Username>" + username + "</wsse:Username>"; 
    xml += "<wsse:Password>" + password + "</wsse:Password>"; 
    xml += "</wsse:UsernameToken></wsse:Security></Header><Body>"; 
    xml += "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">"; 
    xml += "<wst:RequestSecurityToken Id=\"RST0\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"; 
    xml += "<wsp:AppliesTo><wsa:EndpointReference><wsa:Address>http://Passport.NET/tb"; 
    xml += "</wsa:Address></wsa:EndpointReference></wsp:AppliesTo></wst:RequestSecurityToken>"; 
    xml += "<wst:RequestSecurityToken Id=\"RST1\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType><wsp:AppliesTo><wsa:EndpointReference>"; 
    xml += "<wsa:Address>messengerclear.live.com</wsa:Address></wsa:EndpointReference></wsp:AppliesTo>"; 
    xml += "<wsse:PolicyReference URI=\"" + policy + "\"></wsse:PolicyReference></wst:RequestSecurityToken>"; 
    xml += "<wst:RequestSecurityToken Id=\"RST2\">"; 
    xml += "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"; 
    xml += "<wsp:AppliesTo>"; 
    xml += "<wsa:EndpointReference>"; 
    xml += "<wsa:Address>contacts.msn.com</wsa:Address>"; 
    xml += "</wsa:EndpointReference>"; 
    xml += "</wsp:AppliesTo>"; 
    xml += "<wsse:PolicyReference URI=\"MBI\">"; 
    xml += "</wsse:PolicyReference>"; 
    xml += "</wst:RequestSecurityToken>"; 
    xml += "</ps:RequestMultipleSecurityTokens></Body></Envelope>"; 

    xmlDoc = SOAPRequest(xml) 

    m = re.search(r'<wsse:BinarySecurityToken Id="Compact1">(.*?)</wst:BinarySecret>', xmlDoc) 
    secret = saxutils.unescape(m.group(1)) 
    secret = secret.split("<wst:BinarySecret>")[1] 

    print "secret:" 
    print secret 

    m = re.search(r'<wsse:BinarySecurityToken Id="Compact1">(.*?)</wsse:BinarySecurityToken>',xmlDoc) 
    ticket = saxutils.unescape(m.group(1)) 

    SSOTicket = GetSSOTicket(secret, nonce) 

    return ticket + " " + SSOTicket 



def LogIntoNS(): 
    address = ("64.4.61.219", 1863) 

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.connect(address) 
    s.settimeout(3) 

    s.send("VER 1 MSNP15 CVR0\r\n") 

    ReadAll(s) 

    s.send("CVR 2 0x0407 win 6.0 i386 MSNMSGR 8.5 MSMSGS " + username + "\r\n") 

    ReadAll(s) 

    s.send("USR 3 SSO I " + username + "\r\n") 

    recvbuf = ReadAll(s) 

    recvbuf = recvbuf[recvbuf.find("USR"):] 

    policy = recvbuf.split()[4] 

    print "policy:" 
    print policy 

    nonce = recvbuf.split()[5] 
    print "nonce:" 
    print nonce 

    ticket = GetTicket(policy, nonce) 

    print "ticket:" 
    print ticket 

    s.send("USR 4 SSO S " + ticket + "\r\n") 

    print "Sent" 

    print s.recv(4096) 


LogIntoNS() 
+0

謝謝,這完美的作品:) – combatdave 2011-02-13 16:53:31

相關問題