modified: nfig1.py
[GalaxyCodeBases.git] / etc / Windows / py-kms / client.py
bloba4930658d048c314c1ac793eead4578136adc3ee
1 import argparse
2 import binascii
3 import datetime
4 import random
5 import socket
6 import string
7 import struct
8 import sys
9 import uuid
10 import filetimes, rpcBind, rpcRequest
12 from dcerpc import MSRPCHeader, MSRPCBindNak, MSRPCRequestHeader, MSRPCRespHeader
13 from kmsBase import kmsBase, UUID
14 from kmsRequestV4 import kmsRequestV4
15 from kmsRequestV5 import kmsRequestV5
16 from kmsRequestV6 import kmsRequestV6
17 from rpcBase import rpcBase
19 config = {}
21 def main():
22 parser = argparse.ArgumentParser()
23 parser.add_argument("ip", action="store", help="The IP address or hostname of the KMS host.", type=str)
24 parser.add_argument("port", nargs="?", action="store", default=1688, help="The port the KMS service is listening on. The default is \"1688\".", type=int)
25 parser.add_argument("-m", "--mode", dest="mode", choices=["WindowsVista","Windows7","Windows8","Windows81","Office2010","Office2013"], default="Windows7")
26 parser.add_argument("-c", "--cmid", dest="cmid", default=None, help="Use this flag to manually specify a CMID to use. If no CMID is specified, a random CMID will be generated.", type=str)
27 parser.add_argument("-n", "--name", dest="machineName", default=None, help="Use this flag to manually specify an ASCII machineName to use. If no machineName is specified, a random machineName will be generated.", type=str)
28 parser.add_argument("-v", "--verbose", dest="verbose", action="store_const", const=True, default=False, help="Use this flag to enable verbose output.")
29 parser.add_argument("-d", "--debug", dest="debug", action="store_const", const=True, default=False, help="Use this flag to enable debug output. Implies \"-v\".")
30 config.update(vars(parser.parse_args()))
31 checkConfig()
32 config['call_id'] = 1
33 if config['debug']:
34 config['verbose'] = True
35 updateConfig()
36 s = socket.socket()
37 print "Connecting to %s on port %d..." % (config['ip'], config['port'])
38 s.connect((config['ip'], config['port']))
39 if config['verbose']:
40 print "Connection successful!"
41 binder = rpcBind.handler(None, config)
42 RPC_Bind = str(binder.generateRequest())
43 if config['verbose']:
44 print "Sending RPC bind request..."
45 s.send(RPC_Bind)
46 try:
47 bindResponse = s.recv(1024)
48 except socket.error, e:
49 if e[0] == 104:
50 print "Error: Connection reset by peer. Exiting..."
51 sys.exit()
52 else:
53 raise
54 if bindResponse == '' or not bindResponse:
55 print "No data received! Exiting..."
56 sys.exit()
57 packetType = MSRPCHeader(bindResponse)['type']
58 if packetType == rpcBase.packetType['bindAck']:
59 if config['verbose']:
60 print "RPC bind acknowledged."
61 kmsRequest = createKmsRequest()
62 requester = rpcRequest.handler(kmsRequest, config)
63 s.send(str(requester.generateRequest()))
64 response = s.recv(1024)
65 if config['debug']:
66 print "Response:", binascii.b2a_hex(response)
67 parsed = MSRPCRespHeader(response)
68 kmsData = readKmsResponse(parsed['pduData'], kmsRequest, config)
69 kmsResp = kmsData['response']
70 try:
71 hwid = kmsData['hwid']
72 except:
73 hwid = None
74 print "KMS Host ePID:", kmsResp['kmsEpid']
75 if hwid is not None:
76 print "KMS Host HWID:", binascii.b2a_hex(hwid).upper()
77 print "KMS Host Current Client Count:", kmsResp['currentClientCount']
78 print "KMS VL Activation Interval:", kmsResp['vLActivationInterval']
79 print "KMS VL Renewal Interval:", kmsResp['vLRenewalInterval']
80 elif packetType == rpcBase.packetType['bindNak']:
81 print MSRPCBindNak(bindResponse).dump()
82 sys.exit()
83 else:
84 print "Something went wrong."
85 sys.exit()
87 def checkConfig():
88 if config['cmid'] is not None:
89 try:
90 uuid.UUID(config['cmid'])
91 except:
92 print "Error: Bad CMID. Exiting..."
93 sys.exit()
94 if config['machineName'] is not None:
95 if len(config['machineName']) < 2 or len(config['machineName']) > 63:
96 print "Error: machineName must be between 2 and 63 characters in length."
97 sys.exit()
99 def updateConfig():
100 if config['mode'] == 'WindowsVista':
101 config['RequiredClientCount'] = 25
102 config['KMSProtocolMajorVersion'] = 4
103 config['KMSProtocolMinorVersion'] = 0
104 config['KMSClientLicenseStatus'] = 2
105 config['KMSClientAppID'] = "55c92734-d682-4d71-983e-d6ec3f16059f"
106 config['KMSClientSkuID'] = "cfd8ff08-c0d7-452b-9f60-ef5c70c32094"
107 config['KMSClientKMSCountedID'] = "212a64dc-43b1-4d3d-a30c-2fc69d2095c6"
108 elif config['mode'] == 'Windows7':
109 config['RequiredClientCount'] = 25
110 config['KMSProtocolMajorVersion'] = 4
111 config['KMSProtocolMinorVersion'] = 0
112 config['KMSClientLicenseStatus'] = 2
113 config['KMSClientAppID'] = "55c92734-d682-4d71-983e-d6ec3f16059f"
114 config['KMSClientSkuID'] = "ae2ee509-1b34-41c0-acb7-6d4650168915"
115 config['KMSClientKMSCountedID'] = "7fde5219-fbfa-484a-82c9-34d1ad53e856"
116 elif config['mode'] == 'Windows8':
117 config['RequiredClientCount'] = 25
118 config['KMSProtocolMajorVersion'] = 5
119 config['KMSProtocolMinorVersion'] = 0
120 config['KMSClientLicenseStatus'] = 2
121 config['KMSClientAppID'] = "55c92734-d682-4d71-983e-d6ec3f16059f"
122 config['KMSClientSkuID'] = "458e1bec-837a-45f6-b9d5-925ed5d299de"
123 config['KMSClientKMSCountedID'] = "3c40b358-5948-45af-923b-53d21fcc7e79"
124 elif config['mode'] == 'Windows81':
125 config['RequiredClientCount'] = 25
126 config['KMSProtocolMajorVersion'] = 6
127 config['KMSProtocolMinorVersion'] = 0
128 config['KMSClientLicenseStatus'] = 2
129 config['KMSClientAppID'] = "55c92734-d682-4d71-983e-d6ec3f16059f"
130 config['KMSClientSkuID'] = "81671aaf-79d1-4eb1-b004-8cbbe173afea"
131 config['KMSClientKMSCountedID'] = "cb8fc780-2c05-495a-9710-85afffc904d7"
132 elif config['mode'] == 'Office2010':
133 config['RequiredClientCount'] = 5
134 config['KMSProtocolMajorVersion'] = 4
135 config['KMSProtocolMinorVersion'] = 0
136 config['KMSClientLicenseStatus'] = 2
137 config['KMSClientAppID'] = "59a52881-a989-479d-af46-f275c6370663"
138 config['KMSClientSkuID'] = "6f327760-8c5c-417c-9b61-836a98287e0c"
139 config['KMSClientKMSCountedID'] = "e85af946-2e25-47b7-83e1-bebcebeac611"
140 elif config['mode'] == 'Office2013':
141 config['RequiredClientCount'] = 5
142 config['KMSProtocolMajorVersion'] = 5
143 config['KMSProtocolMinorVersion'] = 0
144 config['KMSClientLicenseStatus'] = 2
145 config['KMSClientAppID'] = "0ff1ce15-a989-479d-af46-f275c6370663"
146 config['KMSClientSkuID'] = "b322da9c-a2e2-4058-9e4e-f59a6970bd69"
147 config['KMSClientKMSCountedID'] = "e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0"
149 def createKmsRequestBase():
150 requestDict = kmsBase.kmsRequestStruct()
151 requestDict['versionMinor'] = config['KMSProtocolMinorVersion']
152 requestDict['versionMajor'] = config['KMSProtocolMajorVersion']
153 requestDict['isClientVm'] = 0
154 requestDict['licenseStatus'] = config['KMSClientLicenseStatus']
155 requestDict['graceTime'] = 43200
156 requestDict['applicationId'] = UUID(uuid.UUID(config['KMSClientAppID']).bytes_le)
157 requestDict['skuId'] = UUID(uuid.UUID(config['KMSClientSkuID']).bytes_le)
158 requestDict['kmsCountedId'] = UUID(uuid.UUID(config['KMSClientKMSCountedID']).bytes_le)
159 requestDict['clientMachineId'] = UUID(uuid.UUID(config['cmid']).bytes_le if (config['cmid'] is not None) else uuid.uuid4().bytes_le)
160 requestDict['previousClientMachineId'] = '\0' * 16 #requestDict['clientMachineId'] # I'm pretty sure this is supposed to be a null UUID.
161 requestDict['requiredClientCount'] = config['RequiredClientCount']
162 requestDict['requestTime'] = filetimes.dt_to_filetime(datetime.datetime.utcnow())
163 requestDict['machineName'] = (config['machineName'] if (config['machineName'] is not None) else ''.join(random.choice(string.letters + string.digits) for i in range(random.randint(2,63)))).encode('utf-16le')
164 requestDict['mnPad'] = '\0'.encode('utf-16le') * (63 - len(requestDict['machineName'].decode('utf-16le')))
166 # Debug Stuff
167 if config['debug']:
168 print "Request Base Dictionary:", requestDict.dump()
170 return requestDict
172 def createKmsRequest():
173 # Update the call ID
174 config['call_id'] += 1
176 # KMS Protocol Major Version
177 if config['KMSProtocolMajorVersion'] == 4:
178 handler = kmsRequestV4(None, config)
179 elif config['KMSProtocolMajorVersion'] == 5:
180 handler = kmsRequestV5(None, config)
181 elif config['KMSProtocolMajorVersion'] == 6:
182 handler = kmsRequestV6(None, config)
183 else:
184 return None
186 requestBase = createKmsRequestBase()
187 return handler.generateRequest(requestBase)
189 def readKmsResponse(data, request, config):
190 if config['KMSProtocolMajorVersion'] == 4:
191 print "Received V4 response"
192 response = readKmsResponseV4(data, request)
193 elif config['KMSProtocolMajorVersion'] == 5:
194 print "Received V5 response"
195 response = readKmsResponseV5(data)
196 elif config['KMSProtocolMajorVersion'] == 6:
197 print "Received V6 response"
198 response = readKmsResponseV6(data)
199 else:
200 print "Unhandled response version: %d.%d" % (config['KMSProtocolMajorVersion'], config['KMSProtocolMinorVersion'])
201 print "I'm not even sure how this happened..."
202 return response
204 def readKmsResponseV4(data, request):
205 response = kmsRequestV4.ResponseV4(data)
206 hashed = kmsRequestV4(data, config).generateHash(bytearray(str(response['response'])))
207 print "Response Hash has expected value:", hashed == response['hash']
208 return response
210 def readKmsResponseV5(data):
211 response = kmsRequestV5.ResponseV5(data)
212 decrypted = kmsRequestV5(data, config).decryptResponse(response)
213 return decrypted
215 def readKmsResponseV6(data):
216 response = kmsRequestV6.ResponseV5(data)
217 decrypted = kmsRequestV6(data, config).decryptResponse(response)
218 message = decrypted['message']
219 return message
221 if __name__ == "__main__":
222 main()