Commit 421f9469 authored by Lorenzo Faletra's avatar Lorenzo Faletra

Import Upstream version 3.4

parent 5937a491
---
name: Feature request
about: Suggest an idea for this
---
**What's the problem this feature will solve?**
<!-- What are you trying to do, that you are unable to achieve with faraday as it currently stands? -->
**Describe the solution you'd like**
<!-- Clear and concise description of what you want to happen. -->
<!-- Provide examples of real world use cases that this would enable and how it solves the problem described above. -->
**Alternative Solutions**
<!-- different approach to solving this issue? Please elaborate here. -->
**Additional context**
<!-- Add any other context, links, etc. about the feature here. -->
---
name: Bug report
about: Create a report an issue
---
Please search the [Wiki](https://github.com/infobyte/faraday/wiki) for a solution before posting a ticket. Use the <strong>“New Support Request”</strong> button to the right of the screen to submit a ticket for technical support.
## Issue Type
......
......@@ -34,6 +34,7 @@ Project contributors
* Jorge Luis Gonzalez Iznaga
* Juan Urbano
* Korantin Auguste
* logdot
* Martin Tartarelli
* Mike Zhong (go bears)
* Necrose99
......@@ -44,3 +45,4 @@ Project contributors
* tsxltjecwb
* Ulisses Albuquerque
* xtr4nge
October 17th, 2018
* Added logical operator AND to status report search
* Restkit dependency removed.
* Improvement on manage.py change-password
* Add feature to show only unconfirmed vulns.
* Add ssl information to manage.py status-check
* Update wpscan plugin to support latest version.
* Allow workspace names starting with numbers.
Novemeber 14th, 2018
* Add workspace disable feature
* Add mac vendor to host and services
* Fix typos and add sorting in workspace name (workspace list view)
* Improve warning when you try to select hosts instead of services as targets of a Vulnerability Web
* Deleted old Nexpose plugin. Now Faraday uses Nexpose-Full.
* Update sqlmap plugin
* Add updated zap plugin
* Add hostnames to nessus plugin
* Python interpreter in SSLCheck plugin is not hardcoded anymore.
* Fix importer key error when some data from couchdb didn't contain the "type" key
* Fix AttributeError when importing vulns without exploitation from CouchDB
* Fix KeyError in importer.py. This issue occurred during the import of Vulnerability Templates
* Fix error when file config.xml doesn't exist as the moment of executing initdb
* Improve invalid credentials warning by indicating the user to run Faraday GTK with --login option
* Fix typos in VulnDB and add two new vulnerabilities (Default Credentials, Privilege Escalation)
* Improved tests performance with new versions of the Faker library
* `abort()` calls were checked and changed to `flask.abort()`
* In GTK, check active_workspace its not null
* Add fbruteforce services fplugin
* Attachments can be added to a vulnerability through the API.
* Catch gaierror error on lynis plugin
* Add OR and NOT with parenthesis support on status report search
* Info API now is public
* Web UI now detects Appscan plugin
* Improve performance on the workspace using cusotm query
* Workspaces can be set as active/disable in welcome page.
* Change Nmap plugin, response field in VulnWeb now goes to Data field.
* Update code to support latest SQLAlchemy version
* Fix `create_vuln` fplugin bug that incorrectly reported duplicated vulns
The **RELEASE.md** generation process is as follows:
* An _CHANGELOG_ folder, containing files for the wanted generated **RELEASE.md** (release file upon now)
* As root of this folder, we have:
* A folder **for each** version, each one containing various (0 to multiple) .md one line file, explaining a single change released in the proper version
* The version folder can contains a _date.md_ file, which contains the realease date
* The only reserved file names are _white.md, pink.md, black.md_ and _date.md_
* Any other file not ending in .md will be ignored
* _header.md_, md format lines at the beginning of the release file
* _footer.md_, md format lines at the ending of the release file
* _changelog.py_, a python file, which will generate the release file
* The python file process is:
* Iterate over all the version folder in sorted order, joining all .md files in only one ( _white/pink/black.md_ ) in the proper version folder.
* Generate the release file as header/v0file.md/.../vnfile.md/footer
* The release step-by-step generation should be:
1. Checkout white/master and go to CHANGELOG/
1. Run _changelog.py_ (All .md file will be compressed to _white.md_ files, excluding reserved filenames files)
1. Replace _old **RELEASE.md**_ with new generated file
1. Git add CHANGELOG/
1. Commit & push
1. Checkout pink/master and go to CHANGELOG/
1. Merge white/master
1. Run _changelog.py_ (All .md file will be compressed to _pink.md_ files, excluding reserved filenames files)
1. Replace _old **RELEASE.md**_ with new generated file
1. Git add CHANGELOG/
1. Commit & push
1. Checkout black/master and go to CHANGELOG/
1. Merge pink/master
1. Run _changelog.py_ (All .md file will be compressed to _black.md_ files, excluding reserved filenames files)
1. Replace _old **RELEASE.md**_ with new generated file
1. Git add CHANGELOG/
1. Commit & push
This diff is collapsed.
import os
import packaging.version
LEVEL = "white"
def match(elem):
try:
ans = packaging.version.Version(elem)
except packaging.version.InvalidVersion as e:
# print folder/file ommited
return False
return ans
IGNORED_FILES = ["white.md", "pink.md", "black.md", "date.md"]
def addFile(filename,changelog_file,to=None):
with open(filename, "r") as date_file:
if to:
changelog_file.write(date_file.readline()[:to])
else:
changelog_file.writelines(date_file.readlines())
def main(level):
ls_ans = os.listdir(".")
folders = list(sorted(filter(lambda el: el, map(lambda elem: match(elem),ls_ans)),reverse=True))
with open("RELEASE.md","w") as changelog_file:
if "header.md" in ls_ans:
with open("header.md", "r") as header_file:
changelog_file.writelines(header_file.readlines())
changelog_file.writelines("\n\n")
for folder in folders:
changelog_file.write(str(folder))
inner_files = list(filter(lambda elem: elem.endswith(".md") ,os.listdir("./" + str(folder))))
if "date.md" in inner_files:
changelog_file.write(" [")
addFile("./" + str(folder) + "/date.md",changelog_file,-1)
changelog_file.write("]")
changelog_file.writelines(":\n---\n")
if level != "white":
addFile("./" + str(folder) + "/white.md",changelog_file)
if level == "black":
addFile("./" + str(folder) + "/pink.md",changelog_file)
level_filename = "./" + str(folder) + "/" + level + ".md"
previous = [""]
if level + ".md" in os.listdir("./" + str(folder)):
with open(level_filename, "r") as level_file:
previous = level_file.readlines()
with open(level_filename, "w") as level_file:
level_file.writelines(previous)
for inner_file_name in inner_files:
if inner_file_name not in IGNORED_FILES:
level_file.write(" * ")
addFile("./" + str(folder) + "/" + inner_file_name, level_file)
level_file.write("\n")
os.remove("./" + str(folder) + "/" + inner_file_name)
addFile(level_filename, changelog_file)
changelog_file.writelines("\n")
if "footer.md" in ls_ans:
with open("footer.md", "r") as footer_file:
changelog_file.writelines(footer_file.readlines())
if __name__ == '__main__':
level = LEVEL # if not level_passed else level_pased
main(level)
This diff is collapsed.
IMPORTANT
===========
Please be kind to remove all your pyc files before running faraday if you are updating this piece of software.
Make sure you run ```./faraday.py --update``` the first time after an update!
New features in the latest update
=====================================
......@@ -18,20 +18,20 @@ To read about the latest features check out the [release notes](https://github.c
## Getting Started!
Check out our documentacion for datailed information on how to install Faraday in all of our supported platforms:
Check out our documentation for detailed information on how to install Faraday in all of our supported platforms:
![Supported Os](https://raw.github.com/wiki/infobyte/faraday/images/platform/supported.png)
To begin the instalation process check our out [First Step](https://raw.github.com/wiki/infobyte/faraday/First-steps) Wiki.
To begin the installation process, check out our [Installation Wiki](https://github.com/infobyte/faraday/wiki/Installation-Community).
## New Features!
All of Faraday's latest features and updates are always available on our [blog](http://blog.infobytesec.com/search/label/english).
There are new entries every few weeks, don't forget to check out our amaizing new improvements on it's last entry!
There are new entries every few weeks, don't forget to check out our amazing new improvements on it's last entry!
## Plugins list
You feed data to Faraday from your favorite tools through Plugins. Right now there are more than [60+ supported tools](https://github.com/infobyte/faraday/wiki/Plugin-List), among which you will find:
You feed data to Faraday from your favorite tools through Plugins. Right now there are more than [70+ supported tools](https://github.com/infobyte/faraday/wiki/Plugin-List), among which you will find:
![](https://raw.github.com/wiki/infobyte/faraday/images/plugins/Plugins.png)
......
......@@ -8,7 +8,65 @@ Make sure you run ```./faraday.py --update``` the first time after an update!
New features in the latest update
=====================================
3.4:
---
* In GTK, check active_workspace its not null
* Add fbruteforce services fplugin
* Attachments can be added to a vulnerability through the API.
* Catch gaierror error on lynis plugin
* Add OR and NOT with parenthesis support on status report search
* Info API now is public
* Web UI now detects Appscan plugin
* Improve performance on the workspace using cusotm query
* Workspaces can be set as active/disable in welcome page.
* Change Nmap plugin, response field in VulnWeb now goes to Data field.
* Update code to support latest SQLAlchemy version
* Fix `create_vuln` fplugin bug that incorrectly reported duplicated vulns
3.3 [Novemeber 14th, 2018]:
---
* Add workspace disable feature
* Add mac vendor to host and services
* Fix typos and add sorting in workspace name (workspace list view)
* Improve warning when you try to select hosts instead of services as targets of a Vulnerability Web
* Deleted old Nexpose plugin. Now Faraday uses Nexpose-Full.
* Update sqlmap plugin
* Add updated zap plugin
* Add hostnames to nessus plugin
* Python interpreter in SSLCheck plugin is not hardcoded anymore.
* Fix importer key error when some data from couchdb didn't contain the "type" key
* Fix AttributeError when importing vulns without exploitation from CouchDB
* Fix KeyError in importer.py. This issue occurred during the import of Vulnerability Templates
* Fix error when file config.xml doesn't exist as the moment of executing initdb
* Improve invalid credentials warning by indicating the user to run Faraday GTK with --login option
* Fix typos in VulnDB and add two new vulnerabilities (Default Credentials, Privilege Escalation)
* Improved tests performance with new versions of the Faker library
* `abort()` calls were checked and changed to `flask.abort()`
3.2 [October 17th, 2018]:
---
* Added logical operator AND to status report search
* Restkit dependency removed.
* Improvement on manage.py change-password
* Add feature to show only unconfirmed vulns.
* Add ssl information to manage.py status-check
* Update wpscan plugin to support latest version.
* Allow workspace names starting with numbers.
September 21, 2018:
---
* Fix bug: manage.py status_check
* Fix bug: manage.py initdb
......
......@@ -8,6 +8,10 @@ See the file 'doc/LICENSE' for the license information
from model.common import factory
from persistence.server import models
from persistence.server.server_io_exceptions import (
CantCommunicateWithServerError,
ConflictInDatabase
)
__description__ = 'Creates a new vulnerability'
__prettyname__ = 'Create Vulnerability'
......@@ -31,8 +35,6 @@ def main(workspace='', args=None, parser=None):
default='false')
parser.add_argument('--description', help='Vulnerability description', default='')
parser.add_argument('--dry-run', action='store_true', help='Do not touch the database. Only print the object ID')
parsed_args = parser.parse_args(args)
obj = factory.createModelObject(models.Vuln.class_signature,
......@@ -53,20 +55,28 @@ def main(workspace='', args=None, parser=None):
'parent': parsed_args.parent,
}
old = models.get_vulns(
try:
models.create_vuln(workspace, obj)
except ConflictInDatabase as ex:
if ex.answer.status_code == 409:
try:
old_id = ex.answer.json()['object']['_id']
except KeyError:
print "Vulnerability already exists. Couldn't fetch ID"
return 2, None
else:
print "A vulnerability with ID %s already exists!" % old_id
return 2, None
else:
print "Unknown error while creating the vulnerability"
return 2, None
except CantCommunicateWithServerError as ex:
print "Error while creating vulnerability:", ex.response.text
return 2, None
new = models.get_vulns(
workspace,
**params
)
if not old:
if not parsed_args.dry_run:
models.create_vuln(workspace, obj)
old = models.get_vulns(
workspace,
**params
)
else:
print "A vulnerability with ID %s already exists!" % old[0].getID()
return 2, None
return 0, old[0].getID()
return 0, new[0].getID()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Faraday Penetration Test IDE
Copyright (C) 2018 Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information
'''
import os
import sys
import base64
import shlex
import time
import re
import requests
from subprocess import Popen, PIPE, call
from persistence.server import models, server
from persistence.server.server import SERVER_URL
__description__ = 'Script to perform a brute force attack on different services in a workspace'
__prettyname__ = 'FBrute'
SUPPORTED_SERVICES = ["asterisk", "cisco", "cisco-enable", "cvs", "firebird", "ftp", "ftps", "http",
"https", "http-proxy", "icq" "imap", "imaps", "irc", "ldap2", "ldap3",
"mssql", "mysql", "nntp", "oracle-listener", "oracle-sid", "pcanywhere",
"pcnfs", "pop3", "pop3s", "postgres", "rdp", "redis", "rexec", "rlogin",
"rsh", "rtsp", "s7-300", "sip", "smb", "smtp", "smtps", "smtp-enum", "snmp",
"socks5", "ssh", "sshkey", "svn", "teamspeak", "telnet"
"telnets", "vmauthd", "vnc", "xmpp"]
PID = os.getpid()
def check_hydra():
p = Popen(["which", "hydra"], stdout=PIPE)
p.communicate()[0]
return p.returncode == 0
def add_output(output):
pwd = os.getcwd()
data = {"cmd" : base64.b64encode(output), "pid" : PID, "pwd" : base64.b64encode(pwd)}
requests.post("http://localhost:9977/cmd/input", json=data)
def send_output(output):
output = base64.b64encode(open(output, "r").read())
data = {"exit_code" : 0, "pid" : PID, "output" : output}
requests.post("http://localhost:9977/cmd/output", json=data)
def search_hosts_by_service(workspace, b_service):
output = ""
all_hosts = list(models.get_hosts(workspace))
all_services = list(models.get_services(workspace))
for host in all_hosts:
for service in all_services:
id_service_host = service.parent_id
if host.id == id_service_host and service.name == b_service:
output += host.name + "\n"
break
return output
def total_credentials(workspace):
json_creds = server._get(
SERVER_URL + "/_api/v2/ws/%s/credential" % workspace)
return len(json_creds["rows"])
def get_credentials(workspace, key):
credentials = ""
json_creds = server._get(
SERVER_URL + "/_api/v2/ws/%s/credential" % workspace)
if len(json_creds["rows"]) > 0:
for c in json_creds["rows"]:
credentials += c["value"][key] + "\n"
return credentials
else:
sys.exit("No credentials were found on faraday")
def show_table_services(workspace):
services = []
table = ""
j_parsed = server._get(
SERVER_URL + "/_api/v2/ws/%s/services/count?group_by=name" % workspace)
if len(j_parsed["groups"]) > 0:
table += "Number\tService\tCount\n"
table += "------\t-------\t------\n"
for l in j_parsed["groups"]:
if l["name"] in SUPPORTED_SERVICES:
services.append(l["name"])
table += "[" + str(services.index(l["name"])) + "]\t"
table += l["name"] + "\t" + str(l["count"]) + "\n"
return table, services
else:
sys.exit("No services availables")
def input_index(text, leng):
while 1:
stdin = raw_input(text+"[0-"+str(leng-1)+"/q]: ")
if re.search("[0-9]", stdin) is not None:
if int(stdin) > leng-1 or int(stdin) < 0:
continue
else:
return stdin
elif stdin == "q":
sys.exit(1)
else:
continue
def show_options(workspace):
user_define_dictionary = False
usernames_dic_path = None
passwords_dic_path = None
user_faraday = None
passwd_faraday = None
# Muestro los servicios en el workspace soportados por hydra, en formato tabla
table_services, services = show_table_services(workspace)
print table_services
service = int(input_index("What service do you want to bruteforce?", len(services)))
# Verifico si el usuario quiere armar un diccionario con las credenciales
# guardadas en faraday o si quiere utilizar uno propio
print "\n[0] Choose a dictionary"
print "[1] Create dictionary from Faraday (based in credentials stored in Faraday)\n"
dictionary = int(input_index("Options ", 2))
#Le pido el path de el user dic y el password dic
if dictionary == 0:
usernames_dic_path = raw_input("Usernames file: ")
passwords_dic_path = raw_input("Passwords file: ")
user_define_dictionary = True
else:
print "\n[*] Obtaining credentials from the workspace %s" % workspace
user_faraday = save_targets(get_credentials(workspace, "username"))
passwd_faraday = save_targets(get_credentials(workspace, "password"))
print "[*] Credentials found: %s" % total_credentials(workspace)
print "\nUsername\t\tPassword"
print "--------\t\t--------"
for user, passw in zip(
open(user_faraday, "r"), open(passwd_faraday, "r")):
print "%s\t\t%s" % (user.strip(), passw.strip())
return service, services, user_define_dictionary, user_faraday, passwd_faraday, usernames_dic_path, passwords_dic_path
def save_targets(output):
dicc = "/tmp/targets_"+str(time.time())
f = open(dicc, "w")
f.write(output)
f.close()
return dicc
def main(workspace='', args=None, parser=None):
print "\nThis script needs to be run inside from Faraday GTK.\n"
if check_hydra():
service, services, user_define_dictionary, user_faraday, passwd_faraday, usernames_dic_path, passwords_dic_path = show_options(workspace)
b_service = services[service]
output = search_hosts_by_service(workspace, b_service)
targets = save_targets(output)
hydra_output = "/tmp/hydra_output-%s.txt" % time.time()
print "Running Hydra, please wait to finish the bruteforce...\n"
if user_define_dictionary:
hydra_command1 = "hydra -L {0} -P {1} -e sr -M {2} -V -q {3} -o {4}".format(
usernames_dic_path,
passwords_dic_path,
targets,
b_service,
hydra_output)
add_output(hydra_command1)
call(shlex.split(hydra_command1))
else:
hydra_command2 = "hydra -L {0} -P {1} -e sr -M {2} -V -q {3} -o {4}".format(
user_faraday,
passwd_faraday,
targets,
b_service,
hydra_output)
add_output(hydra_command2)
call(shlex.split(hydra_command2))
print "Processing information found in Faraday...\n"
send_output(hydra_output)
return None, None
else:
sys.exit("Hydra is not installed on the system. Install hydra to continue execution")
return None, None
......@@ -31,7 +31,7 @@ def screenshot(path, protocol, ip, port):
except Exception:
print("Coudn't connect")
finally:
driver.quit
driver.quit()
return 0
......@@ -42,7 +42,6 @@ def main(workspace='', args=None, parser=None):
parsed_args = parser.parse_args(args)
protocols = parsed_args.protocol.split(",")
print(protocols)
path = parsed_args.path
for protocol in protocols:
......
......@@ -6,6 +6,8 @@ See the file 'doc/LICENSE' for the license information
'''
import os
import json
import shutil
try:
import xml.etree.cElementTree as ET
......@@ -14,6 +16,7 @@ except ImportError:
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, ElementTree
the_config = None
CONST_API_CON_INFO = "api_con_info"
......@@ -645,6 +648,12 @@ class Configuration:
def getInstanceConfiguration():
global the_config
if the_config is None:
config_dir = os.path.expanduser("~/.faraday/config")
if not os.path.exists(config_dir):
os.mkdir(config_dir)
faraday_user_config = os.path.expanduser("~/.faraday/config/user.xml")
if not os.path.isfile(faraday_user_config):
shutil.copy(DEFAULT_XML, faraday_user_config)
if os.path.exists(os.path.expanduser("~/.faraday/config/user.xml")):
the_config = Configuration(os.path.expanduser("~/.faraday/config/user.xml"))
else:
......
......@@ -2,7 +2,7 @@
<faraday>
<appname>Faraday - Penetration Test IDE</appname>
<version>3.1.1</version>
<version>3.3</version>
<debug_status>0</debug_status>
<font>-Misc-Fixed-medium-r-normal-*-12-100-100-100-c-70-iso8859-1</font>
<home_path>~/</home_path>
......
......@@ -2847,3 +2847,5 @@ https://www.owasp.org/index.php/Testing_for_MySQL#Read_from_a_File",high,
,EN-Cifrado Debil (SSL weak ciphers),"El host remoto es compatible con el uso de sistemas de cifrado SSL que ofrecen ya sea cifrado debil o sin cifrado en absoluto.