בונים סורק פורטים משלכם בפייתון - ולומדים איך nmap באמת עובד¶
כולם משתמשים ב-nmap, וזה כלי מעולה, אבל רוב האנשים שמריצים אותו לא ממש מבינים מה קורה מתחת למכסה. הדרך הכי מהירה לתקן את זה היא לבנות סורק פורטים משלכם מאפס. זה לא פרויקט מסובך - אפשר לכתוב גרסה עובדת ב-30 שורות קוד - אבל הוא מלמד יותר על רשתות ופרוטוקול TCP מכל הסבר תיאורטי.
מה זה בכלל סריקת פורטים¶
כשמחשב רוצה לבדוק אם שירות מסוים פתוח על מכונה אחרת - נגיד, אם יש שרת ווב שמאזין על פורט 80 - הוא פשוט מנסה לפתוח חיבור TCP לאותו פורט. אם המכונה השנייה עונה ומאשרת את החיבור, הפורט פתוח. אם היא דוחה אותו, הפורט סגור. ואם אין תגובה בכלל, לרוב יש שם חומת אש שחוסמת.
זו בדיוק הטכניקה שנקראת TCP connect scan, וזו הדרך הכי בסיסית והכי אמינה לסרוק פורטים, כי היא פשוט משתמשת במנגנון החיבור הרגיל של TCP בלי שום טריק. nmap יודע לעשות גם טכניקות מתקדמות יותר כמו SYN scan חצי-פתוח, אבל connect scan הוא הבסיס שממנו כדאי להתחיל להבין.
הכלי הבסיסי - מודול socket¶
פייתון כולל מודול בשם socket שנותן גישה ישירה ליצירת חיבורי רשת. יצירת חיבור TCP בודד לפורט נראית בערך ככה:
import socket
def check_port(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.5)
result = sock.connect_ex((host, port))
sock.close()
return result == 0
הפונקציה connect_ex מנסה ליצור חיבור, ומחזירה 0 אם הוא הצליח - כלומר הפורט פתוח. שימו לב לפרמטר settimeout - בלעדיו, ניסיון חיבור לפורט שלא עונה בכלל יכול להיתקע לדקות ארוכות, כי המערכת מחכה לתשובה שלא תגיע.
הרחבה - סריקת טווח שלם¶
סורק בודד לפורט אחד לא ממש שימושי. השלב הבא הוא לרוץ בלולאה על טווח פורטים, בדרך כלל 1 עד 1024 לשירותים הנפוצים, ולבדוק כל אחד. זה עובד, אבל אם תריצו את זה ברצף על אלף פורטים עם timeout של חצי שנייה כל אחד, הסריקה כולה יכולה לקחת דקות ארוכות - כי כל בדיקה מחכה לקודמת שתסתיים.
למה חייבים ת'רדים¶
כאן נכנס החלק שבאמת מלמד משהו על ביצועים - ריבוי תהליכונים, threading. במקום לבדוק פורט אחד ואז לעבור לבא, פותחים כמה עשרות בדיקות במקביל. כל בדיקת פורט מחכה בעיקר לרשת, לא לעיבוד, אז זה תרחיש קלאסי שבו threading בפייתון עוזר מאוד למרות ה-GIL המפורסם, כי החסימה קורית ברשת ולא ב-CPU.
שימוש פשוט ב-ThreadPoolExecutor ממודול concurrent.futures נותן לכם את זה כמעט בחינם - מגדירים כמה עובדים במקביל, נגיד 50, ומריצים את פונקציית הבדיקה על כל הפורטים דרך המאגר. ההבדל בזמן ריצה בין גרסה טורית לגרסה מקבילית הוא דרמטי, ורואים אותו מיד.
מה זה מלמד אתכם על nmap¶
אחרי שבניתם את זה בעצמכם, כשתריצו nmap -p 1-1000 target, זה כבר לא קסם שחור. אתם יודעים שברמה הבסיסית ביותר, nmap עושה בדיוק את מה שהסורק שלכם עושה - מנסה חיבורים ומודד תגובות - רק בצורה הרבה יותר מתוחכמת, עם טכניקות סריקה שונות, זיהוי גרסאות שירות, וכתיבה מותאמת ברמת החבילות עצמן כדי להיות מהיר ופחות בולט.
זה גם נותן לכם בסיס להבין למה חלק מהסריקות "מתות" מול חומת אש שעושה drop שקט, בעוד אחרות מקבלות תשובת דחייה מיידית - ההבדל הזה נראה ממש בקוד שלכם כשמנסים לתפוס אותו עם timeout.
הערה חשובה על אתיקה¶
סורק פורטים הוא כלי לגיטימי, אבל הפעלה שלו נגד כתובת שאינה שלכם, בלי אישור, יכולה להיחשב לפעולה עוינת ואפילו להפעיל התראות אצל ספקי אינטרנט או צוותי אבטחה. תריצו את הסורק שלכם נגד המכונה הפגיעה במעבדה הביתית שלכם, או נגד פלטפורמות שנועדו לזה במפורש. לא נגד שרת אקראי באינטרנט, גם אם זה "רק בשביל לבדוק".
לסיכום¶
בניית סורק פורטים משלכם היא אחד הפרויקטים הכי משתלמים למי שרוצה להבין רשתות ופנטסט ברמה עמוקה, לא רק ברמת "להריץ פקודה". זה פרויקט קטן שאפשר לגמור בישיבה אחת, ומשאיר אחריו הבנה שנשארת.
אם אתם רוצים להמשיך מכאן לתרגול שיטתי עם כלים אמיתיים ומעבדות מלאות, קורס בודק החדירות שלי בעברית ממשיך בדיוק מהנקודה הזאת.