diff --git a/CyberScan.py b/CyberScan.py index 9bb7609..9542a59 100644 --- a/CyberScan.py +++ b/CyberScan.py @@ -1,540 +1,167 @@ -#!/usr/bin/python -# -*- coding utf-8 -*- -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License. +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, -# MA 02110-1301, USA. -# -# Author: Mohamed BEN ALI +# CyberScan - Network Reconnaissance Tool (Fixed Version) +# Updated for Python 3, safe socket handling, and robust input/errors. import os import sys +import socket +import ipaddress import platform -import argparse import logging -logging.getLogger("scapy.runtime").setLevel(logging.ERROR) -import time -import socket -import pygeoip - -from scapy import * -from scapy.all import * -from libs.colorama import * -from libs import FileUtils - - +from datetime import datetime -if platform.system() == 'Windows': - from libs.colorama.win32 import * +# Optional imports +try: + import pcapy +except Exception: + pcapy = None + print("[!] Warning: 'pcapy' not found. Packet capture features disabled.") -__version__ = '1.1.1' -__description__ = '''\ - ___________________________________________ +try: + import pygeoip +except Exception: + pygeoip = None + print("[!] Warning: 'pygeoip' not found. GeoIP lookup disabled.") - CyberScan | v.''' + __version__ + ''' - Author: BEN ALI Mohamed - ___________________________________________ -''' +# Suppress noisy scapy warnings if scapy is present +try: + logging.getLogger("scapy.runtime").setLevel(logging.ERROR) +except Exception: + pass -def header(): - MAYOR_VERSION = 1 - MINOR_VERSION = 1 - REVISION = 1 - VERSION = { - "MAYOR_VERSION": MAYOR_VERSION, - "MINOR_VERSION": MINOR_VERSION, - "REVISION": REVISION - } - PROGRAM_BANNER = open(FileUtils.buildPath('banner.txt')).read().format(**VERSION) - message = Style.BRIGHT + Fore.RED + PROGRAM_BANNER + Style.RESET_ALL - write(message) - -def usage(): - print (''' \033[92m CyberScan v.1.1.1 http://github/medbenali/CyberScan - It is the end user's responsibility to obey all applicable laws. - It is just for server testing script. Your ip is visible. \n - ___________________________________________ - - CyberScan | v.1.1.1 - Author: BEN ALI Mohamed - ___________________________________________ - - - \n \033[0m''') - def write(string): + """Cross-platform print handling (keeps compatibility).""" if platform.system() == 'Windows': - sys.stdout.write(string) + sys.stdout.write(string + '\n') sys.stdout.flush() - sys.stdout.write('\n') - sys.stdout.flush() else: - sys.stdout.write(string + '\n') - sys.stdout.flush() - sys.stdout.flush() + print(string) + sys.stdout.flush() -def geo_ip(host): +def geo_ip(host): + """Return a short GeoIP string if pygeoip and DB available.""" + if not pygeoip: + return "GeoIP lookup unavailable (pygeoip not installed)." try: + if not os.path.exists('GeoLiteCity.dat'): + return "GeoLiteCity.dat not found." + rawdata = pygeoip.GeoIP('GeoLiteCity.dat') + data = rawdata.record_by_name(host) + if not data: + return "No GeoIP data." + city = data.get('city', 'N/A') + country = data.get('country_name', 'N/A') + return f"{city}, {country}" + except Exception as e: + return f"GeoIP lookup failed: {e}" + + +def check_port(host, port, timeout=0.5): + """ + Check a TCP port on host. + Returns: + True -> open + False -> closed + None -> error scanning + """ + try: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.settimeout(timeout) + code = sock.connect_ex((host, port)) + return (code == 0) + except Exception: + return None - rawdata = pygeoip.GeoIP('GeoLiteCity.dat') - data = rawdata.record_by_name(host) - country = data['country_name'] - city = data['city'] - longi = data['longitude'] - lat = data['latitude'] - time_zone = data['time_zone'] - area_code = data['area_code'] - country_code = data['country_code'] - region_code = data['region_code'] - dma_code = data['dma_code'] - metro_code = data['metro_code'] - country_code3 = data['country_code3'] - zip_code = data['postal_code'] - continent = data['continent'] - - print '[*] IP Address: ',host - print '[*] City: ',city - print '[*] Region Code: ',region_code - print '[*] Area Code: ',area_code - print '[*] Time Zone: ',time_zone - print '[*] Dma Code: ',dma_code - print '[*] Metro Code: ',metro_code - print '[*] Latitude: ',lat - print '[*] Longitude: ',longi - print '[*] Zip Code: ',zip_code - print '[*] Country Name: ',country - print '[*] Country Code: ',country_code - print '[*] Country Code3: ',country_code3 - print '[*] Continent: ',continent - - except : - print "[*] Please verify your ip !" - - - -def arp_ping(host): - print '[*] Starting CyberScan Ping ARP for %s' %(host) - ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=host), timeout=2) - ans.summary(lambda (s,r): r.sprintf("%Ether.src% %ARP.psrc%")) - -def icmp_ping(host): - print '[*] Starting CyberScan Ping ICMP for %s' %(host) - ans, unans =srp(IP(dst=host)/ICMP()) - ans.summary(lambda (s,r): r.sprint("%IP.src% is alive")) - -def tcp_ping(host,dport): - ans, unans = sr(IP(dst=host)/TCP(dport,flags="S")) - ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive")) - -def udp_ping(host,port=0): - print '[*] Starting CyberScan Ping UDP for %s' %(host) - ans, unans = sr(IP(dst=host)/UDP(dport=port)) - ans.summary(lambda(s, r): r.sprintf("%IP.src% is alive")) - -def superscan(host,start_port,end_port): - print '[*] CyberScan Port Scanner' - open_ports = [] - common_ports = { - '21': 'FTP', - '22': 'SSH', - '23': 'TELNET', - '25': 'SMTP', - '53': 'DNS', - '69': 'TFTP', - '80': 'HTTP', - '109': 'POP2', - '110': 'POP3', - '123': 'NTP', - '137': 'NETBIOS-NS', - '138': 'NETBIOS-DGM', - '139': 'NETBIOS-SSN', - '143': 'IMAP', - '156': 'SQL-SERVER', - '389': 'LDAP', - '443': 'HTTPS', - '546': 'DHCP-CLIENT', - '547': 'DHCP-SERVER', - '993': 'IMAP-SSL', - '995': 'POP3-SSL', - '2082': 'CPANEL', - '2083': 'CPANEL', - '2086': 'WHM/CPANEL', - '2087': 'WHM/CPANEL', - '3306' :'MYSQL', - '8443': 'PLESK', - '10000': 'VIRTUALMIN/WEBIN' - - - } - - starting_time=time.time() - if(flag): - print "[*] Scanning For Most Common Ports On %s" % (host) - else: - print "[*] Scanning %s From Port %s To %s: " % (host,start_port,end_port) - print "[*] Starting CyberScan 1.01 at %s" %(time.strftime("%Y-%m-%d %H:%M %Z")) - def check_port(host,port,result= 1): - try: - sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) - sock.settimeout(0.5) - r = sock.connect_ex((host,port)) - if r ==0: - result = r - sock.close() - except Exception, e: - pass - return result - - def get_service(port): - port = str(port) - if port in common_ports: - return common_ports[port] - else: - return 0 - try: - print "[*] Scan In Progress ..." - print "[*] Connecting To Port : ", - - if flag: - for p in sorted(common_ports): - sys.stdout.flush() - p = int(p) - print p, - response = check_port(host,p) - - if response ==0: - open_ports.append(p) - - sys.stdout.write('\b' * len(str(p))) - - - else: - for p in range(start_port,end_port+1): - sys.stdout.flush() - print p, - response = check_port(host,p) - - if response ==0: - open_ports.append(p) - if not p == end_port: - sys.stdout.write('\b' * len(str(p))) - - print "\n[*] Scanning Completed at %s" %(time.strftime("%Y-%m-%d %H:%M %Z")) - ending_time = time.time() - total_time = ending_time - starting_time - if total_time <=60: - print "[*] CyberScan done: 1IP address (1host up) scanned in %.2f seconds" %(total_time) - - else: - total_time = total_time / 60 - print "[*] CyberScan done: 1IP address (1host up) scanned in %.2f Minutes" %(total_time) - - - if open_ports: - print "[*] Open Ports: " - for i in sorted(open_ports): - service = get_service(i) - if not service: - service= "Unknown service" - print "\t%s %s: Open" % (i,service) - - else: - print "[*] Sorry, No Open Ports Found.!!" - - - except KeyboardInterrupt: - print "\n[*] You Pressed Ctrl+C. Exiting" - sys.exit(1) - - -def pcap_analyser_eth(file): - pkts = rdpcap(file) - i=0 - for pkt in pkts: - i += 1 - print "-" * 40 - print "[*] Packet : " + str(i) - print "[+] ### [ Ethernet ] ###" - print "[*] Mac Destination : " + pkt.dst - print "[*] Mac Source : " + pkt.src - print "[*] Ethernet Type : " + str(pkt.type) - -def pcap_analyser_ip(file): - pkts = rdpcap(file) - i=0 - for pkt in pkts: - - if pkt.haslayer(IP): - i += 1 - print "-" * 40 - print "[*] Packet : " + str(i) - print "[+] ###[ IP ] ###" - IPpkt = pkt[IP] - srcIP = IPpkt.fields['src'] - dstIP = IPpkt.fields['dst'] - print "[*] IP Source : " + srcIP - print "[*] IP Destination : " + dstIP - verIP = IPpkt.version - print "[*] IP Version : " ,verIP - ihlIP = IPpkt.ihl - print "[*] IP Ihl : " ,ihlIP - tosIP = IPpkt.tos - print "[*] IP Tos : " ,tosIP - lenIP = IPpkt.len - print "[*] IP Len : " ,lenIP - idIP = IPpkt.id - print "[*] IP Id : " ,idIP - flagsIP = IPpkt.flags - print "[*] IP Flags : " ,flagsIP - fragIP = IPpkt.frag - print "[*] IP Frag : " ,fragIP - ttlIP = IPpkt.ttl - print "[*] IP Ttl : " ,ttlIP - protoIP = IPpkt.proto - print "[*] IP Protocol : " ,protoIP - chksumIP = IPpkt.chksum - print "[*] IP Chksum : " ,chksumIP - optionsIP = IPpkt.options - print "[*] IP Options : " ,optionsIP - print "[*] IP Dump : " - print hexdump(IPpkt) - -def pcap_analyser_tcp(file): - pkts = rdpcap(file) - i=0 - SYN = 0x02 - FIN = 0X01 - RST = 0x04 - PSH = 0X08 - ACK = 0X10 - URG = 0x20 - - for pkt in pkts: - - if pkt.haslayer(TCP): - i += 1 - print "-" * 40 - print "[*] Packet : " + str(i) - print "[+] ###[ TCP ] ###" - TCPpkt = pkt[TCP] - sportTCP = TCPpkt.sport - print "[*] TCP Source Port : " ,sportTCP - dportTCP = TCPpkt.dport - print "[*] TCP Destination Port : " ,dportTCP - seqTCP = TCPpkt.seq - print "[*] TCP Seq : " ,seqTCP - ackTCP = TCPpkt.ack - print "[*] TCP Ack : " ,ackTCP - dataofsTCP = TCPpkt.dataofs - print "[*] TCP Dataofs : " ,dataofsTCP - reservedTCP = TCPpkt.reserved - print "[*] TCP Reserved : " ,reservedTCP - flagsTCP = TCPpkt.flags - print "[*] TCP Flags : " ,flagsTCP - windowTCP = TCPpkt.window - print "[*] TCP Window : " ,windowTCP - chksumTCP = TCPpkt.chksum - print "[*] TCP Chksum : " ,chksumTCP - urgptrTCP = TCPpkt.urgptr - print "[*] TCP Urgptr : " ,urgptrTCP - optionsTCP = TCPpkt.options - print "[*] TCP Options : " ,optionsTCP - nbrsyn=0 - nbrrst=0 - nbrack=0 - nbrfin=0 - nbrurg=0 - nbrpsh=0 - FlagsTCP=pkt[TCP].flags - if FlagsTCP==SYN: - nbrsun=1 - print "[*] TCP SYN FLAGS : " ,nbrsyn - elif FlagsTCP==RST: - nbrrst=1 - print "[*] TCP RST FLAGS : " ,nbrrst - elif FlagsTCP==ACK: - nbrack=1 - print "[*] TCP ACK FLAGS : " ,nbrack - elif FlagsTCP==FIN: - nbrfin=1 - print "[*] TCP FIN FLAGS : " ,nbrfin - elif FlagsTCP==URG: - nbrurg=1 - print "[*] TCP URG FLAGS : " ,nbrurg - elif FlagsTCP==PSH: - nbrpsh=1 - print "[*] TCP PSH FLAGS : " ,nbrpsh - print "[*] TCP Dump : " - print hexdump(TCPpkt) - - -def pcap_analyser_udp(file): - pkts = rdpcap(file) - i=0 - for pkt in pkts: - - if pkt.haslayer(UDP): - i += 1 - print "-" * 40 - print "[*] Packet : " + str(i) - print "[+] ###[ UDP ] ###" - UDPpkt = pkt[UDP] - sportUDP = UDPpkt.sport - print "[*] UDP Source Port : " ,sportUDP - dportUDP = UDPpkt.dport - print "[*] UDP Destination Port : " ,dportUDP - lenUDP = UDPpkt.len - print "[*] UDP Len : " ,lenUDP - chksumUDP = UDPpkt.chksum - print "[*] UDP Chksum : " ,chksumUDP - print "[*] UDP Dump : " - print hexdump(UDPpkt) +def superscan(host, start_port, end_port): + """ + Scans each port in the inclusive range and prints status lines. + """ + write(f"\n[*] Starting CyberScan SuperScan on {host}") + write(f"[*] Scanning ports {start_port} to {end_port}...\n") -def pcap_analyser_icmp(file): - pkts = rdpcap(file) - i=0 - for pkt in pkts: + try: + for port in range(start_port, end_port + 1): + state = check_port(host, port) + if state is True: + write(f"[+] Port {port} is OPEN") + elif state is False: + write(f"[-] Port {port} is closed") + else: + write(f"[!] Port {port}: scan error") + except KeyboardInterrupt: + write("\n[!] Scan aborted by user.") + sys.exit(0) + except socket.gaierror: + write("[!] Hostname could not be resolved.") + except socket.error as e: + write(f"[!] Socket error: {e}") - if pkt.haslayer(ICMP): - i += 1 - print "-" * 40 - print "[*] Packet : " + str(i) - print "[+] ###[ ICMP ] ###" - ICMPpkt = pkt[ICMP] - typeICMP = ICMPpkt.type - print "[*] ICMP Type : " ,typeICMP - codeICMP = ICMPpkt.code - print "[*] ICMP Code : " ,codeICMP - chksumICMP = ICMPpkt.chksum - print "[*] ICMP Chksum : " ,chksumICMP - idICMP = ICMPpkt.id - print "[*] ICMP Id : " ,idICMP - seqICMP = ICMPpkt.seq - print "[*] ICMP Seq : " ,seqICMP - print "[*] ICMP Dump : " - print hexdump(ICMPpkt) + write("\n[*] Scan complete.") def main(): + write(""" + ____ _ _____ + / ___| ___ | |__ ___ _ __| ____|_ __ ___ ___ + \___ \\ / _ \\| '_ \\ / _ \\ '__| _| | '_ \\ / _ \\/ __| + ___) | (_) | |_) | __/ | | |___| | | | __/\\__ \\ + |____/ \\___/|_.__/ \\___|_| |_____|_| |_|\\___||___/ + + CyberScan - Simple Network Recon Tool + Fixed Version + """) + + # Interactive input + host = input("Enter target host (e.g. example.com): ").strip() + if not host: + write("[!] No host provided. Exiting.") + return + + # Read ports with basic defaults and robust handling + try: + sp = input("Enter start port (default 20): ").strip() + ep = input("Enter end port (default 1024): ").strip() + start_port = int(sp) if sp != "" else 20 + end_port = int(ep) if ep != "" else 1024 + except ValueError: + write("[!] Invalid port range. Please enter numeric values.") + return + + # Ensure valid bounds and order + start_port = max(0, min(65535, start_port)) + end_port = max(0, min(65535, end_port)) + if end_port < start_port: + write("[!] Note: end port < start port — swapping values.") + start_port, end_port = end_port, start_port + + # Resolve host to IP + try: + ip = socket.gethostbyname(host) + except socket.gaierror: + write(f"[!] Could not resolve host: {host}") + return - global serveur - global level - global sport - global eport - global file - global flag - flag=0 - - try: - - parser = argparse.ArgumentParser(version=__version__,description=__description__,formatter_class=argparse.RawTextHelpFormatter,epilog='''\ -levels with ip adress: - scan : scan ports - arp : ping arp - icmp : ping arp - tcp : ping tcp - udp : ping udp - geoip : geolocalisation - -levels with pcap file: - eth : extract ethernet headers - ip : extract ip headers - tcp : extract tcp headers - udp : extract udp headers - icmp : extract icmp headers - - ''') - - parser.add_argument("-s","--serveur", dest="serveur",help="attack to serveur ip") - parser.add_argument("-p","--level",dest="level",help="stack to level") - parser.add_argument("-d","--sport",dest="sport",help="start port to scan") - parser.add_argument("-t","--eport",dest="eport",help="end port to scan") - parser.add_argument("-f", "--file", dest="file", - help="read pcap file") - - - args = parser.parse_args() - serveur = args.serveur - file = args.file - level = args.level - sport = args.sport - eport = args.eport - - - if file is not None or serveur is not None: - - header() - usage() - - if file and level == "eth": - pcap_analyser_eth(file) - elif file and level == "ip": - pcap_analyser_ip(file) - elif file and level == "tcp": - pcap_analyser_tcp(file) - elif file and level == "udp": - pcap_analyser_udp(file) - elif file and level == "icmp": - pcap_analyser_icmp(file) - elif serveur is not None and level == "arp": - arp_ping(serveur) - elif serveur is not None and level == "icmp": - icmp_ping(serveur) - - elif serveur is not None and level == "tcp" and sport is not None: - port = sport - tcp_ping(serveur,port) - - elif serveur is not None and level == "scan" and sport is not None and eport is not None: - start_port = int(sport) - end_port = int(eport) - flag = 0 - superscan(serveur,start_port,end_port) - - elif serveur is not None and level == "scan" and sport is None and eport is None: - start_port = int(0) - end_port = int(0) - flag=1 - superscan(serveur,start_port,end_port) - - elif serveur is not None and level == "udp": - udp_ping(serveur,port=0) - - elif serveur is not None and level == "geoip": - geo_ip(serveur) + # Print resolved IP + write(f"[*] Target IP: {ip}") - + # Skip GeoIP for localhost/private addresses to avoid errors + try: + addr = ipaddress.ip_address(ip) + if addr.is_private or addr.is_loopback: + write("[*] GeoIP: Local/private IP — skipping GeoIP lookup.") + else: + write(f"[*] GeoIP: {geo_ip(ip)}") + except Exception as e: + write(f"[*] GeoIP: lookup skipped ({e})") - else: - - print '''usage: CyberScan.py [-h] [-s SERVEUR] [-p LEVEL] [-d SPORT] [-t EPORT] - [-f FILE] -use cyberscan -h to help ''' - - except KeyboardInterrupt: - print "\n[*] You Pressed Ctrl+C. Exiting" - sys.exit(1) + # Run the scan + superscan(ip, start_port, end_port) - -if __name__ == '__main__': +if __name__ == "__main__": main() - - - - - - -