파이썬(Python)/화이트해킹,침투테스트(Hack,Penetration)

Python Socket 만으로 포트 스캐너 만들기(Port Scanner)

끄적끄적아무거나 2021. 8. 13. 09:01

Python Socket 만으로 포트 스캐너만들기(Port Scanner)

 

이번 파이썬 프로젝트는 파이선 내부 라이브러리 socket으로 해당 IP주소의 포트가 열려있는지 검색하는 코드를 제작할 것이다. 포트 검색을 위한 조건으로 아래 2개의 입력을 받을 것이다.

 

  • IP주소 또는 도메인 주소 (Ex. 127.0.0.1 or www.famtech.co.kr)
  • 포트 범위 (Ex. 0-65535)

구현 방식을 간단하게 설명하면 IP주소값인지 도메인 주소인지 구분을 위해 정규 표현식을 사용해서 구분한다. 정규표현식 구현에 대한 설명은 괄호안에 링크를 참조하길 바란다. (https://scribblinganything.tistory.com/256)

 

그렇게 받은 입력 받은 값으로 socket.socket 함수를 사용하여 연결할 것이다. TCP 연결 방식과 IPv4 방식을 사용한다. socket에 대한 설명은 https://scribblinganything.tistory.com/247 을 참조 하길 바란다. 

 

연결이 되면 valid_port 리스트에 집어 넣고 출력한다. 

 


구현하기

 

코드>>

import socket
import ipaddress
import re

port_regex = re.compile("([0-9]+){1,5}-([0-9]+){1,5}")
ip_regex1 = re.compile("^\d")
ip_regex2 = re.compile("^www\.")

while True:
    ip_addr_input = input("IP주소 또는 도메인 주소를 입력하세요(ex: 127.0.0.1 or www.naver.com) :")
    try:
        ip_regex1_valid = ip_regex1.search(ip_addr_input.replace(" ",""))
        ip_regex2_valid = ip_regex2.search(ip_addr_input.replace(" ",""))
        if ip_regex1_valid:
            ip_addr = ipaddress.ip_address(ip_addr_input)
            break
        elif ip_regex2_valid: 
            ip_addr = ip_addr_input
            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

valid_ports = []
for port in range(port_min, port_max + 1):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(0.5)
            s.connect((ip_addr, port))
            valid_ports.append(port)

    except:
        print("port",port,"not open")
        pass

for port in valid_ports:
    print(f"{ip_addr_input} 주소에 {port}가 연결되었습니다")

 

결과>>

IP주소 또는 도메인 주소를 입력하세요(ex: 127.0.0.1 or www.naver.com) :www.famtech.co.kr
포트범위를 정해주세요(ex:0-65535) :440-445
port 440 not open
port 441 not open
port 442 not open
port 444 not open
port 445 not open

 

주석>>

 

import ipaddress

 

해당 라이브러리는 ip주소가 양식에 맞춰 잘작성되었는지를 확인해 준다. 제대로 된 ip이면<class 'ipaddress.IPv4Address'> 형식으로 return 해준다.

만일 잘못된 형식이면 에러를 발생시킨다. 아래는 잘못된 ip address에 대한 결과이다. 

IP주소 또는 도메인 주소를 입력하세요(ex: 127.0.0.1 or www.naver.com) :999.1234.1234.134
잘못된 주소 형식입니다.

 

s.settimeout(0.5)

 

타임아웃은 연결이 안되는 경우 socket 닫고 다시 만들 수 있게 해준다.