Skip to content

OSQuery queryScript

dataBridges exposes powerful Client Function messaging service for devices and applications to implement high performance non-blocking request / response messages. Detailed API documentation

TODO

Project Source

Download source

Download the osQuery.queryScript by clicking on this link

Download source

Download the osQuery.queryScript by clicking on this link

Dependencies

Dependencies

For this application, you will require to use databridges-sio-server-lib (dataBridges Server Library) with NodeJS.

  • Install dataBridges library
  • npm install databridges-sio-server-lib --save

Download the package.json by clicking on this link

Dependencies

For this application, you will require to use databridges-sio-server-lib (dataBridges Server Library).

  • Install External dependencies
  • pip3 install asyncio

  • Install dataBridges library

  • pip3 install databridges_sio_server_lib

OSQuery Sample scripts

Download JSON files

Download the open_system_ports by clicking on this link

Download the open_system_ports by clicking on this link

Set up a dataBridges account and app

Before we jump right into setting up an application with dataBridges, you’ll need to create a dataBridges account and app, if you don’t already have one:

  1. Sign up for a dataBridges account.

  2. Create a new app by selecting Apps and clicking Create New button.

  3. You can retrieve your app credentials from the App Keys tab.

Preparing to run osQuery queryScript

Download the osQuery.queryScript code from above given link and move it to application folder.

If you are preferring to use the environmental variable (preferred due to security reasons), you need to create 3 environment variables (dBridgeServerAuthURL, dBridgeServerAppKey, dBridgeServerAppSecret) and store the required data. If you are not using environment variable, In the osQuery.queryScript file you need to do few modification to store the keys and important data.

Property Description
dBridgeServerAuthURL (string) Server authentication url from dataBridges dashboard.
dBridgeServerAppKey (string) Server application Key from dataBridges dashboard.
dBridgeServerAppSecret (string) Server application Secret from dataBridges dashboard.

Understanding important sections of osQuery queryScript source code.

Query Selection initialization.

This script accepts 2 paramters, First one is osGroupName and second one is queryFileName. Both parameters are required to run this script. queryFileName is in JSON structure as shown in example below.

{
    "win": { "format": "", "query": "\"SELECT DISTINCT process.name, listening.port, process.pid FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid WHERE listening.address = '0.0.0.0';\"" },
    "macos": { "format": "", "query": "\"SELECT DISTINCT process.name, listening.port, process.pid FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid WHERE listening.address = '0.0.0.0';\"" },
    "linux": { "format": "", "query": "\"SELECT DISTINCT process.name, listening.port, process.pid FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid WHERE listening.address = '0.0.0.0';\"" }
}

dataBridges Network connection and reconnection.

To make sure the dataBridges network connection is always connected, we will be tweaking few porperties and code. Application will try to do reconnection using dataBridges auto reconnection process for 500 times as defined in the property. Also after disconnection from the network (when reconnection fails) we will be calling the connection process again. This will do a infinite try till it get successfull connection.

// Connect to dataBridges. If any runtime error it will be caught in catch().
dbridge.connect().catch((err) => {
    console.log('dBridge Connection exception..', err);
});

//Bind to disconnected event, to get intimation about dataBridges network disconnection. 
dbridge.connectionstate.bind("disconnected", () => {
    console.log('dataBridges network', 'disconnected');
});
# Bind to connected event, to get intimation about dataBridges network connected.
self.dbridge.connectionstate.bind("connected", self.connected)
# Bind to disconnected event, to get intimation about dataBridges network disconnection.
self.dbridge.connectionstate.bind("disconnected", self.disconnected)
# Connect to dataBridges. If any runtime error it will be caught in Exception. 
try:
    await asyncio.sleep(0.0001)
    await self.dbridge.connect()
except Exception as e:
    print(e)

# Bind to disconnected event, to get intimation about dataBridges network disconnection.
async def disconnected(self):
    try:
        print('dBridge Event Bind', 'disconnected');
        quit()
    except Exception as e:
        print(e)

dataBridges on Connection process.

Once the dataBridge network is successfully connected, We will be registering the RPC server osQueryClientAuth for serving trusted_token creation request.

//Bind to connected event.
dbridge.connectionstate.bind("connected", async () => {
    console.log('dBridge Event Bind', 'connected');

    // Subscribe to channel 'sys:' + osGroupName,
    subscribe_channel = await dbridge.channel.subscribe("sys:" + osGroupName);

    // Bind to subscribe.success event
    subscribe_channel.bind("dbridges:subscribe.success", (payload, metadata) => {
        console.log('Subscribed to :', 'sys:' + osGroupName)
    });

    // Bind to subscribe.fail event
    subscribe_channel.bind("dbridges:subscribe.fail", (payload, metadata) => {
        console.log('Subscription failed for ', 'sys:' + osGroupName, payload.source, payload.code, payload.message)
    });
});
# Bind to connected event.
async def connected(self):
    try:
        print("dBridge Event Bind", "connected")
        # Subscribe to channel 'sys:' + osGroupName,
        self.subscribe_channel = await self.dbridge.channel.subscribe("sys:" +  self.osGroupName)
        # Bind to subscribe.success event
        self.subscribe_channel.bind("dbridges:subscribe.success", self.subscribe_success)
        # Bind to subscribe.fail event
        self.subscribe_channel.bind("dbridges:subscribe.fail", self.subscribe_fail)
    except Exception as e:
        print(e)

#  Bind to subscribe.success event
async  def subscribe_success(self, payload , metadata):
    try:
        print('Subscribed to :', 'sys:' + self.osGroupName)
    except Exception as e:
        print(e)

# Bind to subscribe.fail event
async def subscribe_fail(self, payload, metadata):
    print('Subscription failed for ', 'sys:' + self.osGroupName, payload.source, payload.code, payload.message)

dataBridges on Praticipant Joined and left process.

Upon completion of subscrition, if defined databridges triggers participant joined and left events for the subscribed channels. This events can be used to trigger client function calls to get the osQuery data by sending the proper osQuery with OS information retrived using metadata.

// Bind to participant.joined event
subscribe_channel.bind('dbridges:participant.joined', (payload, metadata) => {
    const sysInfo = JSON.parse(payload.sysinfo)
    const clientOS = sysInfo.sysinfo.os;
    console.log('Participant Joined ', clientOS, sysInfo.sysid);
    let osquery = null;
    osquery = queryJson[clientOS];
    if(!osquery){
        console.log(queryFileName ,' dose not contain query for OS:',clientOS);
    }else {
        // databridge client function call with the recieved sessionid 
        dbridge.cf.call(metadata.sessionid, "osquery", JSON.stringify(osquery), 1000 * 60 * 2).then((payload) => {
            console.log('OSQuery Result for', sysInfo.sysid, JSON.parse(payload).osqueryresult);
        }).catch((err) => {
            console.log('OSQuery call => exception', sysInfo.sysid, err.source, err.code, err.message);
        });
    }
});

// Bind to participant.left event
subscribe_channel.bind('dbridges:participant.left', (payload, metadata) => {
    console.log('Participant Left : ', metadata.sourcesysid)
});
# Bind to participant.join event
self.subscribe_channel.bind("dbridges:participant.joined", self.participant_join)
# Bind to participant.left event
self.subscribe_channel.bind("dbridges:participant.left", self.participant_left)

# Bind to participant.joined event
async  def participant_join(self, payload , metadata):
    try:

        sysInfo = json.loads(payload["sysinfo"])
        clientOS = sysInfo["sysinfo"]["os"]
        print('Participant Joined ', clientOS, sysInfo["sysid"])

        osquery = queryDB[clientOS]
        if not osquery:
            print(queryFileName ," dose not contain query for OS:",clientOS)
        else:
            # databridge client function call with the recieved sessionid
            p =  await self.dbridge.cf.call(metadata["sessionid"],  "osquery" , json.dumps(osquery), 1000*60*2, None )

            def onResult(res):
                jres = json.loads(res)
                print('OSQuery Result for', sysInfo["sysid"], "\n", jres["osqueryresult"])

            def onError(err):
                print('OSQuery call => exception', sysInfo["sysid"], err.source, err.code, err.message);

            p.then(onResult).catch(onError)

    except Exception as e:
        print(e)

# Bind to participant left event
async  def participant_left(self, payload , metadata):
    try:
        print('Participant Left : ', metadata["sourcesysid"])
    except Exception as e:
        print(e)