Skip to content

Collecting from Quest Intrust and Change Auditor

Introduction

CyberQuest is the only multi-SIEM solution for security investigation and analysis that unifies the data received from all networks and systems and offers real-time visibility and unlimited horizontal scalability.

CyberQuest can be plugged into the existing security workflows to better leverage and enhance the output of your existing network security tools and SIEM software, with additional analytics, visibility, data unification and incident investigation capabilities.

The solution unifies disparate data sources in one place, allowing for fast and accurate detection and response for security teams. Having all the data in one place ensures ultra-fast correlation between events and a consistent overview of the entire organizational environment.

It also increases the internal team's proactivity in managing daily risk at the corporate level by finding threats through real-time analytics on large datasets.

This document describes how Quest InTrust and Change Auditor shall be configured in order to let CyberQuest collect data from it.

Collecting from Quest InTrust and Change Auditor

For Quest InTrust and Change Auditor software logs can be collected in 2 ways:

• By incrementally gathering data from the local InTrust server database

• The second option is gathering the data in real time from the InTrust server.

Incremental Collection

For incremental collection, the following instructions need to be executed:

• Initialize an RDP (remote desktop protocol) type connection with Quest InTrust server

• Use the Microsoft SQL Server Management Studio.

IF NOT EXISTS (SELECT * FROM sys.views WHEREobject_id
= OBJECT_ID(N'[dbo].[vw_AllEvents]'))
EXEC sp_executesql N'CREATE VIEW [dbo][vw_AllEvents] AS SELECT ''test'' as
test' GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[vw_AllEvents]
AS
select
e.ID,e.SessionID,e.VersionMajor,e.VersionMinor,
e.Computer,e.UserName,e.UserDomain,e.EventType,eSource,e.EventID,e.Category,e.GMT,e.LocalTime,
s.S1,s.S2,s.S3,s.S4,s.S5,s.S6,s.S7,s.S8,s.S9,sS10,s.S11,s.S12,s.S13,s.S14,s.S15,s.S16,s.
S17,s.S18,s.S19,s.S20,s.S21,s.S22,s.S23,s.S24,sS25,s.S26,s.S27,s.S28,s.S29,s.S30,s.S31,s
.S32,s.S33,s.S34,s.S35,s.S36,s.S37,s.S38,s.S39,sS40,s.S41,s.S42,s.S43,s.S44,s.S45,s.S46, s.S47,sS48,s.S49,s.S50,
isnull(d.Description, '') Description , eEventLog as EventLog, e.PlatformID as PlatformID
from
Events e
inner join
(
select
e.ID,
e.SessionID,
max(case s.StringIndex when 1 then s.StringValueelse null end) S1,
max(case s.StringIndex when 2 then s.StringValueelse null end) S2,
max(case s.StringIndex when 3 then s.StringValueelse null end) S3,
max(case s.StringIndex when 4 then s.StringValueelse null end) S4,
max(case s.StringIndex when 5 then s.StringValueelse null end) S5,
max(case s.StringIndex when 6 then s.StringValueelse null end) S6,
max(case s.StringIndex when 7 then s.StringValueelse null end) S7,
max(case s.StringIndex when 8 then s.StringValueelse null end) S8,
max(case s.StringIndex when 9 then s.StringValueelse null end) S9,
max(case s.StringIndex when 10 then s.StringValueelse null end) S10,
max(case s.StringIndex when 11 then s.StringValueelse null end) S11,
max(case s.StringIndex when 12 then s.StringValueelse null end) S12,
max(case s.StringIndex when 13 then s.StringValueelse null end) S13,
max(case s.StringIndex when 14 then s.StringValueelse null end) S14,
max(case s.StringIndex when 15 then s.StringValueelse null end) S15,
max(case s.StringIndex when 16 then s.StringValueelse null end) S16,
max(case s.StringIndex when 17 then s.StringValueelse null end) S17,
max(case s.StringIndex when 18 then s.StringValueelse null end) S18,
max(case s.StringIndex when 19 then s.StringValueelse null end) S19,
max(case s.StringIndex when 20 then s.StringValueelse null end) S20,
max(case s.StringIndex when 21 then s.StringValueelse null end) S21,
max(case s.StringIndex when 22 then s.StringValueelse null end) S22,
max(case s.StringIndex when 23 then s.StringValueelse null end) S23,
max(case s.StringIndex when 24 then s.StringValueelse null end) S24,
max(case s.StringIndex when 25 then s.StringValueelse null end) S25,
max(case s.StringIndex when 26 then s.StringValueelse null end) S26,
max(case s.StringIndex when 27 then s.StringValueelse null end) S27,
max(case s.StringIndex when 28 then s.StringValueelse null end) S28,
max(case s.StringIndex when 29 then s.StringValueelse null end) S29,
max(case s.StringIndex when 30 then s.StringValueelse null end) S30,
max(case s.StringIndex when 31 then s.StringValueelse null end) S31,
max(case s.StringIndex when 32 then s.StringValueelse null end) S32,
max(case s.StringIndex when 33 then s.StringValueelse null end) S33,
max(case s.StringIndex when 34 then s.StringValueelse null end) S34,
max(case s.StringIndex when 35 then s.StringValueelse null end) S35,
max(case s.StringIndex when 36 then s.StringValueelse null end) S36,
max(case s.StringIndex when 37 then s.StringValueelse null end) S37,
max(case s.StringIndex when 38 then s.StringValueelse null end) S38,
max(case s.StringIndex when 39 then s.StringValueelse null end) S39,
max(case s.StringIndex when 40 then s.StringValueelse null end) S40,
max(case s.StringIndex when 41 then s.StringValueelse null end) S41,
max(case s.StringIndex when 42 then s.StringValueelse null end) S42,
max(case s.StringIndex when 43 then s.StringValueelse null end) S43,
max(case s.StringIndex when 44 then s.StringValueelse null end) S44,
max(case s.StringIndex when 45 then s.StringValueelse null end) S45,
max(case s.StringIndex when 46 then s.StringValueelse null end) S46,
max(case s.StringIndex when 47 then s.StringValueelse null end) S47,
max(case s.StringIndex when 48 then s.StringValueelse null end) S48,
max(case s.StringIndex when 49 then s.StringValueelse null end) S49,
max(case s.StringIndex when 50 then s.StringValueelse null end) S50
from
Events e
left join EventsStrings s on s.SessionID=eSessionID and s.EventID=e.ID and s.StringIndex<=50
group by
e.ID,
e.SessionID
) s
on s.SessionID=e.SessionID and s.ID=e.ID
left join EventsDescriptions d on d.SessionID=eSessionID and d.EventID=e.ID go

The script is run by pressing the "Execute" button from the InTrust audit database (default is „InTrust_Audit_DB”)

Alt text

For integrating the Quest InTrust connector into the CyberQuest solution, access the CyberQuest web interface and execute the following instructions:

  • Select the settings icon, then “Connectors”:

    Alt text

  • Select "New Data Connector" from the left side of the page:

    Alt text

  • In the new connector page, the following fields can be edited:

  • Connector Type – the connector type (Quest InTrust , Alienvault etc) in this case Quest InTrust

  • Display Name – The name under which the connector will be displayed in the connector list

  • Description – short SIEM connector description

  • Notes – extra information

  • Schedule – planning data extraction from the SIEM's database

  • Lastvalue – last data that has been read from the SIEM

  • Database host – the IP address of the database in which the SIEM events are stored (Quest InTrust server IP address)

  • Database name – the database name; in this case, InTrust_Audit_DB

  • Database user – the username

  • Database password – user's password

  • For saving press the "submit" button

  • For authentication, an SQL user with reading permission will be used in order to install the integrating view.

Second Method of Collecting Data

The second method of collecting data requires executing the following:

  1. Run the Quest InTrust Deployment Manager
  2. Right click on the collection and choose "Edit collection" from the contextual menu. Alt text
  3. Choose a name for the new collection and press "Next". Alt text
  4. Select the Data sources from the list
  5. Pres the configuration button next to the "Select repository :" field : Alt text
  6. In the new page press the edit button : Alt text
  7. Select the Repository for Forwarding Logs and click "Edit”: Alt text
  8. Select the "Forwarding" tab and check "Enable Forwarding" checkbox Alt text
  9. In the "Destination host" filed, we introduce CyberQuest server IP address in this case 192.168.100.1
  10. The default port (8090) is inserted in the "Port" field – the port is configured from the CyberQuest initial configuration file "config.ini” from the data acquisition service.
  11. From the vertical list, select the "Unicode (UTF-8)” option for the "Message encoding” field
  12. Select "Custom Format” option from the vertical list for the „Message Format” field
  13. Press the "Edit" button to edit the field format and insert the following script:
var __Number;
var Criticality = ["1=info", "1=success", "3=error", "3=failure", "2=warning"];
var Format
    = "%RecordNumber%|||||%__Number%|||||%VersionMajor%|||||%VersionMinor%|||||%Computer %|||||%__AccountName%|||||%__DomainName%|||||%EventType%|||||%Source%|||||%EventID %|||||%Category%|||||%EventLog%|||||%PlatformID%|||||%__LT%|||||%__GT%|||||%Descriptio n%";
var CRITICALITY = ParseCriticality(Criticality);
var SHORT_WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var SHORT_MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var ERROR_TYPES =
    [
        "Information", // 0
        "Error",  // 1
        "Warning",  // 2
        "",  // 3
        "Information", // 4
        "",  // 5
        "",  // 6
        "",  // 7
        "Success Audit", // 8
        "",  // 9
        "",  // 10
        "",  // 11
        "",  // 12
        "",  // 13
        "",  // 14
        "",  // 15
        "Failure Audit" // 16
    ];

var RE_ACCOUNT_NAME = new RegExp("AccountName:\\s*([^\\-\\s][^\\s\\@]*)(\\@\\S+)?\\s"); var RE_DOMAIN_NAME = new RegExp("AccountDomain:\\s*([^\\-\\s][^\\s\\@]*)(\\@\\S+)?\\s"); var RE_SRC_IP = new RegExp("Source NetworkAddress:\\s*([^\\-\\s][^\\s\\@]*)(\\@\\S+)?\\s");

function Expand(pattern, accesor, param) {

    if (pattern == null)
        return null;

    var a = pattern.split("%");
    var s = "";
    var k = false;
    var cache = {};
    for (var i in a) {
        if (k) {
            if (a[i].length == 0) {
                s += "%";
            }
            else {
                var v = "";
                try {
                    v = accesor(param, a[i], cache);
                    if (v == null)
                        v = "%" + a[i] + "%";
                }
                catch (ex) {
                    v = "%" + a[i] + "%";
                }
                s += v;
            }
        }
        else {
            s += a[i];
        }
        k = !k;
    }
    return s;
}

function LPad(s, n, c) {
    var o = s.toString();
    while (o.length < n)
        o = c.toString() + o;
    return o;
}

function get_diff(s1, s2) {
    var d1 = new Date(s1);
    var d2 = new Date(s2);
    var diff = d2.getTime() - d1.getTime();
    return diff;
}

function DateTimeToString4(v, s) {
    var x = "";
    if (s != undefined) {
        var z = new Date(v);
        x = z.getTime() - s;
    }
    if (x != "")
        var d = new Date(x);
    else
        var d = new Date(v);
    return LPad(d.getFullYear(), 4, "0") + "-" +
        LPad(d.getMonth() + 1, 2, "0") + "-" +
        LPad(d.getDate(), 2, "0") + " " +
        LPad(d.getHours(), 2, "0") + ":" +
        LPad(d.getMinutes(), 2, "0") + ":" +
        LPad(d.getSeconds(), 2, "0") + "." +
        LPad(d.getMilliseconds(), 3, "0");
}

function DateTimeToString(v) {
    var d = new Date(v);
    return LPad(d.getFullYear(), 4, "0") + "-" +
        LPad(d.getMonth() + 1, 2, "0") + "-" +
        LPad(d.getDate(), 2, "0") + " " +
        LPad(d.getHours(), 2, "0") + ":" +
        LPad(d.getMinutes(), 2, "0") + ":" +
        LPad(d.getSeconds(), 2, "0") + "." +
        LPad(d.getMilliseconds(), 3, "0");
}

function DateTimeToString2(v) {
    var d = new Date(v);
    return "<" + LPad(d.getFullYear() % 100, 2, "0") + ">" +
        SHORT_MONTHS[d.getMonth()] + " " +
        LPad(d.getDate(), 2, "0") + " " +
        LPad(d.getHours(), 2, "0") + ":" +
        LPad(d.getMinutes(), 2, "0") + ":" +
        LPad(d.getSeconds(), 2, "0");
}

function DateTimeToStamp(v) {
    var d = new Date(v);
    var stamp = d.getTime() / 1000;
    return stamp.toString();
}

function FindAccountName(s) {
    var result = RE_ACCOUNT_NAME.exec(s);
    if (result == null)
        return "N/A";
    return result[1];
}

function FindAccountName2(s) {
    var result = RE_ACCOUNT_NAME.exec(s);
    if (result == null)
        return "N/A";
    var pos = result.index;
    var s2 = s.substr(pos + 1);
    result = RE_ACCOUNT_NAME.exec(s2);
    if (result == null)
        return "N/A";
    return result[1];
}

function FindDomainName(s) {
    var result = RE_DOMAIN_NAME.exec(s);
    if (result == null)
        return "N/A";
    return result[1];
}

function FindDomainName2(s) {
    var result = RE_DOMAIN_NAME.exec(s);
    if (result == null)
        return "N/A";
    var pos = result.index;
    var s2 = s.substr(pos + 1);
    result = RE_DOMAIN_NAME.exec(s2);
    if (result == null)
        return "N/A";
    return result[1];
}

function FindIpAddress(s) {
    var result = RE_SRC_IP.exec(s);
    if (result == null)
        return "N/A";
    return result[1];
}

function ReplaceSymbols(v, r) {
    var s = v;
    for (var i = 0; i < r.length; ++i) {
        var o = "";
        var c = r.charAt(i);
        var p = 0;
        var n;
        while ((n = s.indexOf(c, p)) >= 0) {
            o += s.substr(p, n - p);
            if (o.length > 0 && o.charAt(o.length - 1) != " ")
                o += " ";
            p = n + 1;
        }
        if (p < s.length)
            o += s.substr(p);
        s = o;
    }
    return s;
}

function ReplaceSymbols2(v) {
    return v
    /* # return v.replace(/\r|\n|\n/g," ") */
}

function IncrimentEventNumber() {
    if (__Number == null)
        __Number = 0;
    else
        ++__Number;
}

function EventFormaterCached(e, prop, cache) {
    if (cache[prop] != null)
        return cache[prop];
    var t = EventFormater(e, prop, cache);
    cache[prop] = t;
    return t;
}

function EventFormater(e, prop, cache) {
    switch (prop) {
        case "__Number":
            return __Number == null ? 0 : __Number;
        case "__GT":
            return DateTimeToString4(e._GMT, get_diff(e._GMT, e._LocalTime));
        case "__LT":
            return DateTimeToString4(e._GMT);
        case "__GT2":
            return DateTimeToString2(e._GMT);
        case "__LT2":
            return DateTimeToString2(e._LocalTime);
        case "__GTS":
            return DateTimeToStamp(e._GMT);
        case "__LTS":
            return DateTimeToStamp(e._LocalTime);
        case "__WTS":
            return DateTimeToStamp(e.TimeWritten);
        case "__EventTypeString":
            return ERROR_TYPES[parseInt(e.EventType)];
        case "__AccountName":
            return e.UserName != "" ? e.UserName : (parseInt(e.EventID) == 4648 ?
                FindAccountName2(e.Description) : FindAccountNam(e.Description));
        case "__DomainName":
            return e.UserDomain != "" ? e.UserDomain : (parseInt(e.EventID) == 4648 ?
                FindDomainName2(e.Description) : FindDomainName(eDescription));
        case "__Description":
            return ReplaceSymbols2(e.Description);
        case "__Criticality":
            return GetCriticality(CRITICALITY,
                e.EventLog.toString().toLowerCase(),
                parseInt(e.EventType), parseInt(e.EventID));
        case "__AccountType":
            var t = EventFormaterCached(e, "__AccountName", cache).toString();
            return t == "N\A" ? "Unknown" : (t.charAt(t.length - 1) == "$" ? "Computer" :
                "User"); default:
            return e[prop];
    }
}

function ParseCriticality(strings) {
    var criticality = [];
    var types = { "none": 0x0000, "success": 0x0008, "failure": 0x0010, "error": 0x0001, "info": 0x0004, "warning": 0x0002 };
    for (var i = 0; i < strings.length; ++i) {
        var s = strings[i];
        var p = s.indexOf("=");
        if (p > 0) {
            var level = parseInt(s.substr(0, p));
            var v = s.substr(p + 1).split(";");
            var type = v.length > 0 ? ((v[0] == "*" || v[0] == "") ? null : types[v[0].toLowerCase()]) : null;
            var log = v.length > 1 ? ((v[1] == "*" || v[1] == "") ? null : v[1].toLowerCase()) : null;
            var low = v.length > 2 ? ((v[2] == "*" || v[2] == "") ? 0 : parseInt(v[2])) : 0;
            var high = v.length > 3 ? ((v[3] == "*" || v[3] == "") ? 0xFFFF : parseInt(v[3])) :
                (v.length > 2 ? ((v[2] == "*" || v[2] == "") ? 0xFFFF : low) : 0xFFFF);
            if (criticality[level] == null)
                criticality[level] = [];
            criticality[level][criticality[level].length] = [log, type, low, high];
        }
    }
    return criticality;
}

function GetCriticality(criticality, e_log, e_type, e_id) {
    for (var i = criticality.length - 1; i >= 0; --i) {
        if (criticality[i] != null) {
            for (var j = 0; j < criticality[i].length; ++j) {
                var entry = criticality[i][j];
                var log = entry[0];
                var type = entry[1];
                var low = entry[2];
                var high = entry[3];
                if (e_id >= low && e_id <= high &&
                    (type == null || type == e_type) && (log == null || log == e_log)) {
                        return i;
                }
            }
        }
    }
    return 0;
}

function Transform(e, numer) {
    __Number = numer;
    var message = Expand(Format, EventFormaterCached, e);
    SetEventMessage(message);
}

Alt text

The script can be found in the documentation folder:

„\Documentation\Integration scripts\Intrust\realTimeForwarding. Script”

  • Press the OK button for all the contextual windows

  • Press Next, then Finish