شنود (Sniffing) و جعل (Spoofing) در شبکه با پایتون و Scapy

0 172
۵/۵ - (۶ امتیاز)

فهرست

در این مقاله قصد داریم در خصوص دو مورد از مهم ترین اعمال در شبکه یعنی شنود (استراق سمع) یا Sniff و جعل یا Spoof صحبت کنیم و نمونه ای عملی از آن ها را با استفاده از Scapy در زبان پایتون پیاده سازی کنیم. مقاله شنود (Sniffing) و جعل (Spoofing) در شبکه با پایتون و Scapy می تواند پیش نیازی برای مقاله ها و آموزش های بعدی باشد.

شنود بسته یا Packet Sniffing

در مقالات قبلی در قالب های مختلف در مورد شنود صحبت شده است. برای مثال در این مقاله عملیات شنود را درک می کنیم. به طور کلی فرآیند ضبط بسته های شبکه را شنود می نامند. این عمل در ذات خود یک عمل غیرفعال یا Passive است. عملیات شنود صرفا به دلیل اهداف بدخواهانه صورت نمی گیرد بلکه این عمل می تواند کمک زیادی به فعالیت های مختلف در شبکه بکند. برای مثال مدیران شبکه برای درک ویژگی های شبکه و عیب یابی از شنود استفاده می کنند. از طرف دیگر یک مهاجم می تواند با استفاده از عمل شنود اقداماتی از جمله شناسایی و جمع آوری اطلاعات و همچنین اکسپلویت کردن را انجام دهد. به طور کلی به ابزاری که عمل شنود یا Sniff را در شبکه انجام می دهد Packet Sniffer گفته می شود. برای شنود باید مواردی رعایت شود که در این مقاله می توانید با اساسی ترین آن ها آشنا شوید.

جعل بسته یا Packet Spoofing

واضح است که جعل بسته به معنی ایجاد یک بسته شمال سرآیندها (هدر / Header) و داده هایی است که آن بسته به طور طبیعی تولید نشده است. برای مثال فرض کنید قصد داریم یک بسته IP با آدرس IP مبدا ۱۹۲.۱۶۸.۱.۲ به مقصدی ارسال کنیم. حال می خواهیم این بسته رو طوری تولید کنیم که بجای آدرس IP مبدا در آن مقدار ۱۹۲.۱۶۸.۱.۳ قرار گیرد. طبیعی است که عمل جعل یک عمل فعال یا Active است.

شنود (Sniffing) و جعل (Spoofing) در شبکه با پایتون و Scapy

عمل شنود و جعل بسته در شبکه به روش های مختلفی قابل پیاده سازی است. برای مثال در C و ++C به طور گسترده با API های جذابی برای این اعمال روبرو هستیم که مزیت استفاده از آن ها کارایی و سرعت بسیار بالاست. اما در بسیاری از موارد کارایی اهمیت بالایی ندارد و سادگی و سرعت تولید اسکریپت برای توسعه دهنده جذاب می شود. در این مورد می توان از پایتون و ماژول (فریم ورک) Scapy استفاده کرد. بنابراین در این بخش مقاله شنود (Sniffing) و جعل (Spoofing) در شبکه با پایتون و Scapy عملیات شنود و جعل بسته در شبکه را با استفاده از پایتون و Scapy ارائه می کنیم.

نصب Scapy

یکی از جذاب ترین کتابخانه های موجود در پایتون برای کار با شبکه Scapy است. این کتابخانه یا ماژول که به عنوان یک فریم ورک معرفی می شود دارای قابلیت های بی نظیری برای ساخت کار با بسته در شبکه به صورت بسیار ساده است.
از ابتدا Scapy با پایتون نصب نیست (اگر پایتون را هم ندارید با استفاده از این مقاله می توانید آن را در ویندوز نصب کنید) و نیاز است که آن را نصب کنیم. روش های مختلفی برای نصب ماژول در پایتون وجود دارد که ساده ترین آن ها استفاده از pip است. اگر pip را ندارید با یکی از دو روش زیر می توانید آن را نصب کنید:

$ sudo apt-get install python3-pip        روش اول//

$ curl -O https://bootstrap.pypa.io/get-pip.py        روش دوم//
$ sudo python3 get-pip.py

پس از نصب pip می توان Scapy را نصب کرد:

$ sudo pip3 install scapy

تا اینجا Scapy را نصب کردیم. با وارد کردن scapy در ترمینال می توانید وارد محیط تعاملی آن شوید.

شنود بسته یا Packet Sniffing با Scapy

در این قسمت اسکریپتی توسعه می دهیم که با اجرای آن بتوان بسته های شبکه را روی یک واسط یا Interface شنود کرد. مراحل توسعه را خط به خط توضیح می دهیم. توجه کنید کلیه این اعمال را می توان به صورت Interactive انجام داد اما به دلیل استفاده مجدد از اسکریپت و جلوگیری از تکرار ترجیح می دهیم آن را در قالب یک اسکریپت ارائه دهیم.
تابعی برای چاپ اطلاعاتی که از بسته نیاز داریم تعریف می کنیم:

from scapy.all import *


def print_packet(pkt)

این تابع یک ورودی که همان بسته باشد دریافت می کند و اطلاعات موجود در آن را چاپ می کند. لازم به ذکر است که در یک بسته سرآیندهای زیادی وجود دارد که ما در اینجا برای سادگی تعدادی از آن ها که معروف تر و مهم تر هستند را در نظر میگیریم. نمایش بقیه سرآیندها نیز به همین صورت است.
در بدنه تابع ابتدا آدرس IP مبدا بسته را استخراج و چاپ می کنیم:

print("Source IP: " pkt[IP].src)

عبارت pkt[IP].src مقدار مبدا بسته۷ یعنی ارسال کننده بسته یا Source آن را استخراج می کند. همین عمل را می توان در مورد مقصد انجام داد فقط کافیست به جای src از dst استفاده شود.
پس از این می توان برای مثال پروتکل را نیز استخراج کرد. برای این کار فقط کافی است بجای src یا dst در مرحله قبل، proto را جایگزین کنیم:

print("Source IP: " pkt[IP].proto)

پس از این کار کافی است به روشی تابع ایجاد شده را صدا بزنیم. تابع sniff در Scapy برای شنود طراحی شده که خروجی آن یک بسته است. این تابع آرگمان های مختلفی دریافت می کند که در ساده ترین حالت می توان آن را بدون آرگمان صدا زد. در این صورت هیچ واکنشی نشان نمی دهد و فقط شنود می کند اما می توان به صورت دستی به اطلاعات دریافتی آن دسترسی پیدا کرد.
چون ما تابعی برای استخراج اطلاعات مورد نیاز خود نوشتیم می توانیم این تابع را به صورت یک تایع Callback یا Callback Function به تابع sniff ارائه کرد که هر بار بسته ای دریافت شد تابع با آن بسته اجرا شود:

pkt = sniff(prn=print_packet)

اسکریپت نهایی به صورت زیر است:

from scapy.all import *


def print_packet(pkt):
    print("Source IP: ", pkt[IP].src)
    print("Destination IP: ", pkt[IP].dst)
    print("Protocol: ", pkt[IP].proto)
    print("\n")

pkt = sniff(prn=print_packet)

حال فرض کنید فقط به دنبال بسته های ICMP هستیم. برای این کار می توان با استفاده از آرگمان filter در تابع sniff تنها بسته هایی که مربوط به ICMP هستند را مورد توجه قرار داد:

from scapy.all import *


def print_packet(pkt):
    print("Source IP: ", pkt[IP].src)
    print("Destination IP: ", pkt[IP].dst)
    print("Protocol: ", pkt[IP].proto)
    print("\n")

pkt = sniff(filter="icmp", prn=print_packet)

لازم به ذکر است این فیلتر از دستورزبان Berkeley Packet Filter (BFP) استفاده می کند که این دستورزبان در tcpdump و pcap هم مورد استفاده قرار می گیرد.

جعل بسته یا Packet Spoofing با Scapy

حال نوبت به جعل بسته می رسد. طبیعی است برای جعل یک بسته باید حداقل سرآیندهایی که برای یک بسته معتبر مورد نیاز است مقداردهی شوند (خیلی از این سرآیندها توسط خود Scapy مقداردهی می شوند). در این بخش قصد داریم یک بسته ICMP جعل کنیم.
برای جعل بسته ICMP ابتدا مبدا و مقصد بسته را مشخص می کنیم:

ip = IP(src="192.198.1.3", dst="192.168.1.4")

حال می توان بسته را با استفاده از سازنده کلاس ICMP در Scapy ایجاد کرد:

icmp = ICMP()

در نهایت بسته به ترتیب پایین به بالا در پشته پروتکل TCP/IP یا OSI با دستورزبان زیر تولید می شود:

pkt = ip/icmp

همانطور که گفته شد بسته های مربوط به لایه های پایین تر در پشته پروتکل ابتدا و بسته های مربوط به لایه های بالاتر به ترتیب پس از آن ها قرار می گیرند. مثلا چون لایه IP پایین تر از لایه ای است که ICMP ساخته می شود، ابتدا IP تولید شده را می آوریم که در متغیر ip ذخیره شده است. با استفاده از تابع show می توان اطلاعات بسته تولید شده را مشاهده و با استفاده از تابع send می توان بسته را ارسال کرد:

pkt.show()
send(pkt)

اسکریپت نهایی به صورت زیر است:

from scapy.all import *


ip = IP(src="192.168.1.3", dst="192.168.1.4")
icmp = ICMP()
pkt = ip/icmp
pkt.show()
send(pkt)

توجه کنید ما هیچ سرآیند یا هدری برای ICMP ایجاد نکردیم. بنابراین این موارد توسط Scapy به صورت پیش فرض مقداردهی می شوند. توجه شود اپراتور / توسط کلاس IP اصطلاحا Override می شود و بنابراین عمل تقسیم انجام نمی دهد و عمل پشته کردن را انجام می دهد.

جعل بسته UDP با Scapy

در این بخش قصد داریم یک بسته UDP جعل یا تولید کنیم. مشخص است که برای تولید یک بسته UDP علاوه بر آدرس IP نیاز به پورت مبدا و پورت مقصد داریم که در لایه ای که UDP کار می کند مشخص می شود:

udp = UDP(sport=8080, dport=9090)

همچنین می توان داده ای ایجاد کرد که در بسته ارسال شود (برای مثال داده می تواند پیام در یک چت باشد):

data = "Hello!\n"

خطوط کد واضح است و اسکریپت نهایی به صورت زیر است:

from scapy.all import *


ip = IP(src="192.168.1.3", dst="192.168.1.4")
udp = UDP(sport=8080, dport=9090)
data = "Hello!\n"
pkt = ip/udp/data
pkt.show()
send(pkt)

اول شنود بعد جعل!

ترکیب عملیات شنود و جعل می تواند ما را در موارد مختلف از جمله اجرای حملاتی چون مرد میانی یا MitM یاری کند. اسکریپت شنود و جعل به صورت زیر است:

from scapy.all import *


def spoof_packet(pkt):
    if ICMP in pkt and pkt[ICMP].ty[e == 8:
        print("Original Packet...")
        print("Source IP: ", pkt[IP].src)
        print("Destination IP: ", pkt[IP].dst)

        ip = IP(src=pkt[IP].dst, dst=pkt[IP].src, ihl=pkt[IP].ihl)
        icmp = ICMP(type=0, id=pkt[ICMP].id, seq=pkt[ICMP].seq)
        data = pkt[Raw].load
        spoofed_pkt = ip/icmp/data


        print("Spoofed Packet...")
        print("Source IP: ", spoofed_pkt[IP].src)
        print("Destination IP: ", spoofed_pkt[IP].dst)
        send(spoofed_pkt)

pkt = sniff(filter="icmp and src host 192.168.1.3", prn=spoof_packet)

بسیاری از خطوط با توجه به توضیحات قبلی واضح و تکراری هستند اما مواردی وجود دارد که توضیح آن ها خالی از لطف نیست:

  •  در بسته ICMP خاصیت type نوع بسته را نشان می دهد که نوع ۸ یعنی یک echo request
  • در بسته IP خاصیت ihl مقدار طول سرآیند IP (که عموما ۴ بایت است) را در برمیگیرد
  • در بسته ICMP خاصیت seq مقدار شماره دنباله یا Sequence Number را در برمیگیرد

ارسال و دریافت بسته ها با Scapy

واقعیت این است که Scapy تنها برای شنود و جعل مورد استفاده قرار نمی گیرد. Scapy می تواند در ارتباطات عادی شبکه ای مورد استفاده قرار گیرد. ما در این مقاله قصد آموزش Scapy را نداریم بلکه با تمرکز روی شنود و جعل سعی کردیم مرور مختصری بر Scapy نیز داشته باشیم اما سعی کرده ایم در لیست زیر ‌API های مهم آن را معرفی کنیم:

  • تابع ()send: ارسال بسته در لایه ۳
  • تابع ()sendp: ارسال بسته در لایه ۲
  • تابع ()sr: ارسال بسته در لایه ۳ و دریافت پاسخ
  • تابع ()srp: ارسال بسته در لایه ۲ و دریافت پاسخ
  • تابع ()sr1: ارسال بسته در لایه ۳ و انتظار برای اولین پاسخ
  • تابع ()sr1p: ارسال بسته در لایه ۲ و انتظار برای اولین پاسخ
  • تابع ()srloop: ارسال یک بسته در لایه ۳ و چاپ متداوم پاسخ
  • تابع ()srploop: ارسال یک بسته در لایه ۲ و چاپ متداوم پاسخ

برای مثال در اسکریپت زیر با استفاده از تابع ()sr1 یک بسته ICMP از نوع echo request یعنی ۸ ارسال می کنیم و منتظر پاسخ می شویم. هنگامی که پاسخ دریافت شد می توان آن را چاپ کرد:

from scapy.all import *


ip = IP(dst="192.168.1.4")
icmp= ICMP()
pkt = ip/icmp
reply = sr1(pkt)

print("Source IP: ", reply[IP].src)
print("Destination IP: ", reply[IP].dst)

سخن پایانی

در این مقاله در مورد شنود و جعل بسته ها در شبکه صحبت کردیم و سعی کردیم در عمل نمونه ای از آن ها را نشان دهیم. در مقالات بعدی آموزش هایی مثل ایجاد یک پویشگر پورت یا Port Scanner و عملیات شناسایی یا Reconnaissance در Scapy را مدنظر قرار می دهیم.

درباره ما

ترجنس | thregence.ir
آکادمی ترجنس | edu.thregence.ir
دوره‌های آکادمی ترجنس | courses.thregence.ir
اینستاگرام | instagram.com/thregence
تلگرام | t.me/thregence
یوتوب | https://bit.ly/30mGowo
آپارات | aparat.com/thregence

ارسال یک پاسخ