|
| 1 | +#!/usr/bin/env python2.7 |
| 2 | +''' |
| 3 | +Faraday Penetration Test IDE |
| 4 | +Copyright (C) 2014 Infobyte LLC (http://www.infobytesec.com/) |
| 5 | +See the file 'doc/LICENSE' for the license information |
| 6 | +
|
| 7 | +''' |
| 8 | +''' |
| 9 | +This script either updates or removes Interfaces, Services and Vulnerabilities in case their parent property is null. |
| 10 | +If the property is null but a parent is found in Couch, the document is updated. |
| 11 | +If the parent is not found in Couch the document is deleted, since it is an invalid one. |
| 12 | +''' |
| 13 | + |
| 14 | +import argparse |
| 15 | +import json |
| 16 | +import requests |
| 17 | +import os |
| 18 | +from pprint import pprint |
| 19 | + |
| 20 | +def main(): |
| 21 | + #arguments parser |
| 22 | + parser = argparse.ArgumentParser(prog='fixBrokenChildren', epilog="Example: ./%(prog)s.py") |
| 23 | + parser.add_argument('-c', '--couchdburi', action='store', type=str, |
| 24 | + dest='couchdb',default="http://127.0.0.1:5984", |
| 25 | + help='Couchdb URL (default http://127.0.0.1:5984)') |
| 26 | + parser.add_argument('-d', '--db', action='store', type=str, |
| 27 | + dest='db', help='DB to process') |
| 28 | + |
| 29 | + #arguments put in variables |
| 30 | + args = parser.parse_args() |
| 31 | + dbs = list() |
| 32 | + |
| 33 | + #default value from ENV COUCHDB |
| 34 | + couchdb = os.environ.get('COUCHDB') |
| 35 | + #Else from argument |
| 36 | + if not couchdb: |
| 37 | + couchdb = args.couchdb |
| 38 | + |
| 39 | + if args.db: |
| 40 | + dbs.append(args.db) |
| 41 | + |
| 42 | + if len(dbs) == 0: |
| 43 | + dbs = requests.get(couchdb + '/_all_dbs') |
| 44 | + dbs = dbs.json() |
| 45 | + dbs = filter(lambda x: not x.startswith('_') and x != 'cwe' and x != 'reports', dbs) |
| 46 | + |
| 47 | + for db in dbs: |
| 48 | + fixDb(couchdb, db) |
| 49 | + |
| 50 | +def fixDb(couchdb, db): |
| 51 | + couchdb = str(couchdb) |
| 52 | + db = str(db) |
| 53 | + |
| 54 | + #get all broken elements from CouchDB |
| 55 | + headers = {'Content-Type': 'application/json'} |
| 56 | + payload = { "map" : """function(doc) { if(doc.type == \"Interface\" || |
| 57 | + doc.type == \"Service\" || |
| 58 | + doc.type == \"Vulnerability\" || |
| 59 | + doc.type == \"VulnerabilityWeb\"){ if(doc.parent == null) emit(doc.parent, 1); }}""" } |
| 60 | + |
| 61 | + r = requests.post(couchdb + '/' + db + '/_temp_view', headers=headers, data=json.dumps(payload)) |
| 62 | + response_code = r.status_code |
| 63 | + |
| 64 | + if response_code == 200: |
| 65 | + response = r.json() |
| 66 | + rows = response['rows'] |
| 67 | + rows = sorted(rows, key=lambda x: x['id']) |
| 68 | + |
| 69 | + if len(rows) > 0: |
| 70 | + print " [*[ Processing " + str(len(rows)) + " documents for " + db + " ]*]" |
| 71 | + |
| 72 | + for row in rows: |
| 73 | + id = str(row['id']) |
| 74 | + parent = str(id[:id.rfind('.')]) |
| 75 | + |
| 76 | + parent_response = requests.get(couchdb + '/' + db + '/' + parent) |
| 77 | + parent_code = parent_response.status_code |
| 78 | + |
| 79 | + child_response = requests.get(couchdb + '/' + db + '/' + id) |
| 80 | + child = child_response.json() |
| 81 | + |
| 82 | + #object parent exists in Couch |
| 83 | + #update parent field in obj |
| 84 | + if parent_code == 200: |
| 85 | + print " - Updating " + child['type'] + " \"" + child['name'] + "\" with ID " + id |
| 86 | + child['parent'] = parent |
| 87 | + #print doc['parent'] |
| 88 | + update = requests.put(couchdb + '/' + db + '/' + id, headers=headers, data=json.dumps(child)) |
| 89 | + print " -- " + update.reason + " (" + str(update.status_code) + ")" |
| 90 | + |
| 91 | + #object has no valid parent |
| 92 | + #delete obj |
| 93 | + elif parent_code == 404: |
| 94 | + # delete vuln |
| 95 | + print " - Deleting " + child['type'] + " \"" + child['name'] + "\" with ID " + id |
| 96 | + delete = requests.delete(couchdb + '/' + db + '/' + id + '?rev=' + child['_rev']) |
| 97 | + print " -- " + delete.reason + " (" + str(delete.status_code) + ")" |
| 98 | + elif parent_code == 401: |
| 99 | + print " Autorization required, make sure to add user:pwd to Couch URI using --couchdburi" |
| 100 | + else: |
| 101 | + print " Fail" |
| 102 | + else: |
| 103 | + print "Congratz, " + db + " is just fine!" |
| 104 | + elif response_code == 401: |
| 105 | + print " Autorization required to access " + db + ", make sure to add user:pwd to Couch URI using --couchdburi" |
| 106 | + |
| 107 | +if __name__ == "__main__": |
| 108 | + main() |
0 commit comments