Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement payload contains filtering #57

Merged
merged 2 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions public/syntax_diagram.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,45 @@
}
]
},
{
"type": "Rule",
"name": "searchClause",
"orgText": "",
"definition": [
{
"type": "Alternation",
"idx": 0,
"definition": [
{
"type": "Alternative",
"definition": [
{
"type": "Terminal",
"name": "PAYLOAD",
"label": "PAYLOAD",
"idx": 0,
"pattern": "payload"
},
{
"type": "Terminal",
"name": "CONTAINS",
"label": "contains",
"idx": 0,
"pattern": "contains"
},
{
"type": "Terminal",
"name": "STRING",
"label": "STRING",
"idx": 0,
"pattern": "\\\"[a-zA-Z0-9]+\\\""
}
]
}
]
}
]
},
{
"type": "Rule",
"name": "portItemClause",
Expand Down Expand Up @@ -265,6 +304,16 @@
"pattern": "([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
}
]
},
{
"type": "Alternative",
"definition": [
{
"type": "NonTerminal",
"name": "searchClause",
"idx": 0
}
]
}
]
}
Expand Down
6 changes: 6 additions & 0 deletions src/__tests__/dsl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@ describe('parseDSL', () => {
expect(sx.lexErrors).toHaveLength(0);
expect(sx.parseErrors.length).toBeGreaterThanOrEqual(1);
});

test('parsing payload', () => {
let sx = parseDSL('payload contains "something"');
expect(sx.lexErrors).toHaveLength(0);
expect(sx.parseErrors).toHaveLength(0);
});
});
32 changes: 32 additions & 0 deletions src/dsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const and = createToken({ name: 'AND', pattern: /and/, label: 'and' });
const or = createToken({ name: 'OR', pattern: /or/, label: 'or' });
const not = createToken({ name: 'NOT', pattern: /not/, label: 'not' });

// Search and match operators
const contains = createToken({ name: 'CONTAINS', pattern: /contains/, label: 'contains' });
const matches = createToken({ name: 'MATCHES', pattern: /matches/, label: 'matches' });
const matchesSmb = createToken({ name: 'MATCHES_SMB', pattern: /~/, label: 'matches_smb' });

// Literals
const port = createToken({ name: 'PORT', pattern: /(?:0|[1-9]\d*)/ });
const ipv4 = createToken({
Expand All @@ -35,6 +40,9 @@ const ipDst = createToken({ name: 'IP_DST', pattern: /ip\.dst/ });
const tcpPort = createToken({ name: 'TCP_PORT', pattern: /tcp\.port/ });
const udpPort = createToken({ name: 'UDP_PORT', pattern: /udp\.port/ });

const payload = createToken({ name: 'PAYLOAD', pattern: /payload/ });
const string = createToken({ name: 'STRING', pattern: /\"[a-zA-Z0-9]+\"/ });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider adding special characters here as well, letters and digits should be fine for now.


const whiteSpace = createToken({
name: 'WhiteSpace',
pattern: /\s+/,
Expand All @@ -52,13 +60,20 @@ let allTokens = [
or,
not,

contains,
matches,
matchesSmb,

ipv4,
port,

ipSrc,
ipDst,
tcpPort,
udpPort,

payload,
string,
];

let queryLexer = new Lexer(allTokens);
Expand Down Expand Up @@ -121,6 +136,18 @@ class QueryParser extends CstParser {
]);
});

private searchClause = this.RULE('searchClause', () => {
this.OR([
{
ALT: () => {
this.CONSUME(payload);
this.CONSUME(contains);
this.CONSUME(string);
},
},
]);
});

private portItemClause = this.RULE('portItemClause', () => {
this.OR([
{
Expand Down Expand Up @@ -167,6 +194,11 @@ class QueryParser extends CstParser {
this.CONSUME(ipv4);
},
},
{
ALT: () => {
this.SUBRULE(this.searchClause);
},
},
]);
});

Expand Down
4 changes: 4 additions & 0 deletions src/eventFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ function filterByBooleanClause(event: Event, booleanClauseCstNode: BooleanClause
} else {
throw new Error('Unexpected missing portItemClause');
}
} else if (children.searchClause) {
let payloadString = children.searchClause[0].children.STRING[0].image;
let trimmedString = payloadString.substring(1, payloadString.length - 1);
return atob(event.payload).includes(trimmedString);
} else {
throw new Error('Unexpected booleanClauseCstNode');
}
Expand Down
13 changes: 13 additions & 0 deletions src/generated/chevrotain_dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ export type BooleanClauseCstChildren = {
binaryClause?: BinaryClauseCstNode[];
};

export interface SearchClauseCstNode extends CstNode {
name: 'searchClause';
children: SearchClauseCstChildren;
}

export type SearchClauseCstChildren = {
PAYLOAD?: IToken[];
CONTAINS?: IToken[];
STRING?: IToken[];
};

export interface PortItemClauseCstNode extends CstNode {
name: 'portItemClause';
children: PortItemClauseCstChildren;
Expand Down Expand Up @@ -66,6 +77,7 @@ export type BinaryClauseCstChildren = {
PORT?: IToken[];
ipItemClause?: IpItemClauseCstNode[];
IPV4?: IToken[];
searchClause?: SearchClauseCstNode[];
};

export interface BinaryOperatorCstNode extends CstNode {
Expand All @@ -84,6 +96,7 @@ export interface ICstNodeVisitor<IN, OUT> extends ICstVisitor<IN, OUT> {
query(children: QueryCstChildren, param?: IN): OUT;
booleanSuffixClause(children: BooleanSuffixClauseCstChildren, param?: IN): OUT;
booleanClause(children: BooleanClauseCstChildren, param?: IN): OUT;
searchClause(children: SearchClauseCstChildren, param?: IN): OUT;
portItemClause(children: PortItemClauseCstChildren, param?: IN): OUT;
ipItemClause(children: IpItemClauseCstChildren, param?: IN): OUT;
binaryClause(children: BinaryClauseCstChildren, param?: IN): OUT;
Expand Down
19 changes: 17 additions & 2 deletions src/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ initial query
query
: booleanClause booleanSuffixClause || "NOT" query

booleaSuffixClause:
searchclause
: payload searchOperator string

booleanSuffixClause:
emptyString || OR query || AND query

booleanClause
: binaryClause || unaryClause

binaryClause
: portItemClause binaryOperator integer || ipItemClause binaryOperator ipv4
: portItemClause binaryOperator integer || ipItemClause binaryOperator ipv4 || searchClause

binaryOperator
: "eq" || "==" || "ne" || "!="
Expand All @@ -30,6 +33,18 @@ integer:

ipv4:
: regex([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})

searchClause:
: payload searchOperator string

searchOperators:
"contains" || "matches" || "~"

payload:
: "payload"

string:
: regex([\S]+)
```


Expand Down