Merge branch 'changeme' of https://github.com/AlessandroZ/pupy into unstable

This commit is contained in:
n1nj4sec 2017-03-10 19:51:52 +01:00
commit ce549d661e
6 changed files with 187 additions and 0 deletions

4
.gitmodules vendored
View File

@ -10,6 +10,10 @@
path = pupy/external/LaZagne path = pupy/external/LaZagne
url = https://github.com/AlessandroZ/LaZagne url = https://github.com/AlessandroZ/LaZagne
shallow = false shallow = false
[submodule "pupy/external/changeme"]
path = pupy/external/changeme
url = https://github.com/AlessandroZ/changeme
shallow = false
[submodule "pupy/external/impacket"] [submodule "pupy/external/impacket"]
path = pupy/external/impacket path = pupy/external/impacket
url = https://github.com/CoreSecurity/impacket url = https://github.com/CoreSecurity/impacket

180
pupy/modules/changeme.py Normal file
View File

@ -0,0 +1,180 @@
# -*- coding: utf-8 -*-
# Author: AlessandroZ
from pupylib.PupyModule import *
from pupylib.utils.credentials import Credentials
from netaddr import *
from pupylib.utils.changeme.load_creds import Credentials as changeme_creds
import os
__class_name__="Changeme"
ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
@config(cat="creds", compat=["linux", "windows"])
class Changeme(PupyModule):
"""
Default Credential Scanner
"""
dependencies = {
'all': [
'OpenSSL',
'ftplib', 'zipfile', 'telnetlib',
'_LWPCookieJar', '_MozillaCookieJar', 'Cookie', 'cookielib',
'cgi', 'mimetypes', 'email', 'logutils',
'urllib3', 'requests',
'xml','_elementtree', 'calendar', 'xml', 'xml.etree',
'changeme'
]
}
def init_argparse(self):
header = """
#####################################################
# _ #
# ___| |__ __ _ _ __ __ _ ___ _ __ ___ ___ #
# / __| '_ \ / _` | '_ \ / _` |/ _ \ '_ ` _ \ / _ \\ #
# | (__| | | | (_| | | | | (_| | __/ | | | | | __/ #
# \___|_| |_|\__,_|_| |_|\__, |\___|_| |_| |_|\___| #
# |___/ #
# #
# Default Credential Scanner #
#####################################################
"""
example = '''
Examples:
>> run changeme -c web --name tomcat --target 192.168.1.10
'''
self.arg_parser = PupyArgumentParser(prog="changeme", description=header + self.__doc__, epilog=example)
self.arg_parser.add_argument('--protocol', choices=['ftp', 'http' , 'mssql', 'ssh', 'telnet'], help='Protocol of default creds to scan for', default=None)
self.arg_parser.add_argument('--category', '-c', choices=['webcam', 'web', 'phone', 'printer'], help='Category of default creds to scan for', default=None)
self.arg_parser.add_argument('--name', '-n', type=str, help='Narrow testing to the supplied credential name', default=None)
# Targets to launch scan
self.arg_parser.add_argument('--target', type=str, help='Subnet or IP to scan')
self.arg_parser.add_argument('--targets', type=str, help='File of targets to scan (IP or IP:PORT)', default=None)
self.arg_parser.add_argument('--port', type=int, help='Custom port to connect', default=None)
self.arg_parser.add_argument('--ssl', action='store_true', help='Use ssl', default=None)
self.arg_parser.add_argument('--creds', type=str, help='File of custom credentials to check (login/password)', default=None)
# Log and output
self.arg_parser.add_argument('--proxy', '-p', type=str, help='HTTP(S) Proxy', default=None)
self.arg_parser.add_argument('--log', '-l', type=str, help='Write logs to logfile', default=None)
# self.arg_parser.add_argument('--output', '-o', type=str, help='Name of file to write CSV results', default=None)
# Verbosity
self.arg_parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
self.arg_parser.add_argument('--debug', '-d', action='store_true', help='Debug output')
# Advanced options
self.arg_parser.add_argument('--timeout', type=int, help='Timeout in seconds for a request, default=10', default=10)
self.arg_parser.add_argument('--useragent', '-ua', type=str, help="User agent string to use")
self.arg_parser.add_argument('--delay', '-dl', type=int, help="Specify a delay in milliseconds to avoid 429 status codes default=500", default=500)
def run(self, args):
proxy = None
if args.proxy and re.match('^https?://[0-9\.]+:[0-9]{1,5}$', args.proxy):
proxy = {
'http': args.proxy,
'https': args.proxy
}
elif args.proxy:
print '[!] Invalid proxy, must be http(s)://x.x.x.x:8080'
return
custom_cred = None
if args.creds:
custom_cred = self.get_custom_creds(args.creds)
if not custom_cred:
return
targets_list = self.build_targets_list(target=args.target, file=args.targets)
if targets_list:
# Load credential locally from filesystem
root = os.path.join(ROOT, "external", "changeme")
creds = changeme_creds().load_creds(root, args.protocol, args.name, args.category)
# Run main function
pwd_found = self.client.conn.modules["changeme.core"].run_changeme(
protocol=args.protocol,
category=args.category,
name=args.name,
targets=targets_list,
port=args.port,
ssl=args.ssl,
proxy=proxy,
log=args.log,
verbose=args.verbose,
debug=args.debug,
timeout=args.timeout,
useragent=args.useragent,
delay=args.delay,
creds=creds,
custom_creds=custom_cred
)
if pwd_found:
db = Credentials()
clean_creds = []
for pwd in pwd_found:
self.success('%s' % pwd['name'])
self.success('URL: %s' % pwd['url'])
self.success('%s/%s' % (pwd['username'], pwd['password']))
clean_cred = {}
clean_cred['Category'] = '%s' % pwd['name']
clean_cred['uid']=self.client.short_name()
clean_cred['CredType'] = 'plaintext'
clean_cred['URL'] = pwd['url']
clean_cred['Login'] = pwd['username']
clean_cred['Password'] = pwd['password']
clean_creds.append(clean_cred)
print
try:
db.add(clean_creds)
self.success("Passwords stored on the database")
except Exception, e:
print e
else:
self.warning('passwords not found')
else:
self.error('target not defined')
def get_custom_creds(self, file):
if not os.path.isfile(file):
self.error("file %s not found" % file)
return False
custom_creds = list()
with open(file, 'r') as fin:
for x in fin.readlines():
username, password = x.strip('\n').split('/', 1)
custom_creds.append(
{
'username' : username,
'password' : password
}
)
return custom_creds
def build_targets_list(self, target, file):
targets_list = list()
if target:
for ip in IPNetwork(target).iter_hosts():
targets_list.append(ip)
if file:
if not os.path.isfile(file):
self.error("file %s not found" % file)
return False
with open(file, 'r') as fin:
targets_list = [x.strip('\n') for x in fin.readlines()]
return targets_list

1
pupy/packages/all/changeme Symbolic link
View File

@ -0,0 +1 @@
../../external/changeme/changeme

View File

View File

@ -0,0 +1 @@
../../../external/changeme/load_creds.py

View File

@ -0,0 +1 @@
../../../external/changeme/schema.py