Skip to content

Commit

Permalink
Merge branch 'white/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
micabot committed Jul 21, 2017
2 parents 090be30 + 9bccf7e commit 8b34d77
Show file tree
Hide file tree
Showing 38 changed files with 628 additions and 130 deletions.
6 changes: 5 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ The PRIMARY AUTHORS are:
* Franco Linares
* German Riera
* Joaquín López Pereyra
* Leonardo Lazzaro
* Martín Rocha
* Matias Ariel Ré Medina
* Matias Lang
* Micaela Ranea Sánchez
* Sebastian Kulesz

Project contributors

Expand All @@ -20,14 +23,15 @@ Project contributors
* Andres Tarantini
* Brice Samulenok
* Elian Gidoni
* Endrigo Antonini
* Federico Fernandez
* James Jara
* Jorge Luis Gonzalez Iznaga
* Juan Urbano
* Korantin Auguste
* Martin Tartarelli
* Ronald Iraheta
* Roberto Focke
* Sebastian Kulesz
* Sliim
* Thierry Beauquier
* tsxltjecwb
Expand Down
13 changes: 13 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ Make sure you run ```./faraday.py --update``` the first time after an update!
New features in the latest update
=====================================

July 19, 2017:
---
* Added the ability to select more than one target when creating a vuln in the Web UI
* Merged PR #182 - problems with zonatransfer.me
* Fixed bug in Download CSV of Status report with old versions of Firefox.
* Fixed formula injection vulnerability in export to CSV feature
* Fixed DOM-based XSS in the Top Services widget of the dashboard
* Fix in AppScan plugin.
* Fix HTML injection in Vulnerability template.
* Add new plugin: Junit XML
* Improved pagination in new vuln modal of status report
* Added "Policy Violations" field for Vulnerabilities

May 24, 2017:
---
* Fixed bug when editing workspaces created in GTK
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.5.0
2.6.0
2 changes: 1 addition & 1 deletion config/default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<faraday>

<appname>Faraday - Penetration Test IDE</appname>
<version>2.5.0</version>
<version>2.6.0</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>
Expand Down
6 changes: 4 additions & 2 deletions faraday-server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
# Faraday Penetration Test IDE
# Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/)
# See the file 'doc/LICENSE' for the license information
import argparse
import os
import subprocess
import sys
import argparse
import subprocess

import server.config
import server.couchdb
import server.utils.logger
from server.utils import daemonize
from utils import dependencies
from utils.user_input import query_yes_no
from faraday import FARADAY_BASE

logger = server.utils.logger.get_logger(__name__)

Expand Down Expand Up @@ -87,6 +88,7 @@ def run_server(args):


def main():
os.chdir(FARADAY_BASE)
parser = argparse.ArgumentParser()
parser.add_argument('--ssl', action='store_true', help='enable HTTPS')
parser.add_argument('--debug', action='store_true', help='run Faraday Server in debug mode')
Expand Down
12 changes: 10 additions & 2 deletions persistence/server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ def __init__(self, vuln, workspace_name):
self.confirmed = vuln.get('confirmed', False)
self.resolution = vuln.get('resolution')
self.status = vuln.get('status', "opened")
self.policyviolations = vuln.get('policyviolations', list())

def setID(self, parent_id):
ModelBase.setID(self, parent_id, self.name, self.description)
Expand Down Expand Up @@ -1100,7 +1101,7 @@ def align_string_based_vulns(severity):
return severity

def updateAttributes(self, name=None, desc=None, data=None,
severity=None, resolution=None, refs=None, status=None):
severity=None, resolution=None, refs=None, status=None, policyviolations=None):
if name is not None:
self.name = name
if desc is not None:
Expand All @@ -1115,6 +1116,8 @@ def updateAttributes(self, name=None, desc=None, data=None,
self.refs = refs
if status is not None:
self.setStatus(status)
if policyviolations is not None:
self.policyviolations = policyviolations

def getID(self): return self.id
def getDesc(self): return self.desc
Expand All @@ -1124,6 +1127,7 @@ def getRefs(self): return self.refs
def getConfirmed(self): return self.confirmed
def getResolution(self): return self.resolution
def getStatus(self): return self.status
def getPolicyViolations(self): return self.policyviolations

def setStatus(self, status):
self.status = status
Expand Down Expand Up @@ -1155,6 +1159,7 @@ def __init__(self, vuln_web, workspace_name):
self.tags = vuln_web.get('tags')
self.target = vuln_web.get('target')
self.parent = vuln_web.get('parent')
self.policyviolations = vuln_web.get('policyviolations', list())

def setID(self, parent_id):
ModelBase.setID(self, parent_id, self.name, self.website, self.path, self.description)
Expand All @@ -1178,7 +1183,7 @@ def publicattrsrefs():

def updateAttributes(self, name=None, desc=None, data=None, website=None, path=None, refs=None,
severity=None, resolution=None, request=None,response=None, method=None,
pname=None, params=None, query=None, category=None, status=None):
pname=None, params=None, query=None, category=None, status=None, policyviolations=None):

super(self.__class__, self).updateAttributes(name, desc, data, severity, resolution, refs, status)

Expand All @@ -1200,6 +1205,8 @@ def updateAttributes(self, name=None, desc=None, data=None, website=None, path=N
self.query = query
if category is not None:
self.category = category
if policyviolations is not None:
self.policyviolations = policyviolations

def getDescription(self): return self.description
def getPath(self): return self.path
Expand All @@ -1220,6 +1227,7 @@ def getStatus(self): return self.status
def getTags(self): return self.tags
def getTarget(self): return self.target
def getParent(self): return self.parent
def getPolicyViolations(self): return self.policyviolations

def tieBreakable(self, key):
"""
Expand Down
8 changes: 4 additions & 4 deletions plugins/repo/appscan/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,14 @@ def __init__(self, output):
self.obj_xml = objectify.fromstring(output)

def parse_issues(self):

for issue in self.obj_xml["issue-type-group"]["item"]:
url_list = []
obj_issue = {}

obj_issue["name"] = issue["name"].text
obj_issue['advisory'] = issue["advisory"]["ref"].text

if(issue["cve"]):
if("cve" in issue):
obj_issue['cve'] = issue["cve"].text

for threat in self.obj_xml["url-group"]["item"]:
Expand All @@ -65,7 +64,7 @@ def parse_issues(self):
for item in self.obj_xml["issue-group"]["item"]:

if int(item["url"]["ref"]) == int(threat.get('id')):
if item["issue-type"]["ref"] == threat['issue-type']:
if "test-http-traffic" in item["variant-group"]["item"] and item["issue-type"]["ref"] == threat['issue-type']:

http_traffic = item["variant-group"]["item"]["test-http-traffic"].text.split("\n\n")

Expand All @@ -76,7 +75,8 @@ def parse_issues(self):

obj_issue["severity"] = item["severity"].text
obj_issue["cvss_score"] = item["cvss-score"].text
obj_issue["issue_description"] = item["variant-group"]["item"]["issue-information"]["issue-tip"].text
if ("issue-tip" in item["variant-group"]["item"]["issue-information"]):
obj_issue["issue_description"] = item["variant-group"]["item"]["issue-information"]["issue-tip"].text
break

for recomendation in self.obj_xml["fix-recommendation-group"]["item"]:
Expand Down
16 changes: 8 additions & 8 deletions plugins/repo/arp-scan/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ def parseOutputString(self, output, debug=False):
for line in output.split('\n'):
vals = line.split("\t")

if len(vals[0].split(".")) == 4:

host = vals[0]
h_id = self.createAndAddHost(host)
i_id = self.createAndAddInterface(
h_id, host, ipv4_address=host, mac=vals[1])
n_id = self.createAndAddNoteToHost(
h_id, "NIC VENDOR:", vals[2])
if len(vals) == 3:

if len(vals[0].split(".")) == 4:

host = vals[0]
h_id = self.createAndAddHost(host)
i_id = self.createAndAddInterface(h_id, host, ipv4_address=host, mac=vals[1])
n_id = self.createAndAddNoteToHost(h_id, "NIC VENDOR:", vals[2])

return True

Expand Down
4 changes: 2 additions & 2 deletions plugins/repo/fierce/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def __init__(self, output):
self.items.append(item)

self.isZoneVuln = False
output= output.replace('\\$', '')
r = re.search(
"Whoah, it worked - misconfigured DNS server found:\r\n([^$]+)There isn't much point continuing, you have everything.",
output)
"Whoah, it worked - misconfigured DNS server found:([^$]+)\There isn't much point continuing, you have everything.", output)

if r is not None:

Expand Down
6 changes: 6 additions & 0 deletions plugins/repo/junit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'''
Faraday Penetration Test IDE
Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information
'''
158 changes: 158 additions & 0 deletions plugins/repo/junit/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Faraday Penetration Test IDE
Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information
'''
from __future__ import with_statement
from plugins import core
from model import api
import re
import os
import pprint
import sys
from lxml import etree

try:
import xml.etree.cElementTree as ET
import xml.etree.ElementTree as ET_ORIG
ETREE_VERSION = ET_ORIG.VERSION
except ImportError:
import xml.etree.ElementTree as ET
ETREE_VERSION = ET.VERSION

ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")]

current_path = os.path.abspath(os.getcwd())

__author__ = "Thierry Beauquier"
__license__ = ""
__version__ = "1.0.0"
__maintainer__ = "Thierry Beauquier"
__email__ = "[email protected]"
__status__ = "Development"

'''
This plugin has been designed to be used with python-unittest2/paramiko script to perform security compliancy verification. It enables to have displayed both security scans results (nmap,
nessus, ..) and security verification compliancy (CIS-CAT, compagny's product security requirement) by Faraday-IPE
This plugin requires that a element "host" is added to <testcase/> (sed -i 's/<testcase/<testcase host=\"192.168.1.1\"/' junit.xml)
<testsuite errors="0" failures="1" name="AccountsWithSuperuserPrivilegesShallBeDisabledByDefault-20170118090010" skipped="0" tests="1" time="0.144">
<testcase host="192.168.1.1" classname="AccountsWithSuperuserPrivilegesShallBeDisabledByDefault" name="test_sshdRootLogin" time="0.144">
<failure message="SSH for root account is not disabled: '' matches '' in ''" type="AssertionError">
<![CDATA[Traceback (most recent call last):
File "bsr-ci.py", line 514, in test_sshdRootLogin
self.assertNotRegexpMatches(_ssh('cat /etc/ssh/sshd_config | egrep "^PermitRootLogin" | awk \'{print $2}\' | egrep "no|No|NO"',host),'', 'SSH for root account is not disabled')
AssertionError: SSH for root account is not disabled: '' matches '' in ''
]]> </failure>
</testcase>
<system-out>
<![CDATA[]]> </system-out>
<system-err>
<![CDATA[]]> </system-err>
</testsuite>
'''

class JunitXmlParser(object):
"""
The objective of this class is to parse an xml file generated by the junit.
@param junit_xml_filepath A proper xml generated by junit
"""

def __init__(self, xml_output):

tree = self.parse_xml(xml_output)
if tree:
self.items = [data for data in self.get_items(tree)]
else:
self.items = []

def parse_xml(self, xml_output):
"""
Open and parse an xml file.
@return xml_tree An xml tree instance. None if error.
"""
try:
# return ET.fromstring(xml_output)
tree = etree.fromstring(xml_output)
except SyntaxError, err:
print "SyntaxError: %s. %s" % (err, xml_output)
return None
return tree

def get_items(self, tree):
"""
@return items A list of Failure instances
"""

for node in tree.findall('testsuite/testcase/failure'):
yield Testsuite(node)


class Testsuite(object):

def __init__(self, testsuite_node):
self.node = testsuite_node

self.parent = self.node.getparent()
self.name = self.parent.get('name')
self.host = self.parent.get('host')
if self.host is None:
print 'host element is missing'
self.host = ''

self.message = self.get_text_from_subnode('message')

def get_text_from_subnode(self, subnode_xpath_expr):
"""
Finds a subnode in the host node and the retrieves a value from it.
@return An attribute value
"""
sub_node = self.node.get(subnode_xpath_expr)
if sub_node is not None:
return sub_node

return None

class JunitPlugin(core.PluginBase):
"""
Example plugin to parse junit output.
"""

def __init__(self):
core.PluginBase.__init__(self)
self.id = "Junit"
self.name = "Junit XML Output Plugin"
self.plugin_version = "0.0.1"
self.version = ""
self.framework_version = "1.0.0"
self.options = None
self._current_output = None
self._command_regex = None

def parseOutputString(self, output, debug=False):

parser = JunitXmlParser(output)
for item in parser.items:
h_id = self.createAndAddHost(item.host, os="Linux")
i_id = self.createAndAddInterface(h_id, item.host, ipv4_address=item.host)
self.createAndAddVulnToHost(h_id, name=item.name, desc=item.message, ref=[], severity="High")
del parser

def createPlugin():
return JunitPlugin()

if __name__ == '__main__':
parser = JunitXmlParser(sys.argv[1])
for item in parser.items:
if item.status == 'up':
print item
Loading

0 comments on commit 8b34d77

Please sign in to comment.