파이썬으로 작성한 TCP 포트 스캔 툴….

개인적으로 C 이외의 다른 언어에는 소질이 없고, 특히 포인터 개념(?)이 없는 언어를 접할 때는 지금도 어렵게만 느껴지는데, 파이썬은 왠지 그런 언어임에도 불구하고, 배우고 잘 쓰고 싶은 생각이 들어서, 파이썬 배워가면서, 특정 IP에 대해서 TCP 포트 스캔과, IP의 국가, 및  소유자정보을 같이 명시할 수 있는 툴을 작성했습니다.

Whois 모듈은 https://github.com/secynic/ipwhois 사이트에 확인할 수 있습니다.

__author__ = 'franc3sco'

from socket import *
from threading import *
import optparse
from os import *
import os
import time
from ipwhois import IPWhois
from ipwhois.utils import get_countries


target_ports=['80','443','1723','3128','8080','8088','8118','8123','9064','9999']
screenLock = Semaphore(value=1)
sOutfilename="scanresult.txt"
CONNTIMEOUT=2

def writetofile(scanresult):
    try:
        fp = open(sOutfilename, 'a')
        screenLock.acquire()
        fp.write(scanresult)
        fp.close()
    except Exception as e:
        screenLock.acquire()
        print(e)
    finally:
        screenLock.release()
        fp.close()
    return

def initialize_resultfile():
    strCategory = 'IP Address'
    idx = 0
    count_port = len(target_ports)
    while count_port:
        count_port -= 1
        strCategory += ',' + 'TCP/' + str(target_ports[idx])
        idx += 1
    strCategory += ',Country,'
    strCategory += 'Company'
    strCategory += '\n'

    print("%s" % strCategory, end='')

    writetofile(strCategory)
    return

def get_whois(ip):
    countries = get_countries()
    obj = IPWhois(str(ip))
    results = obj.lookup(False)
    strCountry = countries[results['nets'][0]['country']].split(',')[0]
    return (strCountry,results['nets'][0]['name'])

def port_scan(target_ip, target_port):
    port_result=[]
    (ip_country, ip_company) =get_whois(target_ip)

    for target_port in target_ports:
        setdefaulttimeout(CONNTIMEOUT)
        try:
            s = socket(AF_INET, SOCK_STREAM)
            s.connect((target_ip, int(target_port)))
            port_result.append("O")
            s.close()
        except Exception as e:
            port_result.append("X")
        finally:
            s.close()

    scanresult = target_ip
    for open_port in port_result:
        scanresult += ',' + str(open_port)

    if not ip_country :
        scanresult += ',' + 'None' +','
    else :
        scanresult += ',' + ip_country +','

    if not ip_company :
        scanresult += 'None'
    else :
        scanresult += ip_company

    scanresult += '\n'
    print("%s" % (scanresult), end='')
    writetofile(scanresult)
    return

def get_target_from_file(sFilename):
    threads = []
    try:
        fp = open(sFilename,'r')
        lines = fp.readlines()
    except FileNotFoundError as e:
        print(e)
        exit(0)

    for target_ip in lines:
        target_ip = target_ip.strip('\r').strip('\n')
        t = Thread(target=port_scan, args=(target_ip, target_ports))
        t.start()
        threads.append(t)

    fp.close()

    for t in threads:
        t.join()

    return

def main():
    start_time = time.time()
    print("starting port scan against target hosts ...")
    opt = optparse.OptionParser(usage='usage %prog -t <target_file>')
    opt.add_option('-t', dest='target_file', type='string', help='specify file that include target ip address')
    (options, args) = opt.parse_args()
    sTarget_file = str(options.target_file)

    if (sTarget_file == 'None'):
        opt.print_help()
        exit(0)

    if path.exists(sOutfilename):
        os.remove(sOutfilename)

    initialize_resultfile()
    get_target_from_file(sTarget_file)

    print("portscan ended (Elapsed : %0.2f)Sec" % (time.time() - start_time))

if __name__ == '__main__':
    main()
Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: