Python実装ポートスキャナ

6620 ワード

Pythonのプログラミングの基礎を少し持つ学習者に適しています
実現の原理
最も簡単なポートスキャンツールは、TCP接続スキャン、すなわち、オペレーティングシステムの本来のネットワーク機能を利用し、通常、SYNスキャンの代替オプションとして使用される.Nmapは、Unixシステムのようなconnect()コマンドが使用されているため、このモードを接続スキャンと呼ぶ.ポートがオープンであれば、オペレーティングシステムはTCPの3回の握手を完了し、ポートスキャンツールはすぐに確立した接続を閉じ、サービス攻撃を拒否することを防止します.このスキャンモードの利点は、ユーザが特別な権限を必要としないことである.しかし、オペレーティングシステムのオリジナルネットワーク機能を使用すると、下位制御が実現できないため、このスキャン方式は流行していない.また、TCPスキャンは容易に発見され、特にポート清掃の手段として、これらのサービスは送信者のIPアドレスを記録し、侵入検出システムがアラームをトリガーする可能性がある.
もう1つのスキャン方式はSYNスキャンであり、ポートスキャンツールはオペレーティングシステムのオリジナルネットワーク機能を使用せず、IPパケットを自分で生成し、送信し、応答を監視する.このスキャンモードは、完全なTCP接続が確立されていないため、「半オープンスキャン」と呼ばれる.ポートスキャンツールはSYNパケットを生成し、ターゲットポートが開いている場合はSYN-ACKパケットを返します.スキャン側はRSTパケットに応答し、握手が完了する前に接続を閉じます.ポートが閉じているがフィルタが使用されていない場合、ターゲットポートはRSTパケットを返し続けるはずです.この粗いネットワーク利用方式には、スキャンツールにパケットの送信と応答待ち時間の長さを全権的に制御し、より詳細な応答分析を可能にするいくつかの利点がある.ターゲットホストに対するスキャン方式のどちらが侵入性を備えていないかについては議論があるが,SYNスキャンの利点は完全な接続が確立されないことである.しかしながら、RSTパケットは、特にプリンタのような単純なネットワークデバイスのネットワーク詰まりを引き起こす可能性がある.
インスタンスでは、オペレーティングシステムのsocket接続インタフェースを直接利用して、ターゲットサーバのポートが接続可能かどうかを初歩的にテストし、可能であればポートのオープン状態に戻ります.
シングルスレッドスキャン機能の実装
主にこの簡単なスキャナーを単一スレッドスキャンとして実現し、具体的な手順は以下の通りである.
ポートおよびターゲットサーバの取得
新しいコードは次のとおりです.
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
from socket import *

# port_scan.py  -
host = sys.argv[1]
protstrs = sys.argv[2].splist('-')

start_port = int(portstrs[0])
end_port = int(portstrs[1])

target_ip = gethostbyname(host)
opened_ports = []

for port in range(start_port, end_port):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.settimeout(10)
    result = sock.connect_ex((target_ip, port))
    if result == 0:
        opened_ports.append(port)

print("Opened ports:")

for i in opened_ports:
    print(i)

コード解析:
ターゲットipアドレスを取得するには:
target_ip = gethostbyname(host)

ループ接続:
opened_ports = []

for port in range(start_port, end_port):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.settimeout(10)
    result = sock.connect_ex((target_ip, port))
    if result == 0:
        opened_ports.append(port)
        
opened_portsリストの印刷
print i in opened_ports:
        print(i)

テストスキャン10-200ポートの状況
>> python3 scanning_demo.py 127.0.0.1 10-200
Opened ports:
53
80

53ポートと80ポートが開いているのがわかります.127.0.0.1:80を使用して、どのようなタイプのサービスが開いているかを確認できます.
マルチスレッドスキャン
上記のコードは単一スレッドスキャンポートのテストを実現していますが、通常のプログラムは実行中に実行効率とパフォーマンスの向上を考慮する必要があります.そのため、マルチスレッドプログラムを実現する必要があります.
新しいコードは次のとおりです.
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import thread
from socket import *

def tcp_test(port):
        sock = socket(AF_INET, SOCK_STREAM)
        sock.settimeout(10)
        result = sock.connect_ex((target_ip, port))
        if result == 0:
                lock.acquire()
                print "Opened Port:", port
                lock.release()
if __name__=='__main__':
    # portscan.py  -
    post = sys.argv[1]
    portstrs = sys.argv[2].split('_')
    
    start_port = int(portstrs[0])
    end_port = int(portstrsp[1])
    
    target_ip = gethostbyname(host)
    
    lock = thread.allocate_lock()
    
    for port in range(start_port, end_port):
            thread.start_new_thread(tcp_test, (port,))

コード解析
マルチスレッドを実装するために必要なコードパッケージthreadを導入します.
import thread

TCPテスト関数の実装
print出力にはロックが必要です.ロックをかけないと複数の出力が混在するエラー状態になる可能性があります.ロックはプログラム起動時に作成する必要があります.これにより、新しいスレッドがこのロックを共有できます.
def tcp_test(port):
        sock = socket(AF_INET, SOCK_STREAM)
        sock.settimeout(10)
        result = sock.connect_ex((target_ip, port))
        if result == 0:
                lock.acquire()
                print "Opened Port:", port
                lock.release()

コードの実行が完了したらロックを解除します(ロックを解放します)
入力した処理とlockの作成はmain関数に置くことができます.
if __name__=='__main__':
    # portscan.py  -
    host = sys.argv[1]
    portstrs = sys.argv[2].split('-')

    start_port = int(portstrs[0])
    end_port = int(portstrs[1])

    target_ip = gethostbyname(host)

    lock = thread.allocate_lock()

次にforループを変更します.
for port in range(start_port, end_port):
        thread.start_new_thread(tcp_test, (port,))
thread.start_new_threadは、スレッドを作成するために使用されます.この関数の最初のパラメータは、スレッドで実行される関数であり、2番目のパラメータは、関数の入力としてメタグループでなければなりません.tcp_test関数には1つのパラメータしかないので、(port,)という形式で、このパラメータがメタグループであることを示します.
最後に前節の出力コードを削除した後、私たちのマルチスレッド改造はすでに完了しました.
テスト結果は次のとおりです.
>> python3 all_scanning_demo.py 127.0.0.1 80-200
Opened ports:80

python-nmapパッケージ
Pythonポートスキャンを学ぶ私たちが接触しなければならない非常に強力なPythonポートスキャンパッケージpyton-nmapこれは有名なセキュリティツールで、オープンソースです.pythonプログラムでnmapポートスキャンのPythonパッケージを使用することができ、開発者がnmapスキャン結果を解析し、自動スキャンのタスクを実現し、レポートを出力することができます.また、牛Bは、スキャンが完了した後にユーザがカスタマイズしたコールバック関数を呼び出す非同期操作をサポートすることができる.
install
インストールコマンドの実行
pip install pyton-nmap

Collecting python-nmap
  Downloading python-nmap-0.6.1.tar.gz (41kB)
    100% |████████████████████████████████| 51kB 65kB/s
Building wheels for collected packages: python-nmap
  Running setup.py bdist_wheel for python-nmap ... done
  Stored in directory: /Users/devon/Library/Caches/pip/wheels/d2/20/17/8eb9401fb0fa5ffbd0394c44d9d1c743036896c86029b0a613
Successfully built python-nmap
Installing collected packages: python-nmap
Successfully installed python-nmap-0.6.1

python shell操作に進みます.
nmapパッケージのロード
import nmap

PortScannerオブジェクトの作成
nm = nmap.PortScanner()

127.0.0.1の80~200ポートをスキャンします.
nm.scan('127.0.0.1','22-100')

使用するコマンドラインとスキャン情報を表示します.
nm.command_line()
Nm.scaninfo()

スキャンされたターゲットホスト情報を表示するには、次の手順に従います.
nm.all_hosts()
nm['127.0.0.1'].hostname()
nm['127.0.0.1'].state()
nm['127.0.0.1'].all_protocols()
nm['127.0.0.1']['tcp'].keys()

拡張
nmapによって複雑なスキャンプログラムを実現することができます.上記のプログラムにpython-nmapパッケージを導入し、それを拡張して改版し、いくつかの有用な機能を実現することを試みることができます.
  • 1.GUIを追加し、スキャンのポート範囲とホスト
  • を手動で追加
  • 2.csv形式のスキャンレポート
  • を生成
  • 3.バックグラウンドでスキャンを行い、完了したらスキャンレポートがメールされた形式で管理者
  • に送信される.
    よく手を出して、よく考えて進歩を祈ります!