Python make port scanner(use nmap) #3 - make port scanner (파이썬 포트스캐너 만들기 #3 - port scanner)

앞서 두 과정을 통해 optparse의 사용과 nmap을 설치하였습니다.
이제 파이썬과 nmap 통해 port scanner를 제작 해보도록 하겠습니다.

참조 - 해커의언어, 치명적 파이썬 / TJ오코너

1. optparse 제작

먼저 optparse를 통해 아래와같은 소스를 제작해 보도록 하겠습니다.

import optparse
port = '21,22,23,25,42,53,70,79,80,88,110,118,156,161,220,8080'
def main():
parser = optparse.OptionParser('usage %prog <options> \n-H <target host> : input target host name \n-p <target port> : input target port name \n-A <all port> : target is all port')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] separated by comma')
parser.add_option('-A', dest='allPort', action='store_true', help='target port is all')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(',')
allPort = options.allPort
if ((tgtPorts[0] == 'None') & (allPort == None)) | (tgtHost == None) :
print(parser.usage)
exit(0)
if (allPort == True):
print('allport')
else:
print('port')
if __name__ == '__main__':
main()
view raw gistfile1.txt hosted with ❤ by GitHub

-H와 -p -A 옵션을 통해 각각 아래의 기능을 구현합니다.

-H = Host name (ex. 127.0.0.1)
-p = port number (ex. 22)
-A = 직접 명시해 놓은 port (21,22,23,25,42,53,70,79,80,88,110,118,156,161,220,8080)을 스캐닝 합니다.

line 15: 15번 라인을 통해 -H옵션이 없거나 -p나 -A옵션중 하나가 쓰이지 않았다면 프로그램을 종료하도록 처리합니다.

line 19, 22: 19번 라인과 22번 라인을 통해 각 각 -p옵션과 -A옵션을 처리합니다.
-A옵션이 있을 때엔 위에 port변수에 명시한 port들을 scanning하는 분기를 처리하고
-A옵션이 없고 -p옵션이 있을 때에는 -p옵션에 명시한 port들을 scanning하는 분기를 처리합니다.

2. portscanner 제작

nmap을 통해 아래와 같은 함수를 제작해 줍니다.

import nmap
def nmapScan(tgtHost, tgtPort):
nmScan = nmap.PortScanner()
nmScan.scan(tgtHost, tgtPort)
state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
print(" [*] " + tgtHost + " tcp/" + tgtPort + " " + state)
view raw gistfile1.txt hosted with ❤ by GitHub

line 4: 4번 라인을 통해 nmap.PortScanner를 load해 줍니다.
line 5: 5번 라인을 통해 함수 호출때 입력받은 인자(ip주소, 포트넘버)를 load 합니다.
line 6: 6번 라인을 통해 nmScan을 통해 현재 상태 state값을 받아옵니다.
line 7: 7번 라인을 통해 값을 print 해 줍니다.

3. portscanner 완성 및 실행

위에 제작한 1, 2번을 아래와 같이 합쳐줍니다.

import optparse
import socket
import nmap
port = '21,22,23,25,42,53,70,79,80,88,110,118,156,161,220,8080'
def nmapScan(tgtHost, tgtPort):
nmScan = nmap.PortScanner()
nmScan.scan(tgtHost, tgtPort)
state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
print(" [*] " + tgtHost + " tcp/" + tgtPort + " " + state)
def main():
parser = optparse.OptionParser('usage %prog <options> \n-H <target host> : input target host name \n-p <target port> : input target port name \n-A <all port> : target is all port')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] separated by comma')
parser.add_option('-A', dest='allPort', action='store_true', help='target port is all')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(',')
allPort = options.allPort
if ((tgtPorts[0] == 'None') & (allPort == None)) | (tgtHost == None) :
print(parser.usage)
exit(0)
if (allPort == True):
tgtPorts = str(port).split(',')
for tgtPort in tgtPorts:
nmapScan(tgtHost, tgtPort)
else:
for tgtPort in tgtPorts:
nmapScan(tgtHost, tgtPort)
if __name__ == '__main__':
main()
view raw gistfile1.txt hosted with ❤ by GitHub

27, 32번 line의 if else문도 수정 합니다.


------------------------------------------실행 모습---------------------------------------
# python3 TCPportscanner -H 127.0.0.1 -p 22
 [*] 127.0.0.1 tcp/22 open


# python3 TCPportscanner -H 127.0.0.1 -A
 [*] 127.0.0.1 tcp/21 closed
 [*] 127.0.0.1 tcp/22 open
 [*] 127.0.0.1 tcp/23 open
 [*] 127.0.0.1 tcp/25 closed
 [*] 127.0.0.1 tcp/42 closed
 [*] 127.0.0.1 tcp/53 closed
 [*] 127.0.0.1 tcp/70 closed
 [*] 127.0.0.1 tcp/79 closed
 [*] 127.0.0.1 tcp/80 closed
 [*] 127.0.0.1 tcp/88 closed
 [*] 127.0.0.1 tcp/110 closed
 [*] 127.0.0.1 tcp/118 closed
 [*] 127.0.0.1 tcp/156 closed
 [*] 127.0.0.1 tcp/161 closed
 [*] 127.0.0.1 tcp/220 closed
 [*] 127.0.0.1 tcp/8080 closed


( httpd 80번 포트 서비스 오픈 후 실행)
# service httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for 500009674769
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]

# python3 TCPportscanner -H 127.0.0.1 -A
 [*] 127.0.0.1 tcp/21 closed
 [*] 127.0.0.1 tcp/22 open
 [*] 127.0.0.1 tcp/23 open
 [*] 127.0.0.1 tcp/25 closed
 [*] 127.0.0.1 tcp/42 closed
 [*] 127.0.0.1 tcp/53 closed
 [*] 127.0.0.1 tcp/70 closed
 [*] 127.0.0.1 tcp/79 closed
 [*] 127.0.0.1 tcp/80 open
 [*] 127.0.0.1 tcp/88 closed
 [*] 127.0.0.1 tcp/110 closed
 [*] 127.0.0.1 tcp/118 closed
 [*] 127.0.0.1 tcp/156 closed
 [*] 127.0.0.1 tcp/161 closed
 [*] 127.0.0.1 tcp/220 closed
 [*] 127.0.0.1 tcp/8080 closed
------------------------------------------실행 모습---------------------------------------




Related Posts: