CVE-2019-17059: Preauth-RCE Sophosin Cyberoam-palvelussa selitetty

Olemme työskennelleet ahkerasti sisäisten ja ulkoisten turvallisuustutkijoiden kanssa täällä TheBestVPN: ssä löytääksemme vakavia etäkäyttökelpoisia porsaanreikiä SSL VPN- ja palomuureissa, kuten Cyberoam, Fortigate ja Cisco VPN. Tämä artikkeli on tekninen kuvaus paikallaan olevasta kriittisestä haavoittuvuudesta, joka vaikuttaa Cyberoam SSL VPN: ään, joka tunnetaan myös nimellä CyberoamOS.


Tämä Cyberoam-hyväksikäyttö, nimeltään CVE-2019-17059, on kriittinen haavoittuvuus, jonka avulla hyökkääjät voivat käyttää Cyberoam-laitettasi antamatta käyttäjänimeä tai salasanaa. Lisäksi myönnetty käyttöoikeus on korkein taso (root), joka antaa hyökkääjälle käytännössä rajoittamattomat oikeudet Cyberoam-laitteellasi.

Useimmissa verkkoympäristöissä Cyberoam-laitteita käytetään palomuureina ja SSL VPN -yhdyskäytävinä. Tämä antaa potentiaaliselle hyökkääjälle vahvan jalansijan verkossa. Se helpottaa isäntien hyökkäystä verkon sisällä, ja koska Cyberoam-laitteisiin yleensä luotetaan useimmissa ympäristöissä, tämä antaa mahdolliselle hyökkääjälle lisäreunan..

Shodanin (Internet-yhteyteen kytkettyjen laitteiden hakukone) mukaan kaikkialta maailmasta löytyy yli 96 000 Internet-verkkoon päin olevaa Cyberoam-laitetta. Suurin osa näistä laitteista on asennettu yrityksiin, yliopistoihin ja osa maailmankuuluihin pankkeihin. Tämä johtaa hyökkäyksiin, joilla on valtavia vaikutuksia näihin ympäristöihin.

Yhteistyö Sophos-turvallisuusryhmän kanssa on ollut suuri ilahdutus, koska he toimivat nopeasti tunnustamalla ja ottamalla käyttöön korjauksia vain muutaman päivän kuluttua alkuperäisestä raportista heille. Kudos heille! (tarkoituksellinen sanaleikki!)

havaita Cyberoam

Ja koska suurin osa näistä yksiköistä on houkuttelevia kohteita hyökkääjille, se tekee viruksista kaiken kriittisemmän.

CyberoamOS: n etätodentamattomat juurikomentojen suoritukset

CyberoamOS on muunnettu Linux-pohjainen käyttöjärjestelmä Cyberoam-laitteille. Tässä käyttöjärjestelmässä on verkkopohjainen määritysrajapinta ja SSLVPN-portaali.

Verkkokäyttöliittymä on jaettu kahteen pääosaan:

  • Java-kirjoitettu etusivu
  • Taustaohjelma, joka käyttää C: n ja Perlin yhdistelmää

Emme sukella syvälle etu- tai taustakoodin sisäosiin lähinnä säästääksemme aikaa ja rajoittaaksemme paljastetun tiedon määrää. Mutta keskustelemme lyhyesti siitä, kuinka virhe ilmenee.

Sekä konfiguraatiossa että SSLVPN-rajapinnoissa on servletti, joka käsittelee päätoiminnot. Nämä toiminnot määritetään parametrilla nimeltä “mode”.

Suurin osa näistä on todennettu. Mutta on olemassa muutamia oppeja, joihin pääsemme ilman todennusta (kuten sisäänkirjautumista).

Löytämämme virheet ovat sähköpostin virustentorjunta / roskapostin torjuntamoduuli. Tämän päätepisteen (moduuli, op) pyyntötila on 458.

Yksi huomionarvoista on se, että opoodit on kartoitettu niiden nimiin Cyberoam-tietokannassa (sisäinen Postgres-tietokanta). Etsimällä 458 voimme saada selville, mikä tämän opoodin nimi on.

Tässä on rivi tietokannan alustus SQL-skriptistä, joka näyttää nimen opcode 458:

insert to tblcrevent (opkoodi, kuvaus, tila, vaatimustyyppi)
arvot ('RELEASEQUARANTINEMAILFROMMAIL', 'RELEASE QUARANTINE MAIL FROM POSTI', '458', 2);

Optokooditoiminnot tallennetaan hakemistoon / _conf / csc / cscconf /. Emme paljasta haavoittuvan toiminnon koko koodia, mutta tarjoamme muutaman katkelman, joka osoittaa missä ja miten virhe ilmenee.

Java-käyttöliittymän koodi, joka käsittelee opoodia 458:

if ((jsonObject.getString ("hdnSender") .Equals ("") ||
validateEmail (jsonObject.getString ("hdnSender"))) &&
validateEmail (jsonObject.getString ("hdnRecipient")) &&
isSafeFilePath (jsonObject.getString ("hdnFilePath")) && b) {
httpServletResponse.setContentType ("text / html");
CyberoamLogger.debug ("Antivirus / AntiSpam", "CSC-vakioarvo " +
CSCConstants.isCCC);

Kuten yllä näet, muutama parametri tarkistetaan kelvollisuudesta. Jos ne ovat kelvollisia arvoja, tapahtuu seuraava:

lopullinen EventBean eventByMode = EventBean.getEventByMode (363);
... redacted.
lopullinen int sendWizardEvent = cscClient.sendWizardEvent (eventByMode, hashMap, sqlReader);

Kuten yllä näemme, meillä on uusi tapahtumakoodi (363), joka lähetetään taustalle. Löytämämme vika on koodissa, joka käsittelee tämän taustalla.

Opoodin nimi on sendmail, ja tämän virheen hyväksikäytön välttämiseksi muokkaamme suurimman osan koodista seuraavasta koodista.

Send_mail -koodin käsittelijä.

...redacted ...

$ param = $ pyyntö->{Julkaisu};
param = DLOPEN (base64_decode, param)
LOG-sovellusloki " Dekooda arvot :: $ param \ n"
% requestData = split (/ [&=] /, $ param);
$ mailServerHost = $ requestData {hdnDestDomain};
$ mailFrom = $ requestData {hdnSender};
$ mailTo = $ requestData {hdnRecipient};
$ tiedosto = $ QUARANTINE_PATH."/".$ RequestData {hdnFilePath};

$ Mailfile = $ requestData {hdnFilePath};
$ Validate_email ="väärä";
my $ email_regex = '^ ([\.]? [_ \ - \! \ # \ {\} \ $ \% \ ^ \&\ * \ + \ = \ | \? \ '\\\\\\ / a-ZA-Z0-9]) * @ ([a-ZA-Z0-9] ([-]? [A-zA- Z0-9] +) * \.) + ([a-zA-Z0-9] {0,6}) $ ";
if ($ requestData {hdnRecipient} = ~ / $ email_regex / && ((määritelty $ requestData {hdnSender} && $ requestData {hdnSender} eq '') || $ requestData {hdnSender} = ~ / $ email_regex /) && hakemisto ($ requestData {hdnFilePath}, '.. /') == -1) {
$ Validate_email ="totta";
}
.... redacted....

Kuten yllä näemme, pseudo-Perl-koodi näyttää meille, kuinka taustaohjelma vastaanottaa tuloja käyttöliittymästä ($ requestData) ja kuinka se yrittää tarkistaa joitain lähettämistämme parametreista.

Varmennuksen jälkeen, jos parametrit ovat kelvollisia, seuraava koodi suoritetaan:

% Mailreq = ("mailaction"=>"$ MAIL_FORWARD","aihe"=>"$ strSubject","sähköpostiin"=>"$ mailto","attachmentfile"=>"$ tiedosto","smtpserverhost"=>"$ mailServerHost","FROMADDRESS"=>"$ mailFrom");

out = OPCODE mail_sender json% mailreq

Yllä oleva koodi asettaa pyyntöparametrit mailreq-muuttujaksi ja kutsuu mail_sender-toimintoa (OPCODE). Näemme kuinka tämä opkoodi suoritetaan ja missä RCE tarkalleen tapahtuu:

#postitus 0 = mail_with_var, 1 = mail_forward, 2 = mail_attachment
$ Mailaction = $ pyyntö->{Mailaction};
$ Subject = $ pyyntö->{Aihe};
$ Viestikenttä = '';
$ Attachmentfile = $ pyyntö->{Attachmentfile};
$ ToEmail = $ pyyntö->{sähköpostiin};

#posti elin
JOS("määritelty $ -pyyntö->{Viestikenttä} && '' ei $ -pyyntö->{Viestikenttä}") {
$ Viestikenttä = $ pyyntö->{Viestikenttä};
}
#SMTP-palvelimen isäntä
JOS("määritelty $ -pyyntö->{Smtpserverhost} && '' ei $ -pyyntö->{Smtpserverhost}") {
$ Smtpserverhost = $ pyyntö->{Smtpserverhost};
} ELSE {
tulos = QUERY "valitse palvelun arvo tblclientservices -kohdasta, jossa servicekey = 'MailServer'"
JOS("määritelty tulos $->{Ulostulo}->{Servicevalue} [0] && '' ei tulosta $->{Ulostulo}->{Servicevalue} [0]") {
$ Smtpserverhost = $ tulos->{Ulostulo}->{Servicevalue} [0];
} ELSE {
$ Smtpserverhost ="127.0.0.1";
}
}

#SMTP-palvelimen portti
JOS("määritelty $ -pyyntö->{SMTPServerPort} && '' ei $ -pyyntö->{SMTPServerPort}") {
$ SMTPServerPort = $ pyyntö->{SMTPServerPort};
} ELSE {
tulos = QUERY "valitse palvelun arvo tblclientservices -kohdasta, jossa servicekey = 'MailServerPort'"
JOS("määritelty tulos $->{Ulostulo}->{Servicevalue} [0] && '' ei tulosta $->{Ulostulo}->{Servicevalue} [0]") {
$ SMTPServerPort = $ tulos->{Ulostulo}->{Servicevalue} [0];
} ELSE {
$ SMTPServerPort ="25";
}
}

#SMTP-todennuslippu
$ Smtpauthflag ="0";
JOS("määritelty $ -pyyntö->{Smtpauthflag} && '' ei $ -pyyntö->{Smtpauthflag}") {
$ Smtpauthflag = $ pyyntö->{Smtpauthflag};
} ELSE {
tulos = QUERY "valitse palvelun arvo tblclientservices -kohdasta, jossa servicekey = 'SMTPAuthenticationFlag'"
JOS("määritelty tulos $->{Ulostulo}->{Servicevalue} [0] && '' ei tulosta $->{Ulostulo}->{Servicevalue} [0]") {
$ Smtpauthflag = $ tulos->{Ulostulo}->{Servicevalue} [0];
}
}

JOS("$ smtpauthflag == 1") {
JOS("määritelty $ -pyyntö->{Mailusername} && '' ei $ -pyyntö->{Mailusername}") {

$ Mailusername = $ pyyntö->{Mailusername};
$ Mailpassword = $ pyyntö->{Mailpassword};

} ELSE {
tulos = QUERY "valitse palvelun arvo tblclientservices -kohdasta, jossa servicekey = 'MailServerUsername'"
$ mailusername = $ tulos->{Ulostulo}->{Servicevalue} [0];
tulos = QUERY "valitse palvelun arvo tblclientservices -kohdasta, jossa servicekey = 'MailServerPassword'"
$ mailpassword = $ tulos->{Ulostulo}->{Servicevalue} [0];
}
} ELSE {

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

}
JOS("määritelty $ -pyyntö->{FROMADDRESS} && '' ei $ -pyyntö->{FROMADDRESS}") {
$ FROMADDRESS = $ pyyntö->{FROMADDRESS};
} ELSE {
tulos = QUERY "valitse palveluarvo tblclientservices -kohdasta, jossa servicekey = 'FromAddress'"
$ osoitteesta = $ tulos->{Ulostulo}->{Servicevalue} [0];
}

#Suojaustila
JOS("määritelty $ -pyyntö->{Smtpsecurity} && '' ei $ -pyyntö->{Smtpsecurity}") {
$ Smtpsecurity = $ pyyntö->{Smtpsecurity};
} ELSE {
tulos = QUERY "valitse palvelun arvo tbl-asiakaspalveluista, joissa servicekey = 'smtpsecurity'"
$ smtpsecurity = $ tulos->{Ulostulo}->{Servicevalue} [0];
}

$ Smtpsecuritymode = 0;
JOS("$ smtpsecurity eq 'STARTTLS'") {
$ Smtpsecuritymode = 1;
}MUUTEN JOS("$ smtpsecurity eq 'SSL / TLS'") {
$ Smtpsecuritymode = 2;
}

#SMTP-varmenne

$ smtpcertificate = '';
$ Certpassword = '';

JOS("$ Smtpsecuritymode! = 0") {
JOS("määritelty $ -pyyntö->{Smtpcertificate} && '' ei $ -pyyntö->{Smtpcertificate}") {
tulos = QUERY "Valitse sertifikaatti, salasana tblvpncertificate-kohdasta, jossa certid = $ -pyyntö->{Smtpcertificate}"
} ELSE {
tulos = QUERY "Valitse sertifikaatti, salasana tblvpncertificate -kohdasta missä certid = (valitse servicevalue :: int tblclientservices -kohdasta, jossa servicekey = 'smtpcertificate')"
}

$ smtpcertificate = $ tulos->{Ulostulo}->{Certname} [0];
$ Certpassword = $ tulos->{Ulostulo}->{Salasana} [0];

}

#Osoitteesta nimellä
JOS("määritelty $ -pyyntö->{Fromaddresswithname} && '' ei $ -pyyntö->{Fromaddresswithname}") {
$ Fromaddresswithname = $ pyyntö->{Fromaddresswithname};
} ELSE {
$ fromaddresswithname = $ OEMNAME . " <" . $ FROMADDRESS . ">";
}

Yllä oleva koodi tekee samoin kuin toinen opoodi teki käynnistyessään. Se alustaa muuttujat (jotkut meiltä tai laitteelta, ellei niitä ole määritetty).

Kun muuttujat on osoitettu, seuraava koodilohko suoritetaan.

out = EXECSH "/ bin / cschelper mail_send '$ fromaddress' '$ fromaddresswithname' '$ toEmail' '$ toEmail' '$ subjekt' '$ mailbody' '$ smtpserverhost' '$ smtpserverport' '$ mailusername' '$ mailpassword' '$ mailaction' ' $ smtpsecuritymode '' $ smtpcertificate '' $ certpassword '' 1 '' $ mellékletfile '"

Ja siinä se on, komennon suorittaminen. Nyt puhelu on EXECSH, joka kutsuu / bin / sh -c “ARGUMENTS”. Kun suorittaminen tapahtuu hallitsemillamme arvoilla, voimme helposti saavuttaa etäkomentojen suorituksen, kaikki ilman todennusta.

Julkaisemme täydellisen raportin ja konseptin, jossa on asianmukaiset pääpiirteet muutaman kuukauden kuluessa.

Päivittää: Tämä tutkimus käsiteltiin ensin TechCrunchilla, lue lisää täältä.

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