#!/usr/bin/env python # create a domain trust import sys from optparse import OptionParser sys.path.insert(0, "bin/python") import samba import samba.getopt as options from samba.dcerpc import lsa, security, drsblobs from samba.ndr import ndr_pack import random def arcfour_encrypt(key, data): from Crypto.Cipher import ARC4 c = ARC4.new(key) return c.encrypt(data) def string_to_array(string): blob = [0] * len(string) for i in range(len(string)): blob[i] = ord(string[i]) return blob ########### main code ########### if __name__ == "__main__": parser = OptionParser("createtrust [options] server") sambaopts = options.SambaOptions(parser) credopts = options.CredentialsOptionsDouble(parser) parser.add_option_group(credopts) (opts, args) = parser.parse_args() lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) if len(args) != 1: parser.error("You must supply a server") if not creds.authentication_requested(): parser.error("You must supply credentials") server = args[0] binding_str = "ncacn_np:%s[print]" % server lsaconn = lsa.lsarpc(binding_str, lp, creds) objectAttr = lsa.ObjectAttribute() objectAttr.sec_qos = lsa.QosInfo() pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'), objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED) name = lsa.String() name.string = "sub2.win2k3.obed.home.abartlet.net" try: info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO) lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid) except RuntimeError: pass info = lsa.TrustDomainInfoInfoEx() info.domain_name.string = "sub2.win2k3.obed.home.abartlet.net" info.netbios_name.string = "sub2" info.sid = security.dom_sid("S-1-5-21-538090388-3760119675-95745416") info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_WITHIN_FOREST password_blob = string_to_array("password".encode('utf-16-le')) clear_value = drsblobs.AuthInfoClear() clear_value.size = len(password_blob) clear_value.password = password_blob clear_authentication_information = drsblobs.AuthenticationInformation() clear_authentication_information.LastUpdateTime = 0 clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR clear_authentication_information.AuthInfo = clear_value version_value = drsblobs.AuthInfoVersion() version_value.version = 1 version = drsblobs.AuthenticationInformation() version.LastUpdateTime = 0 version.AuthType = lsa.TRUST_AUTH_TYPE_VERSION version.AuthInfo = version_value authentication_information_array = drsblobs.AuthenticationInformationArray() authentication_information_array.count = 2 authentication_information_array.array = [clear_authentication_information, version] outgoing = drsblobs.trustAuthInOutBlob() outgoing.count = 1 outgoing.current = authentication_information_array trustpass = drsblobs.trustDomainPasswords() confounder = [3] * 512 for i in range(512): confounder[i] = random.randint(0, 255) trustpass.confounder = confounder # print "confounder: ", trustpass.confounder trustpass.outgoing = outgoing trustpass.incoming = outgoing trustpass_blob = ndr_pack(trustpass) # print "trustpass_blob: ", list(trustpass_blob) encrypted_trustpass = arcfour_encrypt(lsaconn.session_key, trustpass_blob) # print "encrypted_trustpass: ", list(encrypted_trustpass) auth_blob = lsa.DATA_BUF2() auth_blob.size = len(encrypted_trustpass) auth_blob.data = string_to_array(encrypted_trustpass) auth_info = lsa.TrustDomainInfoAuthInfoInternal() auth_info.auth_blob = auth_blob # print "auth_info.auth_blob.data: ", auth_info.auth_blob.data trustdom_handle = lsaconn.CreateTrustedDomainEx2(pol_handle, info, auth_info, security.SEC_STD_DELETE)