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
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()))
34 config
['verbose'] = True
37 print "Connecting to %s on port %d..." % (config
['ip'], config
['port'])
38 s
.connect((config
['ip'], config
['port']))
40 print "Connection successful!"
41 binder
= rpcBind
.handler(None, config
)
42 RPC_Bind
= str(binder
.generateRequest())
44 print "Sending RPC bind request..."
47 bindResponse
= s
.recv(1024)
48 except socket
.error
, e
:
50 print "Error: Connection reset by peer. Exiting..."
54 if bindResponse
== '' or not bindResponse
:
55 print "No data received! Exiting..."
57 packetType
= MSRPCHeader(bindResponse
)['type']
58 if packetType
== rpcBase
.packetType
['bindAck']:
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)
66 print "Response:", binascii
.b2a_hex(response
)
67 parsed
= MSRPCRespHeader(response
)
68 kmsData
= readKmsResponse(parsed
['pduData'], kmsRequest
, config
)
69 kmsResp
= kmsData
['response']
71 hwid
= kmsData
['hwid']
74 print "KMS Host ePID:", kmsResp
['kmsEpid']
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()
84 print "Something went wrong."
88 if config
['cmid'] is not None:
90 uuid
.UUID(config
['cmid'])
92 print "Error: Bad CMID. Exiting..."
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."
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')))
168 print "Request Base Dictionary:", requestDict
.dump()
172 def createKmsRequest():
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
)
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
)
200 print "Unhandled response version: %d.%d" % (config
['KMSProtocolMajorVersion'], config
['KMSProtocolMinorVersion'])
201 print "I'm not even sure how this happened..."
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']
210 def readKmsResponseV5(data
):
211 response
= kmsRequestV5
.ResponseV5(data
)
212 decrypted
= kmsRequestV5(data
, config
).decryptResponse(response
)
215 def readKmsResponseV6(data
):
216 response
= kmsRequestV6
.ResponseV5(data
)
217 decrypted
= kmsRequestV6(data
, config
).decryptResponse(response
)
218 message
= decrypted
['message']
221 if __name__
== "__main__":