파이썬 nmap으로 port scanner 만들기
nmap은 네트워크 검사, 모니터, 시험에 유용한 소프트웨어이다. 파이썬에도 라이브러리를 제공해서 파이썬과 연결해서 사용할 수 있다. nmap을 설치하고 간단하게 파이썬에서 사용하는 방법은 https://scribblinganything.tistory.com/235 글을 참조하길 바란다.
앞선 포스트에서 socket으로 포트스캔을 하였다. (https://scribblinganything.tistory.com/258) socket은 파이썬 내장 함수로 별도의 설치 없이 바로 실행할 수 있다. 이번에는 nmap을 사용해서 실행 해보겠다.
구현하기
코드>>
import nmap
import ipaddress
import re
port_regex = re.compile("([0-9]+){1,5}-([0-9]+){1,5}")
ip_regex1 = re.compile("^\d")
nmap_scan = nmap.PortScanner()
while True:
ip_addr_input = input("IP주소를 입력하세요(ex: 127.0.0.1) :")
try:
ip_regex1_valid = ip_regex1.search(ip_addr_input.replace(" ",""))
if ip_regex1_valid:
ip_addr = ipaddress.ip_address(ip_addr_input)
print(ip_addr)
print(type(ip_addr))
break
except:
print("잘못된 주소 형식입니다.")
while True:
port_min = 0
port_max = 65535
port_range = input("포트범위를 정해주세요(ex:0-65535) :")
port_range_valid = port_regex.search(port_range.replace(" ",""))
if port_range_valid:
port_min = int(port_range_valid.group(1))
port_max = int(port_range_valid.group(2))
break
for port in range(port_min, port_max + 1):
try:
port_condition = nmap_scan.scan(ip_addr_input, str(port))
print(port_condition)
state = (port_condition['scan'][ip_addr_input]['tcp'][port]['state'])
print(f"{port} 포트 상태는 '{state}'입니다")
except:
print(f"{port} 포트는 닫혀있습니다")
결과>>
IP주소를 입력하세요(ex: 127.0.0.1) :211.43.203.70
211.43.203.70
<class 'ipaddress.IPv4Address'>
포트범위를 정해주세요(ex:0-65535) :442-444
{'nmap': {'command_line': 'nmap -oX - -p 442 -sV 211.43.203.70', 'scaninfo': {'tcp': {'method': 'syn', 'services': '442'}}, 'scanstats': {'timestr': 'Thu Aug 12 17:35:35 2021', 'elapsed': '1.11', 'uphosts': '1', 'downhosts': '0', 'totalhosts': '1'}}, 'scan': {'211.43.203.70': {'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4': '211.43.203.70'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'reset'}, 'tcp': {442: {'state': 'filtered', 'reason': 'no-response', 'name': 'cvc_hostd', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}}}}}
442 포트 상태는 'filtered'입니다
{'nmap': {'command_line': 'nmap -oX - -p 443 -sV 211.43.203.70', 'scaninfo': {'tcp': {'method': 'syn', 'services': '443'}}, 'scanstats': {'timestr': 'Thu Aug 12 17:35:48 2021', 'elapsed': '13.41', 'uphosts':
'1', 'downhosts': '0', 'totalhosts': '1'}}, 'scan': {'211.43.203.70': {'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4': '211.43.203.70'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'syn-ack'}, 'tcp': {443: {'state': 'open', 'reason': 'syn-ack', 'name': 'http', 'product': 'Apache httpd', 'version': '', 'extrainfo': '', 'conf': '10', 'cpe': 'cpe:/a:apache:http_server'}}}}}
443 포트 상태는 'open'입니다
{'nmap': {'command_line': 'nmap -oX - -p 444 -sV 211.43.203.70', 'scaninfo': {'tcp': {'method': 'syn', 'services': '444'}}, 'scanstats': {'timestr': 'Thu Aug 12 17:35:49 2021', 'elapsed': '1.12', 'uphosts': '1', 'downhosts': '0', 'totalhosts': '1'}}, 'scan': {'211.43.203.70': {'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4': '211.43.203.70'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'syn-ack'}, 'tcp': {444: {'state': 'filtered', 'reason': 'no-response', 'name': 'snpp', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}}}}}
444 포트 상태는 'filtered'입니다
주석>>
이전에 socket으로 포트스캐너를 만들었던 방식과 거의 유사하다. 차이는 아래 코드만 있다.
for port in range(port_min, port_max + 1):
try:
port_condition = nmap_scan.scan(ip_addr_input, str(port))
print(port_condition)
state = (port_condition['scan'][ip_addr_input]['tcp'][port]['state'])
print(f"{port} 포트 상태는 '{state}'입니다")
except:
print(f"{port} 포트는 닫혀있습니다")
위 코드는 원하는 ip 주소와 port를 넣어서 nmap으로 동작시키면 나오는 결과를 port_condition으로 받았다. 해당 내용은 print를 하여서 확인하였는데 결과에서 볼수 있다.
결과는 dictionary 형태로 나와서 포트의 상태를 원하는 키값을 넣어서 가져올 수 있다. 그리고 "command_line"을 보면 nmap을 어떤 명령을 실행 시켜 진행했는지 알 수 있다.
nmap -oX - -p 442 -sV 211.43.203.70
-oX는 nmap을 XML 형식으로 가져오겠다는 의미이다.
-p는 포트번호이다.
-sV는 해당 아이피의 서버나 데몬의 버전을 출력한다.
와이어 샤크로 결과 확인하기
filter : tcp.port == 443 and ip.addr == 211.43.203.70
wireshark의 필터링 기능을 사용해서 필터한 결과 그림1과 같이 443번 포트로 3 핸드쉐이크(3 way handshake)가 진행되고 연결이되었음을 알 수 있다.
'파이썬(Python) > 화이트해킹,침투테스트(Hack,Penetration)' 카테고리의 다른 글
TCP stealth scan이란? (와이어샤크로 확인하기,nmap) (0) | 2021.08.29 |
---|---|
동일 네트워크에 연결된 IP와 Port 찾기 (nmap) (0) | 2021.08.28 |
Python Socket 만으로 포트 스캐너 만들기(Port Scanner) (0) | 2021.08.13 |
Python 버퍼보다 큰 데이터 주고받기 (패킷 보내기, 받기) (0) | 2021.08.07 |
python socket이란? AF_INET, SOCK_STREAM 의미, 간단하게 텍스트 주고 받는 서버 만들기 (0) | 2021.08.04 |