۱۳۹۰ اردیبهشت ۲, جمعه

ترفند 10 - چگونه وسط یک اتصال TCP بنشینیم و محتویاتش را ببینیم؟

تعریف مساله

گاهی اوقات دلمان می‌خواهد ببینیم برنامه‌ها با همدیگر چه صحبتی می‌کنند و چه داده‌هایی بین آنها رد و بدل می‌شود. مثلا من امروز مشغول برنامه‌نویسی بودم و متوجه خطایی در برنامه شدم. می‌خواستم ببینم چه اطلاعاتی بین برنامه من و سرور در حال رد و بدل شدن است تا شاید بتوانم خطا را برطرف کنم. یا ممکن است شما بخواهید اطلاعاتی که بین مرورگر شما و یک سرور رد و بدل می‌شود را ببینید و ...
این مساله زیاد پیش می‌آید؛ و راه‌حل‌های متنوعی هم دارد. مثلا می‌توان با ابزاری مثل WireShark یا WinDump کل بسته‌های اطلاعاتی رد و بدل شده روی شبکه را دید، مربوط به هر برنامه‌ای که می‌خواهد باشد. یا مثلا برنامه‌هایی (مثل مرورگرها) که قابلیت تنظیم پروکسی دارند را می‌توان تنظیم کرد که از یک برنامه پروکسی خاص استفاده کنند که اطلاعات را ذخیره می‌کند و ... که البته این دو راه برای مساله من جوابگو نبودند. چرا؟ چونکه ...
اولا برنامه‌ای که من با آن سر و کار داشتم قادر به استفاده از پروکسی نبود. بنابراین راه حل دوم از دور خارج می‌شود. (که مساله مهمی هم نیست؛ چون راه حلی که خواهم گفت تفاوتی با این راه حل ندارد، فقط عمومی‌تر است)
اما کجا نمی‌توان از WireShark یا WinDump استفاده کرد؟
وقتی - مثل مساله جاری من - هر دو برنامه روی کامپیوتر خودتان اجرا می‌شوند و از آدرس loopback یعنی 127.0.0.1 برای اتصال استفاده می‌کنند این ترافیک برای WinShark و WinDump و مشابه آن قابل رویت نیست. ظاهرا چاره‌ای هم ندارد، مگر اینکه یکسری حرکات آکروباتیک پیاده کنید تا جواب بگیرید ... (اینجا را بخوانید)

... اما راه حل

من احتیاج به یک راه حل سریع، آماده و بدون نیاز به حرکات آکروباتیک داشتم. راه حلی که توضیح می‌دهم می‌تواند روی اتصالات TCP به کار گرفته شود.
خوشبختانه برنامه‌ی ncat روی کامپیوترم موجود بود. (این برنامه همراه با نرم‌افزار ‌nmap نصب می‌شود) برنامه ncat کلا ابزاریست برای «بازی کردن» با اتصالات شبکه و وصل کردن آن‌ها به برنامه‌های مختلف به شیوه‌های مختلف!
فرض کنید یک سرور داریم که روی پورت 8888 منتظر اتصال کلاینت‌ها است. دستور زیر، به کمک ncat یک سرور مجازی روی پورت 9999 راه می‌اندازد، و به محض اینکه اتصالی با آن برقرار شد، با پورت 8888 روی کامپیوتر محلی (127.0.0.1) تماس می‌گیرد و اطلاعات را دست به دست می‌کند. یعنی هر داده‌ای که برای ncat روی پورت 9999 ارسال شود عینا برای سرور روی پورت 8888 ارسال می‌شود و بالعکس.
علاوه بر این به کمک سوییچ x، اطلاعات رد و بدل شده داخل یک فایل (با نام dump) نوشته می‌شود.
> ncat -l 9999 -x dump -e "ncat 127.0.0.1 8888"
شرح مختصر:
  • -l 9999 باعث می‌شود ncat روی پورت 9999 منتظر دریافت اتصال شود.
  • -x dump اطلاعات را به صورت hex درون یک فایل ذخیره می‌کند.
    نکته: اگر می‌خواهید اطلاعات روی صفحه نمایش نشان داده شوند نام فایل را con بزنید!
    نکته: اگر می‌خواهید اطلاعات به صورت خام ذخیره شوند به جای سوییچ x از سوییچ o استفاده کنید.
  • -e "..." باعث می‌شود ncat به محض برقراری تماس، دستور داخل گیومه را اجرا کند و ورودی/خروجی آن را روی شبکه بفرستد. در اینجا یکبار دیگر ncat جهت اتصال با سرور فراخوانی می‌شود.
  • متاسفانه در اطلاعاتی که بدین شیوه ذخیره می‌شوند مشخص نیست هر بسته اطلاعاتی از سمت سرور به کلاینت ارسال شده یا بالعکس. که نشان می‌دهد اگر بتوانید از WireShark استفاده کنید، جواب بسیار بهتری می‌گیرید ...
  • دستور بالا عینا روی لینوکس هم قابل اجرا است، هر چند محدودیت ذکر شده برای WireShark، روی لینوکس وجود ندارد.