vendredi 6 août 2010

How Microsoft fixed the LNK vulnerability... and other things

Microsoft released the awaited patch fixing the LNK vulnerability on Monday. Let's have a look at how Microsoft fixed it, by performing a differential analysis on the shell32.dll library for Windows XP SP3.

Several new functions have been added to the fixed version of the DLL; knowing that the vulnerability is related to the way shortcuts to control panel (CPL) elements are handled, the new CControlPanelFolder:: _IsRegisteredCPLApplet() function immediately focuses our attention. The CControlPanelFolder:GetUIObjectOf() function has been altered to add a new block calling this function:

At the bottom of the screenshot, there is a call to _ControlExtractIcon_CreateInstance(), which will initiate the extraction of the icon. This call will therefore be performed only if the return code of _IsRegisteredCPLApplet() is not null.

Looking at _IsRegisteredCPLApplet(), we see that after having fetched the registered control panel elements with CPLD_GetModules(), the function iterates with DSA_GetItemPtr() until a match is found by CompareString() with the DLL pointed by the shortcut (return value of 2, namely CSTR_EQUAL, in which case _IsRegisteredCPLApplet() returns 1), or if there is no more element to compare with (in which case _IsRegisteredCPLApplet() returns 0):

If we create a CPL shortcut pointing to C:\Windows\system32\zuaucpl.dll (instead of the legitimate wuaucpl.dll), we observe that Windows does compare the name of our DLL with the registered control panel elements:

Windows will therefore only load a CPL to retrieve its icon if it was registered in a legitimate way.

This update also adds support for the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\IsAutorunForCDROMOnly registry value (without creating it by default), enabling to disable AutoRun on any media except CDs and DVDs. This is the default behavior on Windows 7 and Microsoft released the KB971029 for the previous Windows versions.

In fact, there is a call to a new _IsAutorunForCDROMOnly() function at the top of the CMountPoint::_ProcessAutoRunFile() and CContentTypeData::Init() functions:

At the bottom of CContentTypeData::Init(), a new test has been added to decide whether AddRemovableOrFixedDiskAutorunINFHandler() should be called, depending on the return value of _IsAutorunForCDROMOnly() (in CMountPoint::_ProcessAutoRunFile(), there are multiple places where this is checked):

The _IsAutorunForCDROMOnly() simply retrieves the registry value:

More surprising, this update also adds several functions (InitializeFormatDlg(), BeginFormat() and FileSysChange()) which add a new "exFAT" item to the disk format dialog:

But only the dialog has been modified; the exFAT driver is not installed and formating the disk will therefore not be possible... exFAT support requires a distinct update, KB955704, which install several other files, not only shell32.dll.

Besides the security fix, this new version of shell32.dll also comes with two functional updates (support for the complete AutoRun disabling except for CDs and DVDs, as well as a partial support for exFAT disk format), which is, to our knowledge, not documented anywhere (except in shell32.dll updates in previously released KBs).

Comment Microsoft a corrigé la vulnérabilité LNK... mais pas uniquement

Microsoft a donc publié le correctif tant attendu pour la vulnérabilité LNK lundi dernier. Observons la façon dont Microsoft l'a corrigée, par analyse différentielle de la bibliothèque shell32.dll pour Windows XP SP3.

Plusieurs nouvelles fonctions ont été ajoutées à la version corrigée de la DLL ; sachant que la vulnérabilité est liée à la gestion des raccourcis vers des éléments du panneau de configuration (CPL), la nouvelle fonction CControlPanelFolder:: _IsRegisteredCPLApplet() attire immédiatement notre attention. Or, il se trouve que la fonction CControlPanelFolder:GetUIObjectOf() a été modifiée pour se voir ajouter un nouveau bloc appelant cette fonction :

En bas de la capture, on note un appel à la fonction _ControlExtractIcon_CreateInstance(), chargée d'extraire l'icône, qui ne sera donc réalisé que si le code de retour de _IsRegisteredCPLApplet() est non-nul.

Si l'on regarde de plus près _IsRegisteredCPLApplet(), on observe qu'après avoir récupéré la listes des éléments du panneau de configuration enregistrés grâce à CPLD_GetModules(), la fonction itère sur ces éléments grâce à DSA_GetItemPtr() jusqu'à ce qu'une correspondance avec la DLL pointée par le raccourci soit trouvée par CompareString() (valeur de retour 2, soit CSTR_EQUAL, auquel cas la fonction _IsRegisteredCPLApplet() retourne 1), ou qu'il n'y ait plus d'éléments avec qui comparer (auquel cas elle retourne 0) :

Si l'on crée par exemple un raccourci CPL pointant vers C:\Windows\system32\zuaucpl.dll (au lieu du légitime wuaucpl.dll), on remarque bien que Windows compare le nom de notre DLL malveillante à la liste des éléments du panneau de configuration enregistrées :

Windows n'autorisera ainsi que les CPL légitimement enregistrés à être chargés lors de la récupération de l'icône.

Cette mise à jour ajoute également le support de la valeur de registre HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\IsAutorunForCDROMOnly (sans pour autant la créer par défaut), permettant de désactiver l'AutoRun sur tous les supports à l'exception des CD et des DVD. Cette désactivation est le cas par défaut à partir de Windows 7 et Microsoft proposait jusqu'à présent le KB971029 pour l'appliquer aux versions antérieures de Windows.

On trouve en effet un appel à une nouvelle fonction _IsAutorunForCDROMOnly() en tête des fonctions CMountPoint::_ProcessAutoRunFile() et CContentTypeData::Init() :

En bas de fonction CContentTypeData::Init(), un nouveau test a été ajouté afin d'appeler ou non AddRemovableOrFixedDiskAutorunINFHandler(), en fonction du retour de _IsAutorunForCDROMOnly() (dans le cas de CMountPoint::_ProcessAutoRunFile(), il y a plusieurs vérifications au fil du code) :

La fonction _IsAutorunForCDROMOnly() récupère simplement la valeur depuis le registre :

Plus curieux, cette mise à jour modifie plusieurs fonctions (InitializeFormatDlg(), BeginFormat() et FileSysChange()) pour ajouter "exFAT" à la boîte de dialogue du formatage de disque :

Problème : seule la boîte de dialogue a été modifiée ; les pilotes exFAT ne sont pas présents et le formatage ne sera donc pas possible en l'état... Le support de exFAT nécessite l'application d'une mise à jour distincte sous la forme du KB955704 qui comprend d'autres fichiers que shell32.dll.

En plus du correctif, cette nouvelle version de shell32.dll comprend donc deux mises à jour fonctionnelles (support pour la valeur permettant la désactivation complète de l'AutoRun hors CD et DVD, ainsi que support partiel du formatage exFAT), ce qui n'est, à notre connaissance, documenté nulle part (en dehors du fait que des mises à jour de shell32.dll ont été effectuées dans des KB publiés précédemment).