CVE-2019-17059: Preauth-RCE v kyberoamu Sophos

Pracovali jsme tvrdě s interními a externími bezpečnostními vědci zde na TheBestVPN, abychom odhalili závažné vzdáleně využitelné mezery v SSL VPN a Firewallech, jako jsou Cyberoam, Fortigate a Cisco VPN. Tento článek je technickým návodem k opravené kritické chybě zabezpečení, která ovlivňuje Cyberoam SSL VPN známou také jako CyberoamOS..


Toto Cyberoam využívané, dabované CVE-2019-17059 je kritická zranitelnost, která útočníkům umožňuje přístup k vašemu Cyberoam zařízení bez poskytnutí uživatelského jména nebo hesla. Kromě toho je udělený přístup nejvyšší úroveň (root), což v zásadě poskytuje útočníkovi neomezená práva na vaše zařízení Cyberoam.

Ve většině síťových prostředí jsou zařízení Cyberoam používána jako brány firewall a brány SSL VPN. To dává potenciálnímu útočníkovi silnou oporu v síti. Usnadňuje útoky na hostitele v síti a protože zařízení Cyberoam jsou ve většině prostředí obvykle důvěryhodná, poskytuje útočníkovi další výhodu.

Podle Shodana (vyhledávače pro zařízení připojená k internetu) existuje více než 96 000 internetově orientovaných cyberoamových zařízení z celého světa. Většina těchto zařízení je instalována v podnicích, na univerzitách a v některých světově uznávaných bankách. To vede k útokům, které mají na tato prostředí obrovský dopad.

Spolupráce s bezpečnostním týmem Sophos byla velkou radostí, protože jednali rychle tím, že uznali a rozvinuli záplaty pouze několik dní po naší úvodní zprávě. Kudos jim! (slovní hříčka!)

detekování cyberoamu

A protože většina z těchto entit je pro útočníky atraktivním cílem, činí chyby tím kritičtějšími.

Vzdálené neověřené provádění kořenových příkazů CyberoamOS

CyberoamOS je upravený operační systém založený na Linuxu pro zařízení Cyberoam. Tento operační systém má webové konfigurační rozhraní a portál SSLVPN.

Webové rozhraní je rozděleno do dvou hlavních částí:

  • Frontend napsaný v Javě
  • Backend, který používá kombinaci C a Perl

Nebudeme se ponořit hluboko do vnitřních částí kódu front-end nebo back-end, zejména abychom ušetřili čas a omezili množství odhalených informací. Krátce však probereme, jak je chyba vyvolána.

Rozhraní konfigurace i SSLVPN mají servlet, který zpracovává hlavní operace. Tyto operace jsou definovány pomocí parametru s názvem „mode“.

Většina z nich je ověřena. Existuje však několik operací, ke kterým můžeme přistupovat bez ověření (například přihlášení).

Chyby, které jsme našli, leží v emailovém antivirovém / antispamovém modulu. Režim požadavku pro tento koncový bod (modul, op) je 458.

Jedna věc k poznámce je opcodes být mapován k jejich jménům v Cyberoam databázi (interní databáze Postgres). Vyhledáním 458 můžeme zjistit, jak se jmenuje tento operační kód.

Tady je řádek ze skriptu SQL pro inicializaci databáze ukazující jméno opcode 458:

vložit do tblcrevent (opcode, description, mode, requesttype)
hodnoty („RELEASEQUARANTINEMAILFROMMAIL“, „RELEASE QUARANTINE MAIL Z MAIL“, „458“, 2);

Funkce opcode jsou uloženy v adresáři / _conf / csc / cscconf /. Nebudeme odhalovat celý kód zranitelné funkce, ale poskytneme několik úryvků ukazující, kde a jak se chyba vyskytuje.

Kód z rozhraní Java, který zpracovává operační kód 458:

if ((jsonObject.getString ("hdnSender").rovná se("") ||
validateEmail (jsonObject.getString ("hdnSender"))) &&
validateEmail (jsonObject.getString ("hdnRecipient")) &&
isSafeFilePath (jsonObject.getString ("hdnFilePath")) && b) {
httpServletResponse.setContentType ("text / html");
CyberoamLogger.debug ("Antivirus / AntiSpam", "Konstantní hodnota CSC " +
CSCConstants.isCCC);

Jak vidíte výše, několik parametrů se kontroluje z hlediska platnosti. Pokud jsou platné hodnoty, stane se následující:

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

Jak vidíme výše, máme nový kód události (363), který bude zaslán na backend. Chyba, kterou jsme objevili, je v kódu, který to řeší v backendu.

Operační kód se jmenuje sendmail a abychom se vyhnuli zneužití této chyby, převedeme většinu kódu z následujícího kódu..

Obslužný program opcode pro send_mail.

...změněno ...

$ param = $ request->{uvolnění};
param = DLOPEN (base64_decode, param)
LOG applog " Dekódovat hodnoty :: $ param \ n"
% requestData = split (/ [&=] /, $ param);
$ mailServerHost = $ requestData {hdnDestDomain};
$ mailFrom = $ requestData {hdnSender};
$ mailTo = $ requestData {hdnRecipient};
$ file = $ QUARANTINE_PATH."/".$ requestData {hdnFilePath};

$ mailfile = $ requestData {hdnFilePath};
$ validate_email ="Nepravdivé";
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 / && ((definované $ requestData {hdnSender}) && $ requestData {hdnSender} eq '') || $ requestData {hdnSender} = ~ / $ email_regex /) && index ($ requestData {hdnFilePath}, '.. /') == -1) {
$ validate_email ="skutečný";
}
.... redigováno....

Jak vidíme výše, pseudo-Perl kód nám ukazuje, jak backend přijímá vstup z frontendu ($ requestData) a jak se pokouší ověřit některé z parametrů, které posíláme.

Po ověření, pokud jsou naše parametry platné, je spuštěn následující kód:

% mailreq = ("mailaction"=>"$ MAIL_FORWARD","předmět"=>"$ strSubject","do emailu"=>"$ mailTo","příloha"=>"$ file","smtpserverhost"=>"$ mailServerHost","z adresy"=>"$ mailOd");

out = OPCODE mail_sender json% mailreq

Výše uvedený kód nastavuje parametry požadavku do proměnné mailreq a volá funkci mail_sender (OPCODE). Uvidíme, jak se tento operační kód spustí a kde přesně se stane RCE:

#mailaction 0 = mail_with_var, 1 = mail_forward, 2 = mail_attachment
$ mailaction = $ request->{mailaction};
$ subject = $ request->{předmět};
$ mailbody = '';
$ attachfile = $ request->{attachfile};
$ toEmail = $ žádost->{do emailu};

#mail body
LI("definovaný požadavek $->{mailbody} && Žádost o $->{mailbody}") {
$ mailbody = $ request->{mailbody};
}
Hostitel serveru #SMTP
LI("definovaný požadavek $->{smtpserverhost} && Žádost o $->{smtpserverhost}") {
$ smtpserverhost = $ požadavek->{smtpserverhost};
}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices kde servicekey = 'MailServer'"
LI("definovaný výsledek $->{výstup}->{servicevalue} [0] && '' Ne $ výsledek->{výstup}->{servicevalue} [0]") {
$ smtpserverhost = $ výsledek->{výstup}->{servicevalue} [0];
}JINÝ{
$ smtpserverhost ="127,0,0,1";
}
}

#SMTP server port
LI("definovaný požadavek $->{smtpserverport} && Žádost o $->{smtpserverport}") {
$ smtpserverport = $ request->{smtpserverport};
}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices where servicekey = 'MailServerPort'"
LI("definovaný výsledek $->{výstup}->{servicevalue} [0] && '' Ne $ výsledek->{výstup}->{servicevalue} [0]") {
$ smtpserverport = $ výsledek->{výstup}->{servicevalue} [0];
}JINÝ{
$ smtpserverport ="25";
}
}

Příznak #SMTP auth
$ smtpauthflag ="0";
LI("definovaný požadavek $->{smtpauthflag} && Žádost o $->{smtpauthflag}") {
$ smtpauthflag = $ request->{smtpauthflag};
}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices kde servicekey = 'SMTPAuthenticationFlag'"
LI("definovaný výsledek $->{výstup}->{servicevalue} [0] && '' Ne $ výsledek->{výstup}->{servicevalue} [0]") {
$ smtpauthflag = $ výsledek->{výstup}->{servicevalue} [0];
}
}

LI("$ smtpauthflag == 1") {
LI("definovaný požadavek $->{mailusername} && Žádost o $->{mailusername}") {

$ mailusername = $ request->{mailusername};
$ mailpassword = $ request->{mailpassword};

}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices where servicekey = 'MailServerUsername'"
$ mailusername = $ výsledek->{výstup}->{servicevalue} [0];
result = QUERY "vyberte servicevalue z tblclientservices kde servicekey = 'MailServerPassword'"
$ mailpassword = $ výsledek->{výstup}->{servicevalue} [0];
}
}JINÝ{

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

}
LI("definovaný požadavek $->{fromaddress} && Žádost o $->{fromaddress}") {
$ fromaddress = $ request->{fromaddress};
}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices where servicekey = 'FromAddress'"
$ fromaddress = $ výsledek->{výstup}->{servicevalue} [0];
}

#Bezpečnostní mód
LI("definovaný požadavek $->{smtpsecurity} && Žádost o $->{smtpsecurity}") {
$ smtpsecurity = $ request->{smtpsecurity};
}JINÝ{
result = QUERY "vyberte servicevalue z tblclientservices kde servicekey = 'smtpsecurity'"
$ smtpsecurity = $ výsledek->{výstup}->{servicevalue} [0];
}

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

#SMTP certifikát

$ smtpcertificate = '';
$ certpassword = '';

LI("$ smtpsecuritymode! = 0") {
LI("definovaný požadavek $->{smtpcertificate} && Žádost o $->{smtpcertificate}") {
result = QUERY "vyberte certname, heslo z tblvpncertificate kde certid = $ request->{smtpcertificate}"
}JINÝ{
result = QUERY "vyberte certname, heslo z tblvpncertificate where certid = (vyberte servicevalue :: int z tblclientservices where servicekey = 'smtpcertificate')"
}

$ smtpcertificate = $ výsledek->{výstup}->{certname} [0];
$ certpassword = $ výsledek->{výstup}->{heslo} [0];

}

# Od adresy se jménem
LI("definovaný požadavek $->{fromaddresswithname} && Žádost o $->{fromaddresswithname}") {
$ fromaddresswithname = $ request->{fromaddresswithname};
}JINÝ{
$ fromaddresswithname = $ OEMNAME . " <" . $ z adresy . ">";
}

Výše uvedený kód provádí totéž, co ostatní opcode udělal, když se spustí. Inicializuje proměnné (některé z nás nebo ze zařízení, pokud není uvedeno).

Po přiřazení proměnných se provede následující blok kódu.

out = EXECSH "/ bin / cschelper mail_send '$ fromaddress' '$ fromaddresswithname' '$ toEmail' '$ toEmail' '$ Subject' '$ mailbody' '$ smtpserverhost' '$ smtpserverport' '$ mailusername' '$ mailpassword' '$ mailaction' ' $ smtpsecuritymode '' $ smtpcertificate '' $ certpassword '' 1 '' $ attachfile '"

A tam to je, provedení příkazu. Nyní je zde volání EXECSH, které volá / bin / sh -c „ARGUMENTY“. S prováděním provádění pomocí hodnot, které ovládáme, můžeme snadno dosáhnout vzdáleného provádění příkazů, vše bez autentizace.

Za několik měsíců vydáme úplnou zprávu a dokument o ověření s řádnými obrysy.

Aktualizace: Tento výzkum byl poprvé popsán na TechCrunch, více zde.

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