Codebase list python-faraday / 90fc63f
Updated version 2.4.0 from 'upstream/2.4.0' with Debian dir 54289c30c425ac2298f8ea1b42af9ae75354aed4 Sophie Brun 7 years ago
100 changed file(s) with 2906 addition(s) and 861 deletion(s). Raw diff Collapse all Expand all
00 *.py[cod]
1
2 .pc/
31
42 # C extensions
53 *.so
119 build
1210 eggs
1311 parts
14 bin
1512 var
1613 sdist
1714 develop-eggs
5552 #Ignore visual studio code configs
5653 typings/
5754 jsconfig.json
58 .vscode/
55 .vscode/
56
57 # PyCharm project files
58 .idea
59
60 # vFeed DB
61 data/vfeed.db
2727 * Federico Fernandez
2828 * xtr4nge
2929 * Roberto Focke
30 * James Jara
31 * tsxltjecwb
32 * Sliim
66
77 New features in the latest update
88 =====================================
9
10 March 17, 2017:
11 ---
12 * Added link to name column in Hosts list
13 * Created a requirements_extras.txt file to handle optional packages for specific features
14 * Fixed bug in SQLMap plugin that made the client freeze
15 * Fixed bug when creating/updating Credentials
16 * Fixed bug in the WEB UI - menu explanation bubbles were hidden behind inputs
17 * Fixed conflict resolution when the object was deleted from another client before resolving the conflict
18 * Improved fplugin
19 * Improved the installation process
20 * Improved SQLMap plugin to support --tables and --columns options
21 * Improved navigation in Web UI
22 * Merged PR #137 - CScan improvements: bug fixing, change plugin format and removed unnecessary file output
23 * Merged PR #173 - Hostnames: added hostnames to plugins
24 * Merged PR #105 - OSint: added the possibility of using a DB other than Shodan
25 * The Status Report now remembers the sorting column and order
926
1027 February 8, 2017:
1128 ---
0 2.3.1
0 2.4.0
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates new credentials'
12 __prettyname__ = 'Create Credentials'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('parent', help='Parent ID')
17 parser.add_argument('name', help='Credential Name')
18 parser.add_argument('username', help='Username')
19 parser.add_argument('password', help='Password')
20
21 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
22
23 parsed_args = parser.parse_args(args)
24
25 obj = factory.createModelObject(models.Credential.class_signature, parsed_args.name, workspace,
26 username=parsed_args.username,
27 password=parsed_args.password,
28 parent_id=parsed_args.parent
29 )
30
31 old = models.get_credential(workspace, obj.getID())
32
33 if old is None:
34 if not parsed_args.dry_run:
35 models.create_credential(workspace, obj)
36 else:
37 print "A credential with ID %s already exists!" % obj.getID()
38 return 2, None
39
40 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new host in current workspace'
12 __prettyname__ = 'Create Host'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('name', help='Host name')
17 parser.add_argument('os', help='OS')
18
19 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
20
21 parsed_args = parser.parse_args(args)
22
23 obj = factory.createModelObject(models.Host.class_signature, parsed_args.name,
24 workspace, os=parsed_args.os, parent_id=None)
25
26 old = models.get_host(workspace, obj.getID())
27
28 if old is None:
29 if not parsed_args.dry_run:
30 models.create_host(workspace, obj)
31 else:
32 print "A host with ID %s already exists!" % obj.getID()
33 return 2, None
34
35 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new interface in a specified host'
12 __prettyname__ = 'Create Interface'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('host_id', help='Host ID')
17 parser.add_argument('name', help='Interface Name')
18 parser.add_argument('mac', help='Interface MAC Address')
19
20 parser.add_argument('--ipv4address', help='IPV4 Address', default='0.0.0.0')
21 parser.add_argument('--ipv4gateway', help='IPV4 Gateway', default='0.0.0.0')
22 parser.add_argument('--ipv4mask', help='IPV4 Mask', default='0.0.0.0')
23 parser.add_argument('--ipv4dns', help='IPV4 DNS, as a comma separated list', default='')
24
25 parser.add_argument('--ipv6address', help='IPV6 Address', default='0000:0000:0000:0000:0000:0000:0000:0000')
26 parser.add_argument('--ipv6prefix', help='IPV6 Prefix', default='00')
27 parser.add_argument('--ipv6gateway', help='IPV4 Gateway', default='0000:0000:0000:0000:0000:0000:0000:0000')
28 parser.add_argument('--ipv6dns', help='IPV6 DNS, as a comma separated list', default='')
29
30 parser.add_argument('--netsegment', help='Network Segment', default='')
31 parser.add_argument('--hostres', help='Hostname Resolution', default='')
32
33 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
34
35 parsed_args = parser.parse_args(args)
36
37 ipv4_dns = filter(None, parsed_args.ipv4dns.split(','))
38 ipv6_dns = filter(None, parsed_args.ipv6dns.split(','))
39
40 obj = factory.createModelObject(models.Interface.class_signature, parsed_args.name, workspace,
41 mac=parsed_args.mac,
42 ipv4_address=parsed_args.ipv4address,
43 ipv4_mask=parsed_args.ipv4mask,
44 ipv4_gateway=parsed_args.ipv4gateway,
45 ipv4_dns=ipv4_dns,
46 ipv6_address=parsed_args.ipv6address,
47 ipv6_prefix=parsed_args.ipv6prefix,
48 ipv6_gateway=parsed_args.ipv6gateway,
49 ipv6_dns=ipv6_dns,
50 network_segment=parsed_args.netsegment,
51 hostname_resolution=parsed_args.hostres,
52 parent_id=parsed_args.host_id)
53
54 old = models.get_interface(workspace, obj.getID())
55
56 if old is None:
57 if not parsed_args.dry_run:
58 models.create_interface(workspace, obj)
59 else:
60 print "An interface with ID %s already exists!" % obj.getID()
61 return 2, None
62
63 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new note'
12 __prettyname__ = 'Create Note'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('parent', help='Parent ID')
17 parser.add_argument('name', help='Note name')
18 parser.add_argument('text', help='Note content')
19
20 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
21
22 parsed_args = parser.parse_args(args)
23
24 obj = factory.createModelObject(models.Note.class_signature, parsed_args.name, workspace,
25 text=parsed_args.text,
26 parent_id=parsed_args.parent
27 )
28
29 old = models.get_note(workspace, obj.getID())
30
31 if old is None:
32 if not parsed_args.dry_run:
33 models.create_note(workspace, obj)
34 else:
35 print "A note with ID %s already exists!" % obj.getID()
36 return 2, None
37
38 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new service in a specified interface'
12 __prettyname__ = 'Create Service'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('interface_id', help='Interface ID')
17 parser.add_argument('name', help='Service Name')
18 parser.add_argument('ports', help='Service ports, as a comma separated list')
19 parser.add_argument('--protocol', help='Service protocol', default='tcp')
20 parser.add_argument('--status', help='Service status', default='running')
21 parser.add_argument('--version', help='Service version', default='unknown')
22 parser.add_argument('--description', help='Service description', default='')
23
24 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
25
26 parsed_args = parser.parse_args(args)
27
28 ports = filter(None, parsed_args.ports.split(','))
29
30 obj = factory.createModelObject(models.Service.class_signature, parsed_args.name, workspace,
31 protocol=parsed_args.protocol,
32 ports=ports,
33 status=parsed_args.status,
34 version=parsed_args.version,
35 description=parsed_args.description,
36 parent_id=parsed_args.interface_id
37 )
38
39 old = models.get_service(workspace, obj.getID())
40
41 if old is None:
42 if not parsed_args.dry_run:
43 models.create_service(workspace, obj)
44 else:
45 print "A service with ID %s already exists!" % obj.getID()
46 return 2, None
47
48 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new vulnerability'
12 __prettyname__ = 'Create Vulnerability'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('parent', help='Parent ID')
17 parser.add_argument('name', help='Vulnerability Name')
18 parser.add_argument('--reference', help='Vulnerability reference', default='') # Fixme
19
20 parser.add_argument('--severity',
21 help='Vulnerability severity',
22 choices=['critical', 'high', 'med', 'low', 'info', 'unclassified'],
23 default='unclassified')
24
25 parser.add_argument('--resolution', help='Resolution', default='')
26 parser.add_argument('--confirmed', help='Is the vulnerability confirmed',
27 choices=['true', 'false'],
28 default='false')
29 parser.add_argument('--description', help='Vulnerability description', default='')
30
31 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
32
33 parsed_args = parser.parse_args(args)
34
35 obj = factory.createModelObject(models.Vuln.class_signature, parsed_args.name, workspace,
36 ref=parsed_args.reference,
37 severity=parsed_args.severity,
38 resolution=parsed_args.resolution,
39 confirmed=(parsed_args.confirmed == 'true'),
40 desc=parsed_args.description,
41 parent_id=parsed_args.parent
42 )
43
44 old = models.get_vuln(workspace, obj.getID())
45
46 if old is None:
47 if not parsed_args.dry_run:
48 models.create_vuln(workspace, obj)
49 else:
50 print "A vulnerability with ID %s already exists!" % obj.getID()
51 return 2, None
52
53 return 0, obj.getID()
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from model.common import factory
9 from persistence.server import models
10
11 __description__ = 'Creates a new website vulnerability in a specified service'
12 __prettyname__ = 'Create Website Vulnerability'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('service', help='Parent service ID')
17 parser.add_argument('name', help='Vulnerability name')
18 parser.add_argument('--reference', help='Vulnerability reference', default='') # Fixme
19
20 parser.add_argument('--severity',
21 help='Vulnerability severity',
22 choices=['critical', 'high', 'med', 'low', 'info', 'unclassified'],
23 default='unclassified')
24
25 parser.add_argument('--resolution', help='Resolution', default='')
26 parser.add_argument('--description', help='Vulnerability description', default='')
27
28 parser.add_argument('--website', help='Website', default='')
29 parser.add_argument('--path', help='Path', default='')
30 parser.add_argument('--request', help='Request', default='')
31 parser.add_argument('--response', help='Response', default='')
32 parser.add_argument('--method', help='Method', default='')
33 parser.add_argument('--pname', help='pname', default='') # FIXME
34 parser.add_argument('--params', help='Parameters', default='')
35 parser.add_argument('--query', help='Query', default='')
36 parser.add_argument('--category', help='Category', default='')
37
38 parser.add_argument('--confirmed', help='Is the vulnerability confirmed',
39 choices=['true', 'false'],
40 default='false')
41
42 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
43
44 parsed_args = parser.parse_args(args)
45
46 obj = factory.createModelObject(models.VulnWeb.class_signature, parsed_args.name, workspace,
47 desc=parsed_args.description,
48 ref=parsed_args.reference,
49 severity=parsed_args.severity,
50 resolution=parsed_args.resolution,
51
52 website=parsed_args.website,
53 path=parsed_args.path,
54 request=parsed_args.request,
55 response=parsed_args.response,
56 method=parsed_args.method,
57 pname=parsed_args.pname,
58 params=parsed_args.params,
59 query=parsed_args.query,
60 category=parsed_args.category,
61
62 confirmed=(parsed_args.confirmed == 'true'),
63 parent_id=parsed_args.service
64 )
65
66 old = models.get_web_vuln(workspace, obj.getID())
67
68 if old is None:
69 if not parsed_args.dry_run:
70 models.create_vuln_web(workspace, obj)
71 else:
72 print "A web vulnerability with ID %s already exists!" % obj.getID()
73 return 2, None
74
75 return 0, obj.getID()
66 See the file 'doc/LICENSE' for the license information
77 '''
88
9 from persistence.server import server, models
9 from persistence.server import models
1010
11 def main(workspace=''):
12
11 __description__ = 'Deletes all stored hosts'
12 __prettyname__ = 'Delete All Hosts'
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('-y', '--yes', action="store_true")
17 parsed_args = parser.parse_args(args)
18 if not parsed_args.yes:
19 msg = ("Are you sure you want to delete all hosts in the "
20 "workspace {}? This action can't be undone [y/n] ".format(
21 workspace))
22 if raw_input(msg) not in ('y', 'yes'):
23 return 1, None
1324 for host in models.get_hosts(workspace):
1425 print('Delete Host:' + host.name)
15 models.delete_host(workspace, host.id)
26 models.delete_host(workspace, host.id)
27 return 0, None
66 See the file 'doc/LICENSE' for the license information
77 '''
88
9 from persistence.server import server, models
9 from persistence.server import models
10 from utils.user_input import query_yes_no
1011
11 def main(workspace=''):
12 __description__ = 'Deletes all services with a non open port'
13 __prettyname__ = 'Delete All Service Closed'
14
15
16 def main(workspace='', args=None, parser=None):
17 parser.add_argument('-y', '--yes', action="store_true")
18 parsed_args = parser.parse_args(args)
19 if not parsed_args.yes:
20
21 if not query_yes_no("Are you sure you want to delete all closed services in the "
22 "workspace %s" % workspace, default='no'):
23 return 1, None
1224
1325 for service in models.get_services(workspace):
1426 if service.status != 'open' and service.status != 'opened':
1527 print('Deleted service: ' + service.name)
16 models.delete_service(workspace, service.id)
28 models.delete_service(workspace, service.id)
29 return 0, None
77 '''
88
99 import re
10 from persistence.server import server, models
10 from persistence.server import models
1111
12 def main(workspace=''):
12 __description__ = "Delete all vulnerabilities matched with regex"
13 __prettyname__ = "Delete all vulnerabilities with (...)"
1314
14 regex = (
15
16 def main(workspace='', args=None, parser=None):
17 default_regex = (
1518 r"ssl\-cert|ssl\-date|Traceroute Information|TCP\/IP Timestamps Supported"
1619 r"|OS Identification|Common Platform Enumeration")
20 parser.add_argument('-y', '--yes', action="store_true")
21 parser.add_argument('-r', '--regex', default=default_regex)
22 parsed_args = parser.parse_args(args)
23 if not parsed_args.yes:
24 msg = ("Are you sure you want to delete all vulnerabilities "
25 "matching the regex {} in the worspace {}? "
26 "This action can't be undone [y/n] ".format(
27 parsed_args.regex, workspace))
28 if raw_input(msg) not in ('y', 'yes'):
29 return 1, None
1730
1831 for vuln in models.get_all_vulns(workspace):
19 if re.findall(regex, vuln.name, ) != []:
32 if re.findall(parsed_args.regex, vuln.name, ) != []:
2033 print("Delete Vuln: " + vuln.name)
21 models.delete_vuln(workspace, vuln.id)
34 models.delete_vuln(workspace, vuln.id)
35 return 0, None
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from colorama import Fore
10 import sys
11
12 from persistence.server import models
13
14 __description__ = 'Filter services by port or service name'
15 __prettyname__ = 'Filter services'
16
17 SERVICES = {
18 'http': [80, 443, 8080, 8443],
19 'ftp': [21],
20 'ssh': [22],
21 'telnet': [23],
22 'smtp': [25],
23 'domain': [53],
24 'pop3': [110, 995],
25 'imap': [143, 993],
26 'vnc': [5900],
27 }
28
29 # FIXME Update when persistence API changes
30 COLUMNS = {
31 'host': lambda service, workspace: models.get_host(workspace, service.id.split('.')[0]).name,
32 'host_os': lambda service, workspace: models.get_host(workspace, service.id.split('.')[0]).os,
33 'service': lambda service, workspace: service.name,
34 'ports': lambda service, workspace: str(service.ports[0]),
35 'protocol': lambda service, workspace: service.protocol,
36 'status': lambda service, workspace: service.status,
37 }
38
39
40 def main(workspace='', args=None, parser=None):
41 parser.add_argument('-p', type=int, nargs='+', metavar='port', help='List of ports to filter', default=[])
42 parser.add_argument('services', nargs='*', help='List of service names', default=[]),
43 parser.add_argument('--columns', help='Comma separated list of columns to show.',
44 default="host,service,ports,protocol,status,host_os", choices=COLUMNS.keys())
45
46 parser.add_argument('--status', help='Comma separated list of status to filter for.')
47
48 parser.add_argument('-a', help='Show additional information, like ports filtered and column headers.',
49 action='store_true', dest='additional_info')
50
51 parser.add_argument('-f', help='Do not apply any filter. Print every host.',
52 action='store_true', dest='no_filter')
53
54 parser.add_argument('-s', '--sorted', help='Print the list sorted IP..', action='store_true')
55
56 parsed_args = parser.parse_args(args)
57
58 port_list = parsed_args.p
59
60 for service in parsed_args.services:
61 if service in SERVICES:
62 port_list += SERVICES[service]
63 else:
64 sys.stderr.write(Fore.YELLOW +
65 "WARNING: Service definition not found. [%s]\n" % service +
66 Fore.RESET)
67
68 if not port_list and not parsed_args.no_filter:
69 print "Empty filter set."
70 return 1, None
71
72 if parsed_args.additional_info and not parsed_args.no_filter:
73 print 'Filtering services for ports: ' + ', '.join(map(str, sorted(port_list)))
74
75 columns = filter(None, parsed_args.columns.split(','))
76
77 status_filter = None
78
79 if parsed_args.status is not None:
80 status_filter = filter(None, parsed_args.status.split(','))
81
82 lines = []
83
84 for service in models.get_services(workspace):
85 for port in service.ports:
86 if port in port_list or parsed_args.no_filter:
87
88 if not parsed_args.no_filter and status_filter is not None and not service.status in status_filter:
89 continue
90
91 column_data = []
92
93 for column in columns:
94 column_data += [COLUMNS[column](service, workspace)]
95
96 lines += [column_data]
97
98 if not lines:
99 print "No services running on that port found."
100 return 0, None
101
102 col_width = max(len(word) for row in lines for word in row) + 2
103
104 if parsed_args.additional_info:
105 print ''.join(col.ljust(col_width) for col in columns)
106 print '-' * (col_width * len(columns))
107
108 if parsed_args.sorted:
109 # Compare lines using the first column (IP)
110 for row in sorted(lines, cmp=lambda l1, l2: cmp(l1[0], l2[0])):
111 print "".join(word.ljust(col_width) for word in row)
112 else:
113 for row in lines:
114 print "".join(word.ljust(col_width) for word in row)
115
116 return 0, None
00 #!/usr/bin/env python2.7
11 # -*- coding: utf-8 -*-
22
3 '''
3 """
44 Faraday Penetration Test IDE
55 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
66 See the file 'doc/LICENSE' for the license information
7 '''
8
7 """
8
9 import argparse
10 import imp
11 import inspect
912 import os
10 import imp
13 import shlex
1114 import sys
12 import argparse
15 import signal
16 import readline
17 import atexit
1318
1419 parent_path = os.path.abspath(os.path.join(__file__, '../..'))
1520 sys.path.insert(0, parent_path)
21 from plugins import fplugin_utils
22
23 from colorama import Fore
24 from config.configuration import getInstanceConfiguration
25 from managers.mapper_manager import MapperManager
26 from model.controller import ModelController
27
28 CONF = getInstanceConfiguration()
29
30
31 class RawDescriptionAndDefaultsHelpFormatter(argparse.RawDescriptionHelpFormatter,
32 argparse.ArgumentDefaultsHelpFormatter):
33 pass
34
35
36 # Call signature corresponding to a function defined as:
37 # def main(workspace='', args=[], parser = None):
38 CURRENT_MAIN_ARGSPEC = inspect.ArgSpec(args=['workspace', 'args', 'parser'], varargs=None, keywords=None,
39 defaults=('', None, None))
40
41 FPLUGIN_INTERACTIVE_LAST_TOKEN = '$last'
42
43
44 def signal_handler(signal, frame):
45 print('Bye Bye!')
46 os._exit(0)
47
48
49 def dispatch(args, unknown, help):
50 if '--' in unknown:
51 unknown.remove('--')
52
53 # We need the ModelController to register all available models
54 mappers_manager = MapperManager()
55 model_controller = ModelController(mappers_manager)
56
57 if not args.command:
58 print help
59 if not args.interactive:
60 sys.exit(1)
61
62 if args.command not in plugins.keys():
63 sys.stderr.write(Fore.RED +
64 ("ERROR: Plugin %s not found.\n" % args.command) +
65 Fore.RESET)
66 if args.interactive:
67 return None
68 else:
69 sys.exit(1)
70
71 faraday_directory = os.path.dirname(os.path.realpath(os.path.join(__file__, "../")))
72
73 plugin_path = os.path.join(faraday_directory, "bin/", args.command + '.py')
74
75 # Get filename and import this
76 module_fplugin = imp.load_source('module_fplugin', plugin_path)
77 module_fplugin.models.server.FARADAY_UP = False
78 module_fplugin.models.server.SERVER_URL = args.url
79
80 call_main = getattr(module_fplugin, 'main', None)
81
82 if call_main is None:
83 sys.stderr.write(Fore.RED + "ERROR: Main function not found.\n" + Fore.RESET)
84 if args.interactive:
85 return None
86 else:
87 sys.exit(1)
88
89 # Inspect the main function imported from the plugin and decide the best calling option
90 main_argspec = inspect.getargspec(call_main)
91
92 if main_argspec != CURRENT_MAIN_ARGSPEC:
93 # Function argspec does not match current API.
94 # Warn the user and call with original parameteres.
95 sys.stderr.write(Fore.YELLOW +
96 "WARNING: Plugin does not follow current call signature. Please update it! [%s.py]\n" % args.command +
97 Fore.RESET)
98
99 obj_id = None
100
101 if {'args', 'parser'} <= set(main_argspec.args):
102 # Function accepts args and parser arguments
103
104 new_parser = argparse.ArgumentParser(description=plugins[args.command]['description'],
105 prog="fplugin %s" % args.command,
106 formatter_class=RawDescriptionAndDefaultsHelpFormatter)
107
108 ret, obj_id = call_main(workspace=args.workspace, args=unknown, parser=new_parser)
109
110 if obj_id is not None:
111 print obj_id
112 else:
113 # Use old API to call plugin
114 sys.stderr.write(Fore.YELLOW +
115 "WARNING: Call with arguments and parser not supported.\n" +
116 Fore.RESET)
117 ret = call_main(workspace=args.workspace)
118
119 if ret is None:
120 ret = 0
121
122 if args.interactive:
123 # print 'code = %d' % ret
124 return obj_id
125 else:
126 sys.exit(ret)
127
16128
17129 if __name__ == '__main__':
18
19 description = (
20 'Using our plugin you can do different actions in the command line'
21 ' and interact with Faraday. Faraday comes with some presets for bulk'
22 ' actions such as object removal, get object information, etc.')
23
24 parser = argparse.ArgumentParser(description=description)
25
26 parser.add_argument(
27 '-f',
28 '--file',
29 help='Script file.'
30 ' Example:\n./fplugin -f getAllIps.py')
130
131 signal.signal(signal.SIGINT, signal_handler)
132
133 description = ('Using our plugin you can do different actions in the command line\n'
134 'and interact with Faraday. Faraday comes with some presets for bulk\n'
135 'actions such as object removal, get object information, etc.\n'
136 'Any parameter not recognized by fplugin, or everything after -- will be passed on \n'
137 'to the called script.\n')
138
139 epilog = 'Available scripts:\n'
140
141 plugins = fplugin_utils.get_available_plugins()
142
143 for plugin in sorted(plugins.iterkeys()):
144 epilog += '\t- %s: %s\n' % (plugin, plugins[plugin]['description'])
145
146 parser = argparse.ArgumentParser(description=description,
147 epilog=epilog,
148 formatter_class=RawDescriptionAndDefaultsHelpFormatter)
149
150 group = parser.add_mutually_exclusive_group()
151
152 group.add_argument('command', nargs='?', help='Command to execute. Example: ./fplugin getAllIps')
153 group.add_argument('-i', '--interactive', action='store_true', help='Run in interactive mode')
31154
32155 parser.add_argument(
33156 '-w',
34157 '--workspace',
35 help='Use workspace')
158 help='Workspace to use',
159 default=CONF.getLastWorkspace())
36160
37161 parser.add_argument(
38162 '-u',
39163 '--url',
40 help='Faraday Server URL. Example: http://localhost:5984')
41
164 help='Faraday Server URL. Example: http://localhost:5985',
165 default='http://localhost:5985')
166
167 # Only parse known args. Unknown ones will be passed on the the called script
42168 args, unknown = parser.parse_known_args()
43169
44 if args.file:
45
46 # Get filename and import this
47 module_fplugin = imp.load_source('module_fplugin', args.file)
48 module_fplugin.models.server.FARADAY_UP = False
49 module_fplugin.models.server.SERVER_URL = args.url
170 if not args.interactive:
171 dispatch(args, unknown, parser.format_help())
172 else:
173
174 # print "Loading command history..."
175 histfile = os.path.join(CONF.getDataPath(), ".faraday_hist")
176 readline.parse_and_bind('tab: complete')
177 atexit.register(readline.write_history_file, histfile)
50178
51179 try:
52 call_main = getattr(module_fplugin, 'main')
53 call_main(workspace = args.workspace)
54 except AttributeError:
55 print 'Error: main() function missing in script?'
180 readline.read_history_file(histfile)
181 # default history len is -1 (infinite), which may grow unruly
182 readline.set_history_length(1000)
183 except IOError:
184 pass
185
186 print "Welcome to interactive Faraday!"
187 print "Press CTRL-D or run 'exit' to quit interactive mode."
188 last_id = None
189
190 while True:
191 try:
192 line = raw_input("> ")
193
194 if line.strip() == 'exit':
195 os._exit(0)
196
197 # Split line read from stdin into argv
198 new_args = shlex.split(line)
199
200 if '-i' in new_args or '--interactive' in new_args:
201 print 'Already in interactive mode!'
202 continue
203
204 if 'h' in new_args or 'help' in new_args:
205 parser.print_help()
206 continue
207
208 if FPLUGIN_INTERACTIVE_LAST_TOKEN in new_args:
209 i = new_args.index(FPLUGIN_INTERACTIVE_LAST_TOKEN)
210 new_args[i] = last_id or ''
211
212 parsed_args, new_unknown = parser.parse_known_args(new_args)
213 parsed_args.interactive = True
214
215 last_id = dispatch(parsed_args, new_unknown, parser.format_help()) or last_id
216 # print '$last = %s' % last_id
217 except (EOFError, KeyboardInterrupt):
218 print 'Bye Bye!'
219 sys.exit(0)
220 except SystemExit:
221 pass
+0
-14
bin/getAllCreds.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12 for credential in models.get_credentials(workspace):
13 print(credential.username + ' : ' + credential.password)
+0
-14
bin/getAllIps.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12 for host in models.get_hosts(workspace):
13 print(host.name)
66 See the file 'doc/LICENSE' for the license information
77 '''
88
9 from persistence.server import server, models
9 from persistence.server import models
1010
11 def main(workspace=''):
11 __description__ = "Get all scanned interfaces"
12 __prettyname__ = "Get All IPs Interfaces"
13
14
15 def main(workspace='', args=None, parser=None):
1216 for interface in models.get_interfaces(workspace):
13 print(interface.ipv4['address'])
17 print(interface.ipv4['address'])
18
19 return 0, None
+0
-14
bin/getAllOs.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12 for host in models.get_hosts(workspace):
13 print(host.os)
+0
-16
bin/getAllTelnet.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12
13 for service in models.get_services(workspace):
14 if 23 in service.ports:
15 print(service.name)
+0
-16
bin/getAllVnc.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12
13 for service in models.get_services(workspace):
14 if 5900 in service.ports:
15 print(service.name)
+0
-18
bin/getAllbySrv.py less more
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 from persistence.server import server, models
10
11 def main(workspace=''):
12
13 ports = [80, 443, 8080]
14 for service in models.get_services(workspace):
15 for port in ports:
16 if port in service.ports:
17 print(service.name)
1515 www.toolswatch.org
1616 """
1717
18 import os
1819 import sqlite3
19 import os
2020
21 DB_PATH = "./data/vfeed.db"
21 from persistence.server import models
22
23 __description__ = 'Get possible exploits from open services'
24 __prettyname__ = 'Get Exploits'
25
26 faraday_directory = os.path.dirname(os.path.realpath(os.path.join(__file__, "../")))
27
28 DB_PATH = os.path.join(faraday_directory, 'data/vfeed.db')
2229 URL_DB = "http://www.toolswatch.org/vfeed/vfeed.db.tgz"
2330
31
2432 def getExploits(cve_id, cursor):
25
2633 result = {
27 'exploit-db' : [],
28 'metasploit' : [],
29 'milworm' : [],
30 'd2' : [],
31 'saint' : []
34 'exploit-db': [],
35 'metasploit': [],
36 'milworm': [],
37 'd2': [],
38 'saint': []
3239 }
3340
34 value = (cve_id.upper(), )
41 value = (cve_id.upper(),)
3542
36 #D2 exploits
43 # D2 exploits
3744 consult = cursor.execute(
38 "SELECT d2_script_file FROM map_cve_d2 WHERE cveid = ?",
39 value
45 "SELECT d2_script_file FROM map_cve_d2 WHERE cveid = ?",
46 value
4047 )
4148
4249 for row in consult:
4350 for i in row:
4451 result['d2'].append(i)
4552
46 #Exploit-db exploits
53 # Exploit-db exploits
4754 consult = cursor.execute(
48 "SELECT exploitdbscript FROM map_cve_exploitdb WHERE cveid = ?",
49 value
55 "SELECT exploitdbscript FROM map_cve_exploitdb WHERE cveid = ?",
56 value
5057 )
5158
5259 for row in consult:
5360 for i in row:
5461 result['exploit-db'].append(i)
5562
56 #Metasploit exploits
63 # Metasploit exploits
5764 consult = cursor.execute(
58 "SELECT msf_script_file FROM map_cve_msf WHERE cveid = ?",
59 value
65 "SELECT msf_script_file FROM map_cve_msf WHERE cveid = ?",
66 value
6067 )
6168
6269 for row in consult:
6370 for i in row:
6471 result['metasploit'].append(i)
6572
66 #Milworm exploits
73 # Milworm exploits
6774 consult = cursor.execute(
68 "SELECT milw0rmid FROM map_cve_milw0rm WHERE cveid = ?",
69 value
75 "SELECT milw0rmid FROM map_cve_milw0rm WHERE cveid = ?",
76 value
7077 )
7178
7279 for row in consult:
7380 for i in row:
7481 result['milworm'].append(i)
7582
76 #Saint exploits
83 # Saint exploits
7784 consult = cursor.execute(
78 "SELECT saintexploitlink FROM map_cve_saint WHERE cveid = ?",
79 value
85 "SELECT saintexploitlink FROM map_cve_saint WHERE cveid = ?",
86 value
8087 )
8188
8289 for row in consult:
8592
8693 return result
8794
95
8896 def printExploits(vuln, references, cursor):
89
9097 global getExploits
9198
9299 for ref in references:
93100 if ref.startswith('CVE') or ref.startswith('cve'):
94101
95102 ret = getExploits(ref, cursor)
96 if ret :
103 if ret:
97104 print '[Exploits ' + vuln + ' ' + ref + ']\n'
98105
99106 for tool, info in ret.iteritems():
107114 print '\n'
108115
109116
117 def main(workspace='', args=None, parser=None):
118 print '[*]Checking DB...'
110119
111 print '\n[*]Checking DB...'
120 if not os.path.isfile(DB_PATH):
121 print '[!]DB not found: please download the DB from: ' + URL_DB
122 print '[!]Extract this to $FARADAY/data/ and try again!'
123 raise Exception('DB not found', 'Check if DB exists')
112124
113 if not os.path.isfile(DB_PATH):
125 print '[*]DB Found!'
126 print '[*]Searching exploits...\n'
114127
115 print '[!]DB not found: please download the DB from: ' + URL_DB
116 print '[!]Extract this to $FARADAY/data/ and try again!'
117 raise('DB not found','Check if DB exists')
128 connection = sqlite3.connect(DB_PATH)
129 cursor = connection.cursor()
118130
119 print '[*]DB Found!'
120 print '[*]Searching exploits...\n'
131 for host in models.get_hosts(workspace):
132 for v in host.getVulns():
133 print '[' + host.name + '] ' + v.name
134 printExploits(v.name, v.getRefs(), cursor)
121135
122 connection = sqlite3.connect(DB_PATH)
123 cursor = connection.cursor()
136 for i in host.getAllInterfaces():
137 for s in i.getAllServices():
138 for v in s.getVulns():
139 print '[' + host.name + '] ' + v.name
140 printExploits(v.name, v.getRefs(), cursor)
124141
125 for host in api.__model_controller.getAllHosts():
126 for v in host.getVulns():
127
128 print '[' + host.name + '] ' + v._name
129 printExploits(v._name, v.getRefs(), cursor)
130
131 for i in host.getAllInterfaces():
132 for s in i.getAllServices():
133 for v in s.getVulns():
134
135 print '[' + host.name + '] ' + v._name
136 printExploits(v._name, v.getRefs(), cursor)
142 return 0, None
44 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
55 See the file 'doc/LICENSE' for the license information
66 '''
7 import os
7 import json
88
9 def getCweData():
9 import requests
1010
11 import requests
12 import json
11 from persistence.server import models
1312
14 #Get elements from cwe DB in couchdb
13 __description__ = 'Get Vulns filtered by Severity and change Severity based in CWE'
14 __prettyname__ = 'Get Severity By CWE'
15
16 SEVERITY_OPTIONS = ('unclassified', 'info', 'low', 'med', 'high', 'critical', 'all')
17
18
19 def getCweData(couch_url):
20 # Get elements from cwe DB in couchdb
1521 headers = {'Content-Type': 'application/json'}
1622
1723 payload = {
18 'map' :
19 'function(doc) { if(doc.severity && doc.name){'
20 'emit(doc.name, doc.severity); }}'
24 'map':
25 'function(doc) { if(doc.severity && doc.name){'
26 'emit(doc.name, doc.severity); }}'
2127 }
2228
2329 r = requests.post(
24 couchdb + '/cwe/_temp_view',
25 headers = headers,
26 data = json.dumps(payload)
30 couch_url + '/cwe/_temp_view',
31 headers=headers,
32 data=json.dumps(payload)
2733 )
2834
2935 response_code = r.status_code
3945 if value == 'informational':
4046 value = 'info'
4147
42 dict.update( {item['key'] : value} )
48 dict.update({item['key']: value})
4349
4450 if dict == {}:
4551 return None
5359 print 'Error couchDB: ' + str(response_code) + str(r.text)
5460
5561
56 def checkSeverity(vuln, cwe_dict, severity_choose, workspace):
57
58 import requests
59 import json
60
62 def checkSeverity(vuln, cwe_dict, severity_choose, workspace, couch_url):
6163 severity_dict = {
62 'unclassified' : 0,
63 'info' : 1,
64 'low' : 2,
65 'med' : 3,
66 'high' : 4,
67 'critical' : 5,
68 'all' : 100
64 'unclassified': 0,
65 'info': 1,
66 'low': 2,
67 'med': 3,
68 'high': 4,
69 'critical': 5,
70 'all': 100
6971 }
7072
71 if vuln._name in cwe_dict and severity_dict[vuln.severity] <= severity_dict[severity_choose] :
73 if vuln._name in cwe_dict and severity_dict[vuln.severity] <= severity_dict[severity_choose]:
7274
7375 print 'Change: ' + vuln._name + ' to ' + cwe_dict[vuln._name]
7476
75 #Get object Vuln
77 # Get object Vuln
7678 response = requests.get(
77 couchdb + '/' + workspace + '/' + str (vuln._id)
79 models.server.SERVER_URL + '/' + workspace + '/' + str(vuln._id)
7880 )
7981 vulnWeb = response.json()
8082
81 #Change severity
83 # Change severity
8284 vulnWeb['severity'] = cwe_dict[vuln._name]
8385
84 #Put changes...
86 # Put changes...
8587 headers = {'Content-Type': 'application/json'}
8688 update = requests.put(
87 couchdb + '/' + workspace + '/' + vuln._id,
88 headers = headers,
89 data = json.dumps(vulnWeb)
89 couch_url + '/' + workspace + '/' + vuln._id,
90 headers=headers,
91 data=json.dumps(vulnWeb)
9092 )
9193
9294 if update.status_code == 200 or update.status_code == 201:
9597 print 'Error in update Vulnerability, status code: ' + str(update.status_code)
9698 print update.text
9799
98 help = (
99 '\nGet Vulns filtered by Severity and change Severity based in CWE\n'
100 'Parameters:\n'
101 '1º : Filter by Severity (<=) (unclassified, info, low, med, high, critical, all)\n'
102 '2º : Url to Couchdb\n'
103 '3º : Workspace name\n'
104 'Try help for this description.\n'
105 'Example:'
106 './fplugin.py -f getSeverityByCwe.py -p high '
107 'http://username:password@localhost:5984/ workspace_test_name'
108 'Note: In this case, change vulns with severity high, med, low, info and unclassified'
109 )
110100
111 if script_parameters == 'help' or script_parameters == None or script_parameters == '' :
112 print help
113 raise(Exception('Exit for help'))
101 def main(workspace='', args=None, parser=None):
102 parser.add_argument('severity', nargs='?', help='Filter by Severity (<=)', default="info", choices=SEVERITY_OPTIONS)
103 parser.add_argument('--couchdb', nargs='?', help='CouchDB URL', default="http://faraday:faraday@localhost:5984")
114104
115 # Main
116 list_parameters = script_parameters.split(' ')
105 parsed_args = parser.parse_args(args)
117106
118 #default value from ENV COUCHDB
119 global couchdb
120 couchdb = os.environ.get('COUCHDB')
107 cwe = getCweData(parsed_args.couchdb)
121108
122 if not couchdb and list_parameters[1]:
123 couchdb = list_parameters[1]
109 if cwe is None:
110 print 'CWE DB not downloaded....EXIT'
111 return 2, None
124112
125 #Default workspace
126 workspace = 'untitled'
127 if list_parameters[2]:
128 workspace = list_parameters[2]
113 for host in models.get_hosts(workspace):
114 for v in host.getVulns():
115 checkSeverity(v, cwe, parsed_args.severity, workspace, parsed_args.couchdb)
129116
130 #Default severity
131 severity = 'info'
132 if list_parameters[0]:
133 severity = list_parameters[0]
117 for i in host.getAllInterfaces():
118 for s in i.getAllServices():
119 for v in s.getVulns():
120 checkSeverity(v, cwe, parsed_args.severity, workspace, parsed_args.couchdb)
134121
135
136 cwe = getCweData()
137
138 if cwe is None:
139 print 'CWE DB not downloaded....EXIT'
140 raise(Exception('Exit CWE DB not found'))
141
142 for host in api.__model_controller.getAllHosts():
143 for v in host.getVulns():
144 checkSeverity(v, cwe, severity, workspace)
145
146 for i in host.getAllInterfaces():
147 for s in i.getAllServices():
148 for v in s.getVulns():
149 checkSeverity(v, cwe, severity, workspace)
122 return 0, None
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 """
4 Faraday Penetration Test IDE
5 Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 """
8
9 import os
10
11 from model.common import factory
12 from persistence.server import models
13
14 __description__ = 'Import every host found in a PCAP file for further scanning'
15 __prettyname__ = 'Import PCAP'
16
17
18 def main(workspace='', args=None, parser=None):
19
20 parser.add_argument('-s', '--source', nargs='*', help='Filter packets by source'),
21 parser.add_argument('-d', '--dest', nargs='*', help='Filter packets by destination'),
22
23 parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
24
25 parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output from the pcapfile library.')
26 parser.add_argument('pcap', help='Path to the PCAP file'),
27
28 parsed_args = parser.parse_args(args)
29
30 try:
31 from pcapfile import savefile
32 import pcapfile
33 except ImportError:
34 print 'capfile not found, please install it to use this plugin.' \
35 ' You can do it executing pip2 install pcapfile in a shell.'
36 return 1, None
37
38 if not os.path.isfile(parsed_args.pcap):
39 print "pcap file not found: " % parsed_args.pcap
40 return 2, None
41
42 testcap = open(parsed_args.pcap, 'rb')
43
44 try:
45 capfile = savefile.load_savefile(testcap, layers=2, verbose=parsed_args.verbose)
46 except pcapfile.Error:
47 print "Invalid pcap file"
48 return 3, None
49
50 print 'pcap file loaded. Parsing packets...'
51
52 # Set() to store already added hosts. This will save an enormous amount of time by not querying the database
53 # for hosts we already know are in Faraday
54 added = set()
55
56 for packet in capfile.packets:
57
58 if packet.packet.type != 2048:
59 continue
60
61 src = packet.packet.payload.src
62 dst = packet.packet.payload.dst
63
64 if parsed_args.source and not src in parsed_args.source:
65 continue
66
67 if parsed_args.dest and not dst in parsed_args.dest:
68 continue
69
70 if src not in added:
71
72 # Lets save additional queries for this IP, it will already be on the database anyway!
73 added.add(packet.packet.payload.src)
74
75 # Parsing of source field
76 obj = factory.createModelObject(models.Host.class_signature, src,
77 workspace, os=None, parent_id=None)
78
79 old = models.get_host(workspace, obj.getID())
80
81 if old is None:
82 if not parsed_args.dry_run:
83 models.create_host(workspace, obj)
84 print '%s\t%s' % (src, obj.getID())
85
86 if dst not in added:
87
88 # Lets save additional queries for this IP, it will already be on the database anyway!
89 added.add(packet.packet.payload.dst)
90
91 # Parsing of destination field
92 obj = factory.createModelObject(models.Host.class_signature, dst,
93 workspace, os=None, parent_id=None)
94
95 old = models.get_host(workspace, obj.getID())
96
97 if old is None:
98 if not parsed_args.dry_run:
99 models.create_host(workspace, obj)
100 print '%s\t%s' % (dst, obj.getID())
101
102 return 0, None
0 #!/usr/bin/env python2.7
1
2 '''
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 '''
7
8 from persistence.server import models
9
10 __description__ = 'Get all stored credentials'
11 __prettyname__ = 'List Credentials'
12
13
14 def main(workspace='', args=None, parser=None):
15 parsed_args = parser.parse_args(args)
16
17 for credential in models.get_credentials(workspace):
18 print(credential.username + ' : ' + credential.password)
19 return 0, None
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2 """
3 Faraday Penetration Test IDE
4 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
5 See the file 'doc/LICENSE' for the license information
6 """
7
8 from persistence.server import models
9
10 __description__ = 'List hosts'
11 __prettyname__ = 'List Hosts'
12
13
14 def main(workspace='', args=None, parser=None):
15 parser.add_argument('os_filter', nargs='*', help='List of OSs to filter for', default=[]),
16
17 parsed_args = parser.parse_args(args)
18
19 for host in models.get_hosts(workspace):
20
21 if not parsed_args.os_filter or (parsed_args.os_filter and host.os in parsed_args.os_filter):
22 print '%s\t%s' % (host.name, host.os)
23
24 return 0, None
0 #!/usr/bin/env python2.7
1 '''
2 Faraday Penetration Test IDE
3 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
4 See the file 'doc/LICENSE' for the license information
5 '''
6
7 from persistence.server import models
8
9 __description__ = 'List all scanned IPs'
10 __prettyname__ = 'Get All IPs'
11
12
13 def main(workspace='', args=None, parser=None):
14 parser.add_argument('-s', '--sorted', help='Print a sorted list of IPs.', action='store_true')
15
16 parsed_args = parser.parse_args(args)
17
18 ips = []
19
20 for host in models.get_hosts(workspace):
21
22 if parsed_args.sorted:
23 ips += [host.name]
24 else:
25 print(host.name)
26
27 if parsed_args.sorted:
28 print '\n'.join(sorted(ips))
29
30 return 0, None
0 #!/usr/bin/env python2.7
1 # -*- coding: utf-8 -*-
2
3 '''
4 Faraday Penetration Test IDE
5 Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
6 See the file 'doc/LICENSE' for the license information
7 '''
8
9 __description__ = 'Lists all scanned OSs'
10 __prettyname__ = 'Get All OSs'
11
12 from persistence.server import models
13
14
15 def main(workspace='', args=None, parser=None):
16 parser.add_argument('-q', '--unique', help='Group OSs and print the total amount of hosts.', action='store_true')
17
18 parsed_args = parser.parse_args(args)
19
20 host_count = {}
21
22 for host in models.get_hosts(workspace):
23
24 if parsed_args.unique:
25 if host.os in host_count:
26 host_count[host.os] += 1
27 else:
28 host_count[host.os] = 1
29
30 else:
31 print host.os
32
33 if parsed_args.unique:
34 for host, count in host_count.items():
35 print '%s\t(%d)' % (host, count)
36
37 return 0, None
4949 CONST_TKTURI = "tickets_uri"
5050 CONST_TKTAPIPARAMS = "tickets_api"
5151 CONST_TKTTEMPLATE = "tickets_template"
52 CONST_OSINT = "osint"
5253
5354 CONST_LAST_WORKSPACE = "last_workspace"
5455 CONST_PLUGIN_SETTINGS = "plugin_settings"
150151 self._version = self._getValue(tree, CONST_VERSION)
151152 self._last_workspace = self._getValue(tree, CONST_LAST_WORKSPACE, default = "untitled")
152153 self._plugin_settings = json.loads(self._getValue(tree, CONST_PLUGIN_SETTINGS, default = "{}"))
154 self._osint = json.loads(self._getValue(tree, CONST_OSINT, default = "{\"host\": \"shodan.io\",\"icon\": \"shodan\",\"label\": \"Shodan\"}"))
153155
154156 self._updates_uri = self._getValue(tree, CONST_UPDATEURI, default = "https://www.faradaysec.com/scripts/updates.php")
155157 self._tkts_uri = self._getValue(tree, CONST_TKTURI,default = "https://www.faradaysec.com/scripts/listener.php")
271273 def getPluginSettings(self):
272274 return self._plugin_settings
273275
276 def getOsint(self):
277 return self._osint
278
274279 def getUpdatesUri(self):
275280 return self._updates_uri
276281
391396
392397 def setPluginSettings(self, settings):
393398 self._plugin_settings = settings
399
400 def setOsint(self, config):
401 self._osint = config
394402
395403 def setMergeStrategy(self, strategy):
396404 self._merge_strategy = strategy
475483 HOME_PATH.text = self.getHomePath()
476484 ROOT.append(HOME_PATH)
477485
478
479486 HOST_TREE_TOGGLE = Element(CONST_HOST_TREE_TOGGLE)
480487 HOST_TREE_TOGGLE.text = self.getHostTreeToggle()
481488 ROOT.append(HOST_TREE_TOGGLE)
552559 PLUGIN_SETTINGS.text = json.dumps(self.getPluginSettings())
553560 ROOT.append(PLUGIN_SETTINGS)
554561
562 OSINT = Element(CONST_OSINT)
563 OSINT.text = json.dumps(self.getOsint())
564 ROOT.append(OSINT)
565
555566 UPDATE_URI = Element(CONST_UPDATEURI)
556567 UPDATE_URI.text = self.getUpdatesUri()
557568 ROOT.append(UPDATE_URI)
571582 self.indent(ROOT, 0)
572583 xml_file = os.path.expanduser(xml_file)
573584 ElementTree(ROOT).write(xml_file)
585
574586
575587 def getInstanceConfiguration():
576588 global the_config
11 <faraday>
22
33 <appname>Faraday - Penetration Test IDE</appname>
4 <version>2.3.1</version>
4 <version>2.4.0</version>
55 <debug_status>0</debug_status>
66 <font>-Misc-Fixed-medium-r-normal-*-12-100-100-100-c-70-iso8859-1</font>
77 <home_path>~/</home_path>
11 # Faraday Penetration Test IDE
22 # Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
33 # See the file 'doc/LICENSE' for the license information
4 import server.utils.logger
4 import argparse
5 import os
6 import subprocess
7 import sys
58
6 import sys, os
7 import argparse
8 import subprocess
99 import server.config
1010 import server.couchdb
11
11 import server.utils.logger
1212 from server.utils import daemonize
13 from utils.dependencies import DependencyChecker
13 from utils import dependencies
1414 from utils.user_input import query_yes_no
1515
1616 logger = server.utils.logger.get_logger(__name__)
1717
18
19 def setup_environment(check_deps=False):
20 # Configuration files generation
21 server.config.copy_default_config_to_local()
22
23 if check_deps:
24
25 # Check dependencies
26 installed_deps, missing_deps = dependencies.check_dependencies(
27 requirements_file=server.config.REQUIREMENTS_FILE)
28
29 logger.info("Checking dependencies...")
30
31 if missing_deps:
32
33 install_deps = query_yes_no("Do you want to install them?", default="no")
34
35 if install_deps:
36 dependencies.install_packages(missing_deps)
37 logger.info("Dependencies installed. Please launch Faraday Server again.")
38 sys.exit(0)
39 else:
40 logger.error("Dependencies not met. Please refer to the documentation in order to install them. [%s]",
41 ", ".join(missing_deps))
42 sys.exit(1)
43
44 logger.info("Dependencies met")
45
46 # Web configuration file generation
47 server.config.gen_web_config()
48
49 # Reports DB creation
50 server.couchdb.push_reports()
51
52
53 def import_workspaces():
54 import server.importer
55 server.importer.import_workspaces()
56
57
58 def stop_server():
59 if not daemonize.stop_server():
60 # Exists with an error if it couldn't close the server
61 return False
62 else:
63 logger.info("Faraday Server stopped successfully")
64 return True
65
66
67 def is_server_running():
68 pid = daemonize.is_server_running()
69 if pid is not None:
70 logger.error("Faraday Server is already running. PID: {}".format(pid))
71 return True
72 else:
73 return False
74
75
76 def run_server(args):
77 import server.web
78
79 server.database.initialize()
80 server.app.setup()
81 web_server = server.web.WebServer(enable_ssl=args.ssl)
82
83 daemonize.create_pid_file()
84 logger.info('Faraday Server is ready')
85 web_server.run()
86
87
1888 def main():
19 args = parse_arguments()
89 parser = argparse.ArgumentParser()
90 parser.add_argument('--ssl', action='store_true', help='enable HTTPS')
91 parser.add_argument('--debug', action='store_true', help='run Faraday Server in debug mode')
92 parser.add_argument('--start', action='store_true', help='run Faraday Server in background')
93 parser.add_argument('--stop', action='store_true', help='stop Faraday Server')
94 parser.add_argument('--nodeps', action='store_true', help='Skip dependency check')
95 parser.add_argument('--no-setup', action='store_true', help=argparse.SUPPRESS)
96 args = parser.parse_args()
97
98 if args.debug:
99 server.utils.logger.set_logging_level(server.config.DEBUG)
20100
21101 if args.stop:
22102 sys.exit(0 if stop_server() else 1)
23103
24 if not args.no_setup:
25 setup_environment()
26 import_workspaces()
27
28104 if is_server_running():
29105 sys.exit(1)
30106
31 if args.debug:
32 server.utils.logger.set_logging_level(server.config.DEBUG)
107 # Overwrites config option if SSL is set by argument
108 if args.ssl:
109 server.config.ssl.set('enabled', 'true')
110
111 if not args.no_setup:
112 setup_environment(not args.nodeps)
113 import_workspaces()
33114
34115 if args.start:
35116 # Starts a new process on background with --ignore-setup
43124 else:
44125 run_server(args)
45126
46 def parse_arguments():
47 parser = argparse.ArgumentParser()
48 parser.add_argument('--ssl', action='store_true', help='enable HTTPS')
49 parser.add_argument('--debug', action='store_true', help='run Faraday Server in debug mode')
50 parser.add_argument('--start', action='store_true', help='run Faraday Server in background')
51 parser.add_argument('--stop', action='store_true', help='stop Faraday Server')
52 parser.add_argument('--no-setup', action='store_true', help=argparse.SUPPRESS)
53 return parser.parse_args()
54
55 def setup_environment():
56 # Configuration files generation
57 server.config.copy_default_config_to_local()
58
59 # Dependencies installation
60 missing_packages = check_dependencies()
61 if len(missing_packages) > 0:
62 install_packages(missing_packages)
63
64 # Web configuration file generation
65 server.config.gen_web_config()
66
67 # Reports DB creation
68 server.couchdb.push_reports()
69
70 def check_dependencies():
71 checker = DependencyChecker(server.config.REQUIREMENTS_FILE)
72 missing = checker.check_dependencies()
73 return missing
74
75 def install_packages(packages):
76 if ask_to_install(packages):
77 logger.info("Dependencies installed. Please launch Faraday Server again")
78 sys.exit(0)
79 else:
80 logger.error("Dependencies not met")
81 sys.exit(1)
82
83 def ask_to_install(missing_packages):
84 logger.warning("The following packages are not installed:")
85 for package in missing_packages:
86 logger.warning("%s" % package)
87
88 if query_yes_no("Do you want to install them?", default="no"):
89 checker = DependencyChecker(server.config.REQUIREMENTS_FILE)
90 checker.install_packages(missing_packages)
91 return True
92
93 return False
94
95 def import_workspaces():
96 import server.importer
97 server.importer.import_workspaces()
98
99 def stop_server():
100 if not daemonize.stop_server():
101 # Exists with an error if it couldn't close the server
102 return False
103 else:
104 logger.info("Faraday Server stopped successfully")
105 return True
106
107 def is_server_running():
108 pid = daemonize.is_server_running()
109 if pid is not None:
110 logger.error("Faraday Server is already running. PID: {}".format(pid))
111 return True
112 else:
113 return False
114
115 def run_server(args):
116 import server.database
117 import server.app
118 import server.web
119
120 server.database.initialize()
121 server.app.setup()
122 web_server = server.web.WebServer(enable_ssl=args.ssl)
123
124 daemonize.create_pid_file()
125 logger.info('Faraday Server is ready')
126 web_server.run()
127127
128128 if __name__ == '__main__':
129129 main()
130
1010 # - Additionally parse arguments from file.
1111
1212
13 import argparse
1314 import os
15 import shutil
1416 import sys
15 import shutil
16 import argparse
17 import platform
18 import subprocess
19 import json
20
21 from utils.logs import getLogger, setUpLogger
17
2218 from config.configuration import getInstanceConfiguration
2319 from config.globals import *
20 from utils import dependencies
21 from utils.logs import getLogger, setUpLogger
2422 from utils.profilehooks import profile
2523 from utils.user_input import query_yes_no
2624
25 from persistence.server import server
2726
2827 USER_HOME = os.path.expanduser(CONST_USER_HOME)
2928 FARADAY_BASE = os.path.dirname(os.path.realpath(__file__))
3029
3130 FARADAY_USER_HOME = os.path.expanduser(CONST_FARADAY_HOME_PATH)
3231
33 FARADAY_PLUGINS_PATH = os.path.join(FARADAY_USER_HOME,
34 CONST_FARADAY_PLUGINS_PATH)
35
36 FARADAY_PLUGINS_BASEPATH = os.path.join(FARADAY_BASE,
37 CONST_FARADAY_PLUGINS_REPO_PATH)
38
39 FARADAY_BASE_IMAGES = os.path.join(FARADAY_BASE, "data",
40 CONST_FARADAY_IMAGES)
41
42 FARADAY_USER_CONFIG_XML = os.path.join(FARADAY_USER_HOME,
43 CONST_FARADAY_USER_CFG)
44
45 FARADAY_BASE_CONFIG_XML = os.path.join(FARADAY_BASE,
46 CONST_FARADAY_BASE_CFG)
32 FARADAY_PLUGINS_PATH = os.path.join(FARADAY_USER_HOME, CONST_FARADAY_PLUGINS_PATH)
33
34 FARADAY_PLUGINS_BASEPATH = os.path.join(FARADAY_BASE, CONST_FARADAY_PLUGINS_REPO_PATH)
35
36 FARADAY_BASE_IMAGES = os.path.join(FARADAY_BASE, "data", CONST_FARADAY_IMAGES)
37
38 FARADAY_USER_CONFIG_XML = os.path.join(FARADAY_USER_HOME, CONST_FARADAY_USER_CFG)
39
40 FARADAY_BASE_CONFIG_XML = os.path.join(FARADAY_BASE, CONST_FARADAY_BASE_CFG)
4741
4842 USER_ZSHRC = os.path.expanduser(CONST_USER_ZSHRC)
4943
50 FARADAY_USER_IMAGES = os.path.join(FARADAY_USER_HOME,
51 CONST_FARADAY_IMAGES)
44 FARADAY_USER_IMAGES = os.path.join(FARADAY_USER_HOME, CONST_FARADAY_IMAGES)
5245
5346 FARADAY_USER_ZSHRC = os.path.join(FARADAY_USER_HOME, CONST_FARADAY_ZSHRC)
5447 FARADAY_USER_ZSH_PATH = os.path.join(FARADAY_USER_HOME, CONST_ZSH_PATH)
7568 parser_connection = parser.add_argument_group('connection')
7669 parser_profile = parser.add_argument_group('profiling')
7770
78 parser_connection.add_argument('-n', '--hostname', action="store",
79 dest="host",
80 default=None,
81 help="The hostname where both server APIs will listen (XMLRPC and RESTful). \
82 Default = localhost")
83
84 parser_connection.add_argument('-px', '--port-xmlrpc', action="store", dest="port_xmlrpc", default=None, type=int,
85 help="Sets the port where the api XMLRPCServer will listen. Default = 9876")
86 parser_connection.add_argument('-pr', '--port-rest', action="store", dest="port_rest",
87 default=None, type=int,
88 help="Sets the port where the api RESTful server will listen. Default = 9977")
89
90 parser.add_argument('-d', '--debug', action="store_true", dest="debug",
91 default=False,
92 help="Enables debug mode. Default = disabled")
71 parser_connection.add_argument('-n', '--hostname',
72 action="store",
73 dest="host",
74 default=None,
75 help="The hostname where both server APIs will listen (XMLRPC and RESTful). Default = localhost")
76
77 parser_connection.add_argument('-px',
78 '--port-xmlrpc',
79 action="store",
80 dest="port_xmlrpc",
81 default=None,
82 type=int,
83 help="Sets the port where the api XMLRPCServer will listen. Default = 9876")
84
85 parser_connection.add_argument('-pr',
86 '--port-rest',
87 action="store",
88 dest="port_rest",
89 default=None,
90 type=int,
91 help="Sets the port where the api RESTful server will listen. Default = 9977")
9392
9493 parser_profile.add_argument('--profile', action="store_true",
95 dest="profile",
96 default=False,
97 help="Enables application profiling. When this option is used \
98 --profile-output and --profile-depth can also be used. \
99 Default = disabled")
100
101 parser_profile.add_argument('--profile-output', action="store",
102 dest="profile_output",
103 default=None,
104 help="Sets the profile output filename. If no value is provided, \
105 standard output will be used")
106
107 parser_profile.add_argument('--profile-depth', action="store",
108 dest="profile_depth", type=int,
109 default=500,
110 help="Sets the profile number of entries (depth). Default = 500")
111
112 parser.add_argument('--disable-excepthook', action="store_true",
113 dest="disable_excepthook",
114 default=False,
115 help="Disable the application exception hook that allows to send error \
116 reports to developers.")
117
118 parser.add_argument('--dev-mode', action="store_true", dest="dev_mode",
119 default=False,
120 help="Enable dev mode. This will use the user config and plugin folder.")
121
122 parser.add_argument('--ignore-deps', action="store_true",
123 dest="ignore_deps",
124 default=False,
125 help="Ignore python dependencies resolution.")
126
127 parser.add_argument('--update', action="store_true", dest="update",
128 default=False,
129 help="Update Faraday IDE.")
130
131 parser.add_argument('--cert', action="store", dest="cert_path",
132 default=None,
133 help="Path to the valid CouchDB certificate")
134
135 parser.add_argument('--gui', action="store", dest="gui",
136 default="gtk",
137 help="Select interface to start faraday. Supported values are "
138 "gtk and 'no' (no GUI at all). Defaults to GTK")
139
140 parser.add_argument('--cli', action="store_true",
141 dest="cli",
142 default=False,
143 help="Set this flag to avoid gui and use faraday as a cli.")
144
145 parser.add_argument(
146 '-w', '--workspace', action="store",
147 dest="workspace",
148 default=None,
149 help="Workspace to be opened")
150
151 parser.add_argument(
152 '-r', '--report', action="store",
153 dest="filename",
154 default=None,
155 help="Report to be parsed by the cli")
156
157 #args = parser.parse_args(['@parser_args.cfg'])
94 dest="profile",
95 default=False,
96 help="Enables application profiling. When this option is used --profile-output and --profile-depth can also be used. Default = disabled")
97
98 parser_profile.add_argument('--profile-output',
99 action="store",
100 dest="profile_output",
101 default=None,
102 help="Sets the profile output filename. If no value is provided, standard output will be used")
103
104 parser_profile.add_argument('--profile-depth',
105 action="store",
106 dest="profile_depth",
107 type=int,
108 default=500,
109 help="Sets the profile number of entries (depth). Default = 500")
110
111 parser.add_argument('--disable-excepthook',
112 action="store_true",
113 dest="disable_excepthook",
114 default=False,
115 help="Disable the application exception hook that allows to send error reports to developers.")
116
117 parser.add_argument('--dev-mode',
118 action="store_true",
119 dest="dev_mode",
120 default=False,
121 help="Enable dev mode. This will use the user config and plugin folder.")
122
123 parser.add_argument('--ignore-deps',
124 action="store_true",
125 dest="ignore_deps",
126 default=False,
127 help="Ignore python dependencies resolution.")
128
129 parser.add_argument('--update',
130 action="store_true",
131 dest="update",
132 default=False,
133 help="Update Faraday IDE.")
134
135 parser.add_argument('--cert',
136 action="store",
137 dest="cert_path",
138 default=None,
139 help="Path to the valid CouchDB certificate")
140
141 parser.add_argument('--gui',
142 action="store",
143 dest="gui",
144 default="gtk",
145 help="Select interface to start faraday. Supported values are gtk and 'no' (no GUI at all). Defaults to GTK")
146
147 parser.add_argument('--cli',
148 action="store_true",
149 dest="cli",
150 default=False,
151 help="Set this flag to avoid gui and use faraday as a cli.")
152
153 parser.add_argument('-w',
154 '--workspace',
155 action="store",
156 dest="workspace",
157 default=None,
158 help="Workspace to be opened")
159
160 parser.add_argument('-r',
161 '--report',
162 action="store",
163 dest="filename",
164 default=None,
165 help="Report to be parsed by the cli")
166
167 parser.add_argument('-d',
168 '--debug',
169 action="store_true",
170 default=False,
171 help="Enables debug mode. Default = disabled")
172
173 parser.add_argument('--nodeps', action='store_true', help='Skip dependency check')
174
175 # args = parser.parse_args(['@parser_args.cfg'])
158176 return parser.parse_args()
159177
160178
161 def query_user_bool(question, default=True):
162 """Returns a boolean based on user input.
163
164 "question" is a string that is presented to the user.
165 "default" is the presumed answer if the user just hits <Enter>.
166 It must be True (the default), False or None (meaning
167 an answer is required of the user).
168
169 The "answer" return value is one of True or False.
170
171 """
172
173 valid_yes_ans = ["yes", "y"]
174 valid_no_ans = ["no", "n"]
175
176 if default is None:
177 prompt = " [y/n] "
178 elif default:
179 prompt = " [Y/n] "
180 else:
181 prompt = " [y/N] "
182
183 while True:
184 sys.stdout.write(question + prompt)
185 choice = raw_input().lower()
186
187 if default is not None and choice == '':
188 return default
189
190 if choice in valid_yes_ans:
191 return True
192
193 if choice in valid_no_ans:
194 return False
195
196 sys.stdout.write("Please respond with 'yes' or 'no' "
197 "(or 'y' or 'n').\n")
198
199
200 def checkDependencies():
179 def check_dependencies_or_exit():
201180 """Dependency resolver based on a previously specified CONST_REQUIREMENTS_FILE.
202181
203 Currently checks a list of dependencies from a file and asks for user
204 confirmation on whether to install it with a specific version or not.
205
206 """
207
208 if not args.ignore_deps:
209 try:
210 import pip
211 modules = []
212 f = open(FARADAY_REQUIREMENTS_FILE)
213 for line in f:
214 if not line.find('#'):
215 break
216 else:
217 modules.append(line.strip('\n'))
218 f.close()
219 pip_dist = [dist.project_name.lower() for dist in pip.get_installed_distributions()]
220 for module in modules:
221 if module.lower() not in pip_dist:
222 try:
223 __import__(module)
224 except ImportError:
225 if query_user_bool("Missing module %s."
226 " Do you wish to install it?" % module):
227 pip.main(['install', "%s" %
228 module, '--user'])
229
230 else:
231 return False
232 except ImportError:
233 pass
234
235 return True
182 Currently checks a list of dependencies from a file and exits if they are not met.
183
184 """
185
186 installed_deps, missing_deps = dependencies.check_dependencies(requirements_file=FARADAY_REQUIREMENTS_FILE)
187
188 logger.info("Checking dependencies...")
189
190 if missing_deps:
191
192 install_deps = query_yes_no("Do you want to install them?", default="no")
193
194 if install_deps:
195 dependencies.install_packages(missing_deps)
196 logger.info("Dependencies installed. Please launch Faraday Server again.")
197 sys.exit(0)
198 else:
199 logger.error("Dependencies not met. Please refer to the documentation in order to install them. [%s]",
200 ", ".join(missing_deps))
201 sys.exit(1)
202
203 logger.info("Dependencies met")
236204
237205
238206 def startProfiler(app, output, depth):
269237
270238 host = CONF.getApiConInfoHost() if str(CONF.getApiConInfoHost()) != "None" else FARADAY_DEFAULT_HOST
271239 port_xmlrpc = CONF.getApiConInfoPort() if str(CONF.getApiConInfoPort()) != "None" else FARADAY_DEFAULT_PORT_XMLRPC
272 port_rest = CONF.getApiRestfulConInfoPort() if str(CONF.getApiRestfulConInfoPort()) != "None" else FARADAY_DEFAULT_PORT_REST
240 port_rest = CONF.getApiRestfulConInfoPort() if str(
241 CONF.getApiRestfulConInfoPort()) != "None" else FARADAY_DEFAULT_PORT_REST
273242
274243 host = args.host if args.host else host
275244 port_xmlrpc = args.port_xmlrpc if args.port_xmlrpc else port_xmlrpc
292261 from model.application import MainApplication
293262
294263 logger.info("All done. Opening environment.")
295 #TODO: Handle args in CONF and send only necessary ones.
264 # TODO: Handle args in CONF and send only necessary ones.
296265
297266 main_app = MainApplication(args)
298267
299268 if not args.disable_excepthook:
300 logger.info("Main application ExceptHook enabled.")
301 main_app.enableExceptHook()
269 logger.info("Main application ExceptHook enabled.")
270 main_app.enableExceptHook()
302271
303272 if args.profile:
304273 logger.info("Starting main application with profiler.")
313282 couchURL = getInstanceConfiguration().getCouchURI()
314283 if couchURL:
315284 url = "%s/_ui" % couchURL
316 print(Fore.WHITE + Style.BRIGHT + \
317 "\n*" + string.center("faraday ui is ready", 53 - 6) )
318 print(Fore.WHITE + Style.BRIGHT + \
319 """Make sure you got couchdb up and running.\nIf couchdb is up, point your browser to: \n[%s]""" % url)
285 print(Fore.WHITE + Style.BRIGHT + "\n*" + string.center("faraday ui is ready", 53 - 6))
286 print(
287 Fore.WHITE + Style.BRIGHT + "Make sure you got couchdb up and running.\nIf couchdb is up, point your browser to: \n[%s]" % url)
320288 else:
321 print(Fore.WHITE + Style.BRIGHT + \
322 """Please config Couchdb for fancy HTML5 Dashboard (https://github.com/infobyte/faraday/wiki/Couchdb)""")
289 print(
290 Fore.WHITE + Style.BRIGHT + "Please config Couchdb for fancy HTML5 Dashboard (https://github.com/infobyte/faraday/wiki/Couchdb)")
323291
324292 print(Fore.RESET + Back.RESET + Style.RESET_ALL)
325293
354322
355323 shutil.copytree(FARADAY_PLUGINS_BASEPATH, FARADAY_PLUGINS_PATH)
356324
325
357326 def setupZSH():
358327 """Cheks and handles Faraday's integration with ZSH.
359328
375344 f.write("source \"%s\"" % FARADAY_BASE_ZSH)
376345 shutil.copy(FARADAY_BASE_ZSH, FARADAY_USER_ZSH_PATH)
377346
347
378348 def setupXMLConfig():
379349 """Checks user configuration file status.
380350
386356 shutil.copy(FARADAY_BASE_CONFIG_XML, FARADAY_USER_CONFIG_XML)
387357 else:
388358 logger.info("Using custom user configuration.")
359
389360
390361 def setupImages():
391362 """ Copy png icons
434405 os.makedirs(folder)
435406
436407
437
438408 def printBanner():
439409 """Prints Faraday's ascii banner.
440410
449419 \/ \/ \/ \/ \/
450420 """)
451421
452 print(Fore.WHITE + Back.RED + Style.BRIGHT + \
453 "[*[ Open Source Penetration Test IDE ]*]")
422 print(Fore.WHITE + Back.RED + Style.BRIGHT + "[*[ Open Source Penetration Test IDE ]*]")
454423 print(Back.RESET + " Where pwnage goes multiplayer")
455424 print(Fore.RESET + Back.RESET + Style.RESET_ALL)
456425 logger.info("Starting Faraday IDE.")
467436 Updater().doUpdates()
468437 logger.info("Update process finished with no errors")
469438 logger.info("Faraday will start now.")
439
470440
471441 def checkUpdates():
472442 import requests
505475 # Non fatal error
506476 pass
507477
478
508479 def checkVersion():
509480 try:
510481 f = open(FARADAY_VERSION_FILE)
511482 f_version = f.read().strip()
512483 if not args.update:
513 if getInstanceConfiguration().getVersion() != None and getInstanceConfiguration().getVersion() != f_version:
484 if getInstanceConfiguration().getVersion() is not None and getInstanceConfiguration().getVersion() != f_version:
514485 logger.warning("You have different version of Faraday since your last run.\nRun ./faraday.py --update to update configuration!")
515486 if query_yes_no('Do you want to close Faraday?', 'yes'):
516487 sys.exit(-1)
519490 f.close()
520491
521492 except Exception as e:
522 getLogger("launcher").error("It seems that something's wrong with your version\nPlease contact customer support")
493 getLogger("launcher").error(
494 "It seems that something's wrong with your version\nPlease contact customer support")
523495 sys.exit(-1)
524496
525497
526 def init():
527 """Initializes what is needed before starting.
528
529 For now we initialize logger and arguments setup.
530
531 """
532
533 global args
534 global logger
535 logger = None
498 def check_faraday_version():
499 server_info = server.server_info()
500
501 faraday_directory = os.path.dirname(os.path.realpath('faraday.py'))
502
503 file_path = os.path.join(faraday_directory, 'VERSION')
504
505 with open(file_path, 'r') as version_file:
506 version = version_file.read().strip()
507
508 if server_info is not None and version != server_info['Version']:
509 getLogger("launcher").error("The server is running a different Faraday version than the client "
510 "you are running. Version numbers must much!")
511
512 sys.exit(2)
513
514
515 def main():
516 """Main.
517
518 Main function for launcher.
519
520 """
521 os.chdir(FARADAY_BASE)
522
523 global logger, args
524
525 logger = getLogger("launcher")
536526
537527 args = getParserArgs()
538528 setupFolders(CONST_FARADAY_FOLDER_LIST)
539529 setUpLogger(args.debug)
540 logger = getLogger("launcher")
541
542
543 def main():
544 """Main.
545
546 Main function for launcher.
547
548 """
549 os.chdir(FARADAY_BASE)
550
551 init()
552 if checkDependencies():
553 printBanner()
554 logger.info("Dependencies met.")
555 if args.cert_path:
556 os.environ[REQUESTS_CA_BUNDLE_VAR] = args.cert_path
557 checkConfiguration(args.gui)
558 setConf()
559 checkCouchUrl()
560 checkVersion()
561 update()
562 checkUpdates()
563 startFaraday()
564 else:
565 logger.error("Dependencies not met. Unable to start Faraday.")
530
531 if not args.nodeps:
532 check_dependencies_or_exit()
533
534 printBanner()
535 if args.cert_path:
536 os.environ[REQUESTS_CA_BUNDLE_VAR] = args.cert_path
537 checkConfiguration(args.gui)
538 setConf()
539 checkCouchUrl()
540 checkVersion()
541
542 check_faraday_version()
543
544 update()
545 checkUpdates()
546 startFaraday()
566547
567548
568549 if __name__ == '__main__':
66
77 '''
88
9 import os, sys, threading, webbrowser, time
10 from utils.logs import getLogger
9 import os
10 import sys
11 import threading
12 import webbrowser
1113
1214 try:
1315 import gi
4446 from gui.gui_app import FaradayUi
4547 from config.configuration import getInstanceConfiguration
4648 from utils.logs import getLogger
47 from persistence.server import models
4849 from appwindow import AppWindow
4950
5051 from server import ServerIO
6061 from dialogs import ForcePreferenceWindowDialog
6162 from dialogs import errorDialog
6263 from dialogs import ImportantErrorDialog
64 from dialogs import FaradayPluginsDialog
6365
6466 from mainwidgets import Sidebar
6567 from mainwidgets import WorkspaceSidebar
7173 from gui.loghandler import GUIHandler
7274 from utils.logs import addHandler
7375 from utils.common import checkSSL
76
77 from plugins import fplugin_utils
7478
7579 CONF = getInstanceConfiguration()
7680
172176 self.handle_no_active_workspace()
173177
174178 def lost_db_connection(self, explanatory_message=None,
175 handle_connection_lost=None,
176 connect_to_a_different_couch=None):
179 handle_connection_lost=None,
180 connect_to_a_different_couch=None):
177181 """Creates a simple dialog with an error message to inform the user
178182 some kind of problem has happened and the connection was lost.
179183 """
229233 we suddenly find our selves without one, force the user
230234 to select one if possible, or if not, to create one.
231235 """
236
232237 def change_flag(widget):
233238 self.workspace_dialogs_raised = not self.workspace_dialogs_raised
234239
235240 if self.workspace_dialogs_raised:
236241 return False
237242
238 if not self.serverIO.is_server_up():
243 if self.serverIO.server_info() is None:
239244 # make sure it is not because we're not connected to Couch
240245 # there's another whole strategy for that.
241246 return False
256261 self.createWorkspace,
257262 self.workspace_manager,
258263 self.ws_sidebar,
259 self.exit_faraday_without_confirm)
264 self.exit_faraday)
260265
261266 dialog.connect("destroy", change_flag)
262267 dialog.show_all()
356361 looking for the host."""
357362 current_ws_name = self.get_active_workspace().name
358363
359 #for host in self.model_controller.getAllHosts():
364 # for host in self.model_controller.getAllHosts():
360365 host = self.serverIO.get_hosts(couchid=host_id)
361366 if not host:
362367 self.show_normal_error("The host you clicked isn't accessible. "
563568 GObject.idle_add(self.statusbar.update_ws_info, host_count,
564569 service_count, vuln_count)
565570
566 dispatch = {3131: new_log_event,
567 3141: new_conflict_event,
568 5100: new_notification_event,
569 3140: workspace_changed_event,
570 3132: normal_error_event,
571 3134: important_error_event,
571 dispatch = {3131: new_log_event,
572 3141: new_conflict_event,
573 5100: new_notification_event,
574 3140: workspace_changed_event,
575 3132: normal_error_event,
576 3134: important_error_event,
572577 42424: lost_connection_to_server_event,
573578 24242: workspace_not_accessible_event,
574 7777: add_object,
575 8888: delete_object,
576 9999: update_object}
579 7777: add_object,
580 8888: delete_object,
581 9999: update_object}
577582
578583 function = dispatch.get(event.type())
579584 if function is not None:
638643 "quit": self.on_quit,
639644 "preferences": self.on_preferences,
640645 "pluginOptions": self.on_plugin_options,
646 "faradayPlugin": self.on_faraday_plugin,
641647 "new": self.on_new_button,
642648 "new_terminal": self.on_new_terminal_button,
643649 "open_report": self.on_open_report_button,
664670 appmenu = builder.get_object('appmenu')
665671 self.set_app_menu(appmenu)
666672
673 topmenu = Gio.Menu()
674 pluginmenu = Gio.Menu()
675
676 topmenu.append('Faraday Plugin...', 'app.faradayPlugin')
677
678 plugins = fplugin_utils.get_available_plugins()
679
680 for plugin in sorted(plugins.iterkeys()):
681 gio_action = Gio.SimpleAction.new('fplugin_%s' % plugin, None)
682 gio_action.connect("activate", self.type_faraday_plugin_command)
683 self.add_action(gio_action)
684
685 item = Gio.MenuItem.new(plugins[plugin]['prettyname'], 'app.fplugin_%s' % plugin)
686
687 pluginmenu.append_item(item)
688
689 fmenu = Gio.Menu()
690
691 fmenu.append_section(None, topmenu)
692 fmenu.append_section(None, pluginmenu)
693
694 appmenu.insert_submenu(1, "Faraday Plugin", fmenu)
695
667696 helpMenu = builder.get_object('Help')
668697 self.set_menubar(helpMenu)
669698
697726 notifier.widget = self.window
698727 model.guiapi.notification_center.registerWidget(self.window)
699728
700 if not self.serverIO.is_server_up():
729 if self.serverIO.server_info() is None:
701730 self.lost_db_connection(
702731 handle_connection_lost=self.handle_connection_lost,
703732 connect_to_a_different_couch=self.force_change_couch_url)
713742 """Defines what happens when you press "Plugins" on the menu"""
714743 pluginsOption_window = PluginOptionsDialog(self.plugin_manager,
715744 self.window)
745 pluginsOption_window.show_all()
746
747 def on_faraday_plugin(self, action, param):
748 """Defines what happens when you press "Faraday Plugin..." on the menu"""
749 pluginsOption_window = FaradayPluginsDialog(self.window.get_current_focused_terminal(),
750 self.get_active_workspace().getName(),
751 self.window)
716752 pluginsOption_window.show_all()
717753
718754 def on_new_button(self, action=None, params=None, title=None):
851887
852888 def on_help_dispatch(self, action, param=None):
853889 """Open the url contained in "action" in the user's browser."""
854 urls = {"go_to_documentation": "https://faradaysec.com/help/docs",
890 urls = {"go_to_documentation": "https://faradaysec.com/help/docs",
855891 "go_to_faq": "https://faradaysec.com/help/faq",
856892 "go_to_troubleshooting": "https://faradaysec.com/help/troubleshooting",
857893 "go_to_demos": "https://faradaysec.com/help/demos",
860896 "go_to_irc": "https://faradaysec.com/help/irc",
861897 "go_to_twitter": "https://faradaysec.com/help/twitter",
862898 "go_to_googlegroup": "https://faradaysec.com/help/googlegroup"
863 }
899 }
864900 url = urls.get(action.get_name(), "https://faradaysec.com")
865901 webbrowser.open(url, new=2)
902
903 def type_faraday_plugin_command(self, action, param=None):
904 """
905 Types the faraday plugin command on the command line.
906 """
907
908 plugin = "_".join(action.get_name().split('_')[1:])
909 terminal = self.window.get_current_focused_terminal()
910
911 command = fplugin_utils.build_faraday_plugin_command(plugin, self.get_active_workspace().getName())
912 fd = terminal.get_pty().get_fd()
913
914 os.write(fd, command)
77 '''
88 import gi
99 import webbrowser
10 import os
1011
1112 gi.require_version('Gtk', '3.0')
1213
1617 from decorators import scrollable
1718
1819 from compatibility import CompatibleScrolledWindow as GtkScrolledWindow
19
20 from plugins import fplugin_utils
2021
2122 CONF = getInstanceConfiguration()
2223
146147 self.name_entry = Gtk.Entry()
147148 if self.title is not None:
148149 self.name_entry.set_text(self.title)
149 name_box.pack_start(name_label, True, True, 10)
150 name_box.pack_end(self.name_entry, False, False, 10)
150 name_box.pack_start(name_label, False, False, 10)
151 name_box.pack_end(self.name_entry, True, True, 10)
151152 return name_box
152153
153154 def create_description_box(self):
156157 description_label = Gtk.Label()
157158 description_label.set_text("Description: ")
158159 self.description_entry = Gtk.Entry()
159 description_box.pack_start(description_label, True, True, 10)
160 description_box.pack_end(self.description_entry, False, False, 10)
160 description_box.pack_start(description_label, False, False, 10)
161 description_box.pack_end(self.description_entry, True, True, 10)
161162 return description_box
162163
163164 def create_button_box(self):
211212 self.connect("delete_event", lambda _, __: True)
212213 self.exit_faraday = exit_faraday_callback
213214 explanation_message = self.create_explanation_message()
214 self.main_box.pack_start(explanation_message, True, True, 10)
215 self.main_box.pack_start(explanation_message, True, True, 6)
215216 self.main_box.reorder_child(explanation_message, 0)
216217
217218 def on_click_cancel(self, button):
218219 """Override parent's class cancel callback so it exits faraday."""
219 self.exit_faraday()
220 self.exit_faraday(parent=self)
220221
221222 def create_explanation_message(self):
222223 """Returns a simple explanatory message inside a Label"""
223224 message = Gtk.Label()
224225 message.set_text("There are no workspaces available. You must "
225226 "create one to continue using Faraday.")
226 message.set_line_wrap(True)
227 message.set_max_width_chars(38)
228
229227 return message
230228
231229
435433
436434 adecuateModel = self.models[self.id_of_selected]
437435 self.createAdecuatePluginSettingView(adecuateModel)
436
437
438 class FaradayPluginsDialog(Gtk.Window):
439 """The dialog where the user can see details about installed plugins.
440 It is not the prettiest thing in the world but it works.
441 Creating and displaying the models of each plugin settings is specially
442 messy , there's more info in the appropiate methods"""
443
444 def __init__(self, terminal, workspace_name, parent):
445
446 Gtk.Window.__init__(self, title="Faraday Plugin")
447 self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
448 self.set_transient_for(parent)
449 self.set_modal(True)
450 self.set_size_request(800, 300)
451 self._terminal = terminal
452 self._workspace_name = workspace_name
453
454 plugin_info = self.createPluginInfo()
455
456 # self.id_of_selected = plugin_info[0][0] # default selected is first item in list
457 plugin_list = self.createPluginListView(plugin_info)
458 left_side_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
459 left_side_box.pack_start(plugin_list, True, True, 0)
460
461 buttonBox = Gtk.Box()
462 append_button = Gtk.Button.new_with_label("Append")
463 cancel_button = Gtk.Button.new_with_label("Cancel")
464 append_button.connect("clicked", self.on_click_append)
465 cancel_button.connect("clicked", self.on_click_cancel)
466 buttonBox.pack_start(append_button, True, True, 10)
467 buttonBox.pack_start(cancel_button, True, True, 10)
468
469 left_side_box.pack_start(buttonBox, False, False, 10)
470
471 infoBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
472 descriptionBox = Gtk.Box()
473
474 descriptionLabel = Gtk.Label()
475
476 self.descriptionEntry = Gtk.Label()
477
478 descriptionLabel.set_text("Description: ")
479
480 descriptionBox.pack_start(descriptionLabel, False, False, 5)
481 descriptionBox.pack_start(self.descriptionEntry, False, True, 5)
482
483 infoBox.pack_start(descriptionBox, False, False, 5)
484
485 self.pluginSpecsBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
486 self.pluginSpecsBox.pack_start(infoBox, False, False, 5)
487
488 self.mainBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
489 self.mainBox.pack_start(left_side_box, False, True, 10)
490 self.mainBox.pack_end(self.pluginSpecsBox, True, True, 10)
491
492 self.add(self.mainBox)
493
494 def on_click_append(self, button=None):
495 """On click OK button update the plugins settings and then destroy"""
496
497 self.type_faraday_plugin_command(self.name_of_selected)
498
499 self.destroy()
500
501 def on_click_cancel(self, button):
502 """On click cancel button, destroy brutally. No mercy"""
503 self.destroy()
504
505 def createPluginInfo(self):
506 """Creates and return a TreeStore where the basic information about
507 the plugins: the plugin ID, name, intended version of the tool
508 and plugin version"""
509 plugin_info = Gtk.TreeStore(str, str, str)
510
511 for key, plugin_dic in fplugin_utils.get_available_plugins().items():
512 plugin_info.append(None, [key,
513 plugin_dic["description"],
514 plugin_dic["prettyname"]
515 ]
516 )
517
518 # Sort it!
519 sorted_plugin_info = Gtk.TreeModelSort(model=plugin_info)
520 sorted_plugin_info.set_sort_column_id(2, Gtk.SortType.ASCENDING)
521 return sorted_plugin_info
522
523 @scrollable(width=300)
524 def createPluginListView(self, plugin_info):
525 """Creates the view for the left-hand side list of the dialog.
526 It uses an instance of the plugin manager to get a list
527 of all available plugins"""
528
529 plugin_list_view = Gtk.TreeView(plugin_info)
530 renderer = Gtk.CellRendererText()
531 column = Gtk.TreeViewColumn("Title", renderer, text=2)
532 column.set_sort_column_id(1)
533 plugin_list_view.append_column(column)
534
535 selection = plugin_list_view.get_selection()
536 selection.connect("changed", self.on_plugin_selection)
537
538 return plugin_list_view
539
540 def on_plugin_selection(self, selection):
541 """When the user selects a plugin, it will change the text
542 displeyed on the entries to their corresponding values"""
543
544 # if the user searches for something that doesn't exists,
545 # for example, the plugin 'jsaljfdlajs', this avoids
546 # the program trying to get settings for that non-existing plugin
547 try:
548 model, treeiter = selection.get_selected()
549 self.name_of_selected = model[treeiter][0]
550 # self.id_of_selected = model[treeiter][1]
551 description = model[treeiter][1]
552
553 self.descriptionEntry.set_label(description)
554
555 except TypeError:
556 pass
557
558 def type_faraday_plugin_command(self, plugin):
559
560 command = fplugin_utils.build_faraday_plugin_command(plugin, self._workspace_name)
561 fd = self._terminal.get_pty().get_fd()
562
563 os.write(fd, command)
438564
439565
440566 class HostInfoDialog(Gtk.Window):
10011127 return button_box
10021128
10031129 def _next_conflict_or_close(self):
1004 if len(self.conflicts)-1 > self.conflict_n:
1005 self.conflict_n += 1
1006 self.update_current_conflict()
1007 self.update_current_conflict_model()
1008 self.set_conflict_view(self.conflict_n)
1009 else:
1010 self.destroy()
1130 """Move to next conflict and update current conflict View and model."""
1131 if len(self.conflicts) - 1 > self.conflict_n:
1132 self.conflict_n += 1
1133 self.update_current_conflict()
1134 self.update_current_conflict_model()
1135 self.set_conflict_view(self.conflict_n)
1136 else:
1137 self.destroy()
10111138
10121139 def save(self, button, keeper):
10131140 """Saves information to Faraday. Keeper is needed to know if user
10571184 "deleted the conflicting object from "
10581185 "the DB \n"
10591186 "Moving on to the next conflict."))
1187
1188 guiapi.conflictMissing(self.current_conflict)
10601189 dialog.run()
10611190 dialog.destroy()
10621191 self._next_conflict_or_close()
4141 self.connect("key_press_event", self.copy_or_paste)
4242 self.host, self.port = CONF.getApiRestfulConInfo()
4343
44 faraday_directory = os.path.dirname(os.path.realpath('faraday.py'))
45 self.faraday_exec = faraday_directory + "/faraday-terminal.zsh"
44 self.faraday_directory = os.path.dirname(os.path.realpath('faraday.py'))
45 self.faraday_exec = self.faraday_directory + "/faraday-terminal.zsh"
4646
4747 self.start_faraday()
4848
5959 self.spawn_sync(Vte.PtyFlags.DEFAULT,
6060 home_dir,
6161 [self.faraday_exec, str(self.host), str(self.port)],
62 [],
62 ['FARADAY_PATH=%s' % self.faraday_directory],
6363 GLib.SpawnFlags.DO_NOT_REAP_CHILD,
64 None,
6465 None,
6566 None)
6667
314315 @preconditions: host_id must be in self.host_id_to_iter,
315316 self.host_id_to_iter[host_id] must in the model.
316317 """
318
319 # Let's first check if the host_id is in the model to avoid an exception bellow.
320 # Added because of a race condition (?) between the client and the server, where a deletion
321 # in bulk by the fplugin would trigger a KeyError
322 if not self._is_host_in_model_by_host_id(host_id):
323 return
324
317325 host_iter = self.host_id_to_iter[host_id]
318326 current_host_name = self.model[host_iter][3].split(" ")[0]
319327 new_host_string = "{0} ({1})".format(current_host_name, new_vuln_amount)
338346 model by modifying their corresponding hosts in the model. Return None.
339347 """
340348 host_ids = map(self._find_host_id, vulns)
341 self._modify_vuln_amounts_of_hosts_in_model(host_ids, lambda x: x+1)
349 self._modify_vuln_amounts_of_hosts_in_model(host_ids, lambda x: x + 1)
342350
343351 def remove_relevant_vulns_from_model(self, vuln_ids):
344352 """Takes vulns_ids, a list of vuln ids, and removes them from
346354 Return None.
347355 """
348356 host_ids = map(lambda v: v.getID().split(".")[0], vulns_ids)
349 self._modify_vuln_amounts_of_hosts_in_model(host_ids, lambda x: x-1)
357 self._modify_vuln_amounts_of_hosts_in_model(host_ids, lambda x: x - 1)
350358
351359 def add_host(self, host):
352360 """Adds host to the model. Do not use for hosts added after
448456 button_box.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(.1, .1, .1, .1))
449457 self.prev_button = Gtk.Button.new_with_label("<<")
450458 self.next_button = Gtk.Button.new_with_label(">>")
451 self.prev_button.connect("clicked", self.on_click_move_page, lambda x: x-1)
452 self.next_button.connect("clicked", self.on_click_move_page, lambda x: x+1)
459 self.prev_button.connect("clicked", self.on_click_move_page, lambda x: x - 1)
460 self.next_button.connect("clicked", self.on_click_move_page, lambda x: x + 1)
453461 button_box.pack_start(self.prev_button, True, True, 0)
454462 button_box.pack_start(self.progress_label, True, True, 0)
455463 button_box.pack_start(self.next_button, True, True, 0)
471479
472480 def update_progress_label(self):
473481 """Updates the progress label with values from self.page and self.number_of_pages."""
474 self.progress_label.set_label("{0} / {1}".format(self.page+1, self.number_of_pages))
482 self.progress_label.set_label("{0} / {1}".format(self.page + 1, self.number_of_pages))
475483
476484 def create_search_entry(self):
477485 """Returns a simple search entry"""
622630 # change the workspace to the newly selected
623631 self.change_ws(self.get_selected_ws_name())
624632 return True # prevents the click from selecting a workspace
625 # this is handled manually by us on self.change_ws
633 # this is handled manually by us on self.change_ws
626634
627635 def on_right_click(self, view, event):
628636 """On click, check if it was a right click. If it was,
741749
742750 def news_button(self, url, description):
743751
744 anchor = self.textBuffer.create_child_anchor(
745 self.textBuffer.get_end_iter())
746
747 button = Gtk.Button()
748 label = Gtk.Label()
749
750 label.set_markup(
751 'Faraday News: <a href="' + url + '"> ' +
752 description + "</a>")
753
754 button.add(label)
755 button.set_relief(Gtk.ReliefStyle.NONE)
756
757 button.connect("clicked", lambda o: webbrowser.open(url))
758
759 label.show()
760 button.show()
761 self.update("\n")
762
763 self.textView.add_child_at_anchor(button, anchor)
752 anchor = self.textBuffer.create_child_anchor(
753 self.textBuffer.get_end_iter())
754
755 button = Gtk.Button()
756 label = Gtk.Label()
757
758 label.set_markup(
759 'Faraday News: <a href="' + url + '"> ' +
760 description + "</a>")
761
762 button.add(label)
763 button.set_relief(Gtk.ReliefStyle.NONE)
764
765 button.connect("clicked", lambda o: webbrowser.open(url))
766
767 label.show()
768 button.show()
769 self.update("\n")
770
771 self.textView.add_child_at_anchor(button, anchor)
764772
765773 def customEvent(self, text):
766774 """Filters event so that only those with type 3131 get to the log.
794802
795803 # we need to take 1 from the lines to compensate for the default line
796804 lines = self.textBuffer.get_line_count()
797 begin = self.textBuffer.get_iter_at_line(lines-1)
805 begin = self.textBuffer.get_iter_at_line(lines - 1)
798806
799807 # update last position, it isn't the same as when the funcion started
800808 last_position = self.textBuffer.get_end_iter()
903911
904912 def update_ws_info(self, new_host_count, new_service_count,
905913 new_vuln_count):
906
907914 host, service, vuln = self.create_strings(new_host_count,
908915 new_service_count,
909916 new_vuln_count)
7878 return models.get_workspace_numbers(self.active_workspace)
7979
8080 @safe_io_with_server(False)
81 def is_server_up(self):
82 return models.is_server_up()
81 def server_info(self):
82 return models.server_info()
8383
8484 @safe_io_with_server(False)
8585 def test_server_url(self, url):
188188 tolerance = 0
189189 while True:
190190 time.sleep(1)
191 test_was_successful = self.is_server_up()
191 test_was_successful = self.server_info() is not None
192192 if test_was_successful:
193193 tolerance = 0
194194 else:
297297 if sync:
298298 self._sync_api_request = False
299299
300 def conflictMissing(self, conflict):
301 """
302 Conflict missing (Resolved by another one)
303 Remove conflict in original object and notify to clients
304 """
305 conflict.getFirstObject().updateResolved(conflict)
306 notifier.conflictUpdate(-1)
307
300308 def getConflicts(self):
301309 conflicts = []
302310 for obj in self.objects_with_updates:
814822 ipv6_address=ipv6_address, ipv6_prefix=ipv6_prefix,
815823 ipv6_gateway=ipv6_gateway, ipv6_dns=ipv6_dns,
816824 network_segment=network_segment,
817 hostname_resolution=hostname_resolution, parent_id=parent_id)
825 hostnames=hostname_resolution, parent_id=parent_id)
818826
819827 def newService(self, name, protocol="tcp?", ports=[], status="running",
820828 version="unknown", description="", parent_id=None):
446446 def getParent(parent_id):
447447 return __model_controller.find(parent_id)
448448
449 def conflictMissing(conflict):
450 __model_controller.conflictMissing(conflict)
449451
450452 def resolveConflicts():
451453 __model_controller.resolveConflicts()
645645 """Return a list with all the workspace names available."""
646646 return server.get_workspaces_names()['workspaces']
647647
648 def is_server_up():
648 def server_info():
649649 """True if server is up, False otherwise."""
650 return server.is_server_up()
650 return server.server_info()
651651
652652 def test_server_url(url_to_test):
653653 """Return True if url_to_test/_api/info is accessible, False otherwise"""
114114 """
115115 try:
116116 answer = server_io_function(server_url, **payload)
117 if answer.status_code == 409 and answer.json()['error'] == 'conflict':
117 if answer.status_code == 409:
118118 raise ConflictInDatabase(answer)
119119 if answer.status_code == 404:
120120 raise ResourceDoesNotExist(server_url)
12991299 metadata=metadata,
13001300 username=username,
13011301 password=password,
1302 type="Credential")
1302 type="Cred")
13031303
13041304 def update_credential(workspace_name, id, name, username, password,
13051305 owned=None, owner="", description="", metadata=None):
13291329 metadata=metadata,
13301330 username=username,
13311331 password=password,
1332 type="Credential")
1332 type="Cred")
13331333
13341334 def create_command(workspace_name, id, command, duration=None, hostname=None,
13351335 ip=None, itime=None, params=None, user=None):
14471447 db_url = _create_server_db_url(workspace_name)
14481448 return _delete(db_url, database=True)
14491449
1450 def is_server_up():
1451 """Return True if we can stablish a connection with the server,
1452 False otherwise.
1450 def server_info():
1451 """Return server info if we can stablish a connection with the server,
1452 None otherwise.
14531453 """
14541454 try:
1455 _get("{0}/info".format(_create_server_api_url()))
1456 is_server_up = True
1455 return _get("{0}/info".format(_create_server_api_url()))
14571456 except:
1458 is_server_up = False
1459 return is_server_up
1457 return None
14601458
14611459 def test_server_url(url_to_test):
14621460 """Return True if the url_to_test is indeed a valid Faraday Server URL.
0 import imp
1 import os
2 import sys
3
4 from colorama import Fore
5
6 from config.configuration import getInstanceConfiguration
7
8 CONF = getInstanceConfiguration()
9
10
11 def get_available_plugins():
12 faraday_directory = os.path.dirname(os.path.realpath(os.path.join(__file__, "../")))
13
14 scan_path = os.path.join(faraday_directory, "bin/")
15
16 plugin_list = os.listdir(scan_path)
17
18 if 'fplugin' in plugin_list:
19 plugin_list.remove('fplugin')
20
21 plugin_list = filter(lambda p: p[-3:] == '.py', plugin_list)
22
23 plugins_dic = {}
24
25 for plugin in plugin_list:
26 plugin_path = os.path.join(scan_path, plugin)
27
28 try:
29
30 plugin_name = os.path.splitext(plugin)[0]
31
32 module = imp.load_source('module_fplugin_%s' % plugin_name, plugin_path)
33
34 try:
35 description = getattr(module, '__description__')
36 except AttributeError:
37 description = 'Empty'
38 sys.stderr.write(Fore.YELLOW +
39 "WARNING: Plugin missing a description. Please update it! [%s]\n" % plugin +
40 Fore.RESET)
41
42 try:
43 prettyname = getattr(module, '__prettyname__')
44 except AttributeError:
45 prettyname = plugin_name
46 sys.stderr.write(Fore.YELLOW +
47 "WARNING: Plugin missing a pretty name. Please update it! [%s]\n" % plugin +
48 Fore.RESET)
49
50 try:
51 main = getattr(module, 'main')
52 except AttributeError:
53 main = None
54 sys.stderr.write(Fore.YELLOW +
55 "WARNING: Plugin missing a main function. Please fix it! [%s]\n" % plugin +
56 Fore.RESET)
57
58 plugins_dic[plugin[:-3]] = {
59 'description': description,
60 'prettyname': prettyname,
61 'main': main
62 }
63
64 except Exception:
65 sys.stderr.write("Unable to import module %s\n" % plugin_path)
66
67 return plugins_dic
68
69
70 def build_faraday_plugin_command(plugin, workspace_name, absolute_path=False):
71 faraday_directory = os.path.dirname(os.path.realpath(os.path.join(__file__, "../")))
72 path = os.path.join(faraday_directory, "bin/")
73
74 return '{path}fplugin {command} -u {url} -w {workspace} '.format(
75 path='"%s"' % path if absolute_path else '',
76 command=plugin,
77 url=CONF.getCouchURI(),
78 workspace=workspace_name
79 )
166166 ipv6_address=ipv6_address, ipv6_prefix=ipv6_prefix,
167167 ipv6_gateway=ipv6_gateway, ipv6_dns=ipv6_dns,
168168 network_segment=network_segment,
169 hostname_resolution=hostname_resolution, parent_id=host_id)
169 hostnames=hostname_resolution, parent_id=host_id)
170170
171171 int_obj._metadata.creator = self.id
172172 self.__addPendingAction(modelactions.ADDINTERFACE, host_id, int_obj)
1919 from BaseHTTPServer import BaseHTTPRequestHandler
2020 from StringIO import StringIO
2121 from urlparse import urlparse
22 from collections import defaultdict
2223
2324 from plugins.plugin import PluginTerminalOutput
2425
235236
236237 return users
237238
239 def _get_log_message(self, line):
240 """Return the message of a log line.
241
242 If the line isn't from the log it will raise a ValueError
243
244 >>> line = '[16:59:03] [INFO] fetching tables'
245 >>> self._get_log_message('line')
246 'fetching tables'
247 """
248 match = re.match(r'\[[0-9:]+\] \[\w+\] (.+)$', line)
249 if match is None:
250 raise ValueError('Incorrect format of line')
251 return match.group(1)
252
253 def _is_log_and_startswith(self, text, line):
254 try:
255 msg = self._get_log_message(line)
256 except ValueError:
257 return False
258 else:
259 return msg.startswith(text)
260
261 def _is_tables_log_line(self, line):
262 # [16:59:03] [INFO] fetching tables for databases: 'bWAPP, ...
263 return self._is_log_and_startswith('fetching tables for databases',
264 line)
265
266 def _is_columns_log_line(self, line):
267 # [16:59:03] [INFO] fetching columns for table ...
268 return self._is_log_and_startswith('fetching columns for table ',
269 line)
270
271 def _match_start_get_remaining(self, start, text):
272 """
273 If text starts with start, return text with start stripped.
274
275 Return None if it doesn't match.
276 """
277 if not text.startswith(start):
278 return
279 return text[len(start):]
280
281 def gettables(self, data):
282 """
283 Return enumerated tables of the remote database.
284 """
285 tables = defaultdict(list) # Map database names with its tables
286 current_database = None
287 status = 'find_log_line'
288 list_found = False
289 for line in data.splitlines():
290 if status == 'find_log_line':
291 # Look for the correct log line to start searching databases
292 if self._is_tables_log_line(line):
293 # Correct line, change status
294 status = 'find_dbname'
295 elif self._is_log_and_startswith('', line) and list_found:
296 # If another log line is reached, stop looking
297 break
298 elif status == 'find_dbname':
299 database = self._match_start_get_remaining('Database: ', line)
300 if database is not None:
301 current_database = database
302 list_found = True
303 status = 'find_list_start'
304 elif status == 'find_list_start':
305 # Find +--------------+ line
306 if re.match(r'^\+\-+\+$', line):
307 # Line found
308 status = 'find_tables'
309 elif status == 'find_tables':
310 if line.startswith('|') and line.endswith('|'):
311 table = line[1:-1].strip()
312 tables[current_database].append(table)
313 elif re.match(r'^\+\-+\+$', line):
314 # Table list for this db ended
315 status = 'find_dbname'
316 else:
317 raise RuntimeError('unknown status')
318 return tables
319
320 def getcolumns(self, data):
321 """
322 Return enumerated columns of the remote database.
323 """
324 columns = defaultdict(lambda: defaultdict(list))
325 current_table = current_database = None
326 status = 'find_log_line'
327 list_start_count = 0
328 list_found = False
329 for line in data.splitlines():
330 if status == 'find_log_line':
331 if self._is_columns_log_line(line):
332 status = 'find_dbname'
333 elif self._is_log_and_startswith('', line) and list_found:
334 # Don't accept log lines if the DB dump started
335 break
336 elif status == 'find_dbname':
337 database = self._match_start_get_remaining('Database: ', line)
338 if database is not None:
339 list_found = True
340 current_database = database
341 status = 'find_table_name'
342 elif status == 'find_table_name':
343 table = self._match_start_get_remaining('Table: ', line)
344 if database is not None:
345 current_table = table
346 status = 'find_two_list_starts'
347 elif status == 'find_two_list_starts':
348 if re.match(r'^\+[\-\+]+\+$', line):
349 list_start_count += 1
350 if list_start_count == 2:
351 # Start fetching columns
352 list_start_count = 0
353 status = 'find_columns'
354 elif status == 'find_columns':
355 if line.startswith('|') and line.endswith('|'):
356 (name, type_) = [val.strip()
357 for val in line[1:-1].split('|')]
358 columns[current_database][current_table].append(
359 (name, type_))
360 elif re.match(r'^\+[\-\+]+\+$', line):
361 status = 'find_dbname'
362 else:
363 raise RuntimeError('unknown status')
364 return columns
365
238366 def getAddress(self, hostname):
239367 """
240368 Returns remote IP address from hostname.
261389 from lib.core.settings import UNICODE_ENCODING
262390 except:
263391 print 'ERROR: Remember set your Sqlmap Path Setting!... Abort plugin.'
264 sys.exit(-1)
392 return
265393
266394 self.HASHDB_MILESTONE_VALUE = HASHDB_MILESTONE_VALUE
267395 self.HASHDB_KEYS = HASHDB_KEYS
275403
276404 users = self.getuser(output)
277405 dbs = self.getdbs(output)
406 tables = self.gettables(output)
407 columns = self.getcolumns(output)
278408
279409 db = Database(self._output_path)
280410 db.connect()
282412 absFilePaths = self.hashDBRetrieve(
283413 self.HASHDB_KEYS.KB_ABS_FILE_PATHS, True, db)
284414
285 tables = self.hashDBRetrieve(
415 brute_tables = self.hashDBRetrieve(
286416 self.HASHDB_KEYS.KB_BRUTE_TABLES, True, db)
287417
288 columns = self.hashDBRetrieve(
418 brute_columns = self.hashDBRetrieve(
289419 self.HASHDB_KEYS.KB_BRUTE_COLUMNS, True, db)
290420
291421 xpCmdshellAvailable = self.hashDBRetrieve(
294424 dbms_version = self.hashDBRetrieve(self.HASHDB_KEYS.DBMS, False, db)
295425
296426 self.ip = self.getAddress(self.hostname)
297
427
298428 h_id = self.createAndAddHost(self.ip)
299429
300430 i_id = self.createAndAddInterface(
349479 if password:
350480 for k, v in password.iteritems():
351481 self.createAndAddCredToService(h_id, s_id2, k, v)
352
482
353483 # sqlmap.py --file-dest
354484 if absFilePaths:
355485 self.createAndAddNoteToService(
356486 h_id,
357487 s_id2,
358488 "sqlmap.absFilePaths",
359 str(absFilePaths))
489 '\n'.join(absFilePaths))
360490
361491 # sqlmap.py --common-tables
362 if tables:
363 for item in tables:
492 if brute_tables:
493 for item in brute_tables:
364494 self.createAndAddNoteToService(
365495 h_id,
366496 s_id2,
367497 "sqlmap.brutetables",
368498 item[1])
369499
500 # sqlmap.py --tables
501 if tables:
502 table_names = ['{}.{}'.format(db_name, table)
503 for (db_name, db_tables) in tables.items()
504 for table in db_tables]
505 self.createAndAddNoteToService(
506 h_id,
507 s_id2,
508 "sqlmap.tables",
509 '\n'.join(table_names)
510 )
511
512 # sqlmap.py --columns
513 if columns:
514 # Create one note per database
515 for (database, tables) in columns.items():
516 text = ''
517 for (table_name, columns) in tables.items():
518 columns_text = ', '.join(
519 '{} {}'.format(col_name, type_)
520 for (col_name, type_) in columns)
521 text += '{}: {}\n'.format(table_name, columns_text)
522 self.createAndAddNoteToService(
523 h_id,
524 s_id2,
525 "sqlmap.columns." + database,
526 text)
527
370528 # sqlmap.py --common-columns
371 if columns:
529 if brute_columns:
372530
373531 text = (
374 'Db: ' + columns[0][0] +
375 '\nTable: ' + columns[0][1] +
532 'Db: ' + brute_columns[0][0] +
533 '\nTable: ' + brute_columns[0][1] +
376534 '\nColumns:')
377535
378 for element in columns:
536 for element in brute_columns:
379537 text += str(element[2]) + '\n'
380538
381539 self.createAndAddNoteToService(
398556 h_id,
399557 s_id2,
400558 "db.databases",
401 str(dbs))
559 '\n'.join(dbs))
402560
403561 for inj in self.hashDBRetrieve(self.HASHDB_KEYS.KB_INJECTIONS, True, db) or []:
404562
440598
441599 if args.u:
442600
443 if args.u.find('http://') < 0 or args.u.find('https://') < 0:
601 if args.u.find('http://') < 0 and args.u.find('https://') < 0:
444602 urlComponents = urlparse('http://' + args.u)
445603 else:
446604 urlComponents = urlparse(args.u)
447605
448 self.protocol = urlComponents.scheme
606 self.protocol = urlComponents.scheme
449607 self.hostname = urlComponents.netloc
450608
451609 if urlComponents.port:
77 tornado
88 flask
99 colorama
10 #extra
11 psycopg2
0 beautifulsoup4
1 psycopg2
2 w3af_api_client
55 ###
66
77 config = {
8 #Default setup
9 'CS_CATEGORIES': 'network,web',
10 'CS_SCRIPTS': 'nmap.sh,openvas.sh,nikto.sh,nessus.sh,w3af.sh',
811 #NMAP
912 'CS_NMAP' : "nmap",
13 'CS_NMAP_ARGS' : "-O",
1014 #OPENVAS
1115 'CS_OPENVAS_USER' : 'admin',
1216 'CS_OPENVAS_PASSWORD' : 'openvas',
1721 'CS_BURP' : '/root/tools/burpsuite_pro_v1.6.26.jar',
1822 #NIKTO
1923 'CS_NIKTO' : "nikto",
24 'CS_NIKTO_ARGS' : "",
2025 #W3AF
2126 'CS_W3AF' : "/root/tools/w3af/w3af_api",
2227 'CS_W3AF_PROFILE' : "/root/tools/w3af/profiles/fast_scan.pw3af",
2732 'CS_NESSUS_USER' : "nessus",
2833 'CS_NESSUS_PASS' : "nessus",
2934 'CS_NESSUS_PROFILE' : "Basic Network Scan",
35 # MSFRPC
36 'CS_MSF_TMP_WS' : 'enabled',
37 'CS_MSF_EXPORT' : 'enabled',
3038 }
31
1212 from config import config
1313
1414 def lockFile(lockfile):
15
1615 if os.path.isfile(lockfile):
1716 return False
1817 else:
2019 f.close()
2120 return True
2221
22 def target_list(script, categories):
23 dictionary = {
24 "network": "ips.txt",
25 "web": "websites.txt",
26 "extra": "ips.txt"
27 }
28
29 category = 'network'
30 for c in categories:
31 if os.path.exists(os.path.join('scripts', c, script)):
32 return dictionary[c]
33
2334 def main():
24
2535 lockf = ".lock.pod"
2636 if not lockFile(lockf):
2737 print "You can run only one instance of cscan (%s)" % lockf
3040 my_env = os.environ
3141 env = config.copy()
3242 env.update(my_env)
33 #Parser argument in command line
43
3444 parser = argparse.ArgumentParser(description='continues scanning on Faraday')
35 parser.add_argument('-p','--plugin', help='Scan only the following plugin ej: ./cscan.py -p nmap.sh', required=False)
45 parser.add_argument('-s','--script', help='Scan only the following script ej: ./cscan.py -p nmap.sh', required=False)
46 parser.add_argument('-S','--scripts', help='Scan the following scripts list ej: ./cscan.py -p nmap.sh,nikto.sh', required=False)
47 parser.add_argument('-c','--category', help='Scan only for given category ej: ./cscan.py -c network', required=False)
48 parser.add_argument('-t','--targets', help='Choose a custom target list ej: ./cscan.py -t custom-list.txt', required=False)
49 parser.add_argument('-o','--output', help='Choose a custom output directory', required=False)
50 parser.add_argument('-l','--log', help='Choose a custom log directory', required=False)
3651 args = parser.parse_args()
3752
38 for dirpath, dnames, fnames in os.walk("./scripts/web/"):
39 for f in fnames:
40 if args.plugin and args.plugin != f:
41 continue
42 script = os.path.join(dirpath, f)
43 cmd = "%s websites.txt output/" % (script)
44 print "Running: %s" % cmd
45 proc = subprocess.call(cmd, shell=True, stdin=None, stderr=subprocess.PIPE, env=dict(env))
53 output = 'output/'
54 if args.output:
55 output = args.output
4656
47 for dirpath, dnames, fnames in os.walk("./scripts/network/"):
48 for f in fnames:
49 if args.plugin and args.plugin != f:
50 continue
51 script = os.path.join(dirpath, f)
52 cmd = "%s ips.txt output/" % (script)
53 print "Running: %s" % cmd
54 proc = subprocess.call(cmd, shell=True, stdin=None, stderr=subprocess.PIPE, env=dict(env))
57 logdir = 'log/'
58 if args.log:
59 logdir = args.log
5560
56 #Remove lockfile
61 for d in [logdir, output]:
62 if not os.path.isdir(d):
63 os.makedirs(d)
64
65 if args.script:
66 scripts = [args.script]
67 elif args.scripts:
68 scripts = args.scripts.split(",")
69 else:
70 scripts = env["CS_SCRIPTS"].split(",")
71
72 categories = env["CS_CATEGORIES"].split(",")
73 for category in categories:
74 env["PATH"] += ":%s" % os.path.abspath("./scripts/" + category)
75
76 for script in scripts:
77 if args.targets:
78 targets = args.targets
79 else:
80 targets = target_list(script, categories)
81
82 cmd = "%s %s %s %s" % (script, targets, output, logdir)
83 print "\n\nRunning: %s" % cmd
84 proc = subprocess.call(cmd, shell=True, stdin=None, env=dict(env))
85
86 #Remove lockfile
5787 os.remove(lockf)
5888
5989 if __name__ == "__main__":
60 main()
90 main()
+0
-24
scripts/cscan/output/nmap_1442987141.xml less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE nmaprun>
2 <?xml-stylesheet href="file:///usr/bin/../share/nmap/nmap.xsl" type="text/xsl"?>
3 <!-- Nmap 6.49BETA4 scan initiated Wed Sep 23 02:45:41 2015 as: nmap -iL ips.txt -oX output/nmap_1442987141.xml -->
4 <nmaprun scanner="nmap" args="nmap -iL ips.txt -oX output/nmap_1442987141.xml" start="1442987141" startstr="Wed Sep 23 02:45:41 2015" version="6.49BETA4" xmloutputversion="1.04">
5 <scaninfo type="syn" protocol="tcp" numservices="1000" services="1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389"/>
6 <verbose level="0"/>
7 <debugging level="0"/>
8 <host starttime="1442987141" endtime="1442987142"><status state="up" reason="localhost-response" reason_ttl="0"/>
9 <address addr="127.0.0.1" addrtype="ipv4"/>
10 <hostnames>
11 <hostname name="localhost" type="PTR"/>
12 </hostnames>
13 <ports><extraports state="closed" count="998">
14 <extrareasons reason="resets" count="998"/>
15 </extraports>
16 <port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="ssh" method="table" conf="3"/></port>
17 <port protocol="tcp" portid="5432"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="postgresql" method="table" conf="3"/></port>
18 </ports>
19 <times srtt="3" rttvar="1" to="100000"/>
20 </host>
21 <runstats><finished time="1442987142" timestr="Wed Sep 23 02:45:42 2015" elapsed="1.69" summary="Nmap done at Wed Sep 23 02:45:42 2015; 1 IP address (1 host up) scanned in 1.69 seconds" exit="success"/><hosts up="1" down="0" total="1"/>
22 </runstats>
23 </nmaprun>
0 #!/usr/bin/env python2
1
2 import os
3 import time
4 import string
5 import random
6 import argparse
7 import msgpack
8 import httplib
9 import ssl
10
11
12 class Msfrpc:
13 """ Msfrpc class from https://github.com/SpiderLabs/msfrpc """
14
15 class MsfError(Exception):
16 def __init__(self, msg):
17 self.msg = msg
18
19 def __str__(self):
20 return repr(self.msg)
21
22 class MsfAuthError(MsfError):
23 def __init__(self, msg):
24 self.msg = msg
25
26 def __init__(self, opts=[]):
27 self.host = opts.get("host") or "127.0.0.1"
28 self.port = opts.get("port") or 55552
29 self.uri = opts.get("uri") or "/api/"
30 self.ssl = opts.get("ssl") or False
31 self.authenticated = False
32 self.token = False
33 self.headers = {"Content-type": "binary/message-pack"}
34 if self.ssl:
35 self.client = httplib.HTTPSConnection(self.host, self.port, context=ssl._create_unverified_context())
36 else:
37 self.client = httplib.HTTPConnection(self.host, self.port)
38
39 def encode(self, data):
40 return msgpack.packb(data)
41
42 def decode(self, data):
43 return msgpack.unpackb(data)
44
45 def call(self, meth, opts=[]):
46 if meth != "auth.login":
47 if not self.authenticated:
48 raise self.MsfAuthError("MsfRPC: Not Authenticated")
49 opts.insert(0, self.token)
50
51 opts.insert(0, meth)
52 params = self.encode(opts)
53 self.client.request("POST", self.uri,params, self.headers)
54 resp = self.client.getresponse()
55 return self.decode(resp.read())
56
57 def login(self, user, password):
58 ret = self.call("auth.login", [user, password])
59 if ret.get("result") == "success":
60 self.authenticated = True
61 self.token = ret.get("token")
62 return True
63 else:
64 raise self.MsfAuthError("MsfRPC: Authentication failed")
65
66
67 class CscanMsf:
68 """ msfrpc plugin for cscan """
69 def __init__(self, client, logfile=False, quiet=False):
70 self.logfile = logfile
71 self.cid = None
72 self.quiet = quiet
73 self.client = client
74
75 def check_auth(self):
76 if not self.client or not self.client.authenticated:
77 self.log("ERROR: You are not authenticated..", True)
78 return False
79 return True
80
81 def log(self, msg, critical=False):
82 if self.logfile:
83 logfile = open(self.logfile, "a")
84 logfile.write("%s\n" % msg)
85 logfile.close()
86 if not self.quiet or critical:
87 print msg
88
89 def rpc_call(self, meth, opts, key=""):
90 if self.check_auth():
91 res = self.client.call(meth, opts)
92
93 if "error" in res:
94 self.log("ERROR: %s %s" % (res.get("error_code"), res.get("error_message")), True)
95 self.log("%s: %s\n%s" % (res.get("error_class"), res.get("error_string"), res.get("error_backtrace")))
96 return res
97 return res if not key else res.get(key)
98
99 def create_console(self):
100 self.cid = self.rpc_call("console.create", [{}], "id")
101 self.rpc_call("console.read", [self.cid])
102 self.log("Created console ID " + str(self.cid), True)
103 return self.cid
104
105 def destroy_console(self):
106 self.log("Destroy console ID %s.. %s" % (self.cid, self.rpc_call("console.destroy",
107 [self.cid], "result")), True)
108
109 def create_ws(self, ws, switch=False):
110 self.log("Create %s workspace.. %s" % (ws, self.rpc_call("db.add_workspace", [ws], "result")), True)
111 if switch:
112 self.set_ws(ws)
113 return ws
114
115 def set_ws(self, ws):
116 self.log("Switch to %s workspace.. %s" % (ws, self.rpc_call("db.set_workspace", [ws], "result")), True)
117
118 def destroy_ws(self, ws):
119 self.log("Delete %s workspace.. %s" % (ws, self.rpc_call("db.del_workspace", [ws], "result")), True)
120
121 def import_xml_data(self, ws, xml):
122 content = open(xml, "r").read()
123 self.log("Importing data from %s.. %s" % (xml, self.rpc_call("db.import_data", [{"workspace": ws,
124 "data": content}], "result")), True)
125
126 def export_current_ws(self, out):
127 self.log("Exporting workspace..", True)
128 self.rpc_call("console.write", [self.cid, "db_export %s\r\n" % out])
129
130 while True:
131 time.sleep(5)
132 res = self.rpc_call("console.read", [self.cid])
133 if res.get("data"):
134 self.log("%s %s" % (res.get("prompt"), res.get("data")))
135 if "Finished export" in res.get("data"):
136 return True
137
138 def wait_for_jobs(self):
139 while True:
140 job_list = self.rpc_call("job.list", [])
141 self.log("Current jobs: %s (Total: %d)" % (",".join(job_list), len(job_list)), True)
142 if len(job_list) > 0:
143 for j in job_list:
144 jinfo = self.rpc_call("job.info", [j])
145 self.log("%s - %s" % (jinfo.get("jid"), jinfo.get("name")), True)
146 else:
147 return True
148 time.sleep(10)
149
150 def run_commands(self, commands):
151 self.log("Deploy following commands: \n%s" % " msf> " + "\n msf> ".join(commands), True)
152 self.rpc_call("console.write", [self.cid, "\n".join(commands)])
153 self.rpc_call("console.write", [self.cid, "set PROMPT commands_deployed\r\n"])
154
155 while True:
156 time.sleep(2)
157 res = self.rpc_call("console.read", [self.cid])
158 if res.get("data"):
159 self.log("%s %s" % (res.get("prompt"), res.get("data")))
160 if "commands_deployed" in res["prompt"] and not res["busy"]:
161 self.rpc_call("console.write", [self.cid, "set PROMPT msfcscan\r\n"])
162 break
163
164 def banner(args, cws="unknown"):
165 return """ _____________________________________________________
166 | ____ ___________________________________________ |
167 | | | \/ |/ ___| ___/ __ \ | |
168 | | | . . |\ `--.| |_ | / \/___ ___ __ _ _ __ | |
169 | | | |\/| | `--. \ _| | | / __|/ __/ _` | '_ \ | |
170 | | | | | |/\__/ / | | \__/\__ \ (_| (_| | | | | | |
171 | | \_| |_/\____/\_| \____/___/\___\__,_|_| |_| | |
172 | | _____ ______ ______ _____ ______ ______ _____ | |
173 | | |_____|______|______|_____|______|______|_____| |_|
174 | |
175 | | Arguments: Current workspace: %s
176 | | > Temp workspace: %s
177 | | > Quiet mode: %s
178 | | > Command: %s
179 | | > Resource: %s
180 | | > Options: %s
181 | | > Modules: %s
182 |_| > XML import: %s
183 > Log file: %s
184 > Output file: %s
185
186 """ % (
187 cws,
188 "enabled" if not args.disable_tmp_ws else "disabled",
189 "enabled" if args.quiet else "disabled",
190 args.command,
191 args.resource,
192 "\n | | --> " + args.options.replace(":", "\n | | --> ") if args.options else None,
193 "\n | | --> " + args.modules.replace(",", "\n | | --> ") if args.modules else None,
194 args.xml,
195 args.log,
196 args.output
197 )
198
199
200 def main():
201 parser = argparse.ArgumentParser(description="msfrpc cscan plugin, for automated security testing")
202 parser.add_argument("-H","--msfrpc-host", help="Override MSFRPC_HOST envvar", required=False)
203 parser.add_argument("-P","--msfrpc-port", help="Override MSFRPC_PORT envvar", required=False)
204 parser.add_argument("-u","--msfrpc-user", help="Override MSFRPC_USER envvar", required=False)
205 parser.add_argument("-p","--msfrpc-pass", help="Override MSFRPC_PASS envvar", required=False)
206 parser.add_argument("-S","--msfrpc-ssl", help="Override MSFRPC_SSL envvar", required=False, action="store_true")
207 parser.add_argument("-U","--msfrpc-uri", help="Override MSFRPC_URI envvar", required=False)
208
209 parser.add_argument("-o","--output", help="Output file", required=False)
210 parser.add_argument("-l","--log", help="Log file", required=False)
211 parser.add_argument("-x","--xml", help="XML to import in temp workspace", required=False)
212 parser.add_argument("-m","--modules", help="Modules to use", required=False)
213 parser.add_argument("-r","--resource", help="Resource to execute", required=False)
214 parser.add_argument("-O","--options", help="Modules options", required=False)
215 parser.add_argument("-c","--command", help="Command to execute (check, run, exploit)", default="check")
216 parser.add_argument("-T","--disable-tmp-ws", help="Do not create temp workspace and use current", required=False, action="store_true")
217 parser.add_argument("-q","--quiet", help="Quiet mode, set -l options to have log in a file", required=False, action="store_true")
218
219 args = parser.parse_args()
220 try:
221 client = Msfrpc({
222 "host": args.msfrpc_host if args.msfrpc_host else os.environ.get("MSFRPC_HOST"),
223 "port": args.msfrpc_port if args.msfrpc_port else os.environ.get("MSFRPC_PORT"),
224 "uri": args.msfrpc_uri if args.msfrpc_uri else os.environ.get("MSFRPC_URI"),
225 "ssl": args.msfrpc_ssl if args.msfrpc_ssl else os.environ.get("MSFRPC_SSL") == 'true'
226 })
227 client.login(args.msfrpc_user if args.msfrpc_user else os.environ.get("MSFRPC_USER"),
228 args.msfrpc_pass if args.msfrpc_pass else os.environ.get("MSFRPC_PASS"))
229 except:
230 print "ERROR: Cannot connect to server.."
231 exit(1)
232
233 cscan = CscanMsf(client, args.log, args.quiet)
234 commands = []
235 tmp_ws = None
236 current_ws = cscan.rpc_call("db.current_workspace", [], "workspace")
237
238 print banner(args, current_ws)
239 cscan.create_console()
240
241 if not args.disable_tmp_ws and os.environ.get("CS_MSF_TMP_WS") == "enabled":
242 tmp_ws = "cscan_" + "".join(random.sample(string.lowercase,6))
243 cscan.create_ws(tmp_ws, True)
244 if args.xml:
245 cscan.import_xml_data(tmp_ws, args.xml)
246
247 if args.options:
248 for option in args.options.split(":"):
249 commands.append("setg " + option.replace("=", " "))
250 if args.modules:
251 for module in args.modules.split(","):
252 commands.append("use " + module)
253 commands.append("show options")
254 commands.append(args.command)
255 elif args.resource:
256 commands.append("resource " + args.resource)
257
258 commands.append("\r\n")
259 cscan.run_commands(commands)
260 cscan.wait_for_jobs()
261
262 if os.environ.get("CS_MSF_EXPORT") == "enabled" and args.output:
263 cscan.export_current_ws(args.output)
264
265 cscan.destroy_console()
266
267 if tmp_ws:
268 cscan.set_ws(current_ws)
269 cscan.destroy_ws(tmp_ws)
270
271 if __name__ == "__main__":
272 main()
0 #!/usr/bin/env python
0 #!/usr/bin/env python2
11 ###
22 ## Faraday Penetration Test IDE
33 ## Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/)
2020 verify = False
2121 token = ''
2222
23
2324 def build_url(resource):
2425 return '{0}{1}'.format(url, resource)
2526
260261
261262 if __name__ == "__main__":
262263 parser = argparse.ArgumentParser(description='nessus_client is develop for automating security testing')
263 parser.add_argument('-t','--target', help='Network or Host for scan', required=False)
264 parser.add_argument('-o','--output', help='Output file', required=False)
264 parser.add_argument('-t', '--target', help='Network or Host for scan', required=False)
265 parser.add_argument('-o', '--output', help='Output file', required=False)
265266 args = parser.parse_args()
266267
267268 # Review de Command input
268 if args.target == None or args.output == None:
269 print "Argument errors check -h"
270 exit(0)
269 if args.target is None or args.output is None:
270 print "Argument errors check -h"
271 exit(0)
271272
272273 print('Login')
273274 try:
276277 print "Unexpected error:", sys.exc_info()[0]
277278 raise
278279
279
280280 print('Adding new scan.' + token)
281281 print args.target
282
282
283283 policies = get_policies()
284284 policy_id = policies[profile]
285285 scan_data = add('CScan nessus', 'Create a new scan with API', args.target, policy_id)
289289 scan_uuid = launch(scan_id)
290290 history_ids = get_history_ids(scan_id)
291291 history_id = history_ids[scan_uuid]
292 while status(scan_id, history_id) not in ('completed','canceled'):
292 while status(scan_id, history_id) not in ('completed', 'canceled'):
293293 time.sleep(5)
294
295294
296295 print('Exporting the completed scan.')
297296 file_id = export(scan_id, history_id)
302301 delete(scan_id)
303302
304303 print('Logout')
305 logout()
304 logout()
0 #!/usr/bin/env python
1 ###
2 ## Faraday Penetration Test IDE
3 ## Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/)
4 ## See the file 'doc/LICENSE' for the license information
5 ###
0 #!/usr/bin/env python2
1
2 # Faraday Penetration Test IDE
3 # Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/)
4 # See the file 'doc/LICENSE' for the license information
65
76 from w3af_api_client import Connection, Scan
87 import subprocess
1413 import atexit
1514 child_pid = None
1615
16
1717 def kill_child():
1818 global child_pid
1919 if child_pid is None:
2020 pass
2121 else:
2222 os.kill(child_pid, signal.SIGTERM)
23
2324
2425 def main():
2526 atexit.register(kill_child)
2829 cmd = my_env["CS_W3AF"] if 'CS_W3AF' in my_env else "/root/tools/w3af/w3af_api"
2930 profile = my_env["CS_W3AF_PROFILE"] if 'CS_W3AF_PROFILE' in my_env else "/root/tools/w3af/profiles/fast_scan.pw3af"
3031
31 #Parser argument in command line
32 # Parser argument in command line
3233 parser = argparse.ArgumentParser(description='w3af_client is develop for automating security testing')
33 parser.add_argument('-t','--target', help='Network or Host for scan', required=False)
34 parser.add_argument('-o','--output', help='Output file', required=False)
34 parser.add_argument('-t', '--target', help='Network or Host for scan', required=False)
35 parser.add_argument('-o', '--output', help='Output file', required=False)
3536 args = parser.parse_args()
3637
37 if args.target == None or args.output == None:
38 print "Argument errors check -h"
39 exit(0)
38 if args.target is None or args.output is None:
39 print "Argument errors check -h"
40 exit(0)
4041
4142 print 'Starting w3af api ...'
4243 global child_pid
5152 print conn.get_version()
5253
5354 # Define the target and configuration
54 #scan_profile = file('/root/tools/w3af/profiles/fast_scan_xml.pw3af').read()
55 # scan_profile = file('/root/tools/w3af/profiles/fast_scan_xml.pw3af').read()
5556 scan_profile = file(profile).read()
5657 scan_profile = "[output.xml_file]\noutput_file = %s\n%s\n" % (args.output, scan_profile )
5758 # scan_profile = file('/root/tools/w3af/profiles/fast_scan.pw3af').read()
7273 time.sleep(2)
7374
7475 if __name__ == "__main__":
75 main()
76 main()
0 #!/usr/bin/env python
0 #!/usr/bin/env python2
11 ###
22 ## Faraday Penetration Test IDE
33 ## Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/)
1818 import atexit
1919 child_pid = None
2020
21
2122 def kill_child():
2223 global child_pid
2324 if child_pid is None:
2425 pass
2526 else:
2627 os.kill(child_pid, signal.SIGTERM)
28
2729
2830 def is_http_url(page):
2931 """
3638 else:
3739 return False
3840
41
3942 def exportfile(filename,zap):
43
4044 #Output for XML Report
4145 print 'Generating XML Report...'
42 filex=open(filename, 'w')
46 filex = open(filename, 'w')
4347 filex.write(zap.core.xmlreport)
44 filex.close()
48 filex.close()
49
4550
4651 def main():
4752
5055 my_env = os.environ
5156 cmd = my_env["CS_ZAP"] if 'CS_ZAP' in my_env else "/usr/share/zaproxy/zap.sh"
5257
53 #Parser argument in command line
58 # Parser argument in command line
5459 parser = argparse.ArgumentParser(description='PyZap is develop for automating security testing')
55 parser.add_argument('-t','--target', help='Network or Host for scan', required=False)
56 parser.add_argument('-o','--output', help='Output file', required=False)
60 parser.add_argument('-t', '--target', help='Network or Host for scan', required=False)
61 parser.add_argument('-o', '--output', help='Output file', required=False)
5762 args = parser.parse_args()
5863
5964 # Review de Command input
60 if args.target == None:
65 if args.target is None:
6166 # Do nothing
6267 # Input data for test
6368 target = raw_input('[+] Enter your target: ')
64 if is_http_url(target) == True:
69 if is_http_url(target) is True:
6570 print '[-] Target selected: ', target
6671 else:
6772 print '[w] Please type a correct URL address'
6873 quit()
6974 else:
7075 # Check for valid URL addres
71 if is_http_url(args.target) == True:
76 if is_http_url(args.target) is True:
7277 target = args.target
7378 print '[-] Target selected: ', target
7479 else:
7782 print 'Starting ZAP ...'
7883
7984 global child_pid
80 proc = subprocess.Popen([cmd,'-daemon'])
85 proc = subprocess.Popen([cmd, '-daemon'])
8186 child_pid = proc.pid
8287
8388 print 'Waiting for ZAP to load, 10 seconds ...'
98103 zap.spider.scan(target)
99104 # Give the Spider a chance to start
100105 time.sleep(2)
101 #print 'Status %s' % zap.spider.status
106 # print 'Status %s' % zap.spider.status
102107 while(int(zap.spider.status) < 100):
103108 print 'Spider progress %: ' + zap.spider.status
104109 time.sleep(2)
120125 print 'Hosts: ' + ', '.join(zap.core.hosts)
121126 # print 'Alerts: '
122127 # pprint (zap.core.alerts())
123 #pprint (zap.core.xmlreport())
128 # pprint (zap.core.xmlreport())
124129 exportfile(args.output,zap)
125130
126131 print 'Shutting down ZAP ...'
128133 #EOF
129134
130135 if __name__ == "__main__":
131 main()
136 main()
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource auto_cred_checker.rc \
14 --options THREADS=100
15
16 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource auto_brute.rc \
14 --options THREADS=100
15
16 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 modules_file=msf-modules.txt
4
5 if ! test -f $xml; then
6 echo XML file $xml not found
7 exit 1
8 elif ! test -f $modules_file; then
9 echo no modules file found
10 exit 2
11 fi
12
13 while read m; do
14 NAME="$(date +%s)-$(basename $0)"
15 echo "Run msfrpc plugin.."
16 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
17 --log $(realpath $3$NAME.log) \
18 --xml $xml \
19 --resource autoexploit.rc \
20 --options MODE=check:MODULE=$m
21 done <$modules_file
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 modules_file=msf-modules.txt
4
5 if ! test -f $xml; then
6 echo XML file $xml not found
7 exit 1
8 elif ! test -f $modules_file; then
9 echo no modules file found
10 exit 2
11 fi
12
13 while read m; do
14 NAME="$(date +%s)-$(basename $0)"
15 echo "Run msfrpc plugin.."
16 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
17 --log $(realpath $3$NAME.log) \
18 --xml $xml \
19 --resource autoexploit.rc \
20 --options MODE=dry:MODULE=$m
21 done <$modules_file
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 modules_file=msf-modules.txt
4
5 if ! test -f $xml; then
6 echo XML file $xml not found
7 exit 1
8 elif ! test -f $modules_file; then
9 echo no modules file found
10 exit 2
11 fi
12
13 while read m; do
14 NAME="$(date +%s)-$(basename $0)"
15 echo "Run msfrpc plugin.."
16 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
17 --log $(realpath $3$NAME.log) \
18 --xml $xml \
19 --resource autoexploit.rc \
20 --options MODE=exploit:MODULE=$m
21 done <$modules_file
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource $(realpath scripts/resources/autosploit.rc) \
14 --options THREADS=100:TARGET_PLATFORM=aix,android,bsdi,dialup,firefox,freebsd,hpux,irix,linux,mainframe,multi,netware,solaris,unix,windows:BLACKLIST=freebsd/samba/trans2open,linux/samba/trans2open,osx/samba/trans2open,solaris/samba/trans2open
15
16 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 modules_file=msf-modules.txt
3 if ! test -f $modules_file; then
4 echo no modules file found
5 exit 1
6 fi
7
8 while read h; do
9 NAME="$(date +%s)-$(basename $0)-$h"
10 echo "Run msfrpc plugin.."
11 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
12 --log $(realpath $3$NAME.log) \
13 --modules $(sed ':a;N;$!ba;s/\n/,/g' $modules_file) \
14 --options RHOSTS=$h:RHOST=$h \
15 --command=run
16 done <$1
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource mssql_brute.rc \
14 --options THREADS=100
15
16 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --resource nessus_vulns_cleaner.rc \
13 --xml $xml
14
15 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log)
12 --resource port_cleaner.rc \
13 --xml $xml
14
15 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource $(realpath scripts/resources/autoscan.rc) \
14 --options MAX_LEN=100:THREADS=100:BLACKLIST=scanner/telnet/brocade_enable_login,scanner/rogue/rogue_recv \
15 --quiet
16
17 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 NAME="$(date +%s)-$(basename $0)"
3 echo "Run msfrpc plugin.."
4 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
5 --log $(realpath $3$NAME.log) \
6 --resource basic_discovery.rc \
7 --options THREADS=100:NMAP=true:NMAPOPTS="$CS_NMAP_ARGS":RHOSTS=$(sed ':a;N;$!ba;s/\n/,/g' $1)
8
9 cp $2$NAME.xml msf-workspace.xml
0 #!/bin/bash
1
2 NAME="$(date +%s)-$(basename $0)"
3 echo "Run msfrpc plugin.."
4 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
5 --log $(realpath $3$NAME.log) \
6 --resource basic_discovery.rc \
7 --options THREADS=100:NMAP=false:RHOSTS=$(sed ':a;N;$!ba;s/\n/,/g' $1)
8
9 cp $2$NAME.xml msf-workspace.xml
0 #!/bin/bash
1
2 NAME="$(date +%s)-$(basename $0)"
3 echo "Run msfrpc plugin.."
4 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
5 --log $(realpath $3$NAME.log) \
6 --resource portscan.rc \
7 --options THREADS=100:NMAP=true:NMAPOPTS=$CS_NMAP_ARGS:RHOSTS=$(sed ':a;N;$!ba;s/\n/,/g' $1)
8
9 cp $2$NAME.xml msf-workspace.xml
0 #!/bin/bash
1
2 NAME="$(date +%s)-$(basename $0)"
3 echo "Run msfrpc plugin.."
4 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
5 --log $(realpath $3$NAME.log) \
6 --resource portscan.rc \
7 --options THREADS=100:NMAP=false:RHOSTS=$(sed ':a;N;$!ba;s/\n/,/g' $1)
8
9 cp $2$NAME.xml msf-workspace.xml
55 ###
66
77 NAME="nmap_$(date +%s).xml"
8 ${CS_NMAP:=nmap} -iL $1 -oX $2$NAME
8 ${CS_NMAP:=nmap} $CS_NMAP_ARGS -iL $1 -oX $2$NAME
6262
6363 echo "Processing target $h..."
6464
65 #echo $CS_OMP -u $USER_NAME -w $USER_PASSWORD --xml=\
65 echo $CS_OMP -u $USER_NAME -w $USER_PASSWORD --xml=\
6666 "<create_target>\
6767 <name>TARG$(date +%s)</name><hosts>$h</hosts>\
6868 <alive_tests>$ALIVE_TEST</alive_tests>\
0 # autoscan.rc
1 # Author: Sliim (Github: @Sliim / Twitter: @_Sliim_)
2
3 # This Metasploit resource script will run several auxiliary scanners
4 # against present hosts in current workspace. It get all services for
5 # all hosts, and try to find auxiliary modules starting with `scanner/`
6 # where default RPORT option match with a service.
7 # We can blacklist some modules we don't want, the BLACKLIST option
8 # is a comma separated list of module to disable.
9
10 <ruby>
11 begin
12 framework.db.hosts
13 rescue ::ActiveRecord::ConnectionNotEstablished
14 print_error("Database connection isn't established")
15 return
16 end
17
18 # Check for blacklisted modules
19 blacklist = []
20 if (framework.datastore['BLACKLIST'] != nil)
21 blacklist = framework.datastore['BLACKLIST'].split(',')
22 end
23
24 scanners = {}
25 count = 0
26 ran = 0
27
28 print_status("Getting scanners list, this may take a while...")
29 framework.db.hosts.each do |host|
30 port_list = []
31 scanners[host.address] = []
32 print_status("Host: #{host.address} - #{host.os_name}")
33 print_status("Services: ")
34 host.services.each do |serv|
35 next if not serv.host
36 next if (serv.state != Msf::ServiceState::Open)
37 print_status("> :#{serv.port.to_i} - #{serv.proto} - #{serv.name}")
38 port_list << serv.port.to_i if not port_list.include? serv.port.to_i
39 end
40
41 framework.modules.auxiliary.each do |name, mod|
42 next if blacklist.include? name
43 next if not name.starts_with? "scanner/"
44 next unless mod
45 m = mod.new
46 next unless m.datastore.has_key? 'RPORT'
47 if port_list.include? m.datastore['RPORT'].to_i
48 scanners[host.address] << name
49 count += 1
50 end
51 end
52 end
53
54 print_status("Ok! Launching #{count} scanners..")
55 scanners.each do |host, s|
56 s.each do |scanner|
57 print_line("[#{ran+1}/#{count}] Deploying auxiliary #{scanner} against #{host}")
58 run_single("use #{scanner}")
59 run_single("set RHOSTS #{host}")
60 run_single("show options")
61 run_single("run")
62 ran += 1
63 end
64 end
65
66 print_status("Done. Deployed #{ran} scanners.")
67 </ruby>
0 # autosploit.rc
1 # Author: Sliim (Github: @Sliim / Twitter: @_Sliim_)
2
3 # This Metasploit resource script will run several exploits against
4 # present hosts in current workspace. It get all services for all hosts,
5 # and try to find exploits where default RPORT option match with a service.
6 # We can blacklist some modules we don't want, the BLACKLIST option is a
7 # comma separated list of module to disable.
8 # The TARGET_PLATFORM option can be used to define which platform we target
9 # (ex: if all hosts are linux os, no need to launch windows exploits).
10 # Tested on metasploitable 2. Got 6/7 shells without effort :)
11
12 <ruby>
13 begin
14 framework.db.hosts
15 rescue ::ActiveRecord::ConnectionNotEstablished
16 print_error("Database connection isn't established")
17 return
18 end
19
20 # Check for target platform list
21 if (framework.datastore['TARGET_PLATFORM'] == nil)
22 run_single("setg TARGET_PLATFORM aix,android,apple_ios,bsdi,dialup,firefox,freebsd,hpux,irix,linux,mainframe,multi,netware,osx,solaris,unix,windows")
23 end
24
25 # Check for blacklisted modules
26 blacklist = []
27 if (framework.datastore['BLACKLIST'] != nil)
28 blacklist = framework.datastore['BLACKLIST'].split(',')
29 end
30
31 sploits = {}
32 count = 0
33 ran = 0
34
35 print_status("Getting vulns list, this may take a while...")
36 framework.db.hosts.each do |host|
37 port_list = []
38 sploits[host.address] = []
39 print_status("Host: #{host.address} - #{host.os_name}")
40 print_status("Services: ")
41 host.services.each do |serv|
42 next if not serv.host
43 next if (serv.state != Msf::ServiceState::Open)
44 print_status("> :#{serv.port} - #{serv.proto} - #{serv.name}")
45 port_list << serv.port.to_i if not port_list.include? serv.port.to_i
46 end
47
48 framework.modules.exploits.each do |name, mod|
49 next if not framework.datastore['TARGET_PLATFORM'].split(',').include? name.split('/')[0]
50 next if blacklist.include? name
51
52 # TODO Improve platform detection / exploit selection
53 if host.os_name
54 next if name.split('/')[0] == 'windows' && ! host.os_name.match(/Windows/)
55 next if name.split('/')[0] != 'windows' && host.os_name.match(/Windows/)
56 end
57 next unless mod
58 m = mod.new
59 next unless m.datastore.has_key? 'RPORT'
60 if port_list.include? m.datastore['RPORT'].to_i
61 sploits[host.address] << name
62 count += 1
63 end
64 end
65 end
66
67 print_status("Ok dude! I found #{count} matching sploits! #{'Take a beer!' if count > 100}")
68
69 sploits.each do |host, s|
70 s.each do |sploit|
71 print_status("[#{ran+1}/#{count}] Deploying exploit #{sploit} against #{host}")
72 run_single("use #{sploit}")
73 run_single("set RHOST #{host}")
74 run_single("set LPORT #{4444 + rand(65535-44444)}")
75 run_single("show options")
76 run_single("exploit -z")
77 ran += 1
78 print_status('Take another beer ;)') if ran % 100 == 0
79 end
80 end
81
82 print_status("Done. Tried #{ran}/#{count} exploits.")
83 </ruby>
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource autocrawler.rc \
14 --options THREADS=100
15
16 cp $2$NAME.xml $xml
0 #!/bin/bash
1
2 while read h; do
3 NAME="$(date +%s)-$(basename $0)"
4 HOST=$(echo $h | cut -d/ -f3 | cut -d: -f1)
5 PORT=$(echo $h | cut -d/ -f3 | cut -d: -f2)
6 echo "Run msfrpc plugin.."
7 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
8 --log $(realpath $3$NAME.log) \
9 --modules auxiliary/scanner/http/dir_scanner \
10 --options RHOSTS=$HOST:RPORT=$PORT \
11 --command=run
12 done <$1
0 #!/bin/bash
1
2 xml=msf-workspace.xml
3 if ! test -f $xml; then
4 echo XML file $xml not found
5 exit 1
6 fi
7
8 NAME="$(date +%s)-$(basename $0)"
9 echo "Run msfrpc plugin.."
10 ./plugin/msfrpc.py --output $(realpath $2$NAME.xml) \
11 --log $(realpath $3$NAME.log) \
12 --xml $xml \
13 --resource wmap_autotest.rc \
14 --options THREADS=100:WMAP_PROFILE=profile
15
16 cp $2$NAME.xml $xml
55 ###
66 while read h; do
77 NAME="nikto_$(date +%s).xml"
8 ${CS_NIKTO:=nikto} -host $h -output $2$NAME -Format XML
9 done <$1
8 ${CS_NIKTO:=nikto} $CS_NIKTO_ARGS -host $h -output $2$NAME -Format XML
9 done <$1
1414 def list_credentials(workspace=None):
1515
1616 validate_workspace(workspace)
17
18 get_logger(__name__).debug("Request parameters: {!r}"\
19 .format(flask.request.args))
17
18 get_logger(__name__).debug(
19 "Request parameters: {!r}".format(
20 flask.request.args))
2021
2122 cred_filter = filter_request_args()
2223
2324 dao = CredentialDAO(workspace)
2425 result = dao.list(cred_filter=cred_filter)
2526
26 return flask.jsonify(result)
27 return flask.jsonify(result)
44
55 import ConfigParser
66 import json
7 import os, shutil
7 import os
8 import shutil
89 import errno
910
1011 from logging import NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL
1112 from config import globals as CONSTANTS
12
13 from config.configuration import getInstanceConfiguration
1314
1415 LOGGING_LEVEL = INFO
1516
2425 LOCAL_CONFIG_FILE = os.path.expanduser(
2526 os.path.join(CONSTANTS.CONST_FARADAY_HOME_PATH, 'config/server.ini'))
2627
27 CONFIG_FILES = [ DEFAULT_CONFIG_FILE, LOCAL_CONFIG_FILE ]
28 CONFIG_FILES = [DEFAULT_CONFIG_FILE, LOCAL_CONFIG_FILE]
2829 WS_BLACKLIST = CONSTANTS.CONST_BLACKDBS
2930
3031
4546 from server.utils.logger import get_logger
4647 get_logger(__name__).info(u"Local faraday-server configuration created at {}".format(LOCAL_CONFIG_FILE))
4748
49
4850 def parse_and_bind_configuration():
4951 """Load configuration from files declared in this module and put them
5052 on this module's namespace for convenient access"""
6365 for section in __parser.sections():
6466 globals()[section] = ConfigSection(section, __parser)
6567
68
6669 def __get_version():
6770 try:
6871 version = open(VERSION_FILE, 'r').read().strip()
7073 version = ''
7174 return version
7275
76
77 def __get_osint():
78 try:
79 return getInstanceConfiguration().getOsint()
80 except:
81 return ''
82
83
7384 def gen_web_config():
7485 doc = {
7586 'ver': __get_version(),
76 'lic_db': CONSTANTS.CONST_LICENSES_DB
87 'lic_db': CONSTANTS.CONST_LICENSES_DB,
88 "osint": __get_osint()
7789 }
7890 if os.path.isfile(WEB_CONFIG_FILE):
7991 os.remove(WEB_CONFIG_FILE)
8092 with open(WEB_CONFIG_FILE, "w") as doc_file:
8193 json.dump(doc, doc_file)
8294
95
8396 def is_debug_mode():
8497 return LOGGING_LEVEL is DEBUG
8598
8699 parse_and_bind_configuration()
87
77 from server.models import Credential, EntityMetadata
88 from server.utils.database import apply_search_filter
99
10
1011 class CredentialDAO(FaradayDAO):
1112
1213 MAPPED_ENTITY = Credential
1314
1415 COLUMNS_MAP = {
15 'couchid': [EntityMetadata.couchdb_id],
16 'username': [Credential.username],
17 'password': [Credential.password],
18 }
16 'couchid': [EntityMetadata.couchdb_id],
17 'username': [Credential.username],
18 'password': [Credential.password]}
1919
20 STRICT_FILTERING = ["couchid"]
20 STRICT_FILTERING = ["couchid"]
2121
2222 def list(self, search=None, cred_filter={}):
2323 results = self.__query_database(search, cred_filter)
2424
25 rows = [ self.__get_cred_data(result.cred) for result in results ]
26
25 rows = [self.__get_cred_data(result.cred) for result in results]
2726 result = {
2827 'rows': rows
2928 }
6867 'owner': cred.owner,
6968 'command_id': cred.command_id
7069 },
71 'couchid': cred.couchdb_id }}
72
70 'couchid': cred.couchdb_id}}
88 from sqlalchemy.ext.declarative import declarative_base
99
1010
11 SCHEMA_VERSION = 'W.2.3.1'
11 SCHEMA_VERSION = 'W.2.4.0'
1212
1313 Base = declarative_base()
1414
22 # See the file 'doc/LICENSE' for the license information
33
44 import flask
5
5 import os
66 from server.app import app
77
88
99 @app.route('/info', methods=['GET'])
1010 def show_info():
11 response = flask.jsonify({'Faraday Server': 'Running'})
11 faraday_directory = os.path.dirname(os.path.realpath('faraday.py'))
12
13 file_path = os.path.join(faraday_directory, 'VERSION')
14
15 with open(file_path, 'r') as version_file:
16 version = version_file.read().strip()
17
18 response = flask.jsonify({'Faraday Server': 'Running', 'Version': version})
1219 response.status_code = 200
1320
1421 return response
15
4646 return statuses;
4747 })());
4848
49 faradayApp.config(['$routeProvider', 'ngClipProvider', function($routeProvider, ngClipProvider) {
49 faradayApp.config(['$routeProvider', 'ngClipProvider', '$uibTooltipProvider',
50 function($routeProvider, ngClipProvider, $uibTooltipProvider) {
51 $uibTooltipProvider.options({
52 appendToBody: true
53 });
5054 ngClipProvider.setPath("script/ZeroClipboard.swf");
5155 $routeProvider.
5256 when('/dashboard/ws/:wsId', {
131131 },
132132 workspace: function() {
133133 return $scope.workspace;
134 },
135 osint: function() {
136 return $scope.osint;
134137 }
135138 }
136139 });
3131 },
3232 workspace: function() {
3333 return $scope.workspace;
34 },
35 osint: function() {
36 return $scope.osint;
3437 }
3538 }
3639 });
33
44 angular.module('faradayApp')
55 .controller('summarizedCtrlHostsModal',
6 ['$scope', '$modalInstance', 'dashboardSrv', 'workspace', 'srv_name',
7 function($scope, $modalInstance, dashboardSrv, workspace, srv_name) {
8
6 ['$scope', '$modalInstance', 'dashboardSrv', 'workspace', 'srv_name', 'osint',
7 function($scope, $modalInstance, dashboardSrv, workspace, srv_name, osint) {
8
9 $scope.osint = osint;
910 $scope.sortField = 'name';
1011 $scope.sortReverse = false;
1112 $scope.clipText = "Copy to Clipboard";
33
44 angular.module('faradayApp')
55 .controller('summarizedCtrlServicesModal',
6 ['$scope', '$modalInstance', 'dashboardSrv', 'workspace', 'host',
7 function($scope, $modalInstance, dashboardSrv, workspace, host) {
6 ['$scope', '$modalInstance', 'dashboardSrv', 'workspace', 'host', 'osint',
7 function($scope, $modalInstance, dashboardSrv, workspace, host, osint) {
88
99 $scope.host = host
1010 $scope.sortField = 'port';
1111 $scope.sortReverse = false;
12 $scope.osint = osint;
1213
1314 // toggles sort field and order
1415 $scope.toggleSort = function(field) {
3030 <span ng-if="(cmd.hosts_count != 0 && cmd.services_count != 0 && cmd.vulnerabilities_count == 0) || (cmd.hosts_count != 0 && cmd.services_count == 0 && cmd.vulnerabilities_count != 0)"> & </span>
3131 <span ng-if="cmd.services_count > 0">{{cmd.services_count}} {{cmd.services_count == 1 ? 'service' : 'services'}}</span>
3232 <span ng-if="(cmd.hosts_count != 0 && cmd.services_count != 0 && cmd.vulnerabilities_count != 0) || (cmd.hosts_count == 0 && cmd.services_count != 0 && cmd.vulnerabilities_count != 0)"> & </span>
33 <span ng-if="cmd.vulnerabilities_count > 0"><a ng-click="navigate('/status/ws/' + cmd.workspace + '/search/command_id=' + cmd._id)"> {{cmd.vulnerabilities_count}} {{cmd.vulnerabilities_count == 1 ? 'vulnerability' : 'vulnerabilities'}}</a></span>
33 <span ng-if="cmd.vulnerabilities_count > 0"><a ng-click="navigate('/status/ws/' + workspace + '/search/command_id=' + cmd._id)"> {{cmd.vulnerabilities_count}} {{cmd.vulnerabilities_count == 1 ? 'vulnerability' : 'vulnerabilities'}}</a></span>
3434 <span ng-if="cmd.criticalIssue > 0">- {{cmd.criticalIssue}} {{cmd.criticalIssue == 1 ? 'is' : 'are'}} rated as <b>Critical</b>.</span>
3535 <span class ="small-size" am-time-ago="cmd.date"/>
3636 </td>
2222 <tr ng-repeat="host in hosts">
2323 <td class="col-xs-6">
2424 <a href="" class="host" ng-click="showServices(host)">{{host.name}}</a>
25 <a href="//www.shodan.io/search?query={{host.name}}" uib-tooltip="Search in Shodan" target="_blank">
26 <img ng-src="images/shodan.png" height="15px" width="15px" />
25 <a href="//{{osint.host}}/search?query={{host.name}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
26 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
2727 </a>
2828 </td>
2929 <td class="col-xs-6">{{host.services}}</td>
1919 <td><input disabled type="checkbox" ng-model="host.owned"/></td>
2020 <td>
2121 {{host.name}}
22 <a href="//www.shodan.io/search?query={{host.name}}" uib-tooltip="Search in Shodan" target="_blank">
23 <img ng-src="images/shodan.png" height="15px" width="15px" />
22 <a href="//{{osint.host}}/search?query={{host.name}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
23 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
2424 </a>
2525 </td>
2626 <td>{{host.os}}</td>
2020 <tr ng-repeat="srv in services | orderBy:sortField:sortReverse">
2121 <td>
2222 {{srv.name}}
23 <a href="//www.shodan.io/search?query={{srv.name}}" uib-tooltip="Search in Shodan" target="_blank">
24 <img ng-src="images/shodan.png" height="15px" width="15px" />
23 <a href="//{{osint.hostl}}/search?query={{srv.name}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
24 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px"/>
2525 </a>
2626 </td>
2727 <td>{{srv.description}}</td>
2828 <td>
2929 {{srv.ports}}
30 <a href="//www.shodan.io/search?query=port:{{srv.ports}}" uib-tooltip="Search in Shodan" target="_blank">
31 <img ng-src="images/shodan.png" height="15px" width="15px" />
30 <a href="//{{osint.host}}/search?query=port:{{srv.ports}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
31 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
3232 </a>
3333 </td>
3434 <td>{{srv.protocol}}</td>
7575 selection-model-on-change="selectedHosts()">
7676 <td><input type="checkbox" name="{{host._id}}"/></td>
7777 <td>
78 {{host.name}}
79 <a href="//www.shodan.io/search?query={{host.name}}" uib-tooltip="Search in Shodan" target="_blank">
80 <img ng-src="images/shodan.png" height="15px" width="15px" />
78 <a ng-href="#/host/ws/{{workspace}}/hid/{{host._id}}">{{host.name}}</a>
79 <a ng-href="//{{osint.host}}/search?query={{host.name}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
80 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
8181 </a>
8282 </td>
83 <td><a href="#/host/ws/{{workspace}}/hid/{{host._id}}" ng-bind="host.services || '-'"></a></td>
83 <td><a ng-href="#/host/ws/{{workspace}}/hid/{{host._id}}" ng-bind="host.services || '-'"></a></td>
8484 <td><a ng-href="#/status/ws/{{workspace}}/search/target={{host.name}}" ng-bind="host.vulns"></a></td>
8585 <td>
8686 <a ng-href="#/hosts/ws/{{workspace}}/search/os={{host.os}}">
77 function($scope, indexFact) {
88 indexFact.getConf().then(function(conf) {
99 $scope.version = conf.data.ver;
10 $scope.osint = conf.data.osint;
1011 });
1112
1213 }]);
112112 <a ng-href="#/host/ws/{{workspace}}/hid/{{host._id}}/search/name={{service.name}}">
113113 <span ng-bind="service.name"></span>
114114 </a>
115 <a ng-href="//www.shodan.io/search?query={{service.name}}" uib-tooltip="Search in Shodan" target="_blank">
116 <img ng-src="images/shodan.png" height="15px" width="15px" />
115 <a ng-href="//{{osint.host}}/search?query={{service.name}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
116 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
117117 </a>
118118 </td>
119119 <td ng-bind="service.version || '-'"></td>
120120 <td>
121121 <span ng-bind="service.ports"></span>
122 <a ng-href="//www.shodan.io/search?query=port:{{service.ports}}" uib-tooltip="Search in Shodan" target="_blank">
123 <img ng-src="images/shodan.png" height="15px" width="15px" />
122 <a ng-href="//{{osint.host}}/search?query=port:{{service.ports}}" uib-tooltip="Search in {{osint.label}}" target="_blank">
123 <img ng-src="images/{{osint.icon}}.png" height="15px" width="15px" />
124124 </a>
125125 </td>
126126 <td>
186186 });
187187 }
188188
189 // load cookie of columns ordering if exists
190 paginationOptions.sortColumn = $cookies.get('SRsortColumn') || null;
191 paginationOptions.sortDirection = $cookies.get('SRsortDirection') || null;
192
189193 defineColumns();
190194
191195 $scope.vulnWebSelected = false;
201205 $scope.gridOptions.columnDefs.push({ name: 'confirmVuln', width: '40', headerCellTemplate: "<div></div>", cellTemplate: 'scripts/statusReport/partials/ui-grid/confirmbutton.html' });
202206 $scope.gridOptions.columnDefs.push({ name: 'deleteVuln', width: '40', headerCellTemplate: "<div></div>", cellTemplate: 'scripts/statusReport/partials/ui-grid/deletebutton.html' });
203207 $scope.gridOptions.columnDefs.push({ name: 'editVuln', width: '30', headerCellTemplate: "<div></div>", cellTemplate: 'scripts/statusReport/partials/ui-grid/editbutton.html' });
208
209 function getColumnSort(columnName){
210 if($cookies.get('SRsortColumn') === columnName){
211 direction = ($cookies.get('SRsortDirection').toLowerCase() == 'asc')
212 ? uiGridConstants.ASC
213 : uiGridConstants.DESC;
214 return {ignoreSort: true, priority: 0, direction: direction};
215 }else{
216 return {};
217 }
218 }
204219
205220 var header = '<div ng-class="{ \'sortable\': sortable }">'+
206221 ' <div class="ui-grid-cell-contents" col-index="renderIndex" title="TOOLTIP">{{ col.displayName CUSTOM_FILTERS }}'+
220235 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/datecolumn.html',
221236 headerCellTemplate: header,
222237 width: '90',
238 sort: getColumnSort('date'),
223239 visible: $scope.columns["date"]
224240 });
225241 $scope.gridOptions.columnDefs.push({ name : 'name',
226242 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/namecolumn.html',
227243 headerCellTemplate: header,
228244 maxWidth: '230',
245 sort: getColumnSort('name'),
229246 visible: $scope.columns["name"]
230247 });
231248 $scope.gridOptions.columnDefs.push({ name : 'severity',
234251 type: 'string',
235252 width: '70',
236253 visible: $scope.columns["severity"],
254 sort: getColumnSort('severity'),
237255 sortingAlgorithm: compareSeverities
238256 });
239257 $scope.gridOptions.columnDefs.push({ name : 'service',
240258 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/servicecolumn.html',
241259 headerCellTemplate: header,
242260 width: '110',
243 visible: $scope.columns["service"]
261 visible: $scope.columns["service"],
262 sort: getColumnSort('service'),
244263 });
245264 $scope.gridOptions.columnDefs.push({ name : 'hostnames',
246265 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/hostnamescolumn.html',
247266 headerCellTemplate: header,
248267 minWidth: '100',
249268 maxWidth: '200',
269 sort: getColumnSort('hostnames'),
250270 visible: $scope.columns["hostnames"]
251271 });
252272 $scope.gridOptions.columnDefs.push({ name : 'target',
253273 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/targetcolumn.html',
254274 headerCellTemplate: header,
255275 width: '140',
276 sort: getColumnSort('target'),
256277 visible: $scope.columns["target"]
257278 });
258279 $scope.gridOptions.columnDefs.push({ name : 'desc',
260281 headerCellTemplate: header,
261282 minWidth: '300',
262283 maxWidth: '400',
284 sort: getColumnSort('desc'),
263285 visible: $scope.columns["desc"]
264286 });
265287 $scope.gridOptions.columnDefs.push({ name : 'resolution',
266288 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/resolutioncolumn.html',
267289 headerCellTemplate: header,
290 sort: getColumnSort('resolution'),
268291 visible: $scope.columns["resolution"]
269292 });
270293 $scope.gridOptions.columnDefs.push({ name : 'data',
271294 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/resolutioncolumn.html',
272295 headerCellTemplate: header,
296 sort: getColumnSort('data'),
273297 visible: $scope.columns["data"]
274298 });
275299 $scope.gridOptions.columnDefs.push({ name : 'easeofresolution',
276300 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
277301 headerCellTemplate: header,
302 sort: getColumnSort('easeofresolution'),
278303 visible: $scope.columns["easeofresolution"]
279304 });
280305 $scope.gridOptions.columnDefs.push({ name : 'status',
281306 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/statuscolumn.html',
282307 headerCellTemplate: header,
283308 width: '100',
309 sort: getColumnSort('status'),
284310 visible: $scope.columns["status"]
285311 });
286312 $scope.gridOptions.columnDefs.push({ name : 'website',
287313 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
288314 headerCellTemplate: header,
315 sort: getColumnSort('website'),
289316 visible: $scope.columns["website"]
290317 });
291318 $scope.gridOptions.columnDefs.push({ name : 'path',
292319 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
293320 headerCellTemplate: header,
321 sort: getColumnSort('path'),
294322 visible: $scope.columns["path"]
295323 });
296324 $scope.gridOptions.columnDefs.push({ name : 'request',
297325 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/resolutioncolumn.html',
298326 headerCellTemplate: header,
327 sort: getColumnSort('request'),
299328 visible: $scope.columns["request"]
300329 });
301330 $scope.gridOptions.columnDefs.push({ name : 'refs',
302331 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/refscolumn.html',
303332 headerCellTemplate: header,
333 sort: getColumnSort('refs'),
304334 visible: $scope.columns["refs"]
305335 });
306336 $scope.gridOptions.columnDefs.push({ name : '_attachments',
307337 displayName: "evidence",
308338 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/evidencecolumn.html',
309339 headerCellTemplate: header,
340 sort: getColumnSort('_attachments'),
310341 visible: $scope.columns["evidence"]
311342 });
312343 $scope.gridOptions.columnDefs.push({ name : 'impact',
313344 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/impactcolumn.html',
314345 headerCellTemplate: header,
346 sort: getColumnSort('impact'),
315347 visible: $scope.columns["impact"]
316348 });
317349 $scope.gridOptions.columnDefs.push({ name : 'method',
318350 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
319351 headerCellTemplate: header,
352 sort: getColumnSort('method'),
320353 visible: $scope.columns["method"]
321354 });
322355 $scope.gridOptions.columnDefs.push({ name : 'params',
323356 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
324357 headerCellTemplate: header,
358 sort: getColumnSort('params'),
325359 visible: $scope.columns["params"]
326360 });
327361 $scope.gridOptions.columnDefs.push({ name : 'pname',
328362 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
329363 headerCellTemplate: header,
364 sort: getColumnSort('pname'),
330365 visible: $scope.columns["pname"]
331366 });
332367 $scope.gridOptions.columnDefs.push({ name : 'query',
333368 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/defaultcolumn.html',
334369 headerCellTemplate: header,
370 sort: getColumnSort('query'),
335371 visible: $scope.columns["query"]
336372 });
337373 $scope.gridOptions.columnDefs.push({ name : 'response',
338374 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/resolutioncolumn.html',
339375 headerCellTemplate: header,
376 sort: getColumnSort('response'),
340377 visible: $scope.columns["response"]
341378 });
342379 $scope.gridOptions.columnDefs.push({ name : 'web',
343380 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/webcolumn.html',
344381 headerCellTemplate: header,
345382 width: '80',
383 sort: getColumnSort('date'),
346384 visible: $scope.columns["web"]
347385 });
348386 $scope.gridOptions.columnDefs.push({ name : 'metadata.creator',
350388 cellTemplate: 'scripts/statusReport/partials/ui-grid/columns/creatorcolumn.html',
351389 headerCellTemplate: header,
352390 width: '100',
391 sort: getColumnSort('metadata.creator'),
353392 visible: $scope.columns["creator"]
354393 });
355394 };
370409 var sortRowsBy = function(columnName, sortDirection) {
371410 paginationOptions.sortColumn = columnName;
372411 paginationOptions.sortDirection = sortDirection;
412 $cookies.put('SRsortColumn', columnName || '');
413 $cookies.put('SRsortDirection', sortDirection || '');
373414 }
374415
375416 $scope.ifTooltip = function(text) {
285285 };
286286
287287 $scope.redirect = function(path){
288 $location.path("/"+($location.path().split('/')[1] || 'dashboard')+ "/ws/"+path);
289 };
290 $scope.dashboardRedirect = function(path){
288291 $location.path("/dashboard/ws/"+path);
289292 };
290293
5555 <tr ng-repeat="ws in workspaces | filter:query | filter:search | orderBy:sortField:reverse"
5656 selection-model selection-model-selected-class="multi-selected">
5757 <td>
58 <span class="onhover upsize" ng-click="redirect(ws.name)">
58 <span class="onhover upsize" ng-click="dashboardRedirect(ws.name)">
5959 <b>{{ws.name}}</b>
6060 </span>
6161 </td>
44
55 '''
66
7 import pkg_resources
78 import pip
8 import pkg_resources
99
1010
11 class DependencyChecker(object):
12 def __init__(self, requirements_file):
13 self.mandatory = []
14 self.optional = []
11 def check_dependencies(requirements_file='requirements.txt'):
12 dependencies_file = open(requirements_file, 'r')
1513
16 dependencies_file = open(requirements_file, 'r')
14 requirements = list(pkg_resources.parse_requirements(dependencies_file))
1715
18 for line in dependencies_file:
19 if line.find('#') > -1:
20 # Optional dependencies after the '#' character
21 break
22 self.mandatory.append(line.strip())
16 installed = []
17 missing = []
2318
24 for line in dependencies_file:
25 self.optional.append(line.strip())
19 for package in requirements:
20 try:
21 pkg_resources.working_set.resolve([package])
22 installed += [package]
23 except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict):
24 missing += [package.key]
2625
27 dependencies_file.close()
26 return installed, missing
2827
29 def __check_dependency(self, package):
30 try:
31 pkg_resources.require(package)
32 return True
33 except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict):
34 return False
3528
36 def check_dependencies(self, with_optional=True):
37 print "Checking dependencies"
38 missing = []
39 dependencies = self.mandatory
40 if with_optional:
41 dependencies += self.optional
42 for package in dependencies:
43 if not self.__check_dependency(package):
44 missing.append(package)
45 return missing
46
47 def install_packages(self, packages):
48 for package in packages:
49 pip.main(['install', package, '--user'])
29 def install_packages(packages):
30 for package in packages:
31 pip.main(['install', package, '--user'])
8888 send-output
8989 }
9090
91 if [ -n "${FARADAY_PATH+x}" ]; then
92 echo "[+] Faraday path set. Aliasing fplugin"
93
94 function fplugin() {
95 "$FARADAY_PATH/bin/fplugin" $*;
96 }
97 else
98
99 if [ -s "./faraday-server.py" ]; then
100 echo "[+] Faraday path not set, but server found. Aliasing fplugin"
101 function fplugin() {
102 "./bin/fplugin" $*;
103 }
104 else
105
106 echo "[-] Faraday path not set"
107 fi
108
109 fi
110
91111 zle -N accept-line add-output