320 lines
8.6 KiB
Python
Raw Normal View History

2025-08-03 11:16:25 +02:00
# Discovers if any common port is open, if so, it will scan for all ports on that host.
import asyncio
import socket
import ipaddress
import platform
from tqdm import tqdm
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
except Exception:
ip = '127.0.0.1'
finally:
s.close()
return ip
async def ping(ip):
ping_cmd = f"ping -n 1 -w 1000 {ip}" if platform.system() == 'Windows' else f"ping -c 1 -W 1 {ip}"
try:
proc = await asyncio.create_subprocess_shell(
ping_cmd,
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL
)
returncode = await proc.wait()
return returncode == 0
except Exception:
return False
async def check_port(ip, port, timeout=1):
try:
reader, writer = await asyncio.wait_for(asyncio.open_connection(ip, port), timeout)
writer.close()
await writer.wait_closed()
return True
except:
return False
async def scan_ip(ip, ports, ports_services):
ip_str = str(ip)
if not await ping(ip_str):
return ip_str, False, []
tasks = [check_port(ip_str, port) for port in ports]
results = await asyncio.gather(*tasks)
open_ports = [(port, ports_services[port]) for port, is_open in zip(ports, results) if is_open]
return ip_str, True, open_ports
async def full_scan(ip, ports_services):
all_ports = range(1, 65536)
sem = asyncio.Semaphore(200)
with tqdm(total=len(all_ports), desc=f"Full scan {ip}") as pbar:
async def check(port):
async with sem:
if await check_port(ip, port, timeout=0.5):
service = ports_services.get(port, 'Unknown')
pbar.update(1)
return (port, service)
else:
pbar.update(1)
return None
tasks = [check(port) for port in all_ports]
results = await asyncio.gather(*tasks)
open_ports = sorted([p for p in results if p is not None])
return ip, open_ports
async def main():
local_ip = get_local_ip()
network = ipaddress.IPv4Network(f"{local_ip}/24", strict=False)
ports_services = {
1: 'TCPMUX',
7: 'Echo',
9: 'Discard',
13: 'Daytime',
17: 'QOTD',
19: 'Chargen',
20: 'FTP Data',
21: 'FTP Control',
22: 'SSH',
23: 'Telnet',
25: 'SMTP',
37: 'Time',
39: 'RLP',
42: 'Nameserver',
43: 'WHOIS',
49: 'TACACS',
53: 'DNS',
67: 'BOOTPS',
68: 'BOOTPC',
69: 'TFTP',
70: 'Gopher',
79: 'Finger',
80: 'HTTP',
81: 'Hosts2-NS',
88: 'Kerberos',
102: 'ISO-TSAP',
107: 'RTelnet',
109: 'POP2',
110: 'POP3',
111: 'SunRPC',
113: 'Ident',
115: 'SFTP',
119: 'NNTP',
123: 'NTP',
135: 'MS RPC',
137: 'NetBIOS Name',
138: 'NetBIOS Datagram',
139: 'NetBIOS Session',
143: 'IMAP',
161: 'SNMP',
162: 'SNMP Trap',
179: 'BGP',
194: 'IRC',
201: 'AppleTalk Routing',
209: 'QMTP',
213: 'IPX',
220: 'IMAPv3',
389: 'LDAP',
401: 'UPS',
427: 'SLP',
443: 'HTTPS',
445: 'Microsoft DS',
464: 'Kerberos Change',
465: 'SMTPS',
497: 'Dantz Retrospect',
500: 'ISAKMP',
512: 'Exec',
513: 'Login',
514: 'Syslog',
515: 'LPD',
520: 'RIP',
543: 'Klogin',
544: 'Kshell',
546: 'DHCPv6 Client',
547: 'DHCPv6 Server',
554: 'RTSP',
563: 'NNTPS',
587: 'SMTP Submission',
591: 'FileMaker',
593: 'HTTP RPC',
631: 'IPP',
636: 'LDAPS',
639: 'MSDP',
646: 'LDP',
691: 'MS Exchange',
749: 'Kerberos Admin',
873: 'rsync',
990: 'FTPS',
993: 'IMAPS',
994: 'IRCS',
995: 'POP3S',
1080: 'SOCKS',
1194: 'OpenVPN',
1433: 'MSSQL',
1434: 'MSSQL Monitor',
1521: 'Oracle',
1720: 'H.323',
1723: 'PPTP',
1741: 'CiscoWorks',
1812: 'RADIUS',
1813: 'RADIUS Acct',
1985: 'HSRP',
2000: 'Cisco SCCP',
2049: 'NFS',
2082: 'cPanel',
2083: 'cPanel SSL',
2086: 'WHM',
2087: 'WHM SSL',
2095: 'cPanel Webmail',
2096: 'cPanel Webmail SSL',
2100: 'Oracle XDB FTP',
2222: 'DirectAdmin',
2301: 'Compaq Insight',
2381: 'HP Insight',
2401: 'CVS',
2433: 'MS SQL Analysis',
2483: 'Oracle DB SSL',
2484: 'Oracle DB SSL',
2638: 'Sybase',
2710: 'XBT Tracker',
3128: 'Squid',
3260: 'iSCSI',
3268: 'AD Global Catalog',
3269: 'AD Global Catalog SSL',
3306: 'MySQL',
3389: 'RDP',
3478: 'STUN',
3690: 'SVN',
3784: 'Ventrilo',
3785: 'Ventrilo',
3899: 'Remote Web Workplace',
4000: 'Diablo II',
4321: 'BoBo',
4664: 'Google Desktop',
4899: 'Radmin',
5000: 'UPnP',
5001: 'Synology',
5009: 'Airport Admin',
5051: 'IDA Agent',
5060: 'SIP',
5190: 'AIM/ICQ',
5222: 'XMPP',
5269: 'XMPP SSL',
5432: 'PostgreSQL',
5500: 'VNC Hotline',
5554: 'Sasser',
5631: 'pcAnywhere Data',
5632: 'pcAnywhere Master',
5800: 'VNC HTTP',
5900: 'VNC',
6000: 'X11',
6112: 'Battle.net',
6129: 'DameWare',
6346: 'Gnutella',
6347: 'Gnutella',
6379: 'Redis',
6665: 'IRC',
6666: 'IRC',
6667: 'IRC',
6668: 'IRC',
6669: 'IRC',
6697: 'IRC SSL',
6881: 'BitTorrent',
6969: 'BitTorrent',
7212: 'GhostSite',
7777: 'Oracle Web',
8000: 'HTTP Alternate',
8008: 'HTTP Alternate',
8080: 'HTTP Alternate',
8081: 'HTTP Alternate',
8118: 'Privoxy',
8200: 'MiniDLNA',
8443: 'HTTPS Alternate',
8554: 'RTSP Alternate',
8767: 'TeamSpeak',
8888: 'HTTP Alternate',
9000: 'SonarQube',
9001: 'Tor',
9030: 'Tor',
9040: 'Tor',
9050: 'Tor',
9100: 'JetDirect',
9119: 'MXit',
9200: 'Elasticsearch',
9418: 'Git',
9999: 'Abyss',
10000: 'Webmin',
11371: 'OpenPGP',
12345: 'NetBus',
13720: 'NetBackup',
13721: 'NetBackup',
13724: 'Veritas',
13782: 'Veritas',
13783: 'Veritas',
19226: 'Panda',
19638: 'Ensim',
20000: 'Usermin',
22222: 'EasyEngine',
24800: 'Synergy',
25999: 'Yahoo IM',
27015: 'Half-Life',
27017: 'MongoDB',
27374: 'Sub7',
28015: 'Rust',
31337: 'Back Orifice',
33434: 'Traceroute',
37777: 'Dahua DVR',
40193: 'Novell',
41523: 'MS SQL',
43594: 'Runescape',
43595: 'Runescape',
44818: 'EtherNet/IP',
47808: 'BACnet',
49152: 'Dynamic',
49153: 'Dynamic',
49154: 'Dynamic',
49155: 'Dynamic',
49156: 'Dynamic',
49157: 'Dynamic',
55555: 'FreeCiv',
60000: 'Deep Throat',
65000: 'Stacheldraht'
}
ports = list(ports_services.keys())
tasks = [scan_ip(ip, ports, ports_services) for ip in network.hosts()]
results = await asyncio.gather(*tasks)
active_devices = []
devices_need_full = []
common_open_ports = {}
for ip, active, open_ports in results:
if active:
active_devices.append(ip)
if open_ports:
devices_need_full.append(ip)
common_open_ports[ip] = open_ports
full_tasks = [full_scan(ip, ports_services) for ip in devices_need_full]
full_results = await asyncio.gather(*full_tasks)
devices_with_open_ports = {ip: common_open_ports.get(ip, []) for ip in active_devices}
for full_ip, full_open in full_results:
devices_with_open_ports[full_ip] = full_open
print("Active devices:")
for dev in active_devices:
print(dev)
print("\nDevices with open ports:")
for ip, open_ports in devices_with_open_ports.items():
if open_ports:
print(f"{ip}:")
for port, service in open_ports:
print(f" - {port}: {service}")
asyncio.run(main())