آسیب پذیری POODLE که امروز منتشر شده است، از یک ضعف در مبنای تئوری SSLv3 استفاده کرده است، نه یک مشکل پیاده سازی. به همین دلیل تنها راه برطرف کردن آن غیر فعال کردن کامل این پروتوکل میباشد.
اصل مبنای تئوری این آسیب پذیری توسط Serge Vaudenay در سال ۲۰۰۱ مطرح شده بود، اما او فکر میکرده است که امکان استفاده عملی از این آسیب پذیری وجود ندارد. هم اکنون یک روند عملی برای استفاده از این آسیب پذیری مطرح شده است. این روند عملی، اگر چه پیچیده، ولی قطعی است (احتمالی نیست) و فراهم کردن همهی شرایط آن اگر چه نیاز به تلاش بسیاری دارد (و نوشتن یک اسکریپت برای آن شاید سخت باشد) ولی کاملا شدنی است.
تنها شروط پایه برای استفاده از این آسیب پذیری، این موارد است:
از نظر تئوری، این آسیب پذیری اجازه میدهد که حمله کننده قسمتی از درخواست را (با اینکه رمز شده است) بخواند و تشخیص دهد. این قسمت باید شرایط خاصی داشته باشد ولی برای مثال میتواند cookie کاربر باشد.
شرایط ثانویه استفاده از این آسیب پذیری موارد زیر است. دقت نمایید که همهی این شرایط با فرض شماره ۱ قابل دستیابی هستند.
بیشتر الگوریتمهای رمز نگاری مورد استفاده در SSL روی block های ۸ یا ۱۶ بایتی از داده کار میکنند (در اینجا برای راحتی فرض میکنیم که از یک الگوریتم ۱۶ بایتی استفاده میشود) بنابراین مثلا داده باید به تکههای ۱۶ بایتی تقسیم شود و عملیات رمز نگاری روی این بستههای ۱۶ بایتی انجام میشود.
چون ممکن است طول داده مضربی از ۱۶ نباشد، ابتدا باید با اضافه کردن چند کاراکتر اضافی به انتهای داده (که به آن padding میگویند)، طول آن را به مضربی از ۱۶ تغییر داد. روش مورد استفاده در SSLv3 این طور است که آخرین کاراکتر نشان میدهد که چند کاراکتر padding وجود دارد، برای مثال درخواست زیر را ملاحظه کنید. (در شکلها هر خط ۱۶ کاراکتر و بنابراین یک block است)
47 45 54 20 2F 3F 61 62 0D 0A 43 6F 6F 6B 69 65 GET /?ab↲↲Cookie 3A 20 73 65 63 72 65 74 3D 31 32 33 0D 0A 0D 0A : secret=123↲↲↲↲ 72 65 71 75 65 73 74 20 62 6F 64 79 YY YY YY YY request body---- YY YY YY YY YY YY YY YY YY YY YY YY XX XX XX 03 ------------••••
که در مثال بالا کاراکترهای مشکلی، خود درخواست (plaintext)، و کاراکترهای سبز، hash آن است (که برای ما مهم نیست) مقدار 123 که با رنگ زرد مشخص شده، مقداری است که حمله کننده آنرا نمیداند و میخواهد آن را بیابد.
کاراکترهای قرمز padding هستند و آخرین کاراکتر که 03 است، نشان میدهد که ۳ کاراکتر قبل آن نیز جزو padding است. در SSLv3 مقدار ۳ کاراکتر قبلی اصلا مهم نیست (برای همین با XX نشان داده شده است) در صورتیکه در نسخههای بعد، این کاراکترها باید مساوی با همان کاراکتر آخر باشند. همین تفاوت است که باعث آسیب پذیر شدن SSLv3 شده است. دقت کنید که در SSLv3 کاراکترهای padding در hash محاسبه نمیشوند و این نکته هم یکی از مبانی این آسیب پذیری است.
ابتدا حمله کننده باید طول درخواست را به گونهای تغییر دهد که یک کاراکتر (مثلا آخرین کاراکتر کوکی) در آخر یک بلاک قرار بگیرد (طبق فرضها او طول و جای کوکی را میداند). و ضمنا طول درخواست هم به گونهای باشد که یک بلاک کامل به padding اختصاص داده شود.
P1:47 45 54 20 2F 3F 61 62 63 64 65 66 0D 0A 43 6F GET /?abcdef↲↲Co P2:6F 6B 69 65 3A 20 73 65 63 72 65 74 3D 31 32 33 okie: secret=123 P3:0D 0A 0D 0A 72 65 71 75 65 73 74 20 62 6F 64 79 ↲↲↲↲request body P4:YY YY YY YY YY YY YY YY YY YY YY YY YY YY YY YY ---------------- P5:XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 0F ••••••••••••••••
(هر بلاک رمزنگاری نشده (یا plaintext) از P1 تا P5 نام گذاری شده است)
دقت کنید که حمله کننده با استفاده از جاواسکریپت میتواند url و body درخواست را تغییر دهد اما دسترسیای به محتوای cookie ندارد.
متن بالا برای برای ارسال به سرور در سمت کاربر (کلاینت) رمز میشود و محتوای رمز شده به سمت سرور ارسال میشود. حمله کننده در بین راه محتوای رمز شده را چیزی مانند شکل زیر میبیند:
C1:28 DA 27 4E C1 41 34 32 5A 68 53 BB 32 20 CA 69 (Ú'NÁA42ZhS»2 Ê~ C2:27 CC DF 89 7B 4F 2A 69 32 5A E4 BD 24 3A DE 79 'Ì߉{O*i2Zä½$:Þy C3:CA FE D8 6F DD D9 38 7C 76 FF 61 D7 64 78 45 FE ÊþØoÝÙ8|vÿa×dxEþ C4:F0 69 F1 8E C6 C3 73 52 20 EE 7E E2 F1 AF 62 37 ðiñŽÆÃsR î~âñ¯b7 C5:8A 5D 74 7B 31 28 41 61 B6 62 7C 97 80 F7 9E 63 Š]t{1(Aa¶b|—€÷žc
(هر بلاک رمزنگاری شده (یا ciphertext) از C1 تا C5 نام گذاری شده است)
البته او میداند که بلاک آخر متناظر padding و بلاک C2 هم متناظر با P2 است.
به صورت پیشفرض SSL از روش CBC برای chain کردنِ بلاکها استفاده میکند (برای اطلاعات بیشتر میتوانید به ویکی پدیا مراجعه کنید)
بنابراین حمله کننده میداند که این جملات صادق هستند:
Encrypt(C1 ⊕ P2) = C2
Encrypt(C4 ⊕ P5) = C5
و میداند که P5[16] = 0x0F است (چون padding یک سطر کامل است)
در این حال حمله کننده (که بین کلاینت و سرور حائل شده است)، بلاک C5 را (که متناظر با padding است) دستکاری میکند و آنرا مساوی C2 قرار میدهد:
C1:28 DA 27 4E C1 41 34 32 5A 68 53 BB 32 20 CA 69 (Ú'NÁA42ZhS»2 Ê~
C2:27 CC DF 89 7B 4F 2A 69 32 5A E4 BD 24 3A DE 79 'Ì߉{O*i2Zä½$:Þy
C3:CA FE D8 6F DD D9 38 7C 76 FF 61 D7 64 78 45 FE ÊþØoÝÙ8|vÿa×dxEþ
C4:F0 69 F1 8E C6 C3 73 52 20 EE 7E E2 F1 AF 62 37 ðiñŽÆÃsR î~âñ¯b7
C5:27 CC DF 89 7B 4F 2A 69 32 5A E4 BD 24 3A DE 79 'Ì߉{O*i2Zä½$:Þy
در این صورت خواهیم داشت:
C5 = C2 ⇒
Encrypt(C1 ⊕ P2) = Encrypt(C4 ⊕ P5) ⇒
C1 ⊕ P2 = C4 ⊕ P5 ⇒
P2 = C1 ⊕ C4 ⊕ P5
سپس حمله کننده رشتهی جدید را به سرور ارسال میکند.
حمله کننده مقدار C5 را (که رمز شدهی padding بوده) دستکاری کرده است و بنابراین مقدار padding را به رشته نامعلومی تغییر داده است. اما میداند که سمت سرور فقط آخرین کاراکتر padding مهم است نه بقیه آن. در بیشتر موارد مقدار کاراکتر آخر مخالف 0x0F است و سرور تشخیص میدهد که پیام ارسال شده خراب شده است و ارتباط را قطع میکند. اما از هر ۲۵۶ مورد یک مورد امکان دارد که کاراکتر آخر دقیقا برابر 0x0F باشد. در این صورت پیام، صحیح تلقی شده و پاسخ به کلاینت برگردانده میشود. حمله کننده به راحتی (مثلا با بررسی اندازه پاسخ) میتواند تشخیص دهد که آیا این دستکاری، پیام را خراب کرده است یا نه.
اگر پیام خراب نشده باشد، حمله کننده یک کاراکتر از کوکی را فهمیده است، چون میداند که:
P2[16] = C1[16] ⊕ C4[16] ⊕ P5[16]
مقدار P5[16] = 0x07 است و مقدار C1 و C4 نیز جزو ciphertext (درخواست رمز شده) است.
به این ترتیب حمله کننده حدودا با ۲۵۶ تلاش میتواند یک کاراکتر از کوکی کاربر را استخراج کند. حال کاربر با اضافه کردن یک کاراکتر به url و حذف یک کاراکتر از body میتواند مقدار کوکی را یک کاراکتر به جلو شیفت کند و با تکرار روند بالا (حدودا ۲۵۶ درخواست) کاراکترهای کوکی را یک به یک استخراج نماید.
47 45 54 20 2F 3F 61 62 63 64 65 66 67 0D 0A 43 GET /?abcdefg↲↲C 6F 6F 6B 69 65 3A 20 73 65 63 72 65 74 3D 31 32 ookie: secret=12 33 0D 0A 0D 0A 72 65 71 75 65 73 74 20 62 6F 64 3↲↲↲↲request bod
بنابراین یک حمله کننده برای یافتن یک کوکی به طول ۴۰ کاراکتر، حدودا باید ۱۰،۰۰۰ درخواست از سمت کاربر ارسال کند. این تعداد بسیار کم است و با سرعت ۲۰ درخواست در ثانیه، در کمتر از ۱۰ دقیقه قابل انجام میباشد.
*به روز رسانی: ابزار بیان برای تشخیص آنلاین این آسیب پذیری در مرورگرها و وب سایت ها: