Thursday, July 30, 2015

avast! Cache a Virus RPC EoP (et RCE potentiel dans certaines versions)

Un autre probleme corrige dans avast! il y a un peu plus d'un an. Et encore une fois, une vulnerabilite qui ne necessite pas de corruption memoire. Comme le dit le dicton, les corruptions memoire, c'est pour plus tard.

Resume

Type de vulnerabilite: probleme de logique
Vecteur: 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

Le problem reside dans la fonction RestoreFile offerte par l'interface RPC. Une fois appelee pour un identifiant de fichier donne, la fonction de restauration va utiliser les proprietes OrigFolder et OrigFileName associees a ce fichier et restaurer aveuglement le fichier a l'emplacement specifie en tant que SYSTEM, et ce quelque soit le niveau de privilege de l'appelant.

.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):



No comments: