def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() cpe = p.get_cpe() if not cpe: return if not c.get_cfg_allow_inet(): return if 'http' not in module: return if t.has_cves(cpe): self.rule_details = 'List of Vulnerabilities for this version: https://nvd.nist.gov/vuln/search/results?cpe_version={}'.format( cpe) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if not c.get_cfg_allow_bf(): return if port != 21 or 'ftp' not in module: return usernames = c.get_cfg_usernames() + known_users passwords = c.get_cfg_passwords() + known_weak for username in usernames: for password in passwords: if self.ftp_attack(ip, username, password): self.rule_details = 'FTP Server Credentials are set to: {}:{}'.format(username, password) rds.store_vuln({ 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation }) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() # When MongoDB authentication is enabled name=mongodb, when authentication is not enabled name=mongodb if port != 27017 or 'mongodb' not in module: return usernames = c.get_cfg_usernames() + known_users passwords = c.get_cfg_passwords() + known_weak # Check if MongoDB is configured with or without authentication if self.mongodb_attack(ip, port, None, None): js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': 'Remote server with no authentication on MongoDB', 'rule_details': 'MongoDB is configured with no authentication', 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return if not c.get_cfg_allow_bf(): return for username in usernames: for password in passwords: if self.mongodb_attack(ip, port, username, password): self.rule_details = 'MongoDB Credentials are set to: {}:{}'.format( username, password) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return return
def check_rule(self, ip, port, values, conf): t = Triage() c = ConfParser(conf) p = ScanParser(port, values) module = p.get_module() domain = p.get_domain() if not c.get_cfg_allow_bf(): return if 'http' not in module: return usernames = c.get_cfg_usernames() + known_users passwords = c.get_cfg_passwords() + known_weak for uri in self.rule_doc_roots: resp = t.http_request(ip, port, uri=uri) if resp is not None and resp.status_code == 401: if 'WWW-Authenticate' in resp.headers and resp.headers[ 'WWW-Authenticate'].startswith('Basic'): for username in usernames: for password in passwords: auth_attempt = requests.get(resp.url, auth=HTTPBasicAuth( username, password)) if auth_attempt is not None and auth_attempt.status_code == 200: self.rule_details = 'Basic Authentication Credentials are set to {}:{} at {}'.format( username, password, uri) rds.store_vuln({ 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation }) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if module == 'http' or port in http_ports: resp = t.http_request(ip, port, follow_redirects=False) if resp: form = self.contains_password_form(resp.text) if form: if not resp.url.startswith('https://'): self.rule_details = 'Login Page over HTTP' js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = t.http_request(ip, port, uri='/_vti_inf.html') if not resp: return if 'Content-Length' in resp.headers and resp.headers[ 'Content-Length'] == '247': self.rule_details = 'Exposed FrontPage at /_vti_inf.html' js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) module = p.get_module() domain = p.get_domain() if 'http' not in module: return resp = None for uri in self.uris: resp = t.http_request(ip, port, uri=uri) if resp: for match in ('C=N;O=D', 'Index of /'): if match in resp.text: self.rule_details = 'Found Open Directory at {}'.format(uri) js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) break return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() if port in ftp_ports: self.rule_details = 'Open Port: {} ({})'.format( port, ftp_ports[port]) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if port in self.rule_match_port: try: ftp = FTP(ip) res = ftp.login() if res: if '230' in res or 'user logged in' in res or 'successful' in res: self.rule_details = 'FTP with Anonymous Access Enabled' js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) except: pass return
def check_rule(self, ip, port, values, conf): t = Triage() c = ConfParser(conf) p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if not 'F5 BIG-IP' in product or not 'BigIP' in product: return resp = t.http_request(ip, port, uri='/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd') if resp is None: return if 'root:x:0:0' in resp.text: self.rule_details = 'F5 BIGIP Vulnerability - CVE-2020-5902' js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = t.http_request(ip, port, uri='/xmlrpc.php') if resp is None: return if resp.status_code == 405: self.rule_details = 'Server Allows XMLRPC Connections' js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) module = p.get_module() domain = p.get_domain() product = p.get_product() if 'ssh' in module or 'ssh' in product.lower(): if port != 22: self.rule_details = 'SSH is hidden behind port {}'.format(port) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = None for uri in self.uris: resp = t.http_request(ip, port, uri=uri + '/.git/HEAD') if resp and resp.text.startswith('ref:'): self.rule_details = 'Git Path: {}'.format(uri) js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return for uri in self.rule_doc_roots: resp = t.http_request(ip, port, uri=uri) if resp is not None and resp.status_code == 401: if 'WWW-Authenticate' in resp.headers: header = resp.headers['WWW-Authenticate'] if header.startswith('Basic'): self.rule_details = '{} at {}'.format( self.rule_confirm, uri) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' in module: for uri, values in self.rule_match_string.items(): app_name = values['app'] app_title = values['title'] resp = t.http_request(ip, port, uri=uri) if resp is not None: for match in values['match']: if match in resp.text: self.rule_details = 'Exposed {} at {}'.format( app_title, uri) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) break return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() if not domain: return resp = t.http_request(domain, port) if resp is None: return if resp.status_code == 404 and 'NoSuchBucket' in resp.text: self.rule_details = 'S3 Takeover at {}'.format(domain) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = t.http_request(ip, port, follow_redirects=False, headers={'X-Forwarded-Host':'112000as0az7s62s9d7.com', 'Host': '112000as0az7s62s9d7.com'}) if resp: if 'Location' in resp.headers and '112000as0az7s62s9d7.com' in resp.headers['Location']: self.rule_details = 'Host header injection' js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) p = ScanParser(port, values) t = Triage() domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = t.http_request(ip, port) for app, val in self.rule_match_string.items(): app_name = val['app'] app_title = val['title'] for match in val['match']: if resp and t.string_in_headers(resp, match): self.rule_details = '{} - ({})'.format(app, app_title) js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() if port in ssh_ports and t.is_ssh(ip, port): output = t.run_cmd('ssh -o PreferredAuthentications=none -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes user@"{}" -p "{}"'.format(ip, port)) if output and 'password' in str(output): self.rule_details = p.get_product() js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = t.http_request(ip, port, uri='/wp-content/uploads/') if resp and 'Index of /wp-content/uploads' in resp.text: self.rule_details = 'Found Uploads Directory at /wp-content/uploads/' js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): t = Triage() c = ConfParser(conf) p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if 'http' not in module: return resp = t.http_request(ip, port, uri='/.svn/text-base') if resp and 'Index of /' in resp.text: self.rule_details = 'SVN Repository exposed at /.svn/text-base' js_data = { 'ip':ip, 'port':port, 'domain':domain, 'rule_id':self.rule, 'rule_sev':self.rule_severity, 'rule_desc':self.rule_description, 'rule_confirm':self.rule_confirm, 'rule_details':self.rule_details, 'rule_mitigation':self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() h = Helper() p = ScanParser(port, values) domain = p.get_domain() known = False for ports in known_ports: if port in ports: known = True if not known: self.rule_details = 'Open Port: {} ({})'.format( port, h.portTranslate(port)) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) module = p.get_module() domain = p.get_domain() if 'http' in module: resp = t.http_request(ip, port, uri='/server.js', follow_redirects=False) if resp is None: return for i in self.rule_match_string: if i in resp.text: self.rule_details = 'Identified a NodeJS Leakage Indicator: {}'.format( i) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if 'http' not in module: return resp = None for uri in self.uris: resp = t.http_request(ip, port, uri=uri + '/.idea/workspace.xml') if resp: for match in self.rule_match_string: if match in resp.text: self.rule_details = 'Found Intelli IDEA files at {}/.idea/workspace.xml'.format( uri) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if not c.get_cfg_allow_bf(): return if port in ssh_ports or 'ssh' in module: usernames = c.get_cfg_usernames() + known_users passwords = c.get_cfg_passwords() + known_weak output = t.run_cmd( 'ssh -o PreferredAuthentications=none -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes user@"{}" -p "{}"' .format(ip, port)) if output and 'password' in str(output): for username in usernames: for password in passwords: if self.ssh_attack(ip, port, username, password): self.rule_details = 'SSH Server Credentials are set to {}:{}'.format( username, password) rds.store_vuln({ 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation }) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() if not c.get_cfg_allow_bf(): return if port != 6379 or module != 'redis': return passwords = c.get_cfg_passwords() + known_weak try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, port)) s.sendall(b'INFO\n') data = s.recv(1024) if 'Authentication required' in data.decode('utf-8'): for password in passwords: if self.redis_attack(ip, port, password): self.rule_details = 'Redis Credentials are set to: {}'.format( password) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return except: return return
def scan(self, scan): if rds.get_session_state() in ('running', 'created'): return (False, 429, 'There is already a scan in progress!') cfg = ConfParser(scan) self.rds.clear_session() self.rds.create_session() logger.info('Storing the new configuration') self.rds.store_json('sess_config', scan) networks = cfg.get_cfg_networks() domains = cfg.get_cfg_domains() if networks: logger.info('Scheduling network(s): {}'.format(', '.join(networks))) if domains: logger.info('Scheduling domains(s): {}'.format(', '.join(domains))) return (True, 200, 'Registered a new scan successfully!')
def check_rule(self, ip, port, values, conf): t = Triage() c = ConfParser(conf) p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if 'http' not in module: return resp = t.http_request(ip, port) if resp is None: return server_header = resp.headers.get('Server', None) if not server_header or 'nginx' not in server_header.lower(): return content_length = resp.headers.get('Content-Length', 0) bytes_length = int(content_length) + 623 content_length = "bytes=-%d,-9223372036854%d" % (bytes_length, 776000 - bytes_length) resp = t.http_request(ip, port, headers={'Range': content_length}) if resp is None: return if resp.status_code == 206 and 'Content-Range' in resp.text: self.rule_details = 'Nginx Integer Overflow' js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) domain = p.get_domain() module = p.get_module() product = p.get_product() if 'http' not in module: return resp = None random_origin = self.randomize_origin() if domain: resp = t.http_request(domain, port, headers={'Origin': random_origin}) else: resp = t.http_request(ip, port, headers={'Origin': random_origin}) if resp is None: return if 'Access-Control-Allow-Origin' in resp.headers and resp.headers[ 'Access-Control-Allow-Origin'] == random_origin: self.rule_details = 'Header used: "Origin: {}"'.format( random_origin) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) return
def check_rule(self, ip, port, values, conf): c = ConfParser(conf) t = Triage() p = ScanParser(port, values) module = p.get_module() domain = p.get_domain() if 'http' not in module: return for uri in self.uris: filename = self.generate_filename() resp = t.http_request(ip, port, uri=uri + '/.DS_Store') if resp: if os.path.exists(filename): os.remove(filename) with open(filename, "wb") as f: f.write(resp.content) f.close() with open(filename, 'rb') as f: if self.is_file_ds_store(f.read()): self.rule_details = 'Found .DS_Store file at {}'.format( uri) js_data = { 'ip': ip, 'port': port, 'domain': domain, 'rule_id': self.rule, 'rule_sev': self.rule_severity, 'rule_desc': self.rule_description, 'rule_confirm': self.rule_confirm, 'rule_details': self.rule_details, 'rule_mitigation': self.rule_mitigation } rds.store_vuln(js_data) os.remove(filename) return