9
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Python] Pythonとセキュリティ - ②Pythonで作るポートスキャニングツール

Last updated at Posted at 2020-02-18

#はじめに
前回([Python] Pythonとセキュリティ - ②Pythonで作るポートスキャニングツール)でPythonの概要や特徴について調べてみた。
今回はPythonを利用した簡単なポートスキャニングツールを作ってみよう。
また、ツールを利用することで不用意に動作しているサービスを確認して対応することが出来る。

情報を収集する行為である「Banner Grabbing」になるため、許可を得ていない対象に実施するのは犯罪です。当該の記事で問題が発生した場合、弊社では一切責任を負い兼ねますのでご了承ください。

#Port Scan(ポートスキャン)とは?
ポートスキャンは対象のサーバーもしくはネットワーク機器などに対してオープンしているポートを検索し、識別することである。オープンしているポートを確認することで、対象から起動しているサービスの確認ができ、攻撃者にとってはポートスキャンが攻撃のための事前準備とも言える。

Port Scanの種類は以下のものがある

  • UDP Port Scan
  • TCP Port Scan
  • Connect Scan
    • Half-open(SYN) Scan
    • FIN / NULL / Xmas Scan

#Port Scan種類別特徴
##UDP Port Scan
UDP Scanの場合は、UDPプロトコルを利用してポートをスキャンする。ポートがオープンされている場合、対象からは応答はないが、クローズされている場合は、ICMPメッセージ(Destination Unreachable, Port Unreachable)の応答がある。但し、UDP Scanはルータやファイアウォールからパケットが損失される可能性が高いため、信頼性は低い。

image.png

##TCP Connect Scan(TCP Open Scan)
connect()関数を利用して、対象と3 Way-Handshakingを結び、オープンされているポートを確認するスキャン。信頼性が高くて、rootと権限がなくてもスキャンを行えるが、スキャンの速度が遅く、ログが残る。
image.png

##TCP Half-Open Scan(SYN Stealth Scan)
SYNスキャンとも呼ばれるHalf-Open Scanは、TCP Connect Scanとは違って、3 Way-Handshakingで完全なセッションは結ばず、SYNパケットのみ利用してポートを確認する。ログは残らないが、実施のため、root権限が必要である。
image.png

root権限が必要な理由?
TCPプロトコルのヘッダーの制御ビットの設定が必要なため、root権限じゃないとSYNスキャンは実行できない。
ログが残らない理由?
対象からSYN/ACKの応答を受信したら、応答としてACKではなく、RSTに設定したパケットを送信する。
RSTのパケットのため、通信が強制に終了されてしまい、通信設定が最後まで(セッションを結ぶ)行わなかったため、システムにログが残らない可能性が高い。

##FIN/NULL/Xmas Scan
三つのスキャンはFlagをFINに設定するTCP FIN Scan, 何も設定しないNULL Scan, FIN, PSH, HUGを同時に設定するXmas Scanがある。
それぞれ正常な通信ではないため、ログが残らない、対象がUNIX/Linux環境のみ使える、また、Open/Filter/エラーの結果が不明である特徴を持っている。
###FIN Scan
image.png
###NULL Scan
image.png
###Xmas Scan
image.png

#socketモジュールを利用してPythonでScanningツールを作ってみよう
socketモジュールをインポート後、connect()関数を利用し、IPとPort番号を指定したら、TCP通信を行う。send(), recv()関数を利用してデータの送信、受信が可能である。

port_scanning.py
import socket
s = socket.socket()
s.connect(('IPアドレス', ポート番号))
s.close()
「結果」port_scanning.py
#portがオープンされている場合
>> 
#portがオープンされていない場合
Traceback (most recent call last):
  File "C:/~", line 3, in <module>
    s.connect(('127.0.0.1', 23))
ConnectionRefusedError: [WinError 10061] 対象のコンピューターによって拒否されたため接続できませんでした

エラーを解決するために、簡単な方法で「try」と「except」文を利用して成功と失敗に対してそれぞれ区別する。

port_scanning.py
import socket
try:
s = socket.socket()
s.connect(('IPアドレス', ポート番号))
    print('success')
    s.close()
except:
    print('fail')
「結果」port_scanning.py
#portがオープンされている場合
>> success
#portがオープンされていない場合
>> fail

roop文を利用して範囲内のポート番号を自動で確認するように作る。

port_scanning.py
import socket
for port in range(1,101):
    try:
        s = socket.socket()
        s.connect(('IPアドレス', port))
        print('オープンされているポート:%d' % port)
        s.close()
        
    except: pass
「結果」port_scanning.py
>> オープンされているポート:22
>> オープンされているポート:80

1から100までのポートを確認するのは、時間がかかるので、Pythonのリストデータ型を利用して、主に使用されているポートのみスキャンしてみよう。

良く使用されるポート
20, 21(FTP) / 22(SSH) / 23(Telnet) / 25(SMTP) / 53(DNS) / 80(HTTP) / 110(POP3) / 123(NTP) / 443(HTTPS) / 1433(MSSQL) / 3306(MYSQL) / 1521(ORACLE) / 8080(ORACLE, TOMCAT) / 3389(RDP)

port_scanning.py
import socket
ports = [20, 21, 22, 23, 25, 53, 80, 110, 123, 443, 1433, 3306, 1521, 8080, 3389]
for port in ports:
    try:
        s = socket.socket()
        s.connect(('IPアドレス', port))
        print('オープンされているポート:%d' % port)
        s.close()
        
    except: pass
「結果」port_scanning.py
>> オープンされているポート:80
>> オープンされているポート:443
>> オープンされているポート:3306
>> オープンされているポート:8080

input()関数を利用して、ホストアドレスを入力し、ポートスキャニングを実施するコードを作ってみよう。

port_scanning.py
import socket
ports = [20, 21, 22, 23, 25, 53, 80, 110, 123, 443, 1433, 3306, 1521, 8080, 3389]
host = input('IPアドレス:')
for port in ports:
    try:
        s = socket.socket()
        s.connect((host, port))
        print('オープンされているポート:%d' % port)
        s.close()
        
    except: pass
「結果」port_scanning.py
>> IPアドレス127.0.0.1
>> オープンされているポート:80
>> オープンされているポート:443
>> オープンされているポート:3306
>> オープンされているポート:8080

#まとめ
今回はPythonのsokectライブラリを利用して簡単なポートスキャニングツールを作ってみたが、これを実務的に使うためには色々修正が必要である。
但し、ポートスキャンの原理、またPythonで基本的なポートスキャンのツールが作れるので、担当者及び管理者はこの投稿を参考して、より安全なネットワーク環境の構築に役に立てればと思っている。

#記事まとめ

2020年02月14日 - :sunny:[Python] Pythonとセキュリティ - ①Pythonとは

9
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?