{JS – روشن : امنیت – خاموش} : سواستفاده از SQL مبتنی بر JSON برای دور زدن WAF

{JS - روشن : امنیت – خاموش} : سواستفاده از SQL مبتنی بر JSON برای دور زدن WAF

چکیده اجرایی

تیم 82 یک بایپس (Bypass) کلی برای دور زدن دیواره‌های آتش وب اپلیکیشن‌های (WAF) پیشرو در صنعت توسعه داده است.

 تکنیک حمله شامل اضافه کردن دستورنحوی (سینتکس) JSON به پی‌لودهای تزریق SQL است که WAF از تجزیه و تحلیل آن عاجز است.

 عمده فروشندگان WAF از پشتیبانی JSON در محصولاتشان برخوردار نیستند، علیرغم اینکه دهه‌هاست که اکثر موتورهای جستجو از آن پشتیبانی می‌کنند.

 اکثر WAFها به راحتی حملات SQLi را شناسایی می‌کنند، که همراه کردن JSON با دستورات نحوی SQL باعث کور شدن WAF نسبت به این حملات خواهد شد.

 بایپس ما دربرابر WAF های فروخته شده توسط این 5 فروشنده کار کرد: Palo Alto Networks, Amazon Web Services, Cloudflare, F5,  و  Imperv. هر 5 فروشنده هشدار دریافت کردند و محصولاتشان را برای پشتیبانی از دستورات نحوی JSON در فرایند بازرسی تزریق SQL به روزرسانی کردند.

مهاجمانی که از این تکنیک ها استفاده می‌کنند، قادر هستند تا حفاظت WAF را دور بزنند و از آسیب‌پذیری های بیشتر برای استخراج داده استفاده کنند.

مقدمه

 دیواره‌های آتش وب اپلیکیشن‌ها (Web-Application-Firewalls(WAF)) به منظور تامین امنیت اپلیکیشن‌های مبتنی‌بر وب و API ها دربرابر ترافیک‌های خارجی مشکوک HTTP، به‌ویژه حملات XSS و تزریق SQL طراحی شده اند، که به نظر نمی‌رسد باعث از کار افتادن رادار امنیتی شود.

درحالیکه تشخیص و رفع آنها کار نسبتا آسانی است، مخصوصا تزریق SQL که پای ثابت خروجی‌های اسکن‌های کد خودکار و یک ویژگی مرسوم در لیست برترین آسیب‌پذیری های صنعت امنیت سایبری، از جمله OWASP Top 10 است.

 معرفی WAF ها در اوایل سال‌های 2000 تاحدزیادی به عنوان راه حل مناسب مقابله با این خطاهای کدنویسی بود. WAFها اکنون در خط کلیدی دفاع از امنیت اطلاعات سازمانی ذخیره شده در پایگاه داده ها قرار دارند که ازطریق وب اپلیکیشن‌ها می‌توان به آنها دسترسی پیدا کرد. از WAF ها همچنین برای محافظت از پلتفرم های مدیریت مبتنی بر ابر که بر دستگاه های تعبیه شده متصل مانند روترها و نقاط دسترسی نظارت می کنند، به طور فزاینده ای استفاده می شود.

 مهاجمی که قابلیت دور زدن اسکن ترافیک و قابلیت های مسدودسازی WAF را دارد، دراکثر مواقع به اطلاعات حساس مشتری و کسب و کار دسترسی مستقیم دارد. خوشباختانه چنین بایپس‌هایی زیاد رایج نیستند و درصورت وقوع تجهیزات یک فروشنده خاص را مورد هدف قرار می‌دهد.

 اکنون تیم82 تکنیک حمله ای را معرفی می‌کند که به عنوان اولین بایپس کلی دیواره‌های آتش وب اپلیکیشن های چندگانه فروشندگان پیشرو صنعت IT عمل می‌کند. بایپس ما روی WAF های به فروش رفته ازطریق 5 فروشنده پیشرو ازجمله : Palo Alto, F5, Amazon Web Services, Cloudflare, و Imperva کارکرد. تمام فروشندگان آسیب‌دیده افشای تیم 82 را تایید کردند و اصلاحاتی در جهت اضافه کردن پشتیبانی برای دستورات نحوی JSON به فرایندهای بازرسی SQL محصولاتشان، اعمال کردند.

 تکنیک ما درابتدا به درک نحوه چگونگی تشخیص و نشانه گذاری یک دستور نحوی SQL به عنوان مخرب پرداخت که در ادامه متوجه شدیم که WAF این دستور نحوی SQL را ندید. معلوم شد که علت این اتفاق بخاطر JSON است. JSON یک فرمت فایل استاندارد و تبدیل داده است، که در زمان هایی که داده از یک سرور به وب اپلیکیشن ارسال می‌شود، استفاده از آن بسیار رایج است.

 اضافه کردن پشتیبانی از JSON در پایگاه‌ داده‌های SQL تقریبا به 10 سال پیش برمی‌گردد. امروزه موتورهای پایگاه داده مدرن به صورت پیشفرض از دستورات نحوی JSON ، اصلاحات و جستجوهای پایه و همچنین از طیف مختلف توابع و عملگرهای JSON، پشتیبانی می‌کنند. بااینکه پشتیبانی از JSON دربین موتورهای پایگاه داده یک امر عادیست، درمورد WAF ها نمیتوانیم نظر مشابهی داشته باشیم. فروشندگان WAF ها در امر افزودن پشتیبانی JSON بسیار کند عمل کردند، که این امر به مااجازه داد تا با تولید پی‌لودهای جدید تزریق SQL که شامل JSON هم بودند، امنیتی که WAF ها به وجود آورده بودند را دور بزنیم.

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

 این امر به‌ویژه برای پلتفرم‌های OT و IOT که به سیستم های مدیریت و نظارت مبتنی بر ابر منتقل شده‌اند بسیار مهم و حیاتی است. WAF ها نوید تامین امنیت بیشتر برای فضای ابری را ارائه می دهند. مهاجمی که بتواند این حفاظ ها را دور بزند، دسترسی گسترده‌ای به سیستم ها خواهد داشت.

تلاش های قدیمی که به یک تکنیک جدید منتهی می‌شود

سفر ما به سمت توسعه این تکنیک سال گذشته طی پژوهش‌های غیرمرتبط بر روی پلتفرم مدیریت دستگاه های بی سیم  شبکه ی Cambium، از جمله مدیر شبکه بی سیم cnMaestro آن که در محل یا در فضای ابری فروخته می شود، آغاز شد.

اکسس پوینت یک شبکه بی سیم Cambium

 

معماری ابری Cambium’s cnMaestro به کاربران اجازه می‌دهد تا تجهیزات AP Wi-Fi خود را از راه دور و از طریق ابر پیکربندی و کنترل کنند

به منظور درک نحوه ساخت پلتفرم و تعداد API ها  ومسیرهای داخلی آن، یک ماشین مجازی با فرمت مجازی‌سازی باز از cnMaestro را در محل استقرار وب سایت Cambium  دانلود کردیم.

 ما متوجه شدیم که cnMaestro از سرویس‌های بک اند NodeJS مختلف بسیاری ساخته شده است که درخواست های کاربران را به مسیرهای خاصی هدایت می‌کنند. هریک از این سرویس‌ها بخاطر سخت کردن کندوکاو در پلتفرم تاحدودی مبهم هستند. به‌منظور پروکسی هردرخواست به سرویس درست، از Nginx برای ارسال درخواست ها توسط URL درخواست شده استفاده کردیم.

 cnMaestro 2 روش مختلف برای استقرار به کاربر پیشنهاد می‌کند:

  1. استقرار On-Premise: یک سرور اختصاصی cnMaestro ایجاد می شود که توسط کاربر میزبانی و مدیریت می شود.
  2. استقرار ابری: یک سرور cnMaestro موجود روی زیرساخت شبکه ابری Cambium. تمام این نمونه‌های cnMaestro بر روی ابر Amazon AWS زیرنظر سازمان Cambium در یک معماری چند مستاجر میزبانی می‌شوند.

 وقتیکه شروع به کار دقیق و جزئی با اپلیکیشن cnMaestro کردیم، متوجه چند نکته عجیب و جالب دررابطه با استقرار در فضای ابری شدیم.

استقرار در فضای ابری

استقرار درفضای ابری cnMaestro در AWS آمازون نمونه اصلی cnMaestro (موجود روی https://cloud.cambiumnetworks.com) را دربرمیگیرد که لاگین‌ها، استقرار تجهیزات را دربرمی‌گیرد و اکثر داده‌های پلتفرم را داخل پایگاه داده اصلی ذخیره می‌کند.

 هرکاربری که در اپلیکیشن ابری cnMaestro ثبت نام می‌کند، یک نمونه AWS آمازون شخصی، یک URL شخصی (یک زیردامنه متعلق به ابر اصلی Cambium) و یک شناسه سازمانی تعلق می‌گیرد. اینکار باعث می‌شود تا دریک طراحی چندمستاجری، کاربران را بتوانیم به راحتی از هم جدا کنیم. به منظور دسترسی داشتن به نمونه cnMaestro خودتان، با پیروی از طرح زیر یک URL منحصربفرد برای شما ایجاد می‌شود:

https://us-e1-sXX-XXXXXXXXXX.cloud.cambiumnetworks.com

 درانتهای پژوهش مان درباره Cambium cnMaestro، 7 آسیب‌پذیری مختلف کشف کردیم که هم اینجا و هم در داشبورد افشای تیم 82 می‌توانید انها را مشاهده کنید. بااینحال یک آسیب‌پذیری به‌ویژه به ما کمک کرد تا از سوراخ خرگوش پایین برویم و این تکنیک جدید را کشف کنیم و توسعه دهیم.

گرفتار شدن دریک آسیب‌پذیری روز صفر که توانایی بهره‌برداری از آن را ندارید

 آسیب‌پذیری مخصوص Cambium را که پیدا کردیم که واقعا بهره‌برداری از آن بسیار سخت بود: CVE-2022-1361. درهسته آسیب‌پذیری یک آسیب‌پذیری تزریق SQL بسیار ساده ای وجود دارد، با این حال، فرآیند بهره برداری واقعی ما را ملزم می کرد که خارج از چارچوب فکر کنیم و یک تکنیک کاملاً جدید SQL ایجاد کنیم. بااستفاده از این آسیب‌پذیری، ما توانایی استخراج session های کاربر، کلیدهای SSH، هش‌های کلمات عبور، توکن‌ها و کدهای تایید بودیم.

مشکل اساسی این آسیب‌پذیری  دراین مورد خاص این بود که توسعه دهندگان برای اضافه کردن داده‌های عرضه شده از سمت کاربر به کوئری از یک دستور آماده استفاده نکرده بودند. درعوض استفاده از یک روش امن برای اضافه کردن پارامترهای کاربر به کوئری SQL و پاکسازی اصولی ورودی، آنها به سادگی مستقیما این موارد را به کوئری وارد کرده بودند.

نقطه تنزل تزریق SQL که در CVE-2022-1361 از آن سواستفاده کردیم.

 همانطورکه در نقطه تنزل بالا مشاهده کردیم، اپلیکیشن داده‌های عرضه شده از سمت کاربر را میگیرد (اینجا: a.serialNo یا a.mac ) و آن را داخل یک کوئری SQL قرار می‌دهد. با این حال، در حالی که این مشکل خیلی ساده به نظر می‌رسید، پس از تجزیه و تحلیل سریع این آسیب پذیری متوجه شدیم که سه ضعف/محدودیت کلیدی دارد:

  1. ما تنها قادر به بازگردانی integer ها هستیم
  2. سطرهای بازگردانی شده به شکل تصادفی برگردانده شده‌اند
  3. ما فقط قادر به برگرداندن تعداد محدودی از سطرها در هر درخواست بودیم

در ادامه به تجزیه و تحلیل عمیق تر این محدودیت ها پرداخته ایم.

محدودیت 1 : ما تنها قادر به بازگردانی integer ها هستیم

محدودیت اول این است که خروجی‌های ما فقط integer برمی‌گردانند و نه رشته. از آنجاییکه درخواست‌های اصلی integer ها را بازگردانی می‌کند، هر دستور اتصال (union statement) که استفاده می‌کنیم هم integer ها را برمی‌گرداند. در SQL، اگر شما یک عملگر اتصال اجرا کنید، باید مطمئن شوید که نوع مقادیر هردو ستون یکسان است، و از انجاییکه مقادیر واکشی شده در یکی از ستون‌های ما Integer  است پس بایستی به ستون دیگر نیز مقادیر integer برگردانیم. این درحالیست که به احتمال زیاد داده‌هایی که استخراج می‌کنیم از نوع رشته هستند (توکن های Session، کلیدهای SSH و…)، درنتیجه باید کاری بکنیم تا قابلیت استخراج رشته‌ها را داشته باشیم.

 این محدودیت به راحتی با ریختن رشته‌های استخراج شده داخل یک آرایه Integer و بازگردانی هر کاراکتر به‌عنوان یک سطر جداگانه حل شد. بدین منظور از توابع stringtoarray و ASCII در SQL استفاده کردیم.

یک کوئری SQL که یک رشته را به عنوان لیست integer از کاراکترهای خود برمی‌گرداند.

محدودیت شماره2: سطرهای بازگردانی شده به شکل تصادفی برگردانده شده‌اند

 محدودیت دوم ما این بود که وقتی که می‌خواستیم سطرهای بیشتری را برگردانیم، وب سرور آن‌ها به ترتیب تصادفی برمی‌گرداند. وقتی به قطعه کدی که بعد از آسیب‌پذیری اجرا می‌شد نگاه کردیم، متوجه شدیم که برای هرسطر که یک کوئری SQL برگردانده شده، سرور تعدادی عمل ناهمزمان دیگر را هم انجام می‌دهد (که با فراخوانی تابع async.parallel قابل مشاهده هستند). این به این معناست که ترتیب اصلی سطرهای برگردانده شده ممکن است رعایت نشود، بلکه ترتیب آنها براساس ترتیب عمل‌های ناهمزمان تمام شده خواهد بود.

 این به این معناست که اگر مجبور به استخراج یک رشته به عنوان یک آرایه integer باشیم، بنابر تفسیر استخراج نامرتبط، توالی کاراکترها را از دست خواهیم داد.

 با اضافه کردن شاخص سطر، که شاخص کاراکتر داخل رشته را بااستفاده از تابع  row_number در SQL به integer برگشتی ترجمه می‌کند، موفق به پشت سرگذاشتن این محدودیت شدیم. ازانجاییکه ما فقط کاراکترهای ASCII را برمی‌گردانیم، هر مقدار کاراکتر محدود به 128 بود. بااضافه کردن عدد شاخص این مقدار ضربدر هزار شد (i*1000)، بااضافه کردن آن به نتایج، می‌توانیم همیشه با استفاده از یک تقسیم ساده و اقدامات ماژول از شاخص کاراکتر مطمئن باشیم.

پی لود SQL که مقدار ascii هر حرف موجود در رشته را با ضرب کردن شاخص آن کاراکتر در 1000 بازمی‌گرداند.

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

محدودیت 3: ما فقط قادر به برگرداندن تعداد محدودی از سطرها در هر درخواست بودیم

 غلبه بر محدودیت نهایی، سخت‌ترین چالش ما بود: مشکل timeout. برای هر سطری که برگرداندیم، سرور چندعمل دیگر هم انجام می‌دهد، ازجمله کوئری های SQL دیگر و دستکاری داده. زمانیکه سعی در بازگرداندن تعداد زیادی از سطرها داشتیم، درخواست ما timeout شد. بدتراز همه، اندپوینت API نسبتا کند بود، پس بازگردانی سطر به سطر داده‌ها کار بسیار زمانبری بود.

 راه‌حل ما در واقع بسیار ظریف بود: به‌جای اینکه برای هر کاراکتر یک سطر برگردانیم، درعوض یک Integer ازتعداد زیادی سطر ساختیم. این امربخاطر وجود تفاوت در سایز بایت بین integerها و کاراکترها میسر است. در PostgreSQL، سایز هر integer 4 بایت است، این درحالیست‌که سایز کاراکتری که ما می‌خواستیم استخراج کنیم نهایتا 1 بایت بود (البته تا زمانیکه درمورد کاراکترهای Ascii حرف می‌زنیم). این به این معناست که با اجرای عملیات ساده بایت، می‌توانیم 4 کاراکتر مختلف را داخل هر integer جای دهیم. علاوه براین، اگر  در دستورات اتصال (union command) integer خود را داخل یک BIGINT بریزیم، که در PostgreSQL این قابلیت وجود دارد، می‌توانیم هر سطر را تا 8 بایت گسترش دهیم.

تایپ سایزهای PostgreSQL . منبع :PostgreSQL

 این به این معناست که اگر قرار بود ما 8 بایت برای هرکاراکتری که استخراج می‌کنیم اضافه کنیم، و آن را BIGINT درنظربگیریم، می‌توانستیم در هر درخواست 7 برابر کاراکتر بیشتری استخراج کنیم (1بایت برای ایندکس کاراکتر رزرو شده است).

کوئری SQL که رشته را می‌گیرد و از هرچند کاراکتر یک BIGINT می‌سازد

با استفاده از این متدولوژی، ما توانستیم درهر درخواست تا 8 برابر داده‌های بیشتری استخراج کنیم. این امر زمانی را که که ما برای استخراج حجم قابل توجهی از داده ها صرف می کردیم را کاهش داد و سناریوی حمله را قابل قبول کرد.

ساخت پی‌لود مخصوص خودمان

 پس از اینکه هر سه محدودیت را دورزدیم، یک پی لود بزرگ داشتیم که به ما اجازه میداد هر داده‌ای که دلمان می‌خواهد را استخراج کنیم:

 و درواقع، زمانیکه ازاین پی‌لود استفاده کردیم، موفق به استخراج اطلاعات حساس ذخیره شده درپایگاه داده شدیم. این اطلاعات دربرگیرنده اطلاعاتی چون کوکی‌های Session تا توکن‌ها، کلیدهای SSH و پسوردهای هش شده بود.

یک مثال از داده هایی که ما بااستفاده از پی‌لود SQLi خودمان استخراج کردیم

 

رفتن به بالای ابرها (و سقوط!)

 پس از اینکه موفق شدیم تا از این آسیب‌پذیری موجود در نسخه on-prem کامل بهره برداری کنیم، قدم بعدی ما امتحان کردن همان آسیب‌پذیری روی ابر Cambium بود. خیلی زود مسیر ابری متناظر را پیدا کردیم و موفق شدیم ثابت کنیم که این ابزار هم به دلیل وجود آسیب‌پذیری مشابه، آسیب‌پذیر است. سپس بااستفاده از یک نسخه امن از پی‌لودهایمان دوباره امتحان کردیم، و این پاسخ را دریافت کردیم:

پاسخ به آسیب‌پذیری تزریق SQLما. ما با مشاهده یک کد 403 ممنوع، متوجه شدیم که درخواست ما رد شده است.

 پس از یک دوره وحشت کوتاه مدت، متوجه سربرگ سرور HTTP دربرگیرنده awselb/2.0 شدیم. این اتفاق به ما سرنخ داد تا متوجه شویم که درخواست ما توسط اپلیکیشن متوقف نشده است، ولیکن AWS WAF درخواست ما را متوقف کرده چراکه احتمالا آن را به عنوان مخرب نشانه گذاری کرده است. این اتفاق برای یک دقیقه ما را گمراه کرد، ولیکن خیلی زود هدفمان را روی دور زدن این WAF تنظیم کردیم. این تصمیم جرقه شروع پژوهش فعلی ما شد.

تحقیق درمورد  AWS WAF

 به‌منظور تحقیق درمورد WAF متعلق به AWS، درابتدا مجموعه‌ای با تنظیمات خودمان را راه‌اندازی کردیم تا تمام قسمت‌های متحرک و متغیر دست خودمان باشد: اپلیکیشن، کلاینت و تنظیمات WAF و لاگ‌های آن. یک ماشین ساده روی ابر AWS ایجاد کردیم، و AWS WAF را به منظور محافظت از اپلیکیشن دربرابر درخواست‌های مخرب راه‌اندازی کردیم (WAF را راه‌اندازی کردیم).

رابط کاربری پیکربندی تنظیمات قوانین WAF.

 سپس، یک وب اپلیکیشن با یک آسیب‌پذیری SQLi ایجاد کردیم، و آن را روی AWS مستقر کردیم.

 درنهایت، ما شروع به امتحان صدها درخواست که به صورت ویژه ساخته شده بودند کردیم و نحوه نشانه‌گذاری درخواست‌ها به عنوان مخرب ازطرف WAF را تجزیه و تحلیل کردیم.

وب اپلیکیشن Flask آسیب پذیری که ما ساخته بودیم.

 دراین آزمایش ما به این نتیجه رسیدیم که درکل برای اینکه WAF یک درخواست را به عنوان مخرب نشانه گذاری کند، 2 متدلوژی داریم:

درخواست هایی که WAF آنها را به عنوان مخرب نشنه گذاری شده و متوقف شده بودند. دراین درخواست یک پی‌لود رایج SQL ارسال کردیم که توسط WAF نشانه گذاری شد.

 جستجو برای پیدا کردن کلمات لیست سیاه: WAF می‌تواند به دنبال کلماتی بگردد که به عنوان دستورات SQL آنها را شناسایی می‌کند، و اگر دریک درخواست تعداد زیادی از این کلمات همتا پیدا کند، آن درخواست را به عنوان تلاش SQLi مخرب نشانه گذاری خواهد کرد.

 تجزیه و تحلیل دستورنحوی SQL از درخواست: WAF قادر به امتحان و تجزیه دستورات معتبر SQL بااستفاده از قسمت‌های مختلف درخواست است. اگر WAF با موفقیت دستور SQL را تشخیص دهد، درخواست را به عنوان تلاش SQLi مخرب نشانه گذاری خواهد کرد.

 درحالیکه اکثر WAFها علاوه بر هرکار منحصربفردی که WAF انجام می‌دهد، از ترکیب هردو متدولوژی استفاده می‌کنند، که هردو یک ضعف مشترک دارند: برای تشخیص دستورات نحوی SQL به WAF نیاز دارند. این موضوع باعث برانگیخته شدن انگیزه ما شد که یک سوال تحقیقاتی مهم را به میان آورد: چه می‌شود اگر یک دستور نحوی SQL پیدا کنیم که هیچ WAF قادربه شناسایی آن نباشد.

JSON  در SQL

 پاسخ سوال ما به سرعت درقالب یک ویژگی (اصلی) SQL خودش را نشان داد: JSON. در دوران مدرن، JSON به یکی از اشکال غالب ذخیره‌‌سازی و انتقال داده تبدیل شده است. به منظور پشتیبانی از دستورات نحوی JSON و اجازه دادن به توسعه‌دهندگان برای تعامل با داده در روش‌های مشابه با نحوه تعامل آنها با این فرمت در سایر اپلیکیشن‌ها، پشتیبانی از JSON در SQL هم نیاز بود.

 درحال حاضر تمام موتورهای پایگاه داده رابطه‌ای اصلی از دستورات نحوی JSON به صورت محلی پشتیبانی می‌کنند، این موتورها عبارتند از MSSQL، PostgreSQL، SQLite و MySQL. علاوه براین، دراخرین نسخه‌ی تمام این موتورهای ‌پایگاه داده به صورت پیشفرض دستورات نحوی JSON فعال است، این به این معنی است که مروزه این عمل در اکثر پایگاه داده ها مرسوم است.

 توسعه دهندگان از زمان در دسترس بودن آن به دلایل مختلفی استفاده از ویژگی های JSON را در پایگاه داده های SQL انتخاب کرده اند که با کارایی و عملکرد بهتر شروع می شود. از آنجایی که بسیاری از بک‌اند کارها از قبل با داده‌های JSON کار می‌کنند، انجام تمام دستکاری و انتقال داده در موتور SQL، تعداد فراخوانی‌های پایگاه داده مورد نیاز را کاهش می‌دهد. علاوه بر این، اگر پایگاه داده بتواند با فرمت داده JSON کار کند، که API بک‌اند به احتمال زیاد از آن نیز استفاده می‌کند، به پیش‌پردازش و پس پردازش داده کمتری نیاز است و به اپلیکیشن اجازه می‌دهد تا فوراً بدون نیاز به اینکه درابتدا آن را تبدیل کند، از آن استفاده کند.

 بااستفاده از JSON در SQL، اپلیکیشن قادر خواهد بود داده ها را واکشی کند، منابع مختلف را داخل پایگاه داده ترکیب کند، داده ها را تغییر داده و فرمت آنها را به JSON تغییر دهد. تمام این کارها داخل API متعلق به SQL انجام می‌شوند. سپس اپلیکیشن می‌تواند داده تبدیل شده به JSON را دریافت کند و به محض دریافت بدون پردازش داده‌ها با آنها کار کند.

جریان داده نشان دهنده استفاده از JSON در SQL که به توسعه دهندگان اجازه می‌دهد تا از بااستفاده از JSON API در SQL تعامل بهتری با داده ها داشته باشند.

 درحالیکه هر پایگاه داده روش پیاده سازی و تجزیه‌کننده JSON متفاوتی انتخاب می‌کند، هر کدام از طیف متفاوتی از توابع و عمگرهای JSON پشتیبانی می‌کنند. همچنین همه آنها از نوع داده JSON و جستجوها و اصلاحات پایه‌ای JSON هم پشتیبانی می‌کنند.

سطح پشتیبانی از JSON در هر موتورپایگاه داده اصلی.

بااین‌حال، حتی اگر به تمام موتورهای پایگاه داده پشتیبانی از JSON را اضافه کنیم، این به این معنی نیست که تمام ابزارهای امنیتی از این ویژگی “جدید” پشتیبانی خواهندکرد (همانطورکه میدانیم قبلا درسال 2012 اینکار انجام شده بود). این مشکل عدم پشتیبانی در ابزارهای امنیتی باعث به وجود آمدن مشکل عدم‌همخوانی در تجزیه و تحلیل اولیه بین ابزار امنیتی (اینجا WAF) و موتورهای پایگاه‌داده موجود است، که باعث تشخیص نادرست از دستور نحوی SQL می‌شود.

 ‘ or ‘a’=’a جدید

 بااستفاده از دستور نحوی JSON، قادر به ساختن پی‌لودهای جدید SQLi خواهیم بود. ازانجاییکه این پی‌لودها غالبا شناخته شده نیستند، از آنها می‌توان به عنوان پروازه رادارگریز استفاده کرد و ابزارهای امنیتی بسیاری را دور زد. بااستفاده از دستورات نحوی موتورهای پایگاه داده‌ای مختلف،  ما قادر به تفسیر لیست دستورات درست زیر در SQL هستیم:

  • PostgreSQL : ‘{“b”:2}’::jsonb <@ ‘{“a”:1, “b”:2}’::jsonb . آیا JSON سمت چپ در سمت راست هم وجود دارد؟ درست (True).
  • SQLite : ‘{“a”:2,”c”:[4,5,{“f”:7}]}’ -> ‘$.c[2].f’ = 7 . آیا مقدار استخراج شده از این JSON برابر 7 است؟ درست (True).
  • MySQL : JSON_EXTRACT(‘{“id”: 14, “name”: “Aztalan”}’, ‘$.name’) = ‘Aztalan’ . آیا مقدار استخراج شده از این JSON برابر ‘Aztalan’ است؟ درست (True).

 

مسلح با دستور نحوی JSON

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

 همانطور که مشخص است، JSON همان عدم‌همخوانی بین تجزیه‌کننده WAF و موتور پایگاه داده است. وقتی دستورات معتبر SQL که خیلی کم با دستورات نحوی JSON دراراتباط هستند را ارسال کردیم، WAF درواقع درخواست را با عنوان درخواست مخرب شناسایی نکرد.

اینجا یک پی‌لود SQLi مخرب داریم که شامل یک دستور نحوی JSON است. همانطور که میبینید، WAF درخواست را به عنوان مخرب نشانه گذاری نکرده و آن را متوقف نکرده است.

 این عملگر ساده JSON، <@ دراین‌مورد، که بررسی می‌کند آیا درشکل بالا JSON سمت راست در سمت چپی هم موجود است یا نه، WAF را به داخل یک حلقه وارد کرد و به ما اجازه داد تا پی‌لودهای SQLi مخرب را عرضه کنیم و همینطور اجازه داد تا WAF را دور بزنیم. به‌آسانی با اضافه کردن یک دستور نحوی JSON ساده برای شروع ارسال درخواست، قادر بودیم تا اطلاعات حساس را بااستفاده از آسیب‌پذیری SQLi روی ابر استخراج کنیم.

بهره برداری از آسیب‌پذیری تزریق SQL روی فضای ابری

رویای بزرگ: بایپس WAF کلی

 پس از آشکار کردن نتایج بایپس مان روی WAF متعلق به Amazon AWS، از خودمان سوال کردیم: “آیا ممکن است با مشکل بزرگتری مواجه باشیم؟!”. مشکل اصلی این بایپس عدم همخوانی بین موتورهای پایگاه داده و راه‌حل‌های تشخیص SQLi بود، علت این ناهمخوانی این است که JSON در SQL یک ویژگی رایج وشناخته شده نیست، ازاین‌رو دستورات نحوی آن به تجزیه‌کننده (Parser) WAF اضافه نشده بود.

بااین‌حال، مافکرکردیم که شاید این مشکل فقط با این فروشنده WAF مرتبط نباشد، ممکن است سایر فروشندگان WAF هم برای دستورت نحوی JSON پشتیبانی اضافه نکرده‌اند. پس وب اپلیکشن آسیب‌پذیرامان را برداشتیم و روی معروف‌ترین فروشندگان WAF راه اندازی کردیم. بعد از چند روز طولانی، کشف کردیم که از دستورات نحوی JSON می‌توان برای دورزدن بسیاری از این فروشندگان WAF هایی که چک کردیم استفاده کرد:

  • Palo-Alto Next Generation Firewall
  • F5 Big-IP
  • Amazon AWS ELB
  • Cloudflare
  • Imperva
لیستی از فروشندگان و محصولات WAF که بااستفاده از دستور نحوی JSON آن را دور زدیم.

 WAF یکی از فروشندگان که دربرابر حمله ما مصون ماند متعلق به Point’s CloudGuard AppSec و open-appsec بود، که خود ما هم قبلا برخوردار بودن این WAF ها از اقدامات کاهشی محلی برای متوقف کردن تکنیک حملات را تایید کرده بودیم.

 درهمین حال، این واقعیت که ما موفق به مدیریت دورزدن محصولات WAF بسیار بزرگ شدیم، درحالیکه قادر به ایجاد تغییرات محدودی در پی‌لودها بودیم، به این معنی بود که ما یک بایپس WAF عمومی بدست آورده‌ایم. این به این معنی‌است که حتی بدون دانستن اینکه دقیقا چه WAF بین ما و هدف وجود دارد، هنوز هم می‌توانیم با دورزدن حفاظ WAF، از آسیب‌پذیری تزریق SQL بهره برداری کنیم.

اتومیشن سازی فرایند

 برای اینکه نشان دهیم این بایپس WAF چقدر با عظمت است، تصمیم گرفتیم تا پشتیبانی از تکنیک‌های فرار دستورات نحوی JSON را برای بزرگترین ابزار بهره‌برداری منبع باز یعنی SQLMap اضافه کنیم.

ابزار SQLMap که به کاربر اجازه اتومیشن سازی و حمله به اهداف را می‌دهد.

 SQLMap یک فرایند خودکار بهره برداری از تزریق SQL را پیشنهاد می‌کند که به کاربر اجازه می‌دهد کل سایت را برای پیدا کردن آسیب‌پذیری اسکن کند. بعدازاینکه SQLMap یک آسیب‌پذیری SQL را شناسایی کرد، این امکان را برای کاربر فراهم می‌کند که هم بتواند نوع آسیب‌پذیری را انگشت‌نگاری کند و هم بهترین تکنیک بهره برداری مناسب با این آسیب‌پذیری خاص را شناسایی کند.

 پس ازاینکه تکنیک درست برای بهره برداری از آسیب‌پذیری را انتخاب کردیم، SQLMap به کاربران قابلیت استخراج خودکار اطلاعات ذخیره شده در پایگاه داده، شمارش جداول و پایگاه داده‌ها، استخراج هش‌های کلمات عبور و اجرای تعدادی تکنیک post-exploition را می‌دهد.

بااینکه خود SQLMap تعدادی تکنیک فرار از WAF پیشنهاد می‌کند، متوجه شدیم که اکثر WAF های مدرن به راحتی می‌توانند آن را شناسایی کنند، یعنی کاربراین نمی‌توانند درمواردی که WAF وجود دارد استفاده کنند.

به روشنی قابل مشاهده است که حتی اگر اپلیکشن آسیب‌پذیر باشد، SQLMap آن را قابل بهره برداری درنظرنمیگیرد، تازمانیکه اکثر درخواست ها توسط WAF متوقف شوند.

 هدف ما آوردن این تکنیک جدید به SQLMap و استفاده از دستورات نحوی JSON برای دور زدن WAFها بود. برای‌همین، پی‌لودهای تولید شده توسط SQLMap را با اضافه کردن دستورات نحوی که به صورت تصادفی تولید شده بودند، تزریق کردیم. ازآنجاییکه هر موتور پایگاه داده توابع و عملگرهای JSON متفاوتی را پیاده سازی می‌کند، ما نیز برای هرپایگاه داده یک اسکریپت جدا پیاده سازی کردیم. بااستفاده از افزونه خودمان SQLMap، قادر بودیم تا WAF معروف را دور بزنیم و از یک وب اپلیکیشن آسیب‌پذیری بهره برداری کنیم.

اجرای SQLMap بااستفاده از اسکریپت مجاز SQLMap برای بهره برداری موفق از وب اپلیکیشن آسیب‌پذیر و دور زدن WAF

اگر می‌خواهید ازاین اسکریپت برای آزمودن این بایپس استفاده کنید، به راحتی آخرین نسخه SQLMap را از Github بردارید.

نتیجه گیری

تکنیک حمله ماهرانه تیم82 به‌طور موثر قابلیت دیوار آتش وب اپلیکیشن برای شناسایی حملات تزریق SQL را دور زد. ما اینکار را با طی یک مسیر هیجان‌انگیز و پیچیده انجام دادیم که با سفر ما دراین مسیر با یک پژوهش غیرمرتبط آغاز شد که توسط یک فایروالی وب اپلیکشن خنثی شد، و درادامه زنجیره‌ای از رویدادها به راه افتاد که ما را به سمت این بایپس WAF عمومی راهنمایی کرد.

ما متوجه شدیم که فروشندگان WAF پیشرو در فرایند بازرسی تزریق SQL از دستورنحوی JSON پشتیبانی نمی‌کنند. به اینصورت که به ما اجازه داد تا دستور نحوی JSON را به دستورهای SQL اضافه کنیم که باعث شد WAF کد مخرب را نبیند.

تیم82 یافته‌های خود را به 5 فروشنده WAF پیشرو افشا کرد، که تمام این تامین کنندگان WAF پشتیبانی از دستور نحوی JSON را به محصولات خودشان اضافه کردند. ما باور داریم که سایر محصولات این فروشندگان نیز ممکن است در خطر باشند، و بهتر است بقیه محصولاتشان را نیز ازنظر پشتیبانی از JSON مورد بازبینی قرار دهند. برای مثال، در ادامه اقرارنامه و تصحیح نامه Amazon و F5 را میتوانید مشاهده کنید.

AWS بیانیه‌ای درخصوص مجموعه قوانین Amazon AWS ELB منتشر کرد. اضافه کردن پشتیبانی از دستورات نحوی JSON در بررسی های SQLi و مسدود کردن این بایپس

 

تاییدیه F5 SIRT Security از F5 BIG-IP، افزودن پشتیبانی از دستورات نحوی JSON در بررسی SQLi

این روش دور زدن بسیار خطرناک است، مخصوصا وقتی سازمان‌های بسیاری درحال مهاجرت کسب و کارها و فعالیت هایشان به فضای ابری هستند.  فرایندهای IOT  و OT که با ازطریق فضای ابری مدیریت می‌شوند و در مقاله به آنها اشاره کردیم هم ممکن است تحت تاثیر این مشکل قرار بگیرند. ازاینرو سازمانها بایستی مطمئن شوند که برای جلوگیری از چنین حملات بایپس نسخه‌های به روزرسانی شده ابزارهای امنیتی در سیستم های آنها درحال اجراست.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *