CVE-2019-17059: सोफोस के साइबरोम में प्रीथ-आरसीई समझाया

हम एसएसबी वीपीएन और फायरवॉल जैसे साइबरो, फोर्टजेट और सिस्को वीपीएन में गंभीर दूरस्थ शोषक खामियों को उजागर करने के लिए TheBestVPN में आंतरिक और बाहरी सुरक्षा शोधकर्ताओं के साथ कड़ी मेहनत कर रहे हैं। यह लेख साइबरम एसएसएल वीपीएन को प्रभावित करता है जो साइबरोसम के रूप में भी जाना जाता है.


यह साइबर अटैक, डब किया गया CVE-2019-17059 एक महत्वपूर्ण भेद्यता है जो हमलावरों को बिना किसी उपयोगकर्ता नाम या पासवर्ड प्रदान किए आपके साइबरोम डिवाइस तक पहुंचने देता है। उसके ऊपर, दी गई पहुँच उच्चतम स्तर (रूट) है, जो अनिवार्य रूप से आपके साइबरैम डिवाइस पर एक हमलावर को असीमित अधिकार देता है।.

अधिकांश नेटवर्क वातावरणों में, Cyberoam उपकरणों का उपयोग फ़ायरवॉल और SSL VPN गेटवे के रूप में किया जाता है। यह एक संभावित हमलावर को एक नेटवर्क में एक मजबूत पैर जमाने देता है। यह नेटवर्क के अंदर मेजबानों पर हमला करना आसान बनाता है, और चूंकि साइबरो उपकरणों को आमतौर पर अधिकांश वातावरण में भरोसा किया जाता है, इससे अतिरिक्त आक्रमण हो सकता है.

Shodan (इंटरनेट से जुड़े उपकरणों के लिए एक खोज इंजन) के अनुसार, दुनिया भर से 96,000 से अधिक इंटरनेट-सामना करने वाले Cyberoam डिवाइस हैं। इनमें से अधिकांश उपकरण उद्यमों, विश्वविद्यालयों और कुछ विश्व-प्रसिद्ध बैंकों में स्थापित हैं। इसके चलते इन वातावरणों पर भारी प्रभाव पड़ता है.

सोफोस सुरक्षा टीम के साथ काम करना एक बड़ी ख़ुशी की बात है क्योंकि उन्होंने हमारी प्रारंभिक रिपोर्ट के कुछ ही दिनों बाद पैच को स्वीकार करने और रोल आउट करके जल्दी से कार्य किया। उन्हें करने के लिए यश! (जानबूझ का मजाक!)

साइबरो का पता लगाना

और चूंकि इनमें से अधिकांश इकाइयां हमलावरों के लिए आकर्षक लक्ष्य हैं, इसलिए यह बग को और अधिक महत्वपूर्ण बना देता है.

CyberoamOS रिमोट Unauthenticated रूट कमांड निष्पादन

CyberoamOS Cyberoam उपकरणों के लिए एक संशोधित लिनक्स-आधारित ऑपरेटिंग सिस्टम है। इस OS में एक वेब-आधारित कॉन्फ़िगरेशन इंटरफ़ेस और एक SSLVPN पोर्टल है.

वेब इंटरफ़ेस दो मुख्य भागों में विभाजित है:

  • जावा में लिखा गया एक दृश्य
  • एक बैकेंड जो सी और पर्ल के संयोजन का उपयोग करता है

हम सामने या पीछे के अंत के कोड में गहरी डुबकी नहीं लगाएंगे, मुख्य रूप से समय बचाने और प्रकट की गई जानकारी की मात्रा को सीमित करने के लिए। लेकिन हम संक्षेप में चर्चा करेंगे कि बग को कैसे ट्रिगर किया जाता है.

कॉन्फ़िगरेशन और एसएसएलवीपीएन इंटरफेस दोनों में एक सर्वलेट है जो मुख्य संचालन को संभालता है। ये ऑपरेशन "मोड" नामक पैरामीटर का उपयोग करके परिभाषित किए गए हैं.

इनमें से अधिकांश प्रमाणित हैं। लेकिन कुछ ऑप्स हैं जिन्हें हम प्रमाणीकरण के बिना एक्सेस कर सकते हैं (जैसे लॉगिन).

हमें ईमेल एंटीवायरस / एंटीस्पैम मॉड्यूल में कीड़े मिले हैं। इस समापन बिंदु (मॉड्यूल, ऑप) के लिए अनुरोध मोड 458 है.

एक बात ध्यान देने योग्य है कि साइबरकोड डेटाबेस (आंतरिक डेटाबेस पोस्टग्रेज) में ओपकोड को उनके नाम से मैप किया जाता है। 458 को देखकर, हम पता लगा सकते हैं कि इस ओपकोड का नाम क्या है.

यहाँ डेटाबेस इनिशियलाइज़ेशन एसक्यूएल स्क्रिप्ट से एक लाइन दिखाई देती है, जिसका नाम opcode 458 है:

tblcrevent (opcode, description, mode, requesttype) में डालें
मान ('RAILASEQUARANTINEMAILFROMMAIL', 'RAILASE QUARANTINE MAIL FAIL MAIL', '458', 2);

ओपकोड फ़ंक्शन निर्देशिका / _conf / csc / cscconf / में संग्रहीत किए जाते हैं। हम कमजोर फ़ंक्शन के पूरे कोड का खुलासा नहीं करेंगे, लेकिन हम कुछ स्निपेट प्रदान करेंगे कि बग कहाँ और कैसे दिखाई देता है.

जावा फ्रंटएंड का एक कोड जो opcode 458 को संभालता है:

अगर (jsonObject.getString ("hdnSender") .Equals ("") ||
validateEmail (jsonObject.getString ("hdnSender"))) &&
validateEmail (jsonObject.getString ("hdnRecipient")) &&
isSafeFilePath (jsonObject.getString ("hdnFilePath")) && बी) {
httpServletResponse.setContentType ("पाठ / html");
CyberoamLogger.debug ("एंटीवायरस / एंटी स्पैम", "CSC लगातार मूल्य " +
CSCConstants.isCCC);

जैसा कि आप ऊपर देख सकते हैं, वैधता के लिए कुछ मापदंडों की जाँच की जाती है। यदि वे मान्य मान हैं, तो निम्न होता है:

अंतिम EventBean EventByMode = EventBean.getEventByMode (363);
... संशोधित।
अंतिम int sendWizardEvent = cscClient.sendWizardEvent (eventByMode, hashMap, sqlReader);

जैसा कि हम ऊपर देख सकते हैं, हमारे पास एक नया ईवेंट कोड (363) है जिसे बैकएंड पर भेजा जाएगा। हमने जो बग खोजा है वह उस कोड में है जो बैकएंड में इसे हैंडल करता है.

Opcode का नाम sendmail है, और इस बग के शोषण से बचने के लिए, हम निम्नलिखित कोड से अधिकांश कोड को फिर से भेजेंगे।.

Send_mail के लिए opcode हैंडलर.

...संशोधित ...

$ परम = $ अनुरोध->{रिहाई};
param = DLOPEN (base64_decode, परम)
लॉग अप्लॉग " डिकोड मान :: $ param \ n"
% requestData = विभाजन (/ [&=] /, $ परम);
$ mailServerHost = $ requestData {hdnDestDomain};
$ mailFrom = $ requestData {hdnSender};
$ mailTo = $ requestData {hdnRecipient};
$ फ़ाइल = $ QUARANTINE_PATH."/".$ RequestData {hdnFilePath};

$ Mailfile = $ requestData {hdnFilePath};
$ Validate_email ="असत्य";
मेरे $ email_regex = '^ ([\]। [_ \ _-! \ # \ _ \ _ \ _ \ $ \% \ ^ \ "&\ * \ + \ = \ |? \ \ '\\\\\\ / एक-zA-Z0-9]) * @ ([एक-zA-Z0-9] ([-] [एक-zA- Z0-9] +) * \) + ([एक-zA-Z0-9] {0,6}) $ '।
अगर ($ requestData {hdnRecipient} = ~ / $ email_regex / && ((परिभाषित $ requestData {hdnSender) && $ requestData {hdnSender} eq '') || $ requestData {hdnSender} = ~ / $ email_regex /) && सूचकांक ($ requestData {hdnFilePath}, '.. /') == -1) {
$ Validate_email ="सच";
}
.... संशोधित....

जैसा कि हम ऊपर देख सकते हैं, छद्म-पर्ल कोड हमें दिखाता है कि बैकएंड फ्रंटएंड ($ requestData) से इनपुट कैसे प्राप्त करता है और यह हमारे द्वारा भेजे गए कुछ मापदंडों को सत्यापित करने का प्रयास करता है।.

सत्यापन के बाद, यदि हमारे पैरामीटर मान्य हैं, तो निम्न कोड निष्पादित किया गया है:

% Mailreq = ("mailaction"=>"$ MAIL_FORWARD","विषय"=>"$ strSubject","ईमेल करना"=>"$ mailto","अनुलग्नक फ़ाइल"=>"$ फ़ाइल","smtpserverhost"=>"$ mailServerHost","इस पते से"=>"$ mailFrom");

आउट = OPCODE mail_sender json% mailreq

ऊपर दिया गया कोड हमारे अनुरोध पैरामीटर को mailreq चर में सेट करता है और mail_sender फ़ंक्शन (OPCODE) को कॉल करता है। हम देखेंगे कि इस opcode को कैसे निष्पादित किया जाता है और वास्तव में RCE कहां होता है:

# ईमेल 0 = mail_with_var, 1 = mail_forward, 2 = mail_attachment
$ Mailaction = $ अनुरोध->{Mailaction};
$ विषय = $ अनुरोध->{विषय};
$ Mailbody = '';
$ Attachmentfile = $ अनुरोध->{अनुलग्नक फ़ाइल};
$ ToEmail $ अनुरोध =->{ईमेल करना};

# देह
अगर("$ अनुरोध को परिभाषित किया->{} Mailbody && '' ने $ विनती की->{} Mailbody") {
$ Mailbody = $ अनुरोध->{Mailbody};
}
#SMTP सर्वर होस्ट
अगर("$ अनुरोध को परिभाषित किया->{} Smtpserverhost && '' ने $ विनती की->{} Smtpserverhost") {
$ Smtpserverhost = $ अनुरोध->{Smtpserverhost};
}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'MailServer'"
अगर("$ परिणाम को परिभाषित किया->{} उत्पादन->{} Servicevalue [0] && '' ने $ रिजल्ट->{} उत्पादन->{} Servicevalue [0]") {
$ Smtpserverhost = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}अन्य{
$ Smtpserverhost ="127.0.0.1";
}
}

#SMTP सर्वर पोर्ट
अगर("$ अनुरोध को परिभाषित किया->{} Smtpserverport && '' ने $ विनती की->{} Smtpserverport") {
$ Smtpserverport = $ अनुरोध->{Smtpserverport};
}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'MailServerPort'"
अगर("$ परिणाम को परिभाषित किया->{} उत्पादन->{} Servicevalue [0] && '' ने $ रिजल्ट->{} उत्पादन->{} Servicevalue [0]") {
$ Smtpserverport = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}अन्य{
$ Smtpserverport ="25";
}
}

#SMTP को ध्वज
$ Smtpauthflag ="0";
अगर("$ अनुरोध को परिभाषित किया->{} Smtpauthflag && '' ने $ विनती की->{} Smtpauthflag") {
$ Smtpauthflag = $ अनुरोध->{Smtpauthflag};
}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'SMTPAuthenticationFlag'"
अगर("$ परिणाम को परिभाषित किया->{} उत्पादन->{} Servicevalue [0] && '' ने $ रिजल्ट->{} उत्पादन->{} Servicevalue [0]") {
$ Smtpauthflag = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}
}

अगर("$ smtpauthflag == १") {
अगर("$ अनुरोध को परिभाषित किया->{} Mailusername && '' ने $ विनती की->{} Mailusername") {

$ Mailusername = $ अनुरोध->{Mailusername};
$ Mailpassword = $ अनुरोध->{Mailpassword};

}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'MailServerUsername'"
$ mailusername = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'MailServerPassword'"
$ mailpassword = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}
}अन्य{

$ mailusername = "";
$ mailpassword = "";

}
अगर("$ अनुरोध को परिभाषित किया->{इस पते से} && '' ने $ विनती की->{इस पते से}") {
$ FROMADDRESS = $ अनुरोध->{इस पते से};
}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'FromAddress'"
$ अधिपति = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}

#सुरक्षा मोड
अगर("$ अनुरोध को परिभाषित किया->{} Smtpsecurity && '' ने $ विनती की->{} Smtpsecurity") {
$ Smtpsecurity = $ अनुरोध->{Smtpsecurity};
}अन्य{
परिणाम = QUERY "tblclientservices से सेवा का चयन करें जहाँ servicekey = 'smtpsecurity'"
$ smtpsecurity = $ परिणाम->{} उत्पादन->{} Servicevalue [0];
}

$ Smtpsecuritymode = 0;
अगर("$ smtpsecurity eq 'STARTTLS'") {
$ Smtpsecuritymode = 1;
} ELSE IF ("$ smtpsecurity eq 'SSL / TLS'") {
$ Smtpsecuritymode = 2;
}

#SMTP प्रमाण पत्र

$ smtpcert सर्टिफिकेट = '';
$ Certpassword = '';

अगर("$ Smtpsecuritymode! = 0") {
अगर("$ अनुरोध को परिभाषित किया->{} Smtpcertificate && '' ने $ विनती की->{} Smtpcertificate") {
परिणाम = QUERY "सर्टिफिकेट, tblvpncert सर्टिफिकेट से पासवर्ड चुनें जहाँ सर्टिफिकेट = $ अनुरोध->{} Smtpcertificate"
}अन्य{
परिणाम = QUERY "सर्टिफिकेट चुनें, tblvpncert सर्टिफिकेट से पासवर्ड जहाँ सर्टिफ़िकेट = (सिलेक्ट सर्विसव्यू :: int से tblclientservices जहाँ सर्विसि = 'smtpcert सर्टिफ़िकेट')"
}

$ smtpcert सर्टिफिकेट = $ परिणाम->{} उत्पादन->{} Certname [0];
$ Certpassword = $ परिणाम->{} उत्पादन->{} पासवर्ड [0];

}

नाम के साथ # पता
अगर("$ अनुरोध को परिभाषित किया->{} Fromaddresswithname && '' ने $ विनती की->{} Fromaddresswithname") {
$ Fromaddresswithname = $ अनुरोध->{Fromaddresswithname};
}अन्य{
$ fromaddresswithname = $ OEMNAME . " <" . $ FROMADDRESS . ">";
}

ऊपर वाला कोड वही काम करता है जो दूसरे ओपकोड ने शुरू किया था। यह चरों को आरंभ करता है (यदि निर्दिष्ट नहीं है तो हमसे या डिवाइस से कुछ).

चर असाइन किए जाने के बाद, निम्न कोड ब्लॉक निष्पादित किया जाता है.

out = EXECSH "/ बिन / cschelper mail_send '$ fromaddress' '$ fromaddresswithname' '$ toadmail' '$ toEmail' '$ विषय' '$ mailbody' '$ smtpserverhost' '$ smtpserverport' '$ mailusername' '$ mailpassword' '$ mailaction' $ smtpsecuritymode '' $ smtpcert सर्टिफिकेट '' $ certpassword '' 1 '' '' $ ''"

और वहाँ यह है, कमांड निष्पादन। अब यहाँ कॉल EXECSH है जो कॉल / बिन / sh -c “ARGUMENTS” करता है। हमारे द्वारा नियंत्रित मूल्यों का उपयोग करते हुए निष्पादन के साथ, हम आसानी से दूरस्थ कमांड निष्पादन प्राप्त कर सकते हैं, सभी प्रमाणीकरण के बिना.

हम कुछ महीनों में एक पूरी रिपोर्ट और प्रूफ ऑफ कॉन्सेप्ट जारी करेंगे.

अपडेट करें: यह शोध पहले TechCrunch पर कवर किया गया था, यहां और पढ़ें.

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