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:
-
Sign up for a dataBridges account.
-
Create a new app by selecting Apps and clicking Create New button.
-
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)