377 lines
11 KiB
Python
Raw Normal View History

2025-08-03 11:16:25 +02:00
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)
2025-08-04 00:49:53 +02:00
try:
banner = await asyncio.wait_for(reader.read(1024), 1.0)
banner = banner.decode('utf-8', errors='ignore').strip()
except:
banner = ''
2025-08-03 11:16:25 +02:00
writer.close()
await writer.wait_closed()
2025-08-04 00:49:53 +02:00
return True, banner
2025-08-03 11:16:25 +02:00
except:
2025-08-04 00:49:53 +02:00
return False, ''
2025-08-03 11:16:25 +02:00
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)
2025-08-04 00:49:53 +02:00
open_ports = [(port, ports_services.get(port, 'Unknown'), banner) for port, (is_open, banner) in zip(ports, results) if is_open]
2025-08-03 11:16:25 +02:00
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:
2025-08-04 00:49:53 +02:00
is_open, banner = await check_port(ip, port, timeout=0.5)
if is_open:
2025-08-03 11:16:25 +02:00
service = ports_services.get(port, 'Unknown')
pbar.update(1)
2025-08-04 00:49:53 +02:00
return (port, service, banner)
2025-08-03 11:16:25 +02:00
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
2025-08-04 00:49:53 +02:00
async def get_dns_info(ip_str):
loop = asyncio.get_event_loop()
for attempt in range(3):
try:
hostname = (await loop.run_in_executor(None, socket.gethostbyaddr, ip_str))[0]
a_record = await loop.run_in_executor(None, socket.gethostbyname, hostname)
return hostname, a_record
except Exception as e:
print(f"Attempt {attempt+1} failed for {ip_str}: {e}")
await asyncio.sleep(2)
return "Unknown", "Unknown"
2025-08-03 11:16:25 +02:00
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',
2025-08-04 00:49:53 +02:00
1984: 'Big Brother Monitor',
2025-08-03 11:16:25 +02:00
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',
2025-08-04 00:49:53 +02:00
2242: 'Folio Remote Server',
2248: 'User Management Service',
2280: 'LNVPOLLER',
2025-08-03 11:16:25 +02:00
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',
2025-08-04 00:49:53 +02:00
3000: 'Ruby on Rails',
3050: 'Interbase/Firebird',
3100: 'OpCon/xps',
2025-08-03 11:16:25 +02:00
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',
2025-08-04 00:49:53 +02:00
4190: 'Sieve Mail Filter',
2025-08-03 11:16:25 +02:00
4321: 'BoBo',
2025-08-04 00:49:53 +02:00
4369: 'Erlang EPMD',
4431: 'adWISE Pipe',
2025-08-03 11:16:25 +02:00
4664: 'Google Desktop',
4899: 'Radmin',
2025-08-04 00:49:53 +02:00
4949: 'Munin',
2025-08-03 11:16:25 +02:00
5000: 'UPnP',
5001: 'Synology',
5009: 'Airport Admin',
5051: 'IDA Agent',
5060: 'SIP',
5190: 'AIM/ICQ',
5222: 'XMPP',
5269: 'XMPP SSL',
5432: 'PostgreSQL',
2025-08-04 00:49:53 +02:00
54744: 'Unknown',
2025-08-03 11:16:25 +02:00
5500: 'VNC Hotline',
5554: 'Sasser',
2025-08-04 00:49:53 +02:00
5555: 'ADB',
2025-08-03 11:16:25 +02:00
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',
2025-08-04 00:49:53 +02:00
7071: 'IWC Replica',
2025-08-03 11:16:25 +02:00
7212: 'GhostSite',
7777: 'Oracle Web',
8000: 'HTTP Alternate',
2025-08-04 00:49:53 +02:00
8001: 'VCOM Tunnel',
8006: 'Proxmox VE',
2025-08-03 11:16:25 +02:00
8008: 'HTTP Alternate',
2025-08-04 00:49:53 +02:00
8009: 'AJP',
2025-08-03 11:16:25 +02:00
8080: 'HTTP Alternate',
8081: 'HTTP Alternate',
2025-08-04 00:49:53 +02:00
8088: 'HTTP Alternate',
8089: 'Splunk',
8090: 'HTTP Alternate',
2025-08-03 11:16:25 +02:00
8118: 'Privoxy',
8200: 'MiniDLNA',
2025-08-04 00:49:53 +02:00
8424: 'Unknown',
2025-08-03 11:16:25 +02:00
8443: 'HTTPS Alternate',
8554: 'RTSP Alternate',
2025-08-04 00:49:53 +02:00
8762: 'Unknown',
2025-08-03 11:16:25 +02:00
8767: 'TeamSpeak',
8888: 'HTTP Alternate',
9000: 'SonarQube',
9001: 'Tor',
2025-08-04 00:49:53 +02:00
9002: 'Dynamix',
9003: 'Unknown',
2025-08-03 11:16:25 +02:00
9030: 'Tor',
9040: 'Tor',
9050: 'Tor',
9100: 'JetDirect',
9119: 'MXit',
9200: 'Elasticsearch',
2025-08-04 00:49:53 +02:00
9230: 'Unknown',
2025-08-03 11:16:25 +02:00
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 = []
common_open_ports = {}
for ip, active, open_ports in results:
if active:
active_devices.append(ip)
if open_ports:
2025-08-04 00:49:53 +02:00
common_open_ports[str(ip)] = open_ports
dns_tasks = [get_dns_info(str(ip)) for ip in active_devices]
dns_results = await asyncio.gather(*dns_tasks)
dns_infos = {str(active_devices[i]): dns_results[i] for i in range(len(active_devices))}
devices_need_full = []
for ip in active_devices:
ip_str = str(ip)
if common_open_ports.get(ip_str) or dns_infos[ip_str][0] != "Unknown":
devices_need_full.append(ip_str)
2025-08-03 11:16:25 +02:00
full_tasks = [full_scan(ip, ports_services) for ip in devices_need_full]
full_results = await asyncio.gather(*full_tasks)
2025-08-04 00:49:53 +02:00
devices_with_open_ports = {}
for ip in active_devices:
ip_str = str(ip)
devices_with_open_ports[ip_str] = common_open_ports.get(ip_str, [])
2025-08-03 11:16:25 +02:00
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():
2025-08-04 00:49:53 +02:00
hostname, a_record = dns_infos[ip]
print(f"{ip} (Hostname: {hostname}, A: {a_record}):")
if hostname != "Unknown":
print(f" DNS Records:")
print(f" PTR: {hostname}")
print(f" A: {a_record}")
for port, service, banner in open_ports:
print(f" - {port}: {service}" + (f" ({banner})" if banner else ""))
2025-08-03 11:16:25 +02:00
asyncio.run(main())