CVE-2019-17059: Preauth-RCE در سایبروسام Sophos توضیح داد

ما در محله TheBestVPN با محققان امنیتی داخلی و خارجی سخت تلاش کردیم تا از نقاط ضعف جدی از راه دور در SSL VPN و فایروال هایی مانند Cyberoam ، Fortigate و Cisco VPN پرده برداریم. این مقاله یک مورد فنی در مورد آسیب پذیری مهم وصله بر Cyberoam SSL VPN است که به CyberoamOS نیز معروف است..

این مورد سوء استفاده Cyberoam ، لقب CVE-2019-17059 یک آسیب پذیری مهم است که به مهاجمان اجازه می دهد بدون ارائه نام کاربری یا رمزعبور به دستگاه Cyberoam شما دسترسی پیدا کنند مهمتر از آن ، دسترسی اعطا شده بالاترین سطح (ریشه) است که اساساً به مهاجمی حقوق نامحدودی در دستگاه Cyberoam شما می دهد..

در اکثر محیط های شبکه ، از دستگاه های Cyberoam به عنوان دیواره آتش و دروازه SSL VPN استفاده می شود. این به یک مهاجم بالقوه می تواند جایگاه محکمی در یک شبکه دهد. حمله به میزبان های داخل شبکه را آسان تر می کند ، و از آنجا که دستگاه های سایبرامام معمولاً در اکثر محیط ها مورد اعتماد هستند ، این امر باعث می شود یک مهاجم احتمالاً بیشتر شود..

طبق گفته های Shodan (موتور جستجوگر دستگاه های متصل به اینترنت) ، بیش از 96،000 دستگاه سایبرام با اینترنت روبرو هستند و از سراسر جهان وجود دارد. بیشتر این دستگاه ها در شرکت ها ، دانشگاه ها و برخی در بانک های مشهور جهان نصب شده اند. این منجر می شود که حملات دارای تأثیرات زیادی بر این محیط ها باشند.

تنها چند روز پس از گزارش اولیه ما به آنها ، همکاری با تیم امنیتی سوفوس بسیار خوشحال شده است زیرا آنها به سرعت با تأیید و جمع کردن تکه های عمل کردند. Kudos به آنها! (هدفمند!)

کشف سایبرام

و از آنجا که بسیاری از این موجودات اهداف جذاب برای مهاجمین هستند ، این اشکالات را از همه مهم تر می کند.

CyberoamOS از راه دور غیرمستقیم دستور فرمان ریشه

CyberoamOS یک سیستم عامل اصلاح شده مبتنی بر لینوکس برای دستگاه های Cyberoam است. این سیستم عامل دارای رابط پیکربندی مبتنی بر وب و یک درگاه SSLVPN است.

رابط وب به دو بخش اصلی تقسیم می شود:

  • جلویی که به زبان جاوا نوشته شده است
  • پس زمینه ای که از ترکیبی از C و Perl استفاده می کند

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

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

بیشتر این موارد تأیید شده است. اما چند گزینه وجود دارد که می توانیم بدون احراز هویت به آنها دسترسی پیدا کنیم (مانند ورود به سیستم).

اشکالات موجود در ماژول آنتی ویروس / آنتی اسپام ایمیل دروغ است. حالت درخواست برای این نقطه پایانی (ماژول ، op) 458 است.

نکته قابل ذکر این است که کد های رمزگذاری شده به نام آنها در پایگاه داده Cyberoam (پایگاه داده داخلی Postgres) ترسیم می شوند. با جستجوی 458 می توان فهمید که نام این کد چیست؟.

در اینجا خطی از اسکریپت SQL اولیه سازی بانک اطلاعاتی وجود دارد که نام opcode 458 را نشان می دهد:

وارد tblcrevent (کد opcode ، توضیحات ، حالت ، درخواست)
مقادیر ('RELEASEQUARANTINEMAILFROMMAIL' ، 'RELEASE QUARANTINE MAIL از MAIL' ، '458' ، 2).

توابع opcode در دایرکتوری / _conf / csc / cscconf / ذخیره می شوند. ما کل کد عملکرد آسیب پذیر را آشکار نخواهیم کرد ، اما چند قطعه قطعه را ارائه می دهیم که نشان می دهد کجا و چگونه اشکال رخ می دهد.

یک کد از قسمت جلوی جاوا که شامل کد کد 458 است:

if ((jsonObject.getString)"hdnSender") نابرابرها ("") ||
validateEmail (jsonObject.getString ("hdnSender"))) &&
validateEmail (jsonObject.getString ("hdnRecipient")) &&
isSafeFilePath (jsonObject.getString ("hdnFilePath")) && ب)
httpServletResponse.setContentType ("متن / html")؛
CyberoamLogger.debug ("آنتی ویروس / AntiSpam", "مقدار ثابت CSC " +
CSCConstants.isCCC)؛

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

رویداد EventBean نهاییByMode = EventBean.getEventByMode (363)؛
... اصلاح شد
نهایی int sendWizardEvent = cscClient.sendWizardEvent (eventByMode ، hashMap ، sqlReader)؛

همانطور که در بالا می بینیم ، یک کد رویداد جدید (363) داریم که به باطن ارسال می شود. اشکالی که ما کشف کردیم در کدی است که این کار را در باطن انجام می دهد.

opcode به عنوان sendmail خوانده می شود و برای جلوگیری از سوء استفاده از این اشکال ، اکثر کد ها را از کد زیر حذف می کنیم.

کنترل کننده opcode برای send_mail.

...اصلاح شده ...

$ param = $ درخواست->{رهایی}؛
param = DLOPEN (base64_decode ، پارامتر)
برنامه LOG " رمزگشایی مقادیر: $ param \ n"
٪ requestData = تقسیم (/ [&=] / ، $ param)؛
$ mailServerHost = $ درخواست Data {hdnDestDomain؛
$ mailFrom = $ درخواستData {hdnSender}؛
$ mailTo = $ درخواستData {hdnRecipient}؛
$ پرونده = $ QUARANTINE_PATH."/".$ درخواستData {hdnFilePath}؛

$ mailfile = $ درخواستData {hdnFilePath}؛
$ validate_email ="نادرست"؛
my $ email_regex = '^ ([\.]؟ [_ \ - \! \ # \ {\} \ $ \٪ \ ^ \&\ * \ + \ = \ | \؟ \ '\***** / a-zA-Z0-9]) * @ ([a-zA-Z0-9] ([-]؟ [a-zA- Z0-9] +) * \.) + ([a-zA-Z0-9] {0،6}) $ '؛
if ($ درخواستData {hdnRecipient = ~ / $ email_regex / && ((تعریف شده توسط $ درخواستData {hdnSender && $ درخواستData {hdnSender} eq '') || $ درخواستData {hdnSender = ~ / $ email_regex /) && index ($ درخواستData {hdnFilePath ، '.. /') == -1)
$ validate_email ="درست است، واقعی"؛
}
.... اصلاح شد....

همانطور که در بالا مشاهده کردیم ، کد شبه Perl به ما نشان می دهد که چگونه پس زمینه ورودی از قسمت جلویی را دریافت می کند ($ درخواست Data) و چگونگی تلاش برای تأیید برخی از پارامترهای ارسال شده.

پس از تأیید ، اگر پارامترهای ما معتبر باشند ، کد زیر اجرا می شود:

٪ mailreq = ("پست الکترونیکی"=>"$ MAIL_FORWARD","موضوع"=>"$ strSubject","به ایمیل"=>"$ mail برای","فایل پیوست"=>"پرونده $","smtpserverhost"=>"$ mailServerHost","نشانی اینترنتی"=>"$ mail از")؛

بیرون = OP CodeE mail_sender json٪ mailreq

کد بالا پارامترهای درخواست ما را به متغیر mailreq تعیین می کند و تابع mail_sender (OPCODE) را فراخوانی می کند. خواهیم دید که چگونه این opcode اجرا می شود و دقیقاً RCE در کجا اتفاق می افتد:

#mailaction 0 = mail_with_var ، 1 = mail_forward ، 2 = post_attachment
$ postaction = درخواست $->action ارسال نامه}؛
$ موضوع = $ درخواست->{موضوع}؛
$ mailbody = ''؛
$ attachmentfile = درخواست $->{فایل پیوست}؛
$ به ایمیل = درخواست $->{به ایمیل}؛

# بدن_میل
اگر ("درخواست $ تعریف شده->body نامه شخصی && '$ درخواست ما نیست->body نامه شخصی") {
$ mailbody = $ درخواست->body نامه شخصي}؛
}
میزبان سرور #SMTP
اگر ("درخواست $ تعریف شده->{smtpserverhost && '$ درخواست ما نیست->{smtpserverhost") {
$ smtpserverhost = $ درخواست->smtpserverhost}؛
} ELSE
نتیجه = QUERY "از آنجا که servicekey = 'MailServer'"
اگر ("نتیجه $ تعریف شده است->{خروجی->val ارزش خدمات} [0] && نتیجه ما نیست->{خروجی->val ارزش خدمات} [0]") {
$ smtpserverhost = $ نتیجه->{خروجی->val servicevalue} [0]؛
} ELSE
$ smtpserverhost ="127.0.0.1"؛
}
}

درگاه سرور #SMTP
اگر ("درخواست $ تعریف شده->{smtpserverport && '$ درخواست ما نیست->{smtpserverport") {
$ smtpserverport = درخواست $->smtpserverport؛
} ELSE
نتیجه = QUERY "از آنجا که servicekey = 'MailServerPort'"
اگر ("نتیجه $ تعریف شده است->{خروجی->val ارزش خدمات} [0] && نتیجه ما نیست->{خروجی->val ارزش خدمات} [0]") {
$ smtpserverport = $ نتیجه->{خروجی->val servicevalue} [0]؛
} ELSE
$ smtpserverport ="25"؛
}
}

#SMTP پرچم auth
$ smtpauthflag ="0"؛
اگر ("درخواست $ تعریف شده->{smtpauthflag && '$ درخواست ما نیست->{smtpauthflag") {
$ smtpauthflag = درخواست $->smtpauthflag؛
} ELSE
نتیجه = QUERY "ارزش خدمات را از tblclientservice انتخاب کنید که در آن servicekey = 'SMTPA تأیید اعتبار Flag'"
اگر ("نتیجه $ تعریف شده است->{خروجی->val ارزش خدمات} [0] && نتیجه ما نیست->{خروجی->val ارزش خدمات} [0]") {
$ smtpauthflag = $ نتیجه->{خروجی->val servicevalue} [0]؛
}
}

اگر ("$ smtpauthflag == 1") {
اگر ("درخواست $ تعریف شده->us نام کاربری پست الکترونیکی && '$ درخواست ما نیست->us نام کاربری پست الکترونیکی") {

$ nameus = درخواست $->ername نام کاربری ایمیل}؛
$ mailpassword = درخواست $->pass کلمه پستی {

} ELSE
نتیجه = QUERY "از آنجا که servicekey = 'MailServerUsername'"
$ nameusus = نتیجه->{خروجی->val servicevalue} [0]؛
نتیجه = QUERY "از آنجا که servicekey = 'MailServerPassword'"
$ mailpassword = $ نتیجه->{خروجی->val servicevalue} [0]؛
}
} ELSE

$ nameus = ""؛
$ mailpassword = ""؛

}
اگر ("درخواست $ تعریف شده->ازاد ress && '$ درخواست ما نیست->ازاد ress") {
$ fromaddress = درخواست $->fromaddress؛
} ELSE
نتیجه = QUERY "ارزش خدمات را از tblclientservice انتخاب کنید که در آنجا servicekey = 'FromAddress'"
$ fromaddress = $ نتیجه->{خروجی->val servicevalue} [0]؛
}

#حالت امنیتی
اگر ("درخواست $ تعریف شده->{smtpsecurity && '$ درخواست ما نیست->{smtpsecurity") {
$ smtpsecurance = درخواست $->{smtpsecurity}؛
} ELSE
نتیجه = QUERY "ارزش خدمات را از tblclientservice انتخاب کنید که در آن servicekey = 'smtpsecurance'"
$ smtpsecurity = $ نتیجه->{خروجی->val servicevalue} [0]؛
}

$ smtpsecurancemode = 0؛
اگر ("$ smtpsecurance eq "STARTTLS"") {
$ smtpsecurancemode = 1؛
} ELSE IF ("SSL / TLS") {
$ smtpsecurancemode = 2؛
}

گواهی #SMTP

$ smtpcertificate = ''؛
$ certpassword = ''؛

اگر ("$ smtpsecuritymode! = 0") {
اگر ("درخواست $ تعریف شده->{smtpcertificate && '$ درخواست ما نیست->{smtpcertificate") {
نتیجه = QUERY "شناسه ، گذرواژه را از گزینه tblvpncertificate که در آن گواهی = درخواست $ است ، انتخاب کنید->{smtpcertificate"
} ELSE
نتیجه = QUERY "انتخاب شناسنامه ، گذرواژه از tblvpncertificate که در آن گواهی = (انتخاب سرویس خدمات: int از tblclientservice که در آن سرویس = "smtpcertificate")"
}

$ smtpcertificate = $ نتیجه->{خروجی->{گواهی نامه} [0]؛
$ certpassword = $ نتیجه->{خروجی->{رمز عبور} [0]؛

}

# آدرس از نام
اگر ("درخواست $ تعریف شده->{fromaddresswithname && '$ درخواست ما نیست->{fromaddresswithname") {
$ fromaddresswithname = درخواست $->{fromaddresswithname}؛
} ELSE
$ fromaddresswithname = $ OEMNAME . " <" . $ fromaddress . ">"؛
}

کد بالا همان کارهایی را انجام می دهد که opcode دیگر هنگام شروع کار انجام داد. این متغیرها را اولیه می کند (اگر مشخص نشده برخی از ما یا از دستگاه استفاده کنید).

پس از تعیین متغیرها ، بلوک کد زیر اجرا می شود.

بیرون = EXECSH "/ bin / cschelper mail_send '$ fromaddress' '$ fromaddresswithname' '$ toEmail' '$ toEmail' '$ موضوع' '$ mailbody' '$ smtpserverhost' '$ smtpserverport' '$ nameus name' '$ postpassword' '$ mailaction' ' $ smtpsecuritymode '' $ smtpcertificate '' $ certpassword '' 1 '' $ attachmentfile '"

و در آنجاست ، اجرای فرمان. اکنون تماس در اینجا EXECSH است که "ARGUMENTS" را بنام / sh / c می نامد. با اجرای اعدام با استفاده از مقادیری که کنترل می کنیم ، می توانیم به راحتی به اجرای دستور از راه دور برسیم ، همه بدون احراز هویت.

ما ظرف چند ماه یک گزارش کامل و اثبات مفهوم را با طرح های مناسب منتشر خواهیم کرد.

به روز رسانی: این تحقیق ابتدا در مورد TechCrunch پوشش داده شده است ، بیشتر بخوانید در اینجا.

Brayan Jackson
Brayan Jackson Administrator
Sorry! The Author has not filled his profile.
follow me