Commits

Tim Tomes committed 1a7628b

added the wigle module, created a geo category for recon hosts modules, relocated several modules to the new geo category, removed the server_enum module, rebuilt the api key management system including how keys are stored, and made major changes to the framework to utilize a newly created FrameworkException. Framework methods now raise a custom exception rather than return None. The framework also handles all thrown FrameworkExceptions for the do_run method, so minimal error handling is requird within modules. All modules have been updated to reflect the change.

Comments (0)

Files changed (72)

 *.pyc
 workspaces/
-experimental/

core/framework.py

 import textwrap
 import socket
 import datetime
+import HTMLParser
 import subprocess
 import traceback
 import __builtin__
         self.do_help.__func__.__doc__ = '''Displays this menu'''
         self.doc_header = 'Commands (type [help|?] <topic>):'
         self.goptions = __builtin__.goptions
+        self.keys = __builtin__.keys
         self.workspace = __builtin__.workspace
         self.options = {}
 
             category = module.split(self.module_delimiter)[0]
             if category != last_category:
                 # print header
-                print ''
                 last_category = category
-                print '%s%s:' % (self.spacer, last_category.title())
-                print '%s%s' % (self.spacer, self.ruler*key_len)
+                self.heading(last_category)
             # print module
             print '%s%s' % (self.spacer*2, module)
         print ''
 
     def unescape(self, s):
         '''Unescapes HTML markup and returns an unescaped string.'''
-        import htmllib
-        p = htmllib.HTMLParser(None)
-        p.save_bgn()
-        p.feed(s)
-        return p.save_end()
+        h = HTMLParser.HTMLParser()
+        return h.unescape(s)
+        #p = htmllib.HTMLParser(None)
+        #p.save_bgn()
+        #p.feed(s)
+        #return p.save_end()
 
     def is_hash(self, hashstr):
         hashdict = [
     def table(self, tdata, header=False, table=None):
         '''Accepts a list of rows and outputs a table.'''
         if len(set([len(x) for x in tdata])) > 1:
-            self.error('Row lengths not consistent.')
-            return
+            raise FrameworkException('Row lengths not consistent.')
         lens = []
         cols = len(tdata[0])
         for i in range(0,cols):
 
         conn = sqlite3.connect('%s/data.db' % (self.workspace))
         cur = conn.cursor()
-        try: cur.execute(query, values)
-        except sqlite3.OperationalError as e:
-            self.error('Invalid query. %s %s' % (type(e).__name__, e.message))
-            return
+        cur.execute(query, values)
         conn.commit()
         conn.close()
         return cur.rowcount
 
-    def query(self, params, return_results=True):
+    def query(self, query):
         '''Queries the database and returns the results as a list.'''
-        # based on the do_ouput method
-        if not params:
-            self.help_query()
-            return
         conn = sqlite3.connect('%s/data.db' % (self.workspace))
         cur = conn.cursor()
-        try: cur.execute(params)
-        except sqlite3.OperationalError as e:
-            self.error('Invalid query. %s %s' % (type(e).__name__, e.message))
-            return False
-        if not return_results:
-            if cur.rowcount == -1 and cur.description:
-                header = tuple([x[0] for x in cur.description])
-                tdata = cur.fetchall()
-                if not tdata:
-                    self.output('No data returned.')
-                else:
-                    tdata.insert(0, header)
-                    self.table(tdata, True)
-                    self.output('%d rows returned' % (len(tdata)))
-            else:
-                conn.commit()
-                self.output('%d rows affected.' % (cur.rowcount))
-            conn.close()
-            return
+        cur.execute(query)
+        # a rowcount of -1 typically refers to a select statement
+        if cur.rowcount == -1:
+            rows = cur.fetchall()
+            results = rows
+        # a rowcount of 1 == success and 0 == failure
         else:
-            # a rowcount of -1 typically refers to a select statement
-            if cur.rowcount == -1:
-                rows = cur.fetchall()
-                result = rows
-            # a rowcount of 1 == success and 0 == failure
-            else:
-                conn.commit()
-                result = cur.rowcount
-            conn.close()
-            return result
+            conn.commit()
+            results = cur.rowcount
+        conn.close()
+        return results
 
     #==================================================
     # OPTIONS METHODS
             # if value type is bool or int, then we know the options is set
             if not type(self.options[option]['value']) in [bool, int]:
                 if self.options[option]['reqd'].lower() == 'yes' and not self.options[option]['value']:
-                    self.error('Value required for the \'%s\' option.' % (option))
-                    return False
-        return True
+                    raise FrameworkException('Value required for the \'%s\' option.' % (option))
+        return
 
     def get_source(self, params, query=None):
         source = params.split()[0].lower()
-        if source == 'query':
-            query = ' '.join(params.split()[1:])
-            results = self.query(query, True)
+        if source in ['query', 'db']:
+            query = ' '.join(params.split()[1:]) if source == 'query' else query
+            try: results = self.query(query)
+            except sqlite3.OperationalError as e:
+                raise FrameworkException('Invalid source query. %s %s' % (type(e).__name__, e.message))
             if not results:
-                self.error('No items found.')
                 sources = []
             elif len(results[0]) > 1:
-                self.error('Too many columns of data returned.')
-                source = []
+                raise FrameworkException('Too many columns of data as source input.')
             else: sources = [x[0] for x in results]
-        elif source == 'db' and query:
-            rows = self.query(query)
-            if not rows:
-                self.error('No items found.')
-                sources = []
-            else: sources = [x[0] for x in rows]
         elif os.path.exists(source):
             sources = open(source).read().split()
         else:
     #==================================================
 
     def display_keys(self):
-        conn = sqlite3.connect(self.goptions['key_file']['value'])
-        cur = conn.cursor()
-        cur.execute('SELECT * FROM keys')
-        rows = cur.fetchall()
-        conn.close()
-        tdata = [('Name', 'Value')]
-        for row in rows:
-            tdata.append((row[0], row[1]))
-        self.table(tdata, True)
-
-    def manage_key(self, key_name, key_text):
-        '''Automates the API key retrieval and storage process.'''
-        key = self.get_key_from_db(key_name)
-        if not key:
-            key = self.get_key_from_user(key_text)
-            if not key:
-                self.error('No %s.' % (key_text))
-                return False
-            if self.add_key_to_db(key_name, key):
-                self.output('%s added.' % (key_text))
-            else:
-                self.output('Error adding %s.' % (key_text))
-        return key
-
-    def get_key_from_db(self, key_name):
-        '''Retrieves an API key from the API key storage database.'''
-        conn = sqlite3.connect(self.goptions['key_file']['value'])
-        cur = conn.cursor()
-        cur.execute('SELECT value FROM keys WHERE name=?', (key_name,))
-        row = cur.fetchone()
-        conn.close()
-        if row:
-            return str(row[0])
-        else:
-            return False
+        tdata = []
+        for key in sorted(self.keys):
+            tdata.append([key, self.keys[key]])
+        if tdata:
+            tdata.insert(0, ['Name', 'Value'])
+            self.table(tdata, header=True)
+        else: self.output('No API keys stored.')
 
-    def get_key_from_user(self, key_text='API Key'):
-        '''Retrieves an API key from the user.'''
+    def load_keys(self):
+        key_path = './data/keys.dat'
+        if os.path.exists(key_path):
+            try:
+                key_data = json.loads(open(key_path, 'rb').read())
+                for key in key_data: self.keys[key] = key_data[key]
+            except:
+                self.error('Corrupt key file.')
+
+    def save_keys(self):
+        key_path = './data/keys.dat'
+        key_file = open(key_path, 'wb')
+        json.dump(self.keys, key_file)
+        key_file.close()
+
+    def get_key(self, key_name):
         try:
-            key = raw_input("Enter %s (blank to skip): " % (key_text))
-            return str(key)
-        except KeyboardInterrupt:
-            print ''
-            return False
+            return self.keys[key_name]
+        except KeyError:
+            raise FrameworkException('API key \'%s\' not found. Add API keys with the \'key add\' command.' % (key_name))
 
-    def add_key_to_db(self, key_name, key_value):
-        '''Adds an API key to the API key storage database.'''
-        conn = sqlite3.connect(self.goptions['key_file']['value'])
-        cur = conn.cursor()
-        try: cur.execute('INSERT INTO keys VALUES (?,?)', (key_name, key_value))
-        except sqlite3.OperationalError:
-            return False
-        except sqlite3.IntegrityError:
-            try: cur.execute('UPDATE keys SET value=? WHERE name=?', (key_value, key_name))
-            except sqlite3.OperationalError:
-                return False
-        conn.commit()
-        conn.close()
-        return True
+    def add_key(self, name, value):
+        self.keys[name] = value
+        self.save_keys()
+
+    def delete_key(self, name):
+        del self.keys[name]
+        self.save_keys()
 
     #==================================================
     # REQUEST METHODS
     #==================================================
 
     def search_bing_api(self, query, limit=0):
-        api_key = self.manage_key('bing', 'Bing API key')
-        if not api_key: return
+        api_key = self.get_key('bing_api')
         url = 'https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Web'
         payload = {'Query': query, '$format': 'json'}
         results = []
         while True:
             resp = None
             resp = self.request(url, payload=payload, auth=(api_key, api_key))
-            sys.stdout.write('.'); sys.stdout.flush()
             if resp.json == None:
-                self.error('Invalid JSON response.\n%s' % (resp.text))
-                continue
+                raise FrameworkException('Invalid JSON response.\n%s' % (resp.text))
             # add new results
             if 'results' in resp.json['d']:
                 results.extend(resp.json['d']['results'])
                 payload['$skip'] = resp.json['d']['__next'].split('=')[-1]
             else:
                 break
-        print ''
         return results
 
     def search_google_api(self, query, limit=0):
-        api_key = self.manage_key('google_api', 'Google API key')
-        if not api_key: return
-        cse_id = self.manage_key('google_cse', 'Google CSE ID')
-        if not cse_id: return
+        api_key = self.get_key('google_api')
+        cse_id = self.get_key('google_cse')
         url = 'https://www.googleapis.com/customsearch/v1'
         payload = {'alt': 'json', 'prettyPrint': 'false', 'key': api_key, 'cx': cse_id, 'q': query}
         results = []
         while True:
             resp = None
             resp = self.request(url, payload=payload)
-            sys.stdout.write('.'); sys.stdout.flush()
             if resp.json == None:
-                self.error('Invalid JSON response.\n%s' % (resp.text))
-                continue
+                raise FrameworkException('Invalid JSON response.\n%s' % (resp.text))
             # add new results
             if 'items' in resp.json:
                 results.extend(resp.json['items'])
                 payload['start'] = resp.json['queries']['nextPage'][0]['startIndex']
             else:
                 break
-        print ''
         return results
 
     def request(self, url, method='GET', timeout=None, payload={}, headers={}, cookies={}, auth=(), redirect=True):
     def do_info(self, params):
         '''Displays module information'''
         pattern = '%s%s:'
-        for item in ['Name', 'Author', 'Description']:
+        self.info['Path'] = 'modules/%s.py' % (self.modulename)
+        for item in ['Name', 'Path', 'Author', 'Description']:
             print ''
             print pattern % (self.spacer, item)
             print pattern[:-1] % (self.spacer*2, textwrap.fill(self.info[item], 100, initial_indent='', subsequent_indent=self.spacer*2))
                 self.options[name]['value'] = self.autoconvert(value)
             else: self.error('Invalid option.')
 
+    def do_keys(self, params):
+        '''Manages framework API keys'''
+        if params:
+            params = params.split()
+            arg = params.pop(0).lower()
+            if arg in ['add', 'update']:
+                if len(params) == 2:
+                    self.add_key(params[0], params[1])
+                    self.output('Key \'%s\' added.' % (params[0]))
+                else: print 'Usage: keys [add|update] <name> <value>'
+                return
+            elif arg == 'delete':
+                if len(params) == 1:
+                    self.delete_key(params[0])
+                    self.output('Key \'%s\' deleted.' % (params[0]))
+                else: print 'Usage: keys delete <name>'
+                return
+        self.help_keys()
+
     def do_query(self, params):
         '''Queries the database'''
-        self.query(params, False)
+        if not params:
+            self.help_query()
+            return
+        conn = sqlite3.connect('%s/data.db' % (self.workspace))
+        cur = conn.cursor()
+        try: cur.execute(params)
+        except sqlite3.OperationalError as e:
+            self.error('Invalid query. %s %s' % (type(e).__name__, e.message))
+            return
+        if cur.rowcount == -1 and cur.description:
+            header = tuple([x[0] for x in cur.description])
+            tdata = cur.fetchall()
+            if not tdata:
+                self.output('No data returned.')
+            else:
+                tdata.insert(0, header)
+                self.table(tdata, True)
+                self.output('%d rows returned' % (len(tdata)))
+        else:
+            conn.commit()
+            self.output('%d rows affected.' % (cur.rowcount))
+        conn.close()
+        return
 
     def do_show(self, params):
         '''Shows various framework items'''
                 self.display_dashboard()
                 return
             elif arg in [x[0] for x in self.query('SELECT name FROM sqlite_master WHERE type=\'table\'')]:
-                self.query('SELECT * FROM %s ORDER BY 1' % (arg), False)
+                self.do_query('SELECT * FROM %s ORDER BY 1' % (arg))
                 return
         self.help_show()
 
 
     def do_run(self, params):
         '''Runs the module'''
-        if not self.validate_options(): return
         try:
+            self.validate_options()
             self.module_run()
-        except:
-            print '-'*60
-            traceback.print_exc()
-            print '-'*60
-        self.query('INSERT OR REPLACE INTO dashboard (module, runs) VALUES (\'%(x)s\', COALESCE((SELECT runs FROM dashboard WHERE module=\'%(x)s\')+1, 1))' % {'x': self.modulename})
+        except Exception as e:
+            self.error(e.__str__())
+        except KeyboardInterrupt:
+            print ''
+        else:
+            self.query('INSERT OR REPLACE INTO dashboard (module, runs) VALUES (\'%(x)s\', COALESCE((SELECT runs FROM dashboard WHERE module=\'%(x)s\')+1, 1))' % {'x': self.modulename})
 
     def module_run(self):
         pass
         print 'Usage: set <option> <value>'
         self.display_options(None)
 
+    def help_keys(self):
+        print 'Usage: key [add|delete|update]'
+
     def help_query(self):
         print 'Usage: query <sql>'
         print ''
     def complete_set(self, text, *ignored):
         return [x for x in self.options if x.startswith(text)]
 
+    def complete_keys(self, text, line, *ignored):
+        args = line.split()
+        options = ['add', 'delete', 'update']
+        if len(args) > 1 and args[1].lower() in options:
+            return [x for x in self.keys.keys() if x.startswith(text)]
+        return [x for x in options if x.startswith(text)]
+
     def complete_show(self, text, line, *ignored):
         args = line.split()
         if len(args) > 1 and args[1].lower() == 'modules':
             return json.loads(self.text)
         except ValueError:
             return None
+
+class FrameworkException(Exception):
+    pass

modules/discovery/exploitable/http/dnn_fcklinkgallery.py

 
     def module_run(self):
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
 
         # check all hosts for DNN fcklinkgallery page
         protocols = ['http', 'https']
                     resp = self.request(url, redirect=False)
                     code = resp.status_code
                 except KeyboardInterrupt:
-                    print ''
-                    return
+                    raise KeyboardInterrupt
                 except:
                     code = 'Error'
                 if code == 200 and '> Link Gallery' in resp.text:

modules/discovery/exploitable/http/generic_restaurantmenu.py

                      }
 
     def module_run(self):
-        validate = self.options['validate']['value']
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
+        validate = self.options['validate']['value']
 
         # check all hosts for GenericRestaurantMenu Menu Categories Editor Page, SQL Query Info Disclosure, and Possible SQLi Vulnerbility
         protocols = ['http', 'https']
                     resp = self.request(url, redirect=False)
                     code = resp.status_code
                 except KeyboardInterrupt:
-                    print ''
-                    return
+                    raise KeyboardInterrupt
                 except:
                     code = 'Error'
                 if code == 200 and 'Menu Categories' in resp.text:
                             resp = self.request(vulncode, redirect=False)
                             code = resp.status_code
                         except KeyboardInterrupt:
-                            print ''
-                            return
+                            raise KeyboardInterrupt
                         except:
                             code = 'Error'
                         if code == 500 and 'Executing Database Query' in resp.text:

modules/discovery/exploitable/http/webwiz_rte.py

 
     def module_run(self):
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
 
         protocols = ['http', 'https']
         files = [
                         resp = self.request(url, redirect=False)
                         code = resp.status_code
                     except KeyboardInterrupt:
-                        print ''
-                        return
+                        raise KeyboardInterrupt
                     except:
                         code = 'Error'
                     if code == 200 and 'Attach File Properties' in resp.text:

modules/discovery/info_disclosure/dns/cache_snoop.py

                      }
 
     def module_run(self):
-        nameserver = self.options['nameserver']['value']
-        
         domains = self.get_source(self.options['domains']['value'])
-        if not domains: return
+        nameserver = self.options['nameserver']['value']
 
         self.output('Starting queries...')
         
             query = dns.message.make_query(domain, dns.rdatatype.A, dns.rdataclass.IN)
             # unset the Recurse flag 
             query.flags ^= dns.flags.RD
-            try:
-                # try the query
-                response = dns.query.udp(query, nameserver)
-                if len(response.answer) > 0:
-                    self.alert('%s => Snooped!' % (domain))
-                else:
-                    self.verbose('%s => Not Found.' % (domain))
-                continue
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                return
+            response = dns.query.udp(query, nameserver)
+            if len(response.answer) > 0:
+                self.alert('%s => Snooped!' % (domain))
+            else:
+                self.verbose('%s => Not Found.' % (domain))
+            continue

modules/discovery/info_disclosure/http/backup_finder.py

                      }
 
     def module_run(self):
+        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
         uri = self.options['uri']['value']
         searchstr = self.options['searchstr']['value']
-        
-        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
 
         protocols = ['http', 'https']
 
                         resp = self.request(url, redirect=False)
                         code = resp.status_code
                     except KeyboardInterrupt:
-                        print ''
-                        return
+                        raise KeyboardInterrupt
                     except:
                         code = 'Error'
                     if code == 200 and searchstr in resp.text:

modules/discovery/info_disclosure/http/interesting_files.py

         return data_ct
 
     def module_run(self):
-        download = self.options['download']['value']
-        
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
+        download = self.options['download']['value']
 
         protocols = ['http', 'https']
         # (filename, string to search for to prevent false positive)
                         resp = self.request(url, timeout=2, redirect=False)
                         code = resp.status_code
                     except KeyboardInterrupt:
-                        print ''
-                        return
+                        raise KeyboardInterrupt
                     except:
                         code = 'Error'
                     if code == 200:

modules/experimental/rce.py

+import framework
+# unique to module
+import urllib
+
+class Module(framework.module):
+
+    def __init__(self, params):
+        framework.module.__init__(self, params)
+        self.register_option('base_url', None, 'yes', 'the target resource url excluding any parameters')
+        self.register_option('parameters', None, 'yes', 'the query parameters with \'<rce>\' signifying the value of the vulnerable parameter')
+        self.register_option('basic_user', None, 'no', 'username for basic authentication')
+        self.register_option('basic_pass', None, 'no', 'password for basic authentication')
+        self.register_option('cookie', None, 'no', 'cookie string containing authenticated session data')
+        self.register_option('post', False, 'yes', 'set the request method to post. parameters should still be submitted in the url option')
+        self.register_option('mark_start', None, 'no', 'string to match page content preceding the command output')
+        self.register_option('mark_end', None, 'no', 'string to match page content following the command output')
+        self.info = {
+                     'Name': 'Remote Commnd Execution Shell Interface',
+                     'Author': 'Tim Tomes (@LaNMaSteR53)',
+                     'Description': 'Provides a shell interface for remote command execution flaws in web applications.',
+                     'Comments': []
+                     }
+
+    def help(self):
+        return 'Type \'exit\' or \'ctrl-c\' to exit the shell.'
+
+    def parse_params(self, params):
+        params = params.split('&')
+        params = [param.split('=') for param in params]
+        return [(urllib.unquote_plus(param[0]), urllib.unquote_plus(param[1])) for param in params]
+
+    def module_run(self):
+        base_url = self.options['base_url']['value']
+        base_params = self.options['parameters']['value']
+        username = self.options['basic_user']['value']
+        password = self.options['basic_pass']['value']
+        cookie = self.options['cookie']['value']
+        start = self.options['mark_start']['value']
+        end = self.options['mark_end']['value']
+
+        # process authentication
+        auth = (username, password) if username and password else ()
+        headers = {'Cookie': cookie} if cookie else {}
+
+        # set the request method
+        method = 'POST' if self.options['post']['value'] else 'GET'
+
+        print 'Type \'help\' or \'?\' for assistance.'
+        while True:
+            # get command from the terminal
+            cmd = raw_input("cmd> ")
+            if cmd.lower() == 'exit': return
+            elif cmd.lower() in ['help', '?']:
+                print self.help()
+                continue
+            # build the payload from the base_params string
+            payload = {}
+            params = self.parse_params(base_params.replace('<rce>', cmd))
+            for param in params:
+                payload[param[0]] = param[1]
+            # send the request
+            resp = self.request(base_url, method=method, payload=payload, headers=headers, auth=auth)
+            # process the response
+            output = resp.text
+            if start and end:
+                try: output = output[output.index(start)+len(start):]
+                except ValueError: self.error('Invalid start marker.')
+                try: output = output[:output.index(end)]
+                except ValueError: self.error('Invalid end marker.')
+            print '%s' % (output.strip())

modules/exploitation/shell/http/rce.py

-import framework
-# unique to module
-import urllib
-
-class Module(framework.module):
-
-    def __init__(self, params):
-        framework.module.__init__(self, params)
-        self.register_option('base_url', None, 'yes', 'the target resource url excluding any parameters')
-        self.register_option('parameters', None, 'yes', 'the query parameters with \'<rce>\' signifying the value of the vulnerable parameter')
-        self.register_option('basic_user', None, 'no', 'username for basic authentication')
-        self.register_option('basic_pass', None, 'no', 'password for basic authentication')
-        self.register_option('cookie', None, 'no', 'cookie string containing authenticated session data')
-        self.register_option('post', False, 'yes', 'set the request method to post. parameters should still be submitted in the url option')
-        self.register_option('mark_start', None, 'no', 'string to match page content preceding the command output')
-        self.register_option('mark_end', None, 'no', 'string to match page content following the command output')
-        self.info = {
-                     'Name': 'Remote Commnd Execution Shell Interface',
-                     'Author': 'Tim Tomes (@LaNMaSteR53)',
-                     'Description': 'Provides a shell interface for remote command execution flaws in web applications.',
-                     'Comments': []
-                     }
-
-    def help(self):
-        return 'Type \'exit\' or \'ctrl-c\' to exit the shell.'
-
-    def parse_params(self, params):
-        params = params.split('&')
-        params = [param.split('=') for param in params]
-        return [(urllib.unquote_plus(param[0]), urllib.unquote_plus(param[1])) for param in params]
-
-    def module_run(self):
-        base_url = self.options['base_url']['value']
-        base_params = self.options['parameters']['value']
-        username = self.options['basic_user']['value']
-        password = self.options['basic_pass']['value']
-        cookie = self.options['cookie']['value']
-        start = self.options['mark_start']['value']
-        end = self.options['mark_end']['value']
-
-        # process authentication
-        auth = (username, password) if username and password else ()
-        headers = {'Cookie': cookie} if cookie else {}
-
-        # set the request method
-        method = 'POST' if self.options['post']['value'] else 'GET'
-
-        print 'Type \'help\' or \'?\' for assistance.'
-        while True:
-            # get command from the terminal
-            try:
-                cmd = raw_input("cmd> ")
-            except KeyboardInterrupt:
-                print ''
-                return
-            if cmd.lower() == 'exit': return
-            elif cmd.lower() in ['help', '?']:
-                print self.help()
-                continue
-            # build the payload from the base_params string
-            payload = {}
-            params = self.parse_params(base_params.replace('<rce>', cmd))
-            for param in params:
-                payload[param[0]] = param[1]
-            # send the request
-            try: resp = self.request(base_url, method=method, payload=payload, headers=headers, auth=auth)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-            # process the response
-            output = resp.text
-            if start and end:
-                try: output = output[output.index(start)+len(start):]
-                except ValueError: self.error('Invalid start marker.')
-                try: output = output[:output.index(end)]
-                except ValueError: self.error('Invalid end marker.')
-            print '%s' % (output.strip())

modules/recon/contacts/enum/http/namechk.py

 
         # retrive list of sites
         url = 'http://namechk.com/Content/sites.min.js'
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
         
         # extract sites info from the js file
         pattern = 'n:"(.+?)",r:\d+,i:(\d+)'
             # build and send the request
             try: resp = self.request(url, method='POST', headers=headers, payload=payload)
             except KeyboardInterrupt:
-                print ''
-                return
+                raise KeyboardInterrupt
             except Exception as e:
                 self.error('%s: %s' % (name, e.__str__()))
                 continue

modules/recon/contacts/enum/http/pwnedlist.py

 
     def module_run(self):
         accounts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT email FROM contacts WHERE email IS NOT NULL ORDER BY email')
-        if not accounts: return
 
         # retrieve status
         cnt = 0
             status = None
             url = 'https://www.pwnedlist.com/query'
             payload = {'inputEmail': hashlib.sha512(account).hexdigest(), 'form.submitted': ''}
-            try: resp = self.request(url, payload=payload, method='POST', redirect=False)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                break
+            resp = self.request(url, payload=payload, method='POST', redirect=False)
             content = resp.text
-            #if 'Gotcha!' in content:
-            #    self.error('Hm... Got a captcha.')
-            #    return
             if '<h3>Nope,' in content:
                 status = 'safe'
                 self.verbose('%s => %s.' % (account, status))

modules/recon/contacts/enum/http/should_change_password.py

 
     def module_run(self):
         emails = self.get_source(self.options['source']['value'], 'SELECT DISTINCT email FROM contacts WHERE email IS NOT NULL ORDER BY email')
-        if not emails: return
         
         total = 0
         emailsFound = 0
         for emailstr in emails:
             # build the request
             payload = {'email': emailstr}
-            try: resp = self.request(url, method="POST", payload=payload)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-
+            resp = self.request(url, method="POST", payload=payload)
             # retrieve the json response
             jsonobj = resp.json
             numFound = jsonobj['num']

modules/recon/contacts/gather/http/jigsaw/contacts_api.py

                      }
 
     def module_run(self):
-        self.api_key = self.manage_key('jigsaw_key', 'Jigsaw API Key')
-        if not self.api_key: return
+        self.api_key = self.get_key('jigsaw_api')
         company_id = self.get_company_id()
         if company_id:
             self.get_contacts(company_id)
         while True:
             payload = {'token': self.api_key, 'name': params, 'offset': cnt, 'pageSize': size}
             self.verbose('Query: %s?%s' % (url, urllib.urlencode(payload)))
-            try: resp = self.request(url, payload=payload, redirect=False)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                return
+            resp = self.request(url, payload=payload, redirect=False)
             jsonobj = resp.json
             if jsonobj['totalHits'] == 0:
                 self.output('No Company Matches Found.')
         id_len = len(max([str(x[0]) for x in all_companies], key=len))
         for company in all_companies:
             self.output('[%s] %s - %s (%s contacts)' % (str(company[0]).ljust(id_len), company[1], company[3], company[2]))
-        try:
-            company_id = raw_input('Enter Company ID from list [%s - %s]: ' % (all_companies[0][1], all_companies[0][0]))
-            if not company_id: company_id = all_companies[0][0]
-            return company_id
-        except KeyboardInterrupt:
-            print ''
-            return
+        company_id = raw_input('Enter Company ID from list [%s - %s]: ' % (all_companies[0][1], all_companies[0][0]))
+        if not company_id: company_id = all_companies[0][0]
+        return company_id
 
     def get_contacts(self, company_id):
         self.output('Gathering Contacts...')
         url = 'https://www.jigsaw.com/rest/searchContact.json'
         while True:
             payload = {'token': self.api_key, 'companyId': company_id, 'offset': cnt, 'pageSize': size}
-            try: resp = self.request(url, payload=payload, redirect=False)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                return
+            resp = self.request(url, payload=payload, redirect=False)
             jsonobj = resp.json
             for contact in jsonobj['contacts']:
                 contact_id = contact['contactId']

modules/recon/contacts/gather/http/jigsaw/contacts_web.py

         payload = {'opCode': 'search', 'freeText': params}
         while True:
             self.verbose('Query: %s?%s' % (url, urllib.urlencode(payload)))
-            try: resp = self.request(url, payload=payload, redirect=False)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                break
+            resp = self.request(url, payload=payload, redirect=False)
             if resp.status_code == 301:
                 header = resp.headers['location']
                 company_id = re.search('\/(\d+?)\/', resp.headers['location']).group(1)
             id_len = len(max([str(x[0]) for x in all_companies], key=len))
             for company in all_companies:
                 self.output('[%s] %s (%s contacts)' % (str(company[0]).ljust(id_len), company[1], company[2]))
-            try:
-                company_id = raw_input('Enter Company ID from list [%s - %s]: ' % (all_companies[0][1], all_companies[0][0]))
-                if not company_id: company_id = all_companies[0][0]
-            except KeyboardInterrupt:
-                print ''
-                company_id = ''
+            company_id = raw_input('Enter Company ID from list [%s - %s]: ' % (all_companies[0][1], all_companies[0][0]))
+            if not company_id: company_id = all_companies[0][0]
             return company_id
 
     def get_contact_ids(self, company_id):
         while True:
             payload['rpage'] = str(page_cnt)
             self.verbose('Query: %s?%s' % (url, urllib.urlencode(payload)))
-            try: content = self.request(url, payload=payload).text
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                break
+            content = self.request(url, payload=payload).text
             pattern = "showContact\('(\d+?)'\)"
             contacts = re.findall(pattern, content)
             if not contacts: break
         for contact_id in contact_ids:
             url = 'http://www.jigsaw.com/BC.xhtml'
             payload = {'contactId': contact_id}
-            try: content = self.request(url, payload=payload).text
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                break
+            content = self.request(url, payload=payload).text
             if 'Contact Not Found' in content: continue
             fname = self.unescape(re.search('<span id="firstname">(.+?)</span>', content).group(1))
             lname = self.unescape(re.search('<span id="lastname">(.+?)</span>', content).group(1))

modules/recon/contacts/gather/http/jigsaw/point_usage.py

     def module_run(self):
         username = self.options['username']['value']
         password = self.options['password']['value']
-        key = self.manage_key('jigsaw_key', 'Jigsaw API Key')
-        if not key: return
+        key = self.get_key('jigsaw_api')
 
         url = 'https://www.jigsaw.com/rest/user.json'
         payload = {'token': key, 'username': username, 'password': password}
-        try: resp = self.request(url, payload=payload, redirect=False)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload, redirect=False)
         if resp.json: jsonobj = resp.json
         else:
             self.error('Invalid JSON response.\n%s' % (resp.text))

modules/recon/contacts/gather/http/jigsaw/purchase_contact.py

     def module_run(self):
         username = self.options['username']['value']
         password = self.options['password']['value']
-        key = self.manage_key('jigsaw_key', 'Jigsaw API Key')
-        if not key: return
+        key = self.get_key('jigsaw_api')
 
         # point guard
         if not self.api_guard(5): return
 
         url = 'https://www.jigsaw.com/rest/contacts/%s.json' % (self.options['contact']['value'])
         payload = {'token': key, 'username': username, 'password': password, 'purchaseFlag': 'true'}
-        try: resp = self.request(url, payload=payload, redirect=False)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload, redirect=False)
         if resp.json: jsonobj = resp.json
         else:
             self.error('Invalid JSON response.\n%s' % (resp.text))

modules/recon/contacts/gather/http/linkedin_auth.py

                      }
 
     def module_run(self):
-        consumer_key = self.manage_key('linkedin_key', 'LinkedIn API Key')
-        if not consumer_key: return
-        consumer_secret = self.manage_key('linkedin_secret', 'LinkedIn Secret Key') 
-        if not consumer_secret: return
+        consumer_key = self.get_key('linkedin_api')
+        consumer_secret = self.get_key('linkedin_secret')
         # Use API key and secret to instantiate consumer object
         self.consumer = oauth.Consumer(consumer_key, consumer_secret)
-        self.access_token = {'oauth_token': self.get_key_from_db('linkedin_token'),'oauth_token_secret': self.get_key_from_db('linkedin_token_secret')}
-        if not self.access_token['oauth_token']: self.get_access_tokens()
-        if self.access_token['oauth_token']: self.get_contacts()
+        self.access_token = {}
+        try: self.access_token = {'oauth_token': self.get_key('linkedin_token'),'oauth_token_secret': self.get_key('linkedin_token_secret')}
+        except framework.FrameworkException: pass
+        if not self.access_token: self.get_access_tokens()
+        if self.access_token: self.get_contacts()
 
     def get_access_tokens(self):
         client = oauth.Client(self.consumer)
         request_token_url = 'https://api.linkedin.com/uas/oauth/requestToken?scope=r_basicprofile+r_network'
-        try: resp, content = client.request(request_token_url, "POST")
-        except KeyboardInterrupt:
-            print ''
-            return None
+        resp, content = client.request(request_token_url, "POST")
         if resp['status'] != '200':
             raise Exception(self.error('Error: Invalid Response %s.' % resp['status']))
         request_token = dict(urlparse.parse_qsl(content))
         w = webbrowser.get()
         w.open(authorize_url)
         oauth_verifier = ''
-        try: oauth_verifier = raw_input('Enter PIN: ')
-        except KeyboardInterrupt: print ''
+        oauth_verifier = raw_input('Enter PIN: ')
         if not oauth_verifier: return None
         access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken'
         token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
         token.set_verifier(oauth_verifier)
         client = oauth.Client(self.consumer, token)
-        try: resp, content = client.request(access_token_url, "POST")
-        except KeyboardInterrupt:
-            print ''
-            return None
+        resp, content = client.request(access_token_url, "POST")
         self.access_token = dict(urlparse.parse_qsl(content))
-        self.add_key_to_db('linkedin_token', self.access_token['oauth_token'])
-        self.add_key_to_db('linkedin_token_secret', self.access_token['oauth_token_secret'])
+        self.add_key('linkedin_token', self.access_token['oauth_token'])
+        self.add_key('linkedin_token_secret', self.access_token['oauth_token_secret'])
     
     def get_contacts(self):
         if not hasattr(self, 'access_token'): return
         cnt, tot = 0, 0
         page = 1
         while True:
-            try: resp, content = client.request(url)
-            except KeyboardInterrupt:
-                print ''
-                break
+            resp, content = client.request(url)
             jsonstr = content
             try: jsonobj = json.loads(jsonstr)
             except ValueError as e:

modules/recon/contacts/gather/http/pgp_search.py

 
     def module_run(self):
         store = self.options['store']['value']
+
         url = 'http://pgp.rediris.es/pks/lookup'
         payload= {'search' : self.options['domain']['value'] }
-
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return 
-        except Exception as e:
-            self.error(str(e))
-            return 
+        resp = self.request(url, payload=payload)
 
         results = []
         results.extend(re.findall('([^>]*?)(?:\s\(.+?\))?\s&lt;(.*?@%s)&gt;<' % (self.options['domain']['value']), resp.text))

modules/recon/contacts/gather/http/twitter.py

         '''
         url = 'https://api.twitter.com/1/users/show.json'
         payload = {'screen_name': handle, 'include_entities': 'true'}
-        
-        try:
-            resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         
         jsonobj = resp.json
         for item in ['error', 'errors']:
 
         name = jsonobj['name']
         if not [handle, name, time] in self.tdata: self.tdata.append([handle, name, time])
-        sys.stdout.write('.')
-        sys.stdout.flush()
 
     def search_api(self, query):
         payload = {'q': query}
         url = 'http://search.twitter.com/search.json'
-        
-        try:
-            resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         
         jsonobj = resp.json
         for item in ['error', 'errors']:
                 self.error(jsonobj[item])
                 return
 
-        sys.stdout.write('.')
-        sys.stdout.flush()
         return jsonobj
 
     def search_handle_tweets(self):

modules/recon/contacts/gather/http/whois_pocs.py

         new = 0
         url = 'http://whois.arin.net/rest/pocs;domain=%s' % (domain)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url, headers=headers)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, headers=headers)
         if 'Your search did not yield any results.' in resp.text:
             self.output('No contacts found.')
             return
         for handle in handles:
             url = 'http://whois.arin.net/rest/poc/%s' % (handle)
             self.verbose('URL: %s' % url)
-            try: resp = self.request(url, headers=headers)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                continue
+            resp = self.request(url, headers=headers)
             if resp.json: jsonobj = resp.json
             else:
                 self.error('Invalid JSON response for \'%s\'.\n%s' % (handle, resp.text))

modules/recon/creds/pwnedlist/account_creds.py

                      }
 
     def module_run(self):
-        # api key management
-        key = self.manage_key('pwned_key', 'PwnedList API Key')
-        if not key: return
-        secret = self.manage_key('pwned_secret', 'PwnedList API Secret')
-        if not secret: return
+        key = self.get_key('pwnedlist_api')
+        secret = self.get_key('pwnedlist_secret')
         decrypt_key = secret[:16]
-        iv = self.manage_key('pwned_iv', 'PwnedList Decryption IV')
-        if not iv: return
+        iv = self.get_key('pwnedlist_iv')
 
         accounts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT username FROM creds WHERE username IS NOT NULL and password IS NULL ORDER BY username')
-        if not accounts: return
 
         # API query guard
         if not self.api_guard(1): return
         payload = {'account_identifier': ','.join(accounts), 'daysAgo': 0}
         payload = pwnedlist.build_payload(payload, method, key, secret)
         # make request
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         if resp.json: jsonobj = resp.json
         else:
             self.error('Invalid JSON response.\n%s' % (resp.text))

modules/recon/creds/pwnedlist/api_usage.py

                      }
 
     def module_run(self):
-        # required for all PwnedList modules
-        key = self.manage_key('pwned_key', 'PwnedList API Key').encode('ascii')
-        if not key: return
-        secret = self.manage_key('pwned_secret', 'PwnedList API Secret').encode('ascii')
-        if not secret: return
+        key = self.get_key('pwnedlist_api')
+        secret = self.get_key('pwnedlist_secret')
 
         # setup API call
         method = 'usage.info'
         payload = {}
         payload = pwnedlist.build_payload(payload, method, key, secret)
         # make request
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         if resp.json: jsonobj = resp.json
         else:
             self.error('Invalid JSON response.\n%s' % (resp.text))

modules/recon/creds/pwnedlist/domain_creds.py

                      }
 
     def module_run(self):
-        domain = self.options['domain']['value']
-
-        # api key management
-        key = self.manage_key('pwned_key', 'PwnedList API Key')
-        if not key: return
-        secret = self.manage_key('pwned_secret', 'PwnedList API Secret')
-        if not secret: return
+        key = self.get_key('pwnedlist_api')
+        secret = self.get_key('pwnedlist_secret')
         decrypt_key = secret[:16]
-        iv = self.manage_key('pwned_iv', 'PwnedList Decryption IV')
-        if not iv: return
+        iv = self.get_key('pwnedlist_iv')
+
+        domain = self.options['domain']['value']
 
         # API query guard
         if not self.api_guard(10000): return
         payload = {'domain_identifier': domain, 'daysAgo': 0}
         payload = pwnedlist.build_payload(payload, method, key, secret)
         # make request
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         if resp.json: jsonobj = resp.json
         else:
             self.error('Invalid JSON response for \'%s\'.\n%s' % (domain, resp.text))

modules/recon/creds/pwnedlist/domain_ispwned.py

                      }
 
     def module_run(self):
-        domains = self.get_source(self.options['source']['value'])
-        if not domains: return
+        key = self.get_key('pwnedlist_api')
+        secret = self.get_key('pwnedlist_secret')
 
-        # api key management
-        key = self.manage_key('pwned_key', 'PwnedList API Key').encode('ascii')
-        if not key: return
-        secret = self.manage_key('pwned_secret', 'PwnedList API Secret').encode('ascii')
-        if not secret: return
+        domains = self.get_source(self.options['source']['value'])
 
         # API query guard
         if not self.api_guard(1*len(domains)): return
             payload = {'domain_identifier': domain}
             payload = pwnedlist.build_payload(payload, method, key, secret)
             # make request
-            try: resp = self.request(url, payload=payload)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                continue
+            resp = self.request(url, payload=payload)
             jsonobj = resp.json
             # compare to None to confirm valid json as empty json is returned when domain not found
             if jsonobj is None:

modules/recon/creds/pwnedlist/leak_lookup.py

 
     def module_run(self):
         leak_ids = self.get_source(self.options['source']['value'], 'SELECT DISTINCT leak FROM creds WHERE leak IS NOT NULL')
-        if not leak_ids: return
 
         columns = [x[1] for x in self.query('PRAGMA table_info(leaks)')]
         if not columns:

modules/recon/creds/pwnedlist/leaks_dump.py

                      }
 
     def module_run(self):
-        # api key management
-        key = self.manage_key('pwned_key', 'PwnedList API Key').encode('ascii')
-        if not key: return
-        secret = self.manage_key('pwned_secret', 'PwnedList API Secret').encode('ascii')
-        if not secret: return
+        key = self.get_key('pwnedlist_api')
+        secret = self.get_key('pwnedlist_secret')
 
         # API query guard
         if not self.api_guard(1): return
         payload = {'daysAgo': 0}
         payload = pwnedlist.build_payload(payload, method, key, secret)
         # make request
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         if resp.json:
             jsonobj = resp.json
         else:

modules/recon/creds/support/googli.py

 
     def module_run(self):
         hashes = self.get_source(self.options['source']['value'], 'SELECT DISTINCT hash FROM creds WHERE hash IS NOT NULL and password IS NULL')
-        if not hashes: return
 
         # lookup each hash
         url = 'https://goog.li'
         for hashstr in hashes:
             payload = {'j': hashstr}
-            try: resp = self.request(url, payload=payload)
-            except KeyboardInterrupt:
-                print ''
-                break
-            except Exception as e:
-                self.error(e.__str__())
-                continue
+            resp = self.request(url, payload=payload)
             if resp.json: jsonobj = resp.json
             else:
                 self.error('Invalid JSON response for \'%s\'.\n%s' % (account, resp.text))

modules/recon/creds/support/noisette.py

 
     def module_run(self):
         hashes = self.get_source(self.options['source']['value'], 'SELECT DISTINCT hash FROM creds WHERE hash IS NOT NULL and password IS NULL')
-        if not hashes: return
 
         # lookup each hash
         url = 'http://md5.noisette.ch/md5.php'
         for hashstr in hashes:
             payload = {'hash': hashstr}
-            try: resp = self.request(url, payload=payload)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
+            resp = self.request(url, payload=payload)
             dom = parseString(resp.text)
             plaintext = False
             hashtype = "MD5"

modules/recon/hosts/enum/dns/resolve.py

                 answers = q.query(host)
                 address = answers[0].address
                 self.query('UPDATE hosts SET ip_address=\'%s\' WHERE rowid=\'%s\'' % (address, row))
-            except KeyboardInterrupt:
-                print ''
-                return
             except dns.exception.SyntaxError:
                 self.error('Nameserver must be in IP form.')
                 return

modules/recon/hosts/enum/http/age_analyzer.py

         # request the author's age
         url = 'http://ageanalyzer.com/?url=%s' % (host)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
 
         # extract and present results
         content = resp.text

modules/recon/hosts/enum/http/asafaweb.py

         details = [['Check', 'Status']]
         url = 'https://asafaweb.com/Scan?Url=%s' % (host)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
 
         # extract results
         content = resp.text

modules/recon/hosts/enum/http/builtwith.py

 
     def __init__(self, params):
         framework.module.__init__(self, params)
-        self.register_option('host', 'www.google.com', 'yes', 'target host')
+        self.register_option('host', self.goptions['domain']['value'], 'yes', 'target host')
         self.info = {
                      'Name': 'BuiltWith Server-side Enumerator',
                      'Author': 'Tim Tomes (@LaNMaSteR53)',
                      }
 
     def module_run(self):
+        key = self.get_key('builtwith_api')
         host = self.options['host']['value']
-        key = self.manage_key('builtwith', 'BuiltWith API key')
-        if not key: return
         url = ' http://api.builtwith.com/v1/api.json'
         payload = {'key': key, 'lookup': host}
-        try: resp = self.request(url, payload=payload)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url, payload=payload)
         if resp.json == None:
             self.error('Invalid JSON response for \'%s\'.\n%s' % (host, resp.text))
             return

modules/recon/hosts/enum/http/gender_analyzer.py

         # request the author's gender
         url = 'http://genderanalyzer.com/?url=%s' % (host)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
 
         # extract and present results
         content = resp.text

modules/recon/hosts/enum/http/geoip/hostip.py

-import framework
-# unique to module
-import json
-
-class Module(framework.module):
-
-    def __init__(self, params):
-        framework.module.__init__(self, params)
-        self.register_option('source', 'db', 'yes', 'source of addresses for module input (see \'info\' for options)')
-        self.info = {
-                     'Name': 'HostIP GeoIP',
-                     'Author': 'Tim Tomes (@LaNMaSteR53)',
-                     'Description': 'Leverages the hostip.info API to geolocate the given host(s) by IP address and updates the \'hosts\' table of the database with the results.',
-                     'Comments': [
-                                  'Source options: [ db | <address> | ./path/to/file | query <sql> ]'
-                                  ]
-                     }
-   
-    def module_run(self):
-        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not hosts: return
-
-        for host in hosts:
-            # request the scan
-            url = 'http://api.hostip.info/get_json.php?ip=%s&position=true' % (host)
-            self.verbose('URL: %s' % url)
-            try: resp = self.request(url)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-
-            if resp.json: jsonobj = resp.json
-            else:
-                self.error('Invalid JSON response for \'%s\'.\n%s' % (host, resp.text))
-                continue
-
-            if self.options['source']['value'] == 'db':
-                data = [jsonobj['city'].title()]
-                data.append(jsonobj['country_name'].title())
-                data.append(str(jsonobj['lat']))
-                data.append(str(jsonobj['lng']))
-                data.append(host)
-                self.query('UPDATE hosts SET region=\'%s\', country=\'%s\', latitude=\'%s\', longitude=\'%s\' WHERE ip_address=\'%s\'' % tuple(data))
-
-            tdata = [['Host Info', 'Value']]
-            for key in jsonobj:
-                tdata.append([key, jsonobj[key]])
-            # output the results in table format
-            self.table(tdata, True)

modules/recon/hosts/enum/http/geoip/ipinfodb.py

-import framework
-# unique to module
-import json
-
-class Module(framework.module):
-
-    def __init__(self, params):
-        framework.module.__init__(self, params)
-        self.register_option('source', 'db', 'yes', 'source of addresses for module input (see \'info\' for options)')
-        self.info = {
-                     'Name': 'IPInfoDB GeoIP',
-                     'Author': 'Tim Tomes (@LaNMaSteR53)',
-                     'Description': 'Leverages the ipinfodb.com API to geolocate the given host(s) by IP address and updates the \'hosts\' table of the database with the results.',
-                     'Comments': [
-                                  'Source options: [ db | <address> | ./path/to/file | query <sql> ]'
-                                  ]
-                     }
-   
-    def module_run(self):
-        api_key = self.manage_key('ipinfodb', 'IPInfoDB API key')
-        if not api_key: return
-        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not hosts: return
-
-        for host in hosts:
-            # request the scan
-            url = 'http://api.ipinfodb.com/v3/ip-city/?key=%s&ip=%s&format=json' % (api_key, host)
-            self.verbose('URL: %s' % url)
-            try: resp = self.request(url)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-
-            if resp.json: jsonobj = resp.json
-            else:
-                self.error('Invalid JSON response for \'%s\'.\n%s' % (host, resp.text))
-                continue
-            if jsonobj['statusCode'].lower() == 'error':
-                self.error(jsonobj['statusMessage'])
-                continue
-
-            if self.options['source']['value'] == 'db':
-                location = []
-                for name in ['cityName', 'regionName']:
-                    if jsonobj[name]: location.append(str(jsonobj[name]).title())
-                data = [', '.join(location)]
-                data.append(jsonobj['countryName'].title())
-                data.append(str(jsonobj['latitude']))
-                data.append(str(jsonobj['longitude']))
-                data.append(host)
-                self.query('UPDATE hosts SET region=\'%s\', country=\'%s\', latitude=\'%s\', longitude=\'%s\' WHERE ip_address=\'%s\'' % tuple(data))
-
-            tdata = [['Host Info', 'Value']]
-            for key in jsonobj:
-                tdata.append([key, jsonobj[key]])
-            # output the results in table format
-            self.table(tdata, True)

modules/recon/hosts/enum/http/geoip/maxmind.py

-import framework
-# unique to module
-import json
-
-class Module(framework.module):
-
-    def __init__(self, params):
-        framework.module.__init__(self, params)
-        self.register_option('source', 'db', 'yes', 'source of addresses for module input (see \'info\' for options)')
-        self.info = {
-                     'Name': 'Maxmind GeoIP',
-                     'Author': 'Brendan Coles (bcoles[at]gmail.com)',
-                     'Description': 'Leverages the Maxmind.com Demo API to geolocate the given host(s) by IP address and updates the \'hosts\' table of the database with the results.',
-                     'Comments': [
-                                  'Source options: [ db | <address> | ./path/to/file | query <sql> ]',
-                                  'Note: maxmind.com allows a maximum of 25 queries per day per source IP address.'
-                                  ]
-                     }
-   
-    def module_run(self):
-        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not hosts: return
-
-        for host in hosts:
-            # request the scan
-            url = 'http://www.maxmind.com/geoip/city_isp_org/%s?demo=1' % (host)
-            self.verbose('URL: %s' % url)
-            try: resp = self.request(url)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-
-            if resp.json: jsonobj = resp.json
-            else:
-                self.error('Invalid JSON response for \'%s\'.\n%s' % (host, resp.text))
-                continue
-
-            if resp.status_code != 200:
-                self.error(jsonobj['error'])
-            else:
-                if self.options['source']['value'] == 'db':
-                    location = []
-                    for name in ['city', 'region_name']:
-                        if jsonobj[name]: location.append(str(jsonobj[name]).title())
-                    data = [', '.join(location)]
-                    data.append(jsonobj['country_name'].title())
-                    data.append(str(jsonobj['latitude']))
-                    data.append(str(jsonobj['longitude']))
-                    data.append(host)
-                    self.query('UPDATE hosts SET region=\'%s\', country=\'%s\', latitude=\'%s\', longitude=\'%s\' WHERE ip_address=\'%s\'' % tuple(data))
-
-                tdata = [['Host Info', 'Value']]
-                for key in jsonobj:
-                    tdata.append([key, jsonobj[key]])
-                # output the results in table format
-                self.table(tdata, True)

modules/recon/hosts/enum/http/geoip/uniapple.py

-import framework
-# unique to module
-import json
-
-class Module(framework.module):
-
-    def __init__(self, params):
-        framework.module.__init__(self, params)
-        self.register_option('source', 'db', 'yes', 'source of addresses for module input (see \'info\' for options)')
-        self.info = {
-                     'Name': 'Uniapple GeoIP',
-                     'Author': 'Tim Tomes (@LaNMaSteR53)',
-                     'Description': 'Leverages the Uniapple.net API to geolocate the given host(s) by IP address and updates the \'hosts\' table of the database with the results.',
-                     'Comments': [
-                                  'Source options: [ db | <address> | ./path/to/file | query <sql> ]'
-                                  ]
-                     }
-   
-    def module_run(self):
-        hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not hosts: return
-
-        for host in hosts:
-            # request the scan
-            url = 'http://uniapple.net/geoip/?ip=%s' % (host)
-            self.verbose('URL: %s' % url)
-            try: resp = self.request(url)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
-
-            if resp.json: jsonobj = resp.json
-            else:
-                self.error('Invalid JSON response for \'%s\'.\n%s' % (host, resp.text))
-                continue
-
-            if self.options['source']['value'] == 'db':
-                location = []
-                for name in ['city', 'region']:
-                    if jsonobj[name]: location.append(str(jsonobj[name]))
-                data = [', '.join(location)]
-                data.append(jsonobj['country'].title())
-                data.append(str(jsonobj['latitude']))
-                data.append(str(jsonobj['longitude']))
-                data.append(host)
-                self.query('UPDATE hosts SET region=\'%s\', country=\'%s\', latitude=\'%s\', longitude=\'%s\' WHERE ip_address=\'%s\'' % tuple(data))
-
-            tdata = [['Host Info', 'Value']]
-            for key in jsonobj:
-                tdata.append([key, jsonobj[key]])
-            # output the results in table format
-            self.table(tdata, True)

modules/recon/hosts/enum/http/ipvoid.py

    
     def module_run(self):
         addresses = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not addresses: return
 
         for address in addresses:
             url = 'http://www.ipvoid.com/scan/%s/' % (address)
             self.verbose('URL: %s' % url)
-            try: resp = self.request(url)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                return
+            resp = self.request(url)
 
             if '<h1>AN ERROR OCCURRED</h1>' in resp.text:
                 self.output('No data returned for \'%s\'' % (address))

modules/recon/hosts/enum/http/malwaredomain.py

 
         url = 'http://www.malwaredomainlist.com/mdl.php?search=%s&colsearch=Domain&quantity=All' % (domain)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
 
         # Get the malicious domain results
         entries = re.findall(r'<td><nobr>(.*?)_.*?<.+?td><td>(.+?)</td><td>(.*?)</td><td>.*?</td><td>(.*?)</td><td>', resp.text.replace('<wbr>', ''))

modules/recon/hosts/enum/http/mywot.py

 
         url = 'http://api.mywot.com/0.4/public_query2?target=%s' % (domain)
         self.verbose('URL: %s' % url)
-        try: resp = self.request(url)
-        except KeyboardInterrupt:
-            print ''
-            return
-        except Exception as e:
-            self.error(e.__str__())
-            return
+        resp = self.request(url)
 
         # Get the security results
         findings = re.findall(r'<application name="(\d)" r="(\d+)" c="(\d+)"', resp.text)

modules/recon/hosts/enum/http/netbios.py

    
     def module_run(self):
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT ip_address FROM hosts WHERE ip_address IS NOT NULL')
-        if not hosts: return
 
         for host in hosts:
             # request NetBIOS info
             url = 'https://w3dt.net/tools/netbios/?submit=Scan!&clean_opt=1&host=%s' % (host)
             self.verbose('URL: %s' % url)
-            try: resp = self.request(url, timeout=20)
-            except KeyboardInterrupt:
-                print ''
-                return
-            except Exception as e:
-                self.error(e.__str__())
-                continue
+            resp = self.request(url, timeout=20)
 
             # extract and present results
             content = resp.text

modules/recon/hosts/enum/http/netcraft_history.py

                      }
 
     def module_run(self):
-        cookies = {}
-
         hosts = self.get_source(self.options['source']['value'], 'SELECT DISTINCT host FROM hosts WHERE host IS NOT NULL ORDER BY host')
-        if not hosts: return
+        cookies = {}
 
         for host in hosts:
             url = 'http://uptime.netcraft.com/up/graph?site=%s' % (host)
             self.verbose('URL: %s' % url)
-            try: resp = self.request(url, cookies=cookies)
-            except KeyboardInterrupt:
-                print ''