CVE-2019-17059: Preauth-RCE a Sophos Cyberoam magyarázatában

Keményen dolgoztunk itt a TheBestVPN belső és külső biztonsági kutatóival, hogy felfedezzük az SSL VPN-ek és a tűzfalak, például a Cyberoam, a Fortigate és a Cisco VPN-k komoly, távolról kihasználható kiskapuit. Ez a cikk a Cyberoam SSL VPN-t (más néven CyberoamOS néven ismert) tapasztalt kritikus biztonsági rés technikai ismertetését tartalmazza..


Ez a Cyberoam kizsákmányolás, más néven CVE-2019-17059, egy kritikus biztonsági rés, amely lehetővé teszi a támadók számára, hogy felhasználónév vagy jelszó megadása nélkül hozzáférjenek a Cyberoam eszközéhez. Ráadásul a megadott hozzáférés a legmagasabb szintű (root), amely lényegében korlátlan jogokat biztosít a támadónak a Cyberoam eszközön.

A legtöbb hálózati környezetben a Cyberoam eszközöket tűzfalakként és SSL VPN átjárókként használják. Ez egy potenciális támadónak erős lábát biztosítja a hálózatban. Megkönnyíti a házigazdák megtámadását a hálózaton belül, és mivel a Cyberoam eszközöket általában a legtöbb környezetben megbíznak, ez a potenciális támadó számára további élést biztosít.

Shodan (az internethez csatlakoztatott eszközök keresője) szerint több mint 96 000 internetes oldalú Cyberoam eszköz van a világ minden tájáról. Ezen eszközök nagy részét vállalkozásokba, egyetemekbe és néhányat a világhírű bankokba telepítik. Ez ahhoz vezet, hogy a támadások óriási hatással vannak ezekre a környezetre.

Nagyon nagy öröm volt a Sophos biztonsági csoporttal való együttműködés, mivel gyorsan cselekedtek azzal, hogy a javításokat elismerik és bevezetik, csak néhány nappal azután, hogy kezdeti jelentést tettünk nekik. Kudos nekik! (Szójáték szándékolt!)

a Cyberoam észlelése

Mivel ezeknek az entitásoknak a többsége vonzó célpont a támadók számára, mindezt a hibákat ennél kritikusabbá teszi.

CyberoamOS távoli hitelesítetlen gyökérparancs-végrehajtás

A CyberoamOS egy módosított Linux-alapú operációs rendszer a Cyberoam eszközökhöz. Ez az operációs rendszer rendelkezik web alapú konfigurációs felülettel és SSLVPN portállal.

A webes felület két fő részre oszlik:

  • Java nyelven írt előlap
  • Olyan háttér, amely a C és a Perl kombinációját használja

Nem merülünk mélyen a front- vagy a back-end kód belsejébe, főleg az időmegtakarítás és a feltárt információk mennyiségének korlátozása érdekében. De röviden megvitatjuk, hogy miként indul el a hiba.

Mind a konfigurációs, mind az SSLVPN interfészeknek van egy szervlet, amely kezeli a fő műveleteket. Ezeket a műveleteket a „mode” elnevezésű paraméter határozza meg..

Ezek többsége hitelesített. Van azonban néhány olyan lehetőség, amelyhez hitelesítés nélkül hozzáférhetünk (például bejelentkezés).

A talált hibákat az e-mail víruskereső / antispam modulban találjuk. A végpont (modul, op) kérési módja 458.

Meg kell jegyezni, hogy az opódok a nevükre vannak leképezve a Cyberoam adatbázisban (Postgres belső adatbázis). A 458-as nézegetéssel megtudhatjuk, mi a neve ennek az opódnak.

Íme egy sor az adatbázis inicializáló SQL szkriptből, amely az opcode 458 nevet mutatja:

beillesztés a tblcrevent-be (opód, leírás, mód, igényesttípus)
értékek ('RELEASEQUARANTINEMAILFROMMAIL', 'KATALÓGUSKÖNYV KISZERELÉSE POSTABÓL', '458', 2);

Az opcode funkciókat a / _conf / csc / cscconf / könyvtár tárolja. Nem fogjuk nyilvánosságra hozni a sebezhető funkció teljes kódját, de néhány kivonatot adunk meg, amelyek megmutatják, hol és hogyan fordul elő a hiba.

A Java felhasználói felületének egy kódja, amely kezeli a 458 kódot:

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 állandó érték " +
CSCConstants.isCCC);

Ahogy fent láthatja, néhány paraméter érvényességét ellenőrzik. Ha érvényes értékek, akkor a következő történik:

final EventBean eventByMode = EventBean.getEventByMode (363);
... eltakarni.
final int sendWizardEvent = cscClient.sendWizardEvent (eventByMode, hashMap, sqlReader);

Mint fentebb láthatjuk, van egy új eseménykódunk (363), amelyet elküldünk a háttérképnek. A felfedezett hibát abban a kódban találjuk, amely ezt kezeli a háttérprogramban.

Az opcode sendmail elnevezésű, és a hiba kihasználásának elkerülése érdekében a kód nagy részét a következő kódból szerkesztjük..

A send_mail opkódkezelője.

...eltakarni ...

$ param = $ kérés->{kiadás};
param = DLOPEN (base64_decode, param)
LOG applog " Dekódolási értékek :: $ param \ n"
% requestData = split (/ [&=] /, $ param);
$ mailServerHost = $ requestData {hdnDestDomain};
$ mailFrom = $ requestData {hdnSender};
$ mailTo = $ requestData {hdnRecipient};
$ fájl = $ QUARANTINE_PATH."/".$ RequestData {hdnFilePath};

$ Mailfile = $ requestData {hdnFilePath};
$ Validate_email ="hamis";
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 / && ((definiált $ requestData {hdnSender} && $ requestData {hdnSender} eq '') || $ requestData {hdnSender} = ~ / $ email_regex /) && index ($ requestData {hdnFilePath}, '.. /') == -1) {
$ Validate_email ="igaz";
}
.... eltakarni....

Mint fentebb láthatjuk, az ál-Perl-kód megmutatja, hogyan fogadja a háttér a bemenetet a kezelőfelületről ($ requestData), és hogyan próbál ellenőrizni az általunk küldött paramétereket.

Az ellenőrzés után, ha paramétereink érvényesek, a következő kód kerül végrehajtásra:

% Mailreq = ("mailaction"=>"$ MAIL_FORWARD","tantárgy"=>"$ strSubject","ímélezni"=>"$ mailto","csatolt állomány"=>"$ file","smtpserverhost"=>"$ mailServerHost","FROMADDRESS"=>"$ mailFrom");

out = OPCODE mail_sender json% mailreq

A fenti kód a kérési paramétereket mailreq változóba állítja és meghívja a mail_sender függvényt (OPCODE). Látni fogjuk, hogyan hajtják végre ezt az opódot, és hol történik pontosan az RCE:

# levél 0 = mail_with_var, 1 = mail_forward, 2 = mail_attachment
$ Mailaction = $ kérés->{Mailaction};
$ Subject = $ kérés->{tantárgy};
$ Mailbody = '';
$ Attachmentfile = $ kérés->{csatolt állomány};
$ ToEmail = $ kérés->{ímélezni};

# mail test
HA("meghatározott $ kérés->{Mailbody} && '' ne $ kérés->{Mailbody}") {
$ Mailbody = $ kérés->{Mailbody};
}
#SMTP szerver gazdagép
HA("meghatározott $ kérés->{Smtpserverhost} && '' ne $ kérés->{Smtpserverhost}") {
$ Smtpserverhost = $ kérés->{Smtpserverhost};
}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'MailServer'"
HA("meghatározott $ eredmény->{Kimenet}->{Servicevalue} [0] && '' nem $ eredmény->{Kimenet}->{Servicevalue} [0]") {
$ Smtpserverhost = $ result->{Kimenet}->{Servicevalue} [0];
}MÁS{
$ Smtpserverhost ="127.0.0.1";
}
}

#SMTP szerver port
HA("meghatározott $ kérés->{SMTPServerPort} && '' ne $ kérés->{SMTPServerPort}") {
$ SMTPServerPort = $ kérés->{SMTPServerPort};
}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'MailServerPort'"
HA("meghatározott $ eredmény->{Kimenet}->{Servicevalue} [0] && '' nem $ eredmény->{Kimenet}->{Servicevalue} [0]") {
$ SMTPServerPort = $ result->{Kimenet}->{Servicevalue} [0];
}MÁS{
$ SMTPServerPort ="25";
}
}

#SMTP auth zászló
$ Smtpauthflag ="0";
HA("meghatározott $ kérés->{Smtpauthflag} && '' ne $ kérés->{Smtpauthflag}") {
$ Smtpauthflag = $ kérés->{Smtpauthflag};
}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'SMTPAuthenticationFlag'"
HA("meghatározott $ eredmény->{Kimenet}->{Servicevalue} [0] && '' nem $ eredmény->{Kimenet}->{Servicevalue} [0]") {
$ Smtpauthflag = $ result->{Kimenet}->{Servicevalue} [0];
}
}

HA("$ smtpauthflag == 1") {
HA("meghatározott $ kérés->{Mailusername} && '' ne $ kérés->{Mailusername}") {

$ Mailusername = $ kérés->{Mailusername};
$ Mailpassword = $ kérés->{Mailpassword};

}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'MailServerUsername'"
$ mailusername = $ eredmény->{Kimenet}->{Servicevalue} [0];
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'MailServerPassword'"
$ mailpassword = $ eredmény->{Kimenet}->{Servicevalue} [0];
}
}MÁS{

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

}
HA("meghatározott $ kérés->{FROMADDRESS} && '' ne $ kérés->{FROMADDRESS}") {
$ FROMADDRESS = $ kérés->{FROMADDRESS};
}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'FromAddress'"
$ fromaddress = $ eredmény->{Kimenet}->{Servicevalue} [0];
}

#Biztonsági mód
HA("meghatározott $ kérés->{Smtpsecurity} && '' ne $ kérés->{Smtpsecurity}") {
$ Smtpsecurity = $ kérés->{Smtpsecurity};
}MÁS{
eredmény = QUERY "válasszon szolgáltatási értéket a tblclientservices szolgáltatásból, ahol servicekey = 'smtpsecurity'"
$ smtpsecurity = $ eredmény->{Kimenet}->{Servicevalue} [0];
}

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

#SMTP tanúsítvány

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

HA("$ Smtpsecuritymode! = 0") {
HA("meghatározott $ kérés->{Smtpcertificate} && '' ne $ kérés->{Smtpcertificate}") {
eredmény = QUERY "válassza ki a certname, jelszót a tblvpncertificate közül, ahol certid = $ kérés->{Smtpcertificate}"
}MÁS{
eredmény = QUERY "válassza ki a certname-t, a jelszót a tblvpncertificate közül, ahol certid = (válassza a servicevalue :: int tblclientservices-ből, ahol servicekey = 'smtpcertificate')"
}

$ smtpcertificate = $ eredmény->{Kimenet}->{Certname} [0];
$ Certpassword = $ result->{Kimenet}->{Jelszó} [0];

}

#A cím névvel
HA("meghatározott $ kérés->{Fromaddresswithname} && '' ne $ kérés->{Fromaddresswithname}") {
$ Fromaddresswithname = $ kérés->{Fromaddresswithname};
}MÁS{
$ fromaddresswithname = $ OEMNAME . " <" . $ FROMADDRESS . ">";
}

A fenti kód ugyanazt teszi, mint a másik opód, amikor elindult. Inicializálja a változókat (néhány bennünket vagy az eszköztől, ha nincs megadva).

A változók hozzárendelése után a következő kódblokk kerül végrehajtásra.

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

És ott van, a parancs végrehajtása. Most az EXECSH hívás érkezik, amely a / bin / sh -c “ARGUMENTS” hívására szólít fel. Amikor a végrehajtás az általunk ellenőrzött értékekkel történik, könnyen elérhetjük a távoli parancsfuttatást, mindezt hitelesítés nélkül.

Néhány hónapon belül kiadunk egy teljes jelentést és a koncepció igazolását, megfelelő körvonalakkal.

frissítés: Ezt a kutatást először a TechCrunch-on fedezték fel, itt olvashat bővebben.

Brayan Jackson Administrator
Candidate of Science in Informatics. VPN Configuration Wizard. Has been using the VPN for 5 years. Works as a specialist in a company setting up the Internet.
follow me