تقریبا یکسال پیش دانشگاه پیام نور به علت شیوع ویروس کرونا سامانهای را طراحی کرد با نام سامانه LMS. هدف این سامانه ایجاد بستری جهت ایجاد کلاسهای مجازی، همچنین محیطی برای گفت و گوی دانشجوها و اساتید با یک دیگر است. نکته مهمتر اطلاعاتی همچون شماره تماس و تمامی اطلاعات مربوط واحد های گذرانده شده دانشجویان در این سامانه قابل دسترس می باشد. این اطلاعات از اهمیت بالایی برخوردار هستند چراکه مستقیم با حریم شخصی دانشجویان در ارتباط است. توی این پست آسیبپذیری که منجر به دسترسی به اطلاعات دانشجویان متعددی میشد رو بررسی میکنیم.
شرح آسیب پذیری:
با بررسی های بعمل آمده مشخص گردید که نام کاربری افراد شماره دانشجویی آنها و رمزعبور آنها شماره دانشجویی به علاوه دو رقم آخر کد ملی میباشد. خب شماره دانشجویی به صورت الگوریتمی میباشد که به راحتی قابل دستیابی می باشد. از طرف دیگر رمزعبور کاربران نیز کد دانشجویی به علاوه دو رقم آخر کد ملی می باشد که در بدترین حالت می شود از ۰۰ تا ۹۹. طراح سامانه برای اینکه حسابهای کاربری از حمله Brute force در امان باشند از کپچا و مکانیزم قفل حساب کاربری استفاده کرده است. مکانیزم قفل حساب کاربری این سامانه به این صورت است که در صورتی که کاربر رمزعبور خود را بیشتر از ۵ مرتبه اشتباه وارد کند حساب کاربری اش ۵ دقیقه قفل میشود.
خب مکانیزم قفل حساب کاربری زیاد اهمیتی ندارد. همچنین طی بررسی سامانه مشخص گردید که لاگهای سامانه اصلا بررسی نمیشوند و به راحتی امکان حملات مختلف وجود دارد. با این تفاصیل تنها کاری که نفوذگر باید انجام می داد دور زدن مکانیزم کپچا و استفاده از حمله ی Password Spraying میباشد تا به تمامی اطلاعات دانشجویان دسترسی پیدا کند.
حمله Password Spraying حمله ای است که در آن یک پسورد انتخاب میشود و تمامی نامهای کاربری با این پسورد تست می شود. در این سامانه نیاز بود که کمی حمله را تغییر دهیم. برای مثال ما می خواهیم ابتدا تمامی کاربران را با کد ملی ای که آخرش 00 است تست کنیم. برای اینکار نام کاربری فرد اگر 970161111 باشد پسورد 97016111100 برای این اکانت تست می شود. همچنین اکانت بعدی که اگر به صورت 970162222 باشد پسورد 97016222200 می شود. اینکار برای تمامی کاربران باید انجام شود و سپس 00 را به 01 و الی آخر افزایش می دهیم تا در نهایت نتیجه حاصل شود.
خب همه اینا در صورتی جواب می دهد که کپچا سامانه قابل دور زدن باشه. عکس کپچا به شکل زیر بود:
برای دور زدن مکانیزم کپچا اول از نرم افزار Tesseract و پایتون استفاده کردم تا با پردازش تصویر بتوانم کپچا را بخوانم و آن را دور بزنم. اما نتایج مطلوبی حاصل نشد و تقریبا توانستم تا ۲۰ درصد موارد را به درستی تشخیص بدهم. این عملکرد جالبی برای استخراج اطلاعات بهصورت انبوه نیست. برای همین راه دیگه ای پیدا کردم. سامانه قابلیتی داشت که کپچا به صورت صوتی خوانده شود. این را می شود از آیکون صدا زیر کپچا فهمید. صدا کمی نویز داشت اما از نظر من با پایتون می شد نویز گرفت و کپچا را تشخیص داد.
حالا می ریم سراغ مراحل نوشتن اسکریپت پایتونی برای Brute Force رمزعبور یک کاربر.
برای اینکار به چندتا کتابخانه نیاز داریم:
- BeautifulSoup : به جهت اینکه بتوانم HTML پردازش کنم و tag های مورد نظرم استخراج کنم تا درنهایت فایل wav کپچا را دانلود کنم.
- SpeechRecognition: از این کتابخانه هم برای پردازش صدا استفاده کردم تا هم نویز صدا را کم کنم و هم صدا را تبدیل به متن کنم.
- Requests: این هم که مشخصه، برای برقرار ارتباط توسط پروتکل HTTP.
اول از همه فایل صوتی چندتا از کپچا ها را دانلود کردم تا به عنوان نمونه رو آنها کار کنم. توی مرحله بعد رفتم سراغ استفاده از کتابخانه SpeechRecognition که یکی از بهترین ها توی این حوضه است. این کتابخانه متدهای مختلفی برای تبدیل صدا به متن داره که اکثرا آنها نیاز به API Key دارند. اگر شما هم مثل من حوصله گرفتن API Key از Google و Microsoft نداشتید میشه از متد زیر استفاده کرد:
import speech_recognition as sr
def readCaptcha():
r = sr.Recognizer()
captchaText =""
with sr.AudioFile(filename) as source:
audioData = r.record(source)
captchaText = r.recognize_google(audioData)
captchaText = captchaText.replace(" ","")
captchaText = captchaText.replace("to","2")
captchaText = captchaText.replace("euro","0")
captchaText = captchaText.replace("fine","5")
captchaText = captchaText.replace("for","4")
captchaText = captchaText.replace("is","8")
captchaText = captchaText.replace("two","2")
captchaText = captchaText.replace("three","3")
return captchaText
نکته: تمامی جاهایی که .replace استفاده کردم برای این هست که اشتباهات تشخیصی تا حد ممکن کم بشود. با این روش به دقت 90 درصد رسیدم. البته اگر از API های Google و یا Microsoft استفاده کنید، این اشتباهات خیلی کم تر می شود.
مرحله آخر کار هم به کد کامل نوشتم. تنها نکته ای که داره اینه که تمامی درخواست ها را به Burp ارسال می کردم تا لاگ آنها را داشته باشم. پیشنهاد می کنم حتما اینکار کنید چرا که در امر خطایابی خیلی کمک می کند.
کلام آخر:
این آسیبپذیری اصلا پیچیده نبود فقط نیاز به دقت داشت. گاهی وقت ها فقط باید انگیزه کافی داشت و خلاقیت. من برای این مورد انگیزه قوی داشتم.
باحال بود :)) انگیزهی بوده واقعا
انگیزه ای جز افزایش سطح امنیت پورتال دانشگاه نبوده. مدیونید فکر دیگه ای کنید. 🙂
مشابه همچین تجربه ای داشتم (نه روی پیام نور) که یوزر پس ورود به پرتال اساتید درمیومد 🙂
— ادمین اگر دوست داشتی بگو دربارش بنویسم
ادمین که نمی دونم. ولی من خوشحال می شم بدونم چیکار کردی.
سلام
در خصوص لاگ ها که فرمودید: “همچنین طی بررسی سامانه مشخص گردید که لاگهای سامانه اصلا بررسی نمیشوند” با چه نرمافزار هایی می تونیم برسی کنیم? هم برای ویندوز سرور و هم برای گنو/لینوکس.
با تشکر
سلام.
لاگ های سامانه ها توسط خود برنامه نویس ایجاد می شوند. برای مثال زمانی که من حمله ی Brute force میکنم، برنامه نویس باید IP و تلاش های من برای ورود به صورت کامل لاگ کنه. با انجام اینجور کارها برنامه قابل Forensic می شود. یعنی کارشناس های جرایم رایانه ای عدله و شواهدی برای تشخیص جرم می توانند داشته باشند.(منظورم اینه که با بررسی لاگ ها می توانند تشخیص بدند چه اکانت هایی مورد نفوذ قرار گفته و مبدا حملات از کجا بوده). حالا نکته دیگه ای که وجود داره پیشنهاد می شه همیشه لاگ ها در فرمت ها استاندارد باشند تا بشه توسط سیستم های Log Centralization اونها را مجتمع کرد. این نرم افزارها مثل: Elastic Stack (اینو حتما پیشنهاد می کنم یک نگاهی بهش بندازید. خیلی عالیه)، GrayLog, NXLog. البته همه ی اینهایی که نام بردم رایگان و متن باز هستند و البته برای لینوکس. برای ویندوز اطلاعی ندارم متاسفانه. اگر بچه ها کسی می دونست اینجا بگه خیلی خوب میشه.
برای اطلاعات بیشتر این لینک ها را یک نگاه بنداز:
OWASP TOP 10 Insufficient Logging & Monitoring
How to prevent Insufficient Logging and Monitoring
با تشکر از لطف و محبت شما
عالی بود ایول خیلی خوشم اومد دمت گرم
من از شما بینهایت سپاسگذارم . واقعا ممنون که اطلاعات خوب و خفنتون رو در اختیار ما میزارید .
به امید اینکه بازم ازتون بخونم .
آفرین!
البته حوضه درست نیست و حوزه درسته.