CVE-2019-17059: Objašnjen Preauth-RCE u Sophosovom Cyberoamu

Uporno radimo s istraživačima unutarnje i vanjske sigurnosti ovdje na TheBestVPN-u kako bismo otkrili ozbiljne rupe u daljini koje se mogu iskoristiti u SSL VPN-ovima i vatrozidima poput Cyberoam, Fortigate i Cisco VPN-ova. Ovaj je članak tehnički korak prema zakrpanoj kritičnoj ranjivosti koja utječe na Cyberoam SSL VPN također poznat kao CyberoamOS.


Ovaj Cyberoam iskorištavanje, nazvan CVE-2019-17059, kritična je ranjivost koja omogućuje napadačima pristup vašem Cyberoam uređaju bez davanja korisničkog imena ili lozinke. Povrh svega, odobreni pristup je najviša razina (root), što u osnovi pruža napadaču neograničena prava na vašem Cyberoam uređaju.

U većini mrežnih okruženja Cyberoam uređaji koriste se kao firewall i SSL VPN gateway. To potencijalnom napadaču pruža čvrsto uporište u mreži. Olakšava napad na domaćine unutar mreže, a budući da se Cyberoam uređajima obično vjeruje u većini okruženja, to daje dodatnu prednost potencijalnom napadaču.

Prema Shodanu (tražilici za uređaje koji su povezani s internetom) postoji više od 96.000 internetskih Cyberoam uređaja sa svih strana svijeta. Većina ovih uređaja instalirana je u poduzećima, sveučilištima, a neki u svjetski poznatim bankama. To dovodi do napada koji imaju ogroman utjecaj na ta okruženja.

Rad sa Sophosovim timom za sigurnost bio je veliko zadovoljstvo jer su brzo reagirali priznajući i razvrstavajući zakrpe samo nekoliko dana nakon našeg početnog izvještaja o njima. Kudos im! (Dosjetka-namjera!)

otkrivajući Cyberoam

A budući da je većina ovih entiteta atraktivna meta napadačima, to čini bube sve kritičnijim.

CyberoamOS daljinsko neovlašteno izvršavanje korijenske naredbe

CyberoamOS je modificirani Linux operativni sustav za Cyberoam uređaje. Ovaj OS ima internetsko konfiguracijsko sučelje i SSLVPN portal.

Web sučelje podijeljeno je u dva glavna dijela:

  • Prednja strana napisana na Javi
  • Potpora koja koristi kombinaciju C i Perl

Nećemo zaroniti duboko u unutarnji ili prednji kôd, uglavnom radi uštede vremena i ograničavanja količine otkrivenih informacija. Ali ukratko ćemo raspraviti kako se bug aktivira.

I konfiguracijsko i SSLVPN sučelje imaju servlet koji upravlja glavnim operacijama. Te se operacije definiraju korištenjem parametra nazvanog "način rada".

Većina njih je ovjerena. Ali postoji nekoliko mogućnosti kojima možemo pristupiti bez autentifikacije (poput prijave).

Pronađene pogreške su u antivirusnom / antispam modulu e-pošte. Način zahtjeva za ovu krajnju točku (modul, op) je 458.

Jedna stvar koju treba napomenuti je da su kodi preslikani na njihova imena u Cyberoam bazi (interna baza podataka Postgres). Pretražujući 458, možemo saznati kako se zove taj opcode.

Slijedi redak iz SQL skripte za inicijalizaciju baze podataka koji prikazuje naziv opcode 458:

umetnite u tblcrevent (opcode, opis, mode, type type)
vrijednosti ('RELEASEQUARANTINEMAILFROMMAIL', 'RELEASE QUARANTINE MAIL OF MAIL', '458', 2);

Opkodne funkcije pohranjuju se u imenik / _conf / csc / cscconf /. Nećemo otkriti cijeli kod ranjive funkcije, ali pružit ćemo nekoliko isječaka koji prikazuju gdje i kako se bug događa.

Kôd s pročelja Java koji obrađuje opcode 458:

ako ((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 konstantna vrijednost " +
CSCConstants.isCCC);

Kao što vidite gore, nekoliko parametara provjerava se na valjanost. Ako su valjane vrijednosti, događa se sljedeće:

final EventBean eventByMode = EventBean.getEventByMode (363);
... mijenjaju se.
konačni int sendWizardEvent = cscClient.sendWizardEvent (eventByMode, hashMap, sqlReader);

Kao što vidimo gore, imamo novi kod događaja (363) koji će biti poslan nadoknadi. Bug koji smo otkrili nalazi se u kodu koji to rješava u pozadini.

Opcode je nazvan sendmail, a da bismo izbjegli iskorištavanje ove pogreške, mi ćemo većinu koda redigovati iz sljedećeg koda.

Alat za obradu kodova za send_mail.

...mijenjaju se ...

$ param = $ zahtjev->{Oslobađanje};
param = DLOPEN (base64_decode, param)
LOG applog " Vrijednosti dekodiranja: $ param \ n"
% zahtjevData = podijeljen (/ [&=] /, $ param);
$ mailServerHost = $ requestData {hdnDestDomain};
$ mailFrom = $ requestData {hdnSender};
$ mailTo = $ requestData {hdnRecipient};
$ file = $ QUARANTINE_PATH."/".$ {RequestData hdnFilePath};

$ Mailfile = $ {requestData hdnFilePath};
$ Validate_email ="lažan";
moj $ 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 / && ((definirano $ requestData {hdnSender} && $ zahtjevData {hdnSender} eq '') || $ zahtjevData {hdnSender} = ~ / $ email_regex /) && indeks ($ requestData {hdnFilePath}, '.. /') == -1) {
$ Validate_email ="pravi";
}
.... mijenjaju se....

Kao što vidimo gore, pseudo-Perl kod pokazuje nam kako pozadina prima ulaz iz frontenda ($ requestData) i kako pokušava provjeriti neke parametre koje šaljemo.

Nakon provjere, ako su naši parametri važeći, izvršava se sljedeći kod:

% Mailreq = ("mailaction"=>"$ MAIL_FORWARD","predmet"=>"$ strSubject","toEmail"=>"$ mailto","attachmentfile"=>"$ datoteka","smtpserverhost"=>"$ mailServerHost","FROMADDRESS trenutačno"=>"$ mailFrom");

out = OPCODE mail_sender json% mailreq

Gornji kôd postavlja naše parametre zahtjeva u varijablu mailreq i poziva funkciju mail_sender (OPCODE). Vidjet ćemo kako se izvršava taj opcode i gdje se točno događa RCE:

#mailaction 0 = mail_with_var, 1 = mail_naprijed, 2 = mail_attachment
$ Mailaction = $ zahtjev->{Mailaction};
$ Predmet = $ zahtjev->{Subjekt};
$ Mailbody = '';
$ Attachmentfile = $ zahtjev->{Attachmentfile};
$ ToEmail = $ zahtjev->{ToEmail};

#mail tijelo
AKO("definirani $ zahtjev->{Mailbody} && '' ne $ zahtjev->{Mailbody}") {
$ Mailbody = $ zahtjev->{Mailbody};
}
#SMTP poslužitelj
AKO("definirani $ zahtjev->{Smtpserverhost} && '' ne $ zahtjev->{Smtpserverhost}") {
$ Smtpserverhost = $ zahtjev->{Smtpserverhost};
}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz usluge tblclientservices gdje je servicekey = 'MailServer'"
AKO("definirani $ rezultat->{izlaz}->{Servicevalue} [0] && '' ne $ rezultat->{izlaz}->{Servicevalue} [0]") {
$ Smtpserverhost = $ rezultat->{izlaz}->{Servicevalue} [0];
}DRUGO{
$ Smtpserverhost ="127.0.0.1";
}
}

#SMTP port poslužitelja
AKO("definirani $ zahtjev->{Smtpserverport} && '' ne $ zahtjev->{Smtpserverport}") {
$ Smtpserverport = $ zahtjev->{Smtpserverport};
}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz tblclientservices gdje je servicekey = 'MailServerPort'"
AKO("definirani $ rezultat->{izlaz}->{Servicevalue} [0] && '' ne $ rezultat->{izlaz}->{Servicevalue} [0]") {
$ Smtpserverport = $ rezultat->{izlaz}->{Servicevalue} [0];
}DRUGO{
$ Smtpserverport ="25";
}
}

#SMTP auth zastava
$ Smtpauthflag ="0";
AKO("definirani $ zahtjev->{Smtpauthflag} && '' ne $ zahtjev->{Smtpauthflag}") {
$ Smtpauthflag = $ zahtjev->{Smtpauthflag};
}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz tblclientservices gdje jekeykey = 'SMTPAuthenticationFlag'"
AKO("definirani $ rezultat->{izlaz}->{Servicevalue} [0] && '' ne $ rezultat->{izlaz}->{Servicevalue} [0]") {
$ Smtpauthflag = $ rezultat->{izlaz}->{Servicevalue} [0];
}
}

AKO("$ smtpauthflag == 1") {
AKO("definirani $ zahtjev->{Mailusername} && '' ne $ zahtjev->{Mailusername}") {

$ Mailusername = $ zahtjev->{Mailusername};
$ Mailpassword = $ zahtjev->{Mailpassword};

}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz tblclientservices gdje je servicekey = 'MailServerUsername'"
$ mailusername = $ rezultat->{izlaz}->{Servicevalue} [0];
rezultat = QUERY "odaberite servisnu vrijednost iz tblclientservices gdje je servicekey = 'MailServerPassword'"
$ mailpassword = $ rezultat->{izlaz}->{Servicevalue} [0];
}
}DRUGO{

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

}
AKO("definirani $ zahtjev->{FROMADDRESS trenutačno} && '' ne $ zahtjev->{FROMADDRESS trenutačno}") {
$ FROMADDRESS trenutačno = $ zahtjev->{FROMADDRESS trenutačno};
}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz tblclientservices gdje je servicekey = 'FromAddress'"
$ fromaddress = $ rezultat->{izlaz}->{Servicevalue} [0];
}

# Sigurnosni način
AKO("definirani $ zahtjev->{Smtpsecurity} && '' ne $ zahtjev->{Smtpsecurity}") {
$ Smtpsecurity = $ zahtjev->{Smtpsecurity};
}DRUGO{
rezultat = QUERY "odaberite servisnu vrijednost iz usluge tblclientservices gdje je servicekey = 'smtpsecurity'"
$ smtpsecurity = $ rezultat->{izlaz}->{Servicevalue} [0];
}

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

#SMTP potvrda

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

AKO("$ Smtpsecuritymode! = 0") {
AKO("definirani $ zahtjev->{Smtpcertificate} && '' ne $ zahtjev->{Smtpcertificate}") {
rezultat = QUERY "odaberite certname, lozinku iz tblvpncertificate gdje certid = $ zahtjev->{Smtpcertificate}"
}DRUGO{
rezultat = QUERY "odaberite certname, lozinku iz tblvpncertificate gdje certid = (odaberite servicevalue :: int iz tblclientservices gdje jekeykey = 'smtpcertificate')"
}

$ smtpcertificate = $ rezultat->{izlaz}->{Certname} [0];
$ Certpassword = $ rezultat->{izlaz}->{Zaporka} [0];

}

# Iz adrese s imenom
AKO("definirani $ zahtjev->{Fromaddresswithname} && '' ne $ zahtjev->{Fromaddresswithname}") {
$ Fromaddresswithname = $ zahtjev->{Fromaddresswithname};
}DRUGO{
$ fromaddresswithname = $ OEMNAME . " <" . $ FROMADDRESS trenutačno . ">";
}

Gornji kod radi isto što je učinio i drugi opcode kada se pokrene. Pokreće varijable (neke od nas ili s uređaja ako nisu navedene).

Nakon dodjeljivanja varijabli, slijedi slijedeći blok koda.

vani = IZUZETI "/ bin / cschelper mail_send '$ fromadress' '$ fromaddresswithname' '$ toEmail' '$ toEmail' '$ subject' '$ mailbody' '$ smtpserverhost' '$ smtpserverport' '$ mailusername' '$ mailpassword' '$ mailaction' ' $ smtpsecuritymode '' $ smtpcertificate '' $ certpassword '' 1 '' $ attachmentfile '"

I tu je, izvršenje naredbe. Sada je poziv EXECSH koji poziva / bin / sh -c "ARGUMENTI". Kad se izvršavanje događa pomoću vrijednosti koje kontroliramo, lako možemo postići udaljeno izvršavanje naredbi, a sve bez autentifikacije.

Za nekoliko mjeseci objavit ćemo cjelovito izvješće i Dokaz koncepta s pravilnim crtama.

Ažuriraj: Ovo je istraživanje prvo pokriveno na TechCrunch-u, više o tome pročitajte ovdje.

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