وبلاگ فربد | Farbod Blog

توی این وبلاگ راجع به پروژه هام صحبت می کنم

ساخت پورت اسکنر با پایتون

  • ۱۰۱۴

سلام دوستان :)

توی این پست میخوایم با هم نحوه ساخت یک اسکریپت پورت اسکنر با پایتون رو ببینیم.

همینطور که میدونید اسکن کردن پورت ها توی مباحث تست نفوذ و امنیت میتونه خیلی کاربرد داشته باشه و ما میتونیم با استفاده از پورت های باز، بسته به نوع سیستم و سیستم عامل و... بیایم و این پورت ها رو اکسپلویت کنیم.

خب توی این اسکریپت قراره به این صورت عمل کنیم:

1- اول لیست پورت هایی که میخوایم اسکن کنیم رو مشخص میکنیم

2- با استفاده از کتابخونه socket دونه دونه پورت ها رو امتحان میکنیم و پورت هایی که باز بودن رو مشخص میکنیم

 

اول میریم سراغ نوشتن اسکریپت ساده.

 

برای نوشتن این اسکریپت من از ماژول colorama برای رنگی چاپ کردن متن ها استفاده کردم .پس کار رو با نصب ماژول colorama شروع می کنیم.

برای نصب این ماژول توی ویندوز وارد cmd بشین و دستور زیر رو وارد کنین:

pip3 install colorama

برای نصب این ماژول توی لینوکس وارد terminal بشین و دستور زیر رو وارد کنین:

sudo pip3 install colorama

 

خب حالا میتونیم بریم سراغ کد؛

سورس پورت اسکنر ساده:

import socket # for connecting
from colorama import init, Fore

# some colors
init()
GREEN = Fore.GREEN
RESET = Fore.RESET
GRAY = Fore.LIGHTBLACK_EX

def is_port_open(host, port):
    """
    determine whether `host` has the `port` open
    """
    # creates a new socket
    s = socket.socket()
    try:
        # tries to connect to host using that port
        s.connect((host, port))
        # make timeout if you want it a little faster ( less accuracy )
        s.settimeout(0.2)
    except:
        # cannot connect, port is closed
        # return false
        return False
    else:
        # the connection was established, port is open!
        return True

# get the host from the user
host = input("Enter the host:")
# iterate over ports, from 1 to 1024
for port in range(1, 1025):
    if is_port_open(host, port):
        print(f"{GREEN}[+] {host}:{port} is open      {RESET}")
    else:
        print(f"{GRAY}[!] {host}:{port} is closed    {RESET}", end="\r")

اول ماژول های مورد نیاز رو import کردیم. بعد یک سری رنگ با استفاده از ماژول colorama تعریف کردیم. بعدش تابع is_port_open رو تعریف کردیم که دو تا ورودی host و port رو میگیره. خب داخل خط اول تابع، شئ سوکتمون رو درست کردیم. حالا داخل try گفتیم که به اون هاست و پورتی که به تابع داده بودیم وصل بشه. توی except (یعنی اگر کد داخل try اشتباه بود و به معنی این هست که اون پورت مشخص باز نبوده) گفتیم که مقدار False رو برگردونه و داخل else (یعنی اگر پورت باز بود و برنامه با موفقیت به هاست و پورت مد نظر متصل شد) گفتیم که True رو برگردونه. حالا گفتیم که آدرس هاست رو از کاربر دریافت کنه و داخل یک حلقه for از پورت 1 تا 1024 رو با استفاده از تابع is_port_open که قبلا تعریف کرده بودیم اسکن کنه و نتیجه رو چاپ کنه.

 

خب حالا اگر اسکریپت رو اجرا کنین، میبینین که ازتون یک ورودی دریافت میکنه که شما باید آدرس هاست مورد نظر رو وارد کنین. بعد برنامه پورت ها رو اسکن میکنه و نتیجه رو به شما میگه.

حالا ایرادش چیه؟ ایراد این اسکریپت اینه که خیلی کنده ! یعنی هر پورت رو تقریبا توی یک ثانیه اسکن میکنه ! و این خیلی طول میکشه !!!

برای اینکه پیشرفته ترش کنیم میتونیم از multi threading استفاده کنیم که توی این دو تا پست:

1- پست 1

2- پست 2

راجع بهش توضیح دادم :))

خب پس بریم پیشرفته ترش کنیم؛

 

سورس پورت اسکنر پیشرفته:

import argparse
import socket # for connecting
from colorama import init, Fore

from threading import Thread, Lock
from queue import Queue

# some colors
init()
GREEN = Fore.GREEN
RESET = Fore.RESET
GRAY = Fore.LIGHTBLACK_EX

# number of threads, feel free to tune this parameter as you wish
N_THREADS = 200
# thread queue
q = Queue()
print_lock = Lock()

def port_scan(port):
    """
    Scan a port on the global variable `host`
    """
    try:
        s = socket.socket()
        s.connect((host, port))
    except:
        with print_lock:
            print(f"{GRAY}{host:15}:{port:5} is closed  {RESET}", end='\r')
    else:
        with print_lock:
            print(f"{GREEN}{host:15}:{port:5} is open    {RESET}")
    finally:
        s.close()


def scan_thread():
    global q
    while True:
        # get the port number from the queue
        worker = q.get()
        # scan that port number
        port_scan(worker)
        # tells the queue that the scanning for that port 
        # is done
        q.task_done()


def main(host, ports):
    global q
    for t in range(N_THREADS):
        # for each thread, start it
        t = Thread(target=scan_thread)
        # when we set daemon to true, that thread will end when the main thread ends
        t.daemon = True
        # start the daemon thread
        t.start()

    for worker in ports:
        # for each port, put that port into the queue
        # to start scanning
        q.put(worker)
    
    # wait the threads ( port scanners ) to finish
    q.join()


if __name__ == "__main__":
    # parse some parameters passed
    parser = argparse.ArgumentParser(description="Simple port scanner")
    parser.add_argument("host", help="Host to scan.")
    parser.add_argument("--ports", "-p", dest="port_range", default="1-65535", help="Port range to scan, default is 1-65535 (all ports)")
    args = parser.parse_args()
    host, port_range = args.host, args.port_range

    start_port, end_port = port_range.split("-")
    start_port, end_port = int(start_port), int(end_port)

    ports = [ p for p in range(start_port, end_port)]

    main(host, ports)

خب چون اکثرشو توی سورس بالا توضیح دادم الان فقط قسمت های جدید رو میگم. خب تابع scan_thread رو برای این نوشتیم چون از multi threading استفاده میکنیم یک صف درست کنه و process ها رو به ترتیب اجرا کنه یعنی ما بتونیم خروجی نهایی رو بخونیم :))) که اینکار هم با استفاده ازماژول queue انجام دادیم.

توی تابع main گفتیم که بیاد یک thread از تابع scan_thread بسازه و بعد هم مقدار daemon رو برابر True قرار بده یعنی thread وقتی تموم بشه که thread اصلی به پایان میرسه. بعد هم هر پورت رو توی صف پورت ها قرار میدیم که بعدا اسکنشون کنیم.

حالا توی if گفتیم که یک سری پارامتر برای برنامه مون تعریف کنه مثل هاست و رنج پورت ها. بعد هم پورت اول و پورت آخر رو تعریف کردیم، حالا کل پورت ها رو با استفاده از یک حلقه داخل یک لیست قرار دادیم.

در نهایت هم پورت ها رو اسکن کردیم.

 

خب اینم از سورس پیشرفته؛

برای اجرا کردن این برنامه cmd یا terminal رو باز کنید و وارد مسیر برنامه تون بشین. حالا دستور زیر رو وارد کنین:

python3 fast_port_scanner.py --ports [start_port]-[end_port] [host]

توجه کنید که باید جای fast_port_scanner.py اسم برنامه تون رو بذارین، جای [start_port] پورت اول، جای [end_port] باید پورت آخر رو بذارین و جای [host] باید هاستی که میخواین پورت هاشو اسکن کنین وارد کنین.

حالا میتونین ببینین که  سرعت اسکریپت خیلی بیشتر شده و حداقل 20 پورت در ثانیه اسکن میکنه :)). اگر کل پورت ها (1 تا 65535) رو اسکن کنین میبینین که توی چند ثانیه همرو اسکن میکنه !

 

امیدوارم براتون مفید بوده باشه D:
 


  • سلام
    خیلی دقیق و کامل بود
    ممنون از مطالب خوبتون
    پاسخ:
    سلام دوست عزیز
    ممنون از همراهی شما
    موفق باشید
  • مسعود بهادری
    سلام
    مفید بود ممنون
    آینده روشنی براتون آرزو دارم
    پاسخ:
    سلام دوست عزیز
    خوشحالم از اینکه براتون مفید بوده و ممنون از آرزو های خوبتون
    شاد و موفق باشید
  • درود برشما
    بهترینید با اختلاف
    پاسخ:
    سلام دوست عزیز
    ممنون از لطف و همراهی شما
    موفق باشید
ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی