Resume
Type de vulnerabilite: probleme de logiqueVecteur: appel LPC (ou RPC) a c6c94c23-538f-4ac5-b34a-00e76ae7c67a v1.0
Impact: EoP a SYSTEM, ou RCE potentiel dans les versions entreprises d'avast!
Verifie sur: avast! Free ashServ.dll v9.quelquechose
Description
La cache a virus d'avast! est controlee par une interface RPC implementee dans ashServ.dll, cette interface etant c6c94c23-538f-4ac5-b34a-00e76ae7c67a v1.0. Par default, cette interface n'ecoute que sur un point de terminaison local (ncalrpc), mais dans certaines configurations du logiciel - notamment les versions entreprises - elle peut aussi ecouter sur un port TCP (ncacn_ip_tcp). Aucune de ces deux interfaces ne requerait d'authentification, mais certaines fonctions necessitaient un mot de passe sous forme de chaine de characteres dans les donnees RPC (verifie via MD5). Sur une connexion locale (ou si l'option de configuration de la cache "CheckPassword" est desactivee), le mot de passe n'etait pas verifie..text:6512BC91 call ds:RpcStringBindingParseW
.text:6512BC97 test eax, eax
.text:6512BC99 jnz loc_6512BD24
.text:6512BC9F push offset aNcalrpc ; "ncalrpc"
.text:6512BCA4 push [ebp+Protseq] ; wchar_t *
.text:6512BCA7 call ds:_wcsicmp
.text:6512BCAD add esp, 8
.text:6512BCB0 test eax, eax
.text:6512BCB2 jz short AUTH_SUCCESS
.text:6512BCB4 push 1
.text:6512BCB6 push offset aCheckpassword ; "CheckPassword"
.text:6512BCBB push offset aChest ; "Chest"
.text:6512BCC0 call ds:aswGetAvastPropertyInt
.text:6512BCC6 add esp, 0Ch
.text:6512BCC9 test eax, eax
.text:6512BCCB jz short AUTH_SUCCESS
.text:6512BA84 push 104h
.text:6512BA89 lea eax, [ebp+var_834]
.text:6512BA8F push eax
.text:6512BA90 push offset aOrigfolder ; "OrigFolder"
.text:6512BA95 mov ecx, esi
.text:6512BA97 call edi ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *) ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *)
.text:6512BA99 push offset word_65136530
.text:6512BA9E push 104h
.text:6512BAA3 lea eax, [ebp+var_424]
.text:6512BAA9 push eax
.text:6512BAAA push offset aOrigfilename ; "OrigFileName"
.text:6512BAAF mov ecx, esi
.text:6512BAB1 call edi ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *) ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *)
.text:6512BAB3 lea eax, [ebp+var_424]
.text:6512BAB9 push eax
.text:6512BABA lea eax, [ebp+var_834]
.text:6512BAC0 push eax
.text:6512BAC1 push offset aSS_0 ; "%s\\%s"
.text:6512BAC6 lea eax, [ebp+var_21C]
.text:6512BACC push 104h ; size_t
.text:6512BAD1 push eax ; wchar_t *
.text:6512BAD2 call ds:_snwprintf
Pour elever ses privileges, un utilisateur local (ou distant) peut appeler la fonction RPC de la cache AddFile en specifiant les proprietes OrigFolder et OrigFileName comme etant celles d'un fichier qu'il veut ecraser (ou creer), et puis appeler la fonction RestoreFile. De cette facon, il peut ecraser tout binaire SYSTEM, ou creer un fichier MOF a-la-Stuxnet pour execute du code en tant que SYSTEM.
Pour avast! Free, c'est seulement un EoP, mais pour avast! Endpoint Protection, si le RPC de la cache est configure pour ecouter sur un port TCP (16108 par default), cela pourrait se transformer en RCE, le probleme etant que la fonction RestoreFile verifiait le mot de passe.
Notez que la fonction AddFile permet de specifier le contenu du fichier, modulo un "chiffrement" de type XOR avec une cle enorme. Le code suivant utilise impacket pour effecture la requete RPC (j'ai du enlever la cle parceque sinon pastebin part en vrille):