من حافظه ضعیفی دارم و معمولا به جای اینکه روی اون حساب کنم از lastpass استفاده می کنم. چند روز پیش به دلایلی به لستپس دسترسی نداشتم و مجبور شدم از گزینه forgot password سایت diigo استفاده کنم. بعد از وارد کردن ایمیل و سابمیت، سایت اعلام کرد که فلانی، لینک تغییر پسورد رو به ایمیلت فرستادم. اینجوری بود که فکری به سرم زد برای یافتن نام کاربری اعضای سایت دیگو.
اپلیکیشن ها و افزونه هایی مثل Awesome Screenshot، Quick Note، Read Later Fast، Diigolet و کلی سرویس دیگه از محصولات diigo است.
در تصویر زیر پاسخ سایت رو در شرایط متفاوت خواهید دید.
اگر source صفحه اعلام فراموشی رو نگاه کنیم با فرم زیر رو به رو می شیم.
1 2 3 4 | <form id="forgotForm" name="forgotForm" action="/user_mana2/forgot" onsubmit="return submitForgot();" method="post" > <input type='text' id="f_username" name='username' class="inputTxt2" style="background-color:#fff;" size="24" maxlength="64" /> <input type='submit' class='firstIBtn' value='Submit' /> </form> |
می بینید که آدرس ایمیل در متغییری به اسم username به آدرس زیر ارسال می شه.
1 | https://www.diigo.com/user_mana2/forgot |
من برای شبیه سازی این کار و در نهایت انجامش به صورت تکراری، از پایتون کمک گرفتم. برای ارسال اطلاعات متغیر های POST از دستور زیر کمک گرفتم.
1 2 3 4 5 | params = {'username': uemail} data = urlencode(params).encode('utf-8') request = Request("https://www.diigo.com/user_mana2/forgot") #Send request and analyse response f = urlopen(request, data) |
در پایان نیز باید پاسخ سایت رو چک می کردم و نام کاربری رو پیدا می کردم از دل اطلاعات دریافت شده. در صورتیکه به source صفحه پاسخ نگاه کنیم، با قالب زیر رو به رو خوهیم شد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <div id="main"> <div id="mainInner"> <div id="column"> <div id="leftColumn"> <div id="pageName"><h1>Check Your Email to Reset Password</h1></div> <p class="success">Dear <strong>Hooshmandk</strong>. We've sent an email to <strong>hooshma****@gmail.com</strong>. You would receive the email in a few minutes. </p> <div class="tip"> <h2>Didn't Get the Email?</h2> <ul> <li>First, be patient, sometimes it takes a while for the email to arrive.</li> <li>Check above to ensure you entered your username or email address correctly. If it's wrong, resend again.</li> <li>Check your junk email box, the message might have been filtered as junk.</li> <li><a href="mailto:Diigo <support@diigo.com>">Contact us</a> if you can't get it to work.</li> </ul> </div> </div><!--leftColumn--> <div id='rightColumn'> </div><!--rightColumn--> <div style="clear:both"></div> </div><!--column--> </div></div><!--main--> |
با توجه به اینکه تگ strong تنها دوبار استفاده شده از اون برای جدا کردن بخشی از اطلاعات که بین تگ ها قراردارند استفاده کردم.
1 2 | e = re.compile('<strong>(.*?)</strong>') mch = e.findall(response) |
حالا یک function دارم که کار رو برای یک ایمیل انجام می ده. تقریبا دارم به آخر کد می رسم. حالا برای راحتی خودم، ایمیل هایی که می خوام چک کنم رو می ریزم توی یک فایل متنی. تنها شرطش اینه که هر خط شامل یک ایمیل باشه و اطلاعات و متن دیگه ای توش نباشه. (البته می تونم کمی روی کد کار کنم و از دل فایل خونده شده با هر شیوه نگارشی، ایمیل ها رو پیدا کنم.) ایمل ها رو یکی یکی از فایل می خونم و می دم به تابع و اطلاعات دریافتی رو در خروجی چاپ کرده و نیز به یک فایل اضافه می کنم.
برای تستش هم یه لیست ایمیل لازم دارم. کافیه دستم رو دراز کنم و از لیست ۱۵۰ میلیون ایمیل لو رفته ادوب استفاده کنم. ایمیل ها رو در لیستی به اسم maillist.txt کنار اسکریپت پایتون می ذارم. در نهایت غیر از خروجی که در ترمینال نشون داده می شه، فایل out.txt نیز کنار اسکریپت ایجاد می شه و ایمیل نام کاربری های یافته شده در اون ذخیره می شه.
آدرس پروژه در سایت github:
1 | https://github.com/hooshmand/diigoScanner |
این مورد یک ضعف امنیتی در سایت دیگو محسوب نمی شه اما یک ضعف در حفظ اطلاعات کاربریه و می تونه منجر به انتشار اطلاعاتی بشه که در نهایت به ضرر کاربر تموم بشه. در نظر بگیرید شما با آدرس ایمیلتون در این سایت با نام کاربری ثبت نام کردید که نمی خواید کسی بدونه و دوست ندارید هرکسی این نام کاربری رو به شما ربط بده.
این مورد به اطلاع سایت diigo خواهد رسید.
به روز رسانی:
در تاریخ ۲۱ ژانویه ۲۰۱۴ به پشتیبانی سایت دیگو ایمیل زدم و موضوع رو اطلاع دادم
در تاریخ ۲۶ ژانویه پشتیبانی سایت دیگو جواب داد و گفت مشکل رو حل می کنن
من اینطور مواقع از ترکیب curl و بشاسکریپت استفاده میکنم. خیلی سریعه و دردسر هم نداره.
مسلمه که روش های زیادی وجود داره و الزاما روشی که من رفتم بهترین نیست. فقط به خاطر اطلاعاتی که داشتم و علاقه به پایتون، این شکلی انجامش دادم.
خوشحال می شم اگه وقت کنی و نمونه ای از این روشی که گفتی (بش اسکریپت و curl) رو برام ایمیل کنی