security
CHAPTER 71 / 84
읽기 약 2분
FUNCTION
서브넷 스캐너 만들기
핵심 개념
ipaddress 모듈 + ThreadPoolExecutor로 로컬 네트워크의 활성 호스트를 탐지한다.
본문
서브넷 순회 — ipaddress 모듈
# ⚠️ 이 코드는 허가된 환경에서만 사용하세요.
import ipaddress
def list_subnet_hosts(cidr: str) -> list[str]:
"""CIDR 표기로 서브넷 내 모든 호스트 IP 나열."""
network = ipaddress.ip_network(cidr, strict=False)
return [str(ip) for ip in network.hosts()]
# /24 서브넷 — 254개 호스트
hosts = list_subnet_hosts('192.168.1.0/24')
print(len(hosts)) # 254
print(hosts[:3]) # ['192.168.1.1', '192.168.1.2', '192.168.1.3']
# /16 서브넷은 65,534개 — 신중히
# 너무 큰 서브넷 방어
def safe_list_hosts(cidr: str, max_hosts: int = 1024) -> list[str]:
network = ipaddress.ip_network(cidr, strict=False)
if network.num_addresses > max_hosts:
raise ValueError(f'{cidr}: {network.num_addresses}개 호스트 — 너무 큼 (최대 {max_hosts})')
return [str(ip) for ip in network.hosts()]활성 호스트 탐지 — Ping Sweep
# ⚠️ 이 코드는 허가된 환경에서만 사용하세요.
import platform
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
def is_alive(host: str, timeout: int = 1) -> tuple[str, bool]:
"""단일 호스트 ping 1회로 도달 여부 확인."""
is_windows = platform.system().lower() == 'windows'
if is_windows:
cmd = ['ping', '-n', '1', '-w', str(timeout * 1000), host]
else:
cmd = ['ping', '-c', '1', '-W', str(timeout), host]
try:
result = subprocess.run(cmd, capture_output=True, timeout=timeout + 1)
return host, result.returncode == 0
except subprocess.TimeoutExpired:
return host, False
def ping_sweep(cidr: str, workers: int = 50) -> list[str]:
"""서브넷 전체 ping sweep — 활성 호스트 추출."""
hosts = safe_list_hosts(cidr)
alive = []
with ThreadPoolExecutor(max_workers=workers) as ex:
futures = {ex.submit(is_alive, h, 1): h for h in hosts}
for fut in as_completed(futures):
host, ok = fut.result()
if ok:
alive.append(host)
return sorted(alive, key=lambda x: ipaddress.ip_address(x))
# /24 서브넷 sweep → 약 5초
# alive_hosts = ping_sweep('192.168.1.0/24')TCP 기반 활성 탐지 — Ping이 차단됐을 때
일부 환경은 ICMP를 차단하지만 TCP 80/443은 열어둠:
import socket
def tcp_alive(host: str, ports: list[int] = None, timeout: float = 1.0) -> bool:
"""일반적 포트 중 하나라도 응답하면 활성."""
if ports is None:
ports = [80, 443, 22, 8080]
for port in ports:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(timeout)
try:
if s.connect_ex((host, port)) == 0:
return True
finally:
s.close()
return FalseARP 스캔 (root 권한 필요)
같은 LAN 내에서는 ARP가 가장 정확합니다 (방화벽이 못 차단):
# pip install scapy
# 주의: ARP 스캔은 root/Administrator 권한 필요
# ⚠️ 이 코드는 허가된 환경에서만 사용하세요.
# from scapy.all import ARP, Ether, srp
#
# def arp_scan(cidr: str, timeout: int = 2) -> list[dict]:
# """LAN ARP 스캔 — IP+MAC 페어 수집."""
# arp = ARP(pdst=cidr)
# ether = Ether(dst='ff:ff:ff:ff:ff:ff')
# packet = ether / arp
# answered, _ = srp(packet, timeout=timeout, verbose=False)
# return [{'ip': r.psrc, 'mac': r.hwsrc} for _, r in answered]
#
# 후속 트랙(scapy 모듈)에서 자세히 다룸실습: 통합 호스트 디스커버리
def discover_hosts(cidr: str, methods: list[str] = None, workers: int = 50) -> dict:
"""ICMP + TCP 결합 — 어떤 방어를 뚫고도 호스트 탐지."""
if methods is None:
methods = ['icmp', 'tcp']
hosts = safe_list_hosts(cidr)
result = {'cidr': cidr, 'total': len(hosts), 'alive': []}
with ThreadPoolExecutor(max_workers=workers) as ex:
futures = {}
for h in hosts:
futures[ex.submit(_check_host, h, methods)] = h
for fut in as_completed(futures):
host, info = fut.result()
if info['alive']:
result['alive'].append({'host': host, **info})
result['alive'].sort(key=lambda x: ipaddress.ip_address(x['host']))
return result
def _check_host(host: str, methods: list[str]) -> tuple[str, dict]:
info = {'alive': False, 'methods': []}
if 'icmp' in methods:
_, ok = is_alive(host)
if ok:
info['alive'] = True
info['methods'].append('icmp')
if 'tcp' in methods and not info['alive']:
if tcp_alive(host):
info['alive'] = True
info['methods'].append('tcp')
return host, info⚠️ 핵심 안전 규칙
- ✅ 자기 LAN(192.168.x.x, 10.x.x.x, 172.16~31.x.x)
- ✅ TryHackMe/HackTheBox 랩 환경
- ❌ 회사 네트워크(허가 없이) — 인사 문제 + 법적 위험
- ❌ 공용 IP 대역 — 명백한 불법
속도 vs 부하 균형
# 안전한 기본값
SAFE_DEFAULTS = {
'workers': 50, # 동시 50개
'timeout': 1.0, # 1초
'rate_per_host': 'once', # 호스트당 1회만
'delay_between_batches': 0.1, # 배치 간 100ms
}AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 서브넷 스캐너의 동시성·차단 회피·속도 균형을 분석하고 실전 환경에서 안정적으로 동작하도록 개선해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
ICMP vs TCP vs ARP 호스트 디스커버리 각각의 장단점을 표로 비교하고 환경별 추천 방법을 보여줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 LAN 스캔 결과 데이터를 분석해서 알려진 디바이스 vs 미식별 디바이스· 응답 시간 이상 패턴을 종합 리포트로 만들어줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 LAN 스캐닝 트렌드 — IPv6 LAN/SDN 환경에서 전통 스캔이 여전히 유효한지 실무자 관점으로 솔직히 알려줘.
⭐ 이것만 기억하세요
서브넷 스캐너 만들기는 이 3가지만 확실히 잡으세요
1.ipaddress.ip_network로 서브넷을 안전하게 순회하고 ThreadPoolExecutor로 빠르게 스캔할 수 있다
2.ICMP만으로는 부족 — TCP 80/443 fallback을 결합해야 방화벽 환경에서도 호스트를 찾을 수 있다
3.다음 챕터에서 모듈 3 종합 — DNS+포트+서비스를 결합한 정찰 도구를 만든다
공유하기
진행도 71 / 84