matze hat folgendes geschrieben : |
Da im Moment ja grade die DLL Hijacking-Lücke sehr präsent ist, wollte ich einfach mal wissen: Ist Delphi dafür anfällt?
OK das ist jetzt ein bisschen blöd formuliert, da ja jeder Entwickler selber dafür verantwortlich ist.
Aber: Sind evtl in den VCL Sourcen oder anderen mitgelieferten PAS-Files solche verwundbaren LoadLibrary-Aufrufe drinnen?
Weiß da jemand Bescheid? |
Interessant zu dem Thema:
msdn.microsoft.com/e...ff919712(VS.85).aspx
Wenn ich das richtig in Erinnerung habe (ist schon ein paar Tage her), so ist prinzipiell jedes Programm betroffen, welches ein LoadLibrary ohne explizite Pfadangabe macht und sein aktuelles Verzeichnis nicht explizit setzt, so dass es durch den Anwender festgelegt werden kann (File Open / File Save Dialog oder einfach das aktuelle Verzeichnis des aufrufenden Prozesses, z.B. des Explorer-Fensters).
Dagegen hilft laut dieses Artikels der Aufruf von SetDllDirectory('') beim Programmstart. Da ich von dieser Funktion noch nie gehoert hatte, vermute ich mal, dass ich sie auch im RTL/VCL Code noch nicht gesehen habe (und ein Grep auf den Sourcecode gibt mir recht).
Das wuerde bedeuten, dass jeglicher Aufruf von LoadLibrary in der RTL/VCL unsicher ist und davon gibt es diverse:
C:\Program Files\CodeGear\RAD Studio\5.0\source\database\src\pas\dbx\driver\DBXDynalink.pas
816 FLibraryHandle := THandle(LoadLibrary(SDBX_ADAPTER_NAME));
C:\Program Files\CodeGear\RAD Studio\5.0\source\database\src\pas\dbx\driver\DBXDynalinkNative.pas
117 FLibraryHandle := THandle(LoadLibrary(SDBX_ADAPTER_NAME));
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy10\Protocols\IdGlobalProtocols.pas
927 lh:=LoadLibrary('ntdll.dll'); {do not localize}
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy10\Protocols\IdSSLOpenSSLHeaders.pas
4721 If hIdIndySSL = 0 Then hIdIndySSL := LoadLibrary(SSL_Indy_DLL_name) else exit;
4723 if hIdCrypto = 0 then hIdCrypto := LoadLibrary(SSLCLIB_DLL_name);
4724 If hIdSSL = 0 Then hIdSSL := LoadLibrary(SSL_DLL_name) else exit;
4725 // If hIdIndySSL = 0 Then hIdIndySSL := LoadLibrary(SSL_Indy_DLL_name);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy10\Protocols\IdSSLOpenSSLHeadersNET.pas
5075 LIdCrypto := LoadLibrary(SSLCLIB_DLL_name);
5084 LIdSSL := LoadLibrary(SSL_DLL_name);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy10\System\IdWinsock2.pas
4904 @TransmitFile := GetProcAddress(LoadLibrary('WSOCK32.dll'), 'TransmitFile'); {Do not Localize}
5087 hWS2Dll := LoadLibrary( WINSOCK2_DLL );
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy10\System\IdWship6.pas
272 hWship6Dll := LoadLibrary( Wship6_dll );
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy9\IdSSLOpenSSLHeaders.pas
4479 If hIdIndySSL = 0 Then hIdIndySSL := LoadLibrary(SSL_Indy_DLL_name) else exit;
4481 if hIdCrypto = 0 then hIdCrypto := LoadLibrary(SSLCLIB_DLL_name);
4482 If hIdSSL = 0 Then hIdSSL := LoadLibrary(SSL_DLL_name) else exit;
4483 // If hIdIndySSL = 0 Then hIdIndySSL := LoadLibrary(SSL_Indy_DLL_name);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Indy-renamed\Indy9\IdWinSock2.pas
4241 hWS2Dll := LoadLibrary( WINSOCK2_DLL );
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\IBX\IBIntf.pas
994 IBLibrary := LoadLibrary(PChar(IBASE_DLL));
1158 IBXMLLibrary := LoadLibrary(PChar(IBXML_DLL));
1227 IBInstallLibrary := LoadLibrary(PChar(IB_INSTALL_DLL));
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\rtl\common\ComServ.pas
462 OleAutHandle := SafeLoadLibrary('OLEAUT32.DLL');
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\rtl\win\Mapi.pas
439 MAPIModule := LoadLibrary(PChar(MAPIDLL));
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\rtl\win\PsAPI.pas
215 hPSAPI := LoadLibrary('PSAPI.dll');
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\Samples\Source\IBCtrls.pas
209 LibHandle := LoadLibrary('gds32.dll');
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\AxCtrls.pas
4136 OlePro32Dll := SafeLoadLibrary('olepro32.dll');
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\ComCtrls.pas
4225 ShellModule := SafeLoadLibrary(ShellDllName);
11864 FRichEditModule := LoadLibrary(RichEditModuleName);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\Controls.pas
12175 IMM32DLL := LoadLibrary(Imm32ModName);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\ExtActns.pas
1301 UrlMonHandle := LoadLibrary(UrlMonLib);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\GraphUtil.pas
647 MsImgHandle := LoadLibrary(msimg32);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\vcl\Menus.pas
3090 DLLHandle := SafeLoadLibrary(DLLName);
C:\Program Files\CodeGear\RAD Studio\5.0\source\Win32\xml\oxmldom.pas
1713 UrlMonHandle := LoadLibrary(UrlMonLib);
Das ist jetzt Delphi 2007, ich will nicht ausschliessen, dass auch neuere Delphi-Versionen betroffen sind.
Wer sicherstellen will, dass seine programme nicht betroffen sind, ruft einfach beim Programmstart als moeglichst erstes
Delphi-Quelltext
auf. Beschreibung von
msdn.microsoft.com/e...686203(v=VS.85).aspx :
Parameter:
The directory to be added to the search path. If this parameter is an empty string (""), the call removes the current directory from the default DLL search order. If this parameter is NULL, the function restores the default search order.
Einziges Problem: Wie kann ich sicherstellen, dass dieser Aufruf ausgefuehrt wird, bevor einer der potentiell unsicheren LoadLibrary Aufrufe aus der RTL/VCL stattfindet.
Meiner Ansicht nach muesste der Aufruf dafuer in der INITIALIZATION Section einer Unit stehen, die als erste in der Uses-Liste der .DPR-Datei steht und die ihrerseits keine weitere Unit einbindet. Selbst dann wird natuerlich system.pas und der Memory-Manager vorher eingebunden. Man muesste also pruefen, ob da ein Problem besteht. Ausserdem ist SetDllDirectory nirgends deklariert, d.h. man muss erstmal herausfinden, in welcher Windows DLL sie steht (laut Beschreibung kernel32.dll) und diese Funktion dann selbst deklarieren:
function SetDllDirectoryA(lpPathName: PAnsiChar): LongBool;
bzw.
function SetDllDirectoryW(lpPathName: PWideChar): LongBool;
twm