Wednesday, September 28, 2011

حمله جدید به پروتوکل ssl/tls

در دو هفته ای که گذشت سایت های بسیاری گزارش دادند که SSL شکسته شده !. خبر ها مربوط به دو نفر به نام های Thai Duong , Juliano Rizzoبود که در کنفرانس ekoparty برنامه و مقاله خودشون رو ارائه دادند .

خوب نقطه ضعفی که این افراد به اون اشاره کرده بودند مدتها قبل (2002) شناخته شده بود ولی تاحالا فکر میشد که قابل اکسپلویت شدن نیست ! و خوب نشون دادن که هست . ما میخوایم اینجا توضیح بدیم که چه طور این کار صورت میگیره و باید برای اون از پایه شروع کنیم و یک سری مفاهیم رو بگیم . اگر شما این مفاهیم پایه رو میدونید مستقیم به شروع مطلب برید .

میدونیم کامپیوتر از صفر و یک درست شده . هر صفر یا یک رو یک بیت میگند هر هشت بیت رو یک بایت میگند . و هر کاراکتر انگلیسی قابل تبدیل به یک هشت بیت متمایزه و میدونیم که 256 تا هشت بیتی متمایز میتونیم بسازیم .

مثلا 00001000 نمایانگر عدد 8 در مبنای دو است . میبینیم که میتونیم از صفر 00000000 تا دویست و پنجاه و پنج 11111111 رو نشون بدیم پس کلا 256 تا رقم داریم . حالا مثلا کاراکتری مثل A رو معادل 01000001 میگیریم . و B رو معادل 01000010 . به این معادل گیری ها و این بایت ها استاندارد ascii میگیم که در کامپیوتر استفاده میشه .

عملی که روی بیت ها تعریف میکنیم عمل xor است که با هم نشون داده میشه

.

واضحه که xor یک عدد با خودش صفر رو تولید میکنه و اگر دوبار با یک عدد دیگه xor بشه خودش رو تولید میکنه .



میبینیم که اگر A1 با A2 رو xor کنیم حاصل اگر C باشه . حالا اگه این C رو دوباره با A2 xor کنیم حاصل همون A1 اولیه میشه .

به این عمل میشه رمز کردن و از رمز دراوردن گفت .

نکته پایه دیگه مفهوم کوکیه . cookie ها چیزهایی هستند که از طرف سایت به شما داده میشوند تا شما رو از یک کاربر دیگه تشخیص بدند این کوکی ها تاریخ انقصای مشخص دارند و بعد از اون تاریخ دیگه قابل استفاده نیستند . زمانی که شما یک درخواست رو به سمت سرور میفرستید که مثلا این صفحه رو به من نشون بده شما کوکی رو در متن پیغام فرستاده شدتون قرار میدید و سرور هم اون رو میخونه و میتونه بین شما و کاربر دیگه ای که همون لحظه داره از سایت استفاده میکنه فرق بزاره . مثلا اگه شما تیک "remember me " یا " مرا به یاد اور " رو در هنگام ورود به سایت بزنید اون سایت از طریق کوکی هایی که شما براش میفرستید میفهمه که شما باید تو سایت باشید و نیازی به لوگین کردن دوباره ندارید .کوکی ها در http و https مورد استفاده قرار میگیره ولی کوکی های https کوکی های امن هستند و قابل خوندن به وسیله کسی نیستند و با یک اتصال امن هم به سرور فرستاده میشوند درست مثل بقیه پیغام ها .

جایگاه کوکی ها در هدر یک درخواسته .مثلا شما وقتی میخواید یک لوگو از سایت رو درخواست کنید مینویسید و مینویسید

http://www.google.com/index.html

این درخواست به صورت زیر از طرف شما فرستاده میشه

بعد سایت به شما جواب میده

بعد شما اگه دوباره بخواید یه صفحه دیگه از اون سایت رو ببینید


.و این جوری کوکی به شما کمک میکنه از بقیه افراد متمایز بشید

حالا میریم به مفاهیم پایه رمز نگاری

در رمز نگاری ما یک متن مفهوم رو تبدیل به یک متن غیر قابل مفهوم میکنیم مثلا A که معادل 01000001 است رو اگه به نحوی تبدیل به 00111111 بشه دیگه برای گیرنده قابل تشخصی نیست که چی بوده .

چه طوری این کار صورت میگیره ؟ به وسیله یک کلید مثلا در مثال xor کلید A2 بود که A1 رو تبدیل به c کرد حالا اگه گیرنده c رو دریافت کنه ولی A2 رو نداشته باشه نمیتونه A1 رو به دست بیاره !

در رمز نگاری از یک کلید استفاده میشه .انواع الگوریتم های رمز نگاری وجود داره که سایت ها و مرورگرهای مختلفی ازشون استفاده میکنند . ما اینجا قصد توضیح اضافه این الگوریتم ها رو نداریم فقثط فرض میکنیم که این الگوریتم ها پیغام p که مثلا میتونه

A1 باشه و کلید که میتونه A2 باشه رو میگرند و اونو تبدیل به پیغام C میکنند . پس تا اینجا این هارو داریم

یک پیغام به اسم m که حاوی l بایته و هر بایت رو با m[i] نشون میدیم مثلا پیغام ما اینجوری نشون داده میشه

m[1]m[2]m[3]….m[l]

حالا ما این پیغام l بایتی رو به قسمت های بزرگتری تقسیم میکنیم . مثلا قسمت های 128 بایتی . پس پیغام ما میشه n تا قسمت 128 بایتی که هر قسمت رو با p نشون میدیم و ما رمز نگاری رو روی این قسمت ها انجام میدیم .

p1,p2,p3..pn

و مرز بیت بایت m[i] و m[i+1] که دقیقا مرز یکی از بلوک های p هست رو با x نشون میدیم .

دقت کنید که m رو به قسمت های بزرگتری تقسیم کردیم مثلا اگر m ده بایت باشه و قسمت هایی که تقسیم میکنیم 8 بایتی باشه از m[1] تا m[8] در یک بلوک p قرار داره و بقیش در بلوک بعدی بنابراین x میشه مرز بین m[8] و m[9] .

یک تابع رمز نگاری داریم که برای ما مهم نیست چیه با کلید k که مهم نیست چه طور به دست میاد و این تابع بلوک p رو میگیره و اون رو تبدیل به بلوک c میکنه با همون اندازه و بعد این ها رو به سمت سایت میفرسته .

ما بر روی موضوعی که تمرکز میکنیم cbc ایه که یک مد کاریه که اغلب الگوریتم های رمز نگاری از این مود استفاده میکنند . اگر این جمله رو نفهمیدید هیچ مشکلی نداره چون ما روی انواع مد ها و .. تمرکز نمیکنیم . ما فقط به این موضوع توجه داریم که cbc چه طور عمل میکنه

همون طور که در شکل میبینید cbc یک قسمت بلوک مثلا p1 رو میگیره اون رو با چیزی به اسم Iv (initialization vector)

که یک عدد کاملا تصادفیه xor میکنه سپس با استفاده از کلید و الگوریتم رمز نگاری رمز میکنه و ارسال میکنه .

متن ارسال شده که رمز شده ciphertext و متن اولیه رمز نشده plaintext . کلید هم با حرف k مشخص شده و اندازه iv طبیعتا به اندازه بلوک p است . در نهایت این متن های رمز شده پشت سر هم به سمت سایت فرستاده میشه .

میبینیم که برای اولین بلاک iv کاملا تصادفی انتخاب میشه ولی برای بلاک های بعدی iv همان متن رمز شده قبلیه که با اون xor میشه در نهایت iv هم بدون رمز شدن به سمت سرور فرستاده میشه و طبیعیه که سرور باید کلید رو بدونه تا بتونه این متن رمز شده رو باز کنه به صورت زیر

مشکلی که این الگوریتم داره اینه که iv های بعدی از روی iv اولیه به دست میاد و قابل پیش بینیه . حالا ما به عنوان یک فرد سوم که نه فرستندست نه گیرنده میخوایم پیغام رو به دست بیاریم یا باید پیغام رو حدس بزنیم ! یا باید کلید رو داشته باشیم چون ما نه فرستنده ایم نه گیرنده نمیتونیم به کلید دست پیدا کنیم چون کلید رو ما نداریم فقط فرستنده و گیرنده دارند ! . خوب یک راهش اینه که با حمله مرد میانی کلید خودمون رو به دوطرف بدیم و هر چیزی رد و بدل شد ببینیم که خارج از این بحثه . راه اول که حدس زدن پیغام هست رو ما امتحان میکنیم .

فرض میکنیم پیغام m با مرز x که مشخص کننده بلوک p هست رو داریم . گفتیم n تا بلوک p داریم و m هم l بایته که به n تا بلوک p تقسیم شده . فرض میکنیم که هر بلوک p از b بایت تشکیل شده حالا ما فرض میکنیم که قبل از اینکه متن رمز بشه میتونیم r بایت به m اضافه کنیم که باعث میشه مرز x به سمت عقب بره و ما میتونیم فقط بایت اول m رو در بلوک اول p داشته باشیم

در این شکل میبینید که سایز هر بلاک p هشت بایته بنابراین b=8 پیغام ما نه بایتیه بنابراین l=9 و ما هفت بایت به اول این پیغام اضافه میکنیم . r=7 میبینید که مرز جابه جا میشه و به بایت اول m میرسه

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

ما یک متن رو به الیس میدیم به الیس میگیم اینو رمز کنه و برای باب بفرسته و ما دوباره ترافیک رو دریافت میکنیم و متن رمز شده رو میگیرم .

الیس هر بلوک p رو این طوری رمز میکنه و به بلوک c تبدیل میکنه


ما چه متنی رو به الیس میدیم ؟ iv رو قبلا گفتم که داریم r بایت هم به اول پیغام اضافه کردیم بنابراین بایت اول پیغام در بلوک اول وجود داره و ما این رو دریافت کردیم . دقت کنیم که ما متن پیغام رو نداریم و میخوایم اون رو حدس بزنیم . (فعلا اینجا میخوایم بایت اول رو حدس بزنیم ) حالا چه طوری پیغام رو حدس بزنیم ؟ متن دوم رو به الیس میدیم و میگیم اینو رمز کن و بفرست این متن چیه ؟

قبلا گفتیم که xor هر چیزی با خودش صفر میشه الیس پیغام رمز نشده یعنی یک بلوک p رو با iv ، xor میکنه و بعد اون رو با کلید رمز میکنه و میفرسته .

و ما این رو به الیس میدیم تا برای ما رمز کنه

بلوک اول متن رمز شده که به دست ما رسیده +iv که اون رو هم داریم + متن دلخواه r i + که همون بایت اول پیغامه که ما این رو حدس زدیم . اگر درست حدس زده باشیم این اتفاق برای الیس میفته

اگر خروجی که الیس به ما میده برابر با همون بلاک اولی باشه که بار قبلی دریافت کردیم ما متن رو درست حدس زدیم ! اگر نه یکی به i اضافه میکنیم و دوباره برای الیس میفرستیم تا رمز کنه و برای ما بفرسته و همینجوری بالا میریم تا درست حدس بزنیم !

گفتیم که i یک بایته و ما بایت اول پیغام رو حدس میزنیم و هر بایت میتونه 256 تا مقدار داشته باشه بنابراین حداکثر بعد از 256 بار تست کردن میتونیم بایت اول رو پیدا کنیم . در مورد بقیه بایت های پیغام هم با بزرگتر کردن r میتونیم مرز رو جابه جا کنیم تا بایت دوم فقط در بلوک بیفته و همینجوری پیش بریم .

این حمله که به blockwise chosen boundary plaintext attack معروفه ابتدا مرز بلوک رو مشخص میکنیم

Blockwise chosen boundary

سپس بایت اول رو حدس میزنیم به صورت غیر رمز شده پس

plaintext attack

خوب مراحل اینجوری بود . ما r بایت به اول پیغام اضافه میکنیم و به الیس میگیم رمز کن و برای باب بفرست بعد پیغام رو میگیرم حالا iv رو برمیداریم با بلوک صفرم و متن r که خودمون میدونیم چیه و یک بایت i که بایت اول پیغامه حدس زدیم دوباره برای الیس میفرستیم و میگیم رمز کن اگرنتیجه با بلوک اول پیغام رمز شده قبلی یکی بود بایت اول پیغام رو درست حدس زدیم در غیر این صورت یکی دیگه به i اضافه میکنیم و همینجوری جلو میریم. ( گفتیم که بلوک اول از xor پیغام با بلوک رمز شده صفرم به دست میاد به شکل نگاه کنید متوجه میشید و iv برای بلوک صفرم فقط استفاده میشه )

خوب این چیزی بود که سال 2006 شناخته شده بود اما این امسال چه اتفاقی افتاد ؟ امسال این دونفر تونستند این حمله رو پیاده سازی کنند و کوکی های https که به صورت رمز شده ارسال میشد رو رمز گشایی کنند . خوب طبیعیه که اگه کسی کوکی های شما رو داشته باشه میتونه به جای شما و بدون دونستن پوزر پسورد شما به سایت لوگین کنه !

چه طوری این اتفاق میفته ؟

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

فرد مزاحم از مرورگر الیس میخواد به این ادرس درخواست بفرسته

http://bob.com/AAAAAA

مرورگر الیس این درخواست رو برای سایت باب میفرسته


این CR,RF هر کدوم یک کاراکتر هستند پس هر کدوم یک بایت هستند و هر حرف هم یک بایته . ما به توضیح این نمادها کاری نداریم و شما هم فرض کنید که این طور ییغامی از کامپیوتر الیس ارسال میشه و اولین بایت REQUESTHEADERS هم کوکی ها هستند که ارسال میشند . کامیپوتر الیس باید این پیغام رو رمز کنه (همین خط بالا ) پس اون رو با کلید رمز میکنه و در قالب بلوک های رمز شده c به سمت سرور میفرسته

هر بلوک p و c رو هشت بایت در نظر میگیرم . پس

P1=POST /AA

P2=AAAA HTT

که x اولین بایت هدره و در حقیقت همون کوکیه و هدف ما هم حدس زدن همینه . این بلوک های هشت بایتی با استفاده از کلید رمز میشند و تبدیل به c1,c2,c3 میشند .

پس c3 در حقیقت شامل رمز شده حرف اول کوکی + یک قسمت از هدره که برای ما مشخصه

حالا اون فرد مزاحمه میاد این پیغام رو به الیس میده که رمزش کنه

Iv+c2+r +حرف اول کوکی رو به الیس میده و اون رو به ادامه پیغام اضافه میکند مثلا به متن پیغام REQUESTBODY اضافه میکنه چون متن پیغام هنوز به طور کامل رمز نشده و اخرین چیزی که رمز میشه متن پیغامه

خوب حالا اگه درست حدس زده باشه بایت اول کوکی به دست میاد و سراغ بایت دوم میره و ... تا کوکی رو به دست بیاره .

اگر متن رمز شده ای که الیس میده برابر با c3 باشه درست حدس زده وگرنه دوباره امتحان میکنه و ...

خوب حالا اون مردک فضول چه طور میتونه این کارو انجام بده ؟ مشخصه که به حمله مرد میانی احتیاج داره پس میتونه تو شبکه ای که شما هستید باشه یا اینکه یکی از isp های ایران ! باشه مثل پارس انلاین که بار قبلی طبق گزارشات در جریان جعل گواهی جیمیل و سایت های دیگه این کار رو بر روی کاربراش انجام داد .

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

خوب در نهایت اینکه این بود روش کار این حمله فعلا هیچ مرورگری برای این حمله اپدیتی ارائه نداده و همه سایت هایی که از cbc استفاده میکنند اسیب پذیرند که البته تقریبا همه سایت ها رو شامل میشه مثلا میتونید به لیست cipher suit هایی که با تست کردن جیمیل به دست میاد نگاه کنید و ببینید که از cbc استفاده میکنه

خوشبختانه فعلا این برنامه پابلیک نشده ولی در زیر میتونید ویدئو طرز کارش و دونه دونه به دست اوردن کوکی رو ببینید .