[Osquery] Fix sql query parser logic (#114932)
This commit is contained in:
parent
81a84a863b
commit
dfbb397696
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { produce } from 'immer';
|
import { produce } from 'immer';
|
||||||
import { isEmpty, find, orderBy, sortedUniqBy, isArray, map } from 'lodash';
|
import { each, isEmpty, find, orderBy, sortedUniqBy, isArray, map, reduce, get } from 'lodash';
|
||||||
import React, {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
@ -624,30 +624,47 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
|
||||||
return currentValue;
|
return currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tablesOrderMap =
|
const astOsqueryTables: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
columns: OsqueryColumn[];
|
||||||
|
order: number;
|
||||||
|
}
|
||||||
|
> =
|
||||||
ast?.from?.value?.reduce(
|
ast?.from?.value?.reduce(
|
||||||
(
|
(
|
||||||
acc: { [x: string]: number },
|
acc: {
|
||||||
table: { value: { alias?: { value: string }; value: { value: string } } },
|
[x: string]: {
|
||||||
index: number
|
columns: OsqueryColumn[];
|
||||||
) => {
|
order: number;
|
||||||
acc[table.value.alias?.value ?? table.value.value.value] = index;
|
};
|
||||||
return acc;
|
|
||||||
},
|
},
|
||||||
{}
|
table: {
|
||||||
) ?? {};
|
value: {
|
||||||
|
left?: { value: { value: string }; alias?: { value: string } };
|
||||||
const astOsqueryTables: Record<string, OsqueryColumn[]> =
|
right?: { value: { value: string }; alias?: { value: string } };
|
||||||
ast?.from?.value?.reduce(
|
value?: { value: string };
|
||||||
(
|
alias?: { value: string };
|
||||||
acc: { [x: string]: OsqueryColumn[] },
|
};
|
||||||
table: { value: { alias?: { value: string }; value: { value: string } } }
|
}
|
||||||
) => {
|
) => {
|
||||||
const osqueryTable = find(osquerySchema, ['name', table.value.value.value]);
|
each(['value.left', 'value.right', 'value'], (valueKey) => {
|
||||||
|
if (valueKey) {
|
||||||
|
const osqueryTable = find(osquerySchema, [
|
||||||
|
'name',
|
||||||
|
get(table, `${valueKey}.value.value`),
|
||||||
|
]);
|
||||||
|
|
||||||
if (osqueryTable) {
|
if (osqueryTable) {
|
||||||
acc[table.value.alias?.value ?? table.value.value.value] = osqueryTable.columns;
|
acc[
|
||||||
|
get(table, `${valueKey}.alias.value`) ?? get(table, `${valueKey}.value.value`)
|
||||||
|
] = {
|
||||||
|
columns: osqueryTable.columns,
|
||||||
|
order: Object.keys(acc).length,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
|
@ -659,58 +676,60 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
|
||||||
return currentValue;
|
return currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Simple query
|
|
||||||
select * from users;
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
ast?.selectItems?.value?.length &&
|
|
||||||
ast?.selectItems?.value[0].value === '*' &&
|
|
||||||
ast.from?.value?.length &&
|
|
||||||
ast?.from.value[0].value?.value?.value &&
|
|
||||||
astOsqueryTables[ast.from.value[0].value.value.value]
|
|
||||||
) {
|
|
||||||
const tableName =
|
|
||||||
ast.from.value[0].value.alias?.value ?? ast.from.value[0].value.value.value;
|
|
||||||
|
|
||||||
return astOsqueryTables[ast.from.value[0].value.value.value].map((osqueryColumn) => ({
|
|
||||||
label: osqueryColumn.name,
|
|
||||||
value: {
|
|
||||||
name: osqueryColumn.name,
|
|
||||||
description: osqueryColumn.description,
|
|
||||||
table: tableName,
|
|
||||||
tableOrder: tablesOrderMap[tableName],
|
|
||||||
suggestion_label: osqueryColumn.name,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Advanced query
|
|
||||||
select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
|
|
||||||
*/
|
|
||||||
const suggestions =
|
const suggestions =
|
||||||
isArray(ast?.selectItems?.value) &&
|
isArray(ast?.selectItems?.value) &&
|
||||||
ast?.selectItems?.value
|
ast?.selectItems?.value
|
||||||
// @ts-expect-error update types
|
?.map((selectItem: { type: string; value: string; hasAs: boolean; alias?: string }) => {
|
||||||
?.map((selectItem) => {
|
if (selectItem.type === 'Identifier') {
|
||||||
const [table, column] = selectItem.value?.split('.');
|
/*
|
||||||
|
select * from routes, uptime;
|
||||||
if (column === '*' && astOsqueryTables[table]) {
|
*/
|
||||||
return astOsqueryTables[table].map((osqueryColumn) => ({
|
if (ast?.selectItems?.value.length === 1 && selectItem.value === '*') {
|
||||||
|
return reduce(
|
||||||
|
astOsqueryTables,
|
||||||
|
(acc, { columns: osqueryColumns, order: tableOrder }, table) => {
|
||||||
|
acc.push(
|
||||||
|
...osqueryColumns.map((osqueryColumn) => ({
|
||||||
label: osqueryColumn.name,
|
label: osqueryColumn.name,
|
||||||
value: {
|
value: {
|
||||||
name: osqueryColumn.name,
|
name: osqueryColumn.name,
|
||||||
description: osqueryColumn.description,
|
description: osqueryColumn.description,
|
||||||
table,
|
table,
|
||||||
tableOrder: tablesOrderMap[table],
|
tableOrder,
|
||||||
|
suggestion_label: osqueryColumn.name,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
[] as OsquerySchemaOption[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
|
||||||
|
*/
|
||||||
|
|
||||||
|
const [table, column] = selectItem.value.includes('.')
|
||||||
|
? selectItem.value?.split('.')
|
||||||
|
: [Object.keys(astOsqueryTables)[0], selectItem.value];
|
||||||
|
|
||||||
|
if (column === '*' && astOsqueryTables[table]) {
|
||||||
|
const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table];
|
||||||
|
return osqueryColumns.map((osqueryColumn) => ({
|
||||||
|
label: osqueryColumn.name,
|
||||||
|
value: {
|
||||||
|
name: osqueryColumn.name,
|
||||||
|
description: osqueryColumn.description,
|
||||||
|
table,
|
||||||
|
tableOrder,
|
||||||
suggestion_label: `${osqueryColumn.name}`,
|
suggestion_label: `${osqueryColumn.name}`,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (astOsqueryTables && astOsqueryTables[table]) {
|
if (astOsqueryTables[table]) {
|
||||||
const osqueryColumn = find(astOsqueryTables[table], ['name', column]);
|
const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]);
|
||||||
|
|
||||||
if (osqueryColumn) {
|
if (osqueryColumn) {
|
||||||
const label = selectItem.hasAs ? selectItem.alias : column;
|
const label = selectItem.hasAs ? selectItem.alias : column;
|
||||||
|
@ -722,13 +741,43 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
|
||||||
name: osqueryColumn.name,
|
name: osqueryColumn.name,
|
||||||
description: osqueryColumn.description,
|
description: osqueryColumn.description,
|
||||||
table,
|
table,
|
||||||
tableOrder: tablesOrderMap[table],
|
tableOrder: astOsqueryTables[table].order,
|
||||||
suggestion_label: `${label}`,
|
suggestion_label: `${label}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SELECT pid, uid, name, ROUND((
|
||||||
|
(user_time + system_time) / (cpu_time.tsb - cpu_time.itsb)
|
||||||
|
) * 100, 2) AS percentage
|
||||||
|
FROM processes, (
|
||||||
|
SELECT (
|
||||||
|
SUM(user) + SUM(nice) + SUM(system) + SUM(idle) * 1.0) AS tsb,
|
||||||
|
SUM(COALESCE(idle, 0)) + SUM(COALESCE(iowait, 0)) AS itsb
|
||||||
|
FROM cpu_time
|
||||||
|
) AS cpu_time
|
||||||
|
ORDER BY user_time+system_time DESC
|
||||||
|
LIMIT 5;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (selectItem.type === 'FunctionCall' && selectItem.hasAs) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: selectItem.alias,
|
||||||
|
value: {
|
||||||
|
name: selectItem.alias,
|
||||||
|
description: '',
|
||||||
|
table: '',
|
||||||
|
tableOrder: -1,
|
||||||
|
suggestion_label: selectItem.alias,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue