Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/npm_and_yarn/timesketch/fronten…
Browse files Browse the repository at this point in the history
…d-v3/npm_and_yarn-0189ad7b96
  • Loading branch information
jkppr authored Dec 16, 2024
2 parents 1416095 + ea45105 commit bc88d60
Show file tree
Hide file tree
Showing 31 changed files with 13,312 additions and 43 deletions.
30 changes: 21 additions & 9 deletions api_client/python/timesketch_api_client/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,12 +493,19 @@ def _execute_query(self, file_name="", count=False):
"""Execute a search request and store the results.
Args:
file_name (str): optional file path to a filename that
file_name (str): Optional file path to a filename that
all the results will be saved to. If not provided
the results will be stored in the search object.
count (bool): optional boolean that determines whether
count (bool): Optional boolean that determines whether
we want to execute the query or only count the
number of events that the query would produce.
number of events that the query would produce. If
set to True, the results will be stored in the
search object, and the number of events will be
returned.
Returns:
A dict with the search results or the total number of events
(if count=True) or None if saved to file.
"""
query_filter = self.query_filter
if not isinstance(query_filter, dict):
Expand Down Expand Up @@ -531,14 +538,14 @@ def _execute_query(self, file_name="", count=False):
if file_name:
with open(file_name, "wb") as fw:
fw.write(response.content)
return
return None

response_json = error.get_response_json(response, logger)

if count:
meta = response_json.get("meta", {})
self._total_elastic_size = meta.get("total_count", 0)
return
return meta.get("total_count", 0)

scroll_id = response_json.get("meta", {}).get("scroll_id", "")
form_data["scroll_id"] = scroll_id
Expand Down Expand Up @@ -579,6 +586,7 @@ def _execute_query(self, file_name="", count=False):
)

self._raw_response = response_json
return response_json

def add_chip(self, chip):
"""Add a chip to the ..."""
Expand Down Expand Up @@ -647,7 +655,7 @@ def expected_size(self):
if self._total_elastic_size:
return self._total_elastic_size

self._execute_query(count=True)
_ = self._execute_query(count=True)
return self._total_elastic_size

def from_manual( # pylint: disable=arguments-differ
Expand Down Expand Up @@ -1074,8 +1082,10 @@ def scrolling_enable(self):

def to_dict(self):
"""Returns a dict with the respone of the query."""
if not self._raw_response:
if self._raw_response is None:
self._execute_query()
if self._raw_response is None:
raise ValueError("No results to return.")

return self._raw_response

Expand All @@ -1098,8 +1108,10 @@ def to_file(self, file_name):

def to_pandas(self):
"""Returns a pandas DataFrame with the response of the query."""
if not self._raw_response:
self._execute_query()
if self._raw_response is None:
self._raw_response = self._execute_query()
if self._raw_response is None:
raise ValueError("No results to return.")

return_list = []
timelines = {t.id: t.name for t in self._sketch.list_timelines()}
Expand Down
3 changes: 3 additions & 0 deletions api_client/python/timesketch_api_client/story.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,9 @@ def to_string(self):
string_list.append(block.text)
elif block.TYPE == "view":
search_obj = block.view
if search_obj is None:
logging.warning("Block has no view. Skipping")
continue
data_frame = search_obj.to_pandas()
string_list.append(data_frame.to_string(index=False))
elif block.TYPE == "aggregation":
Expand Down
2 changes: 1 addition & 1 deletion api_client/python/timesketch_api_client/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""Version information for Timesketch API Client."""


__version__ = "20240828"
__version__ = "20241129"


def get_version():
Expand Down
2 changes: 1 addition & 1 deletion data/regex_features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ ssh_client_password_ipv4_addresses:
query_string: 'reporter:"sshd"'
attribute: 'message'
store_as: 'client_ip'
re: '(?:Accepted|Failed) (?:password|publickey) for \w+ from ((?:[0-9]{1,3}\.){3}[0-9]{1,3}) port \d+'
re: '(?:Accepted|Failed) (?:password|publickey) for [A-Za-z0-9._-]+? from ((?:[0-9]{1,3}\.){3}[0-9]{1,3}) port \d+'

ssh_disconnected_username:
query_string: 'reporter:"sshd"'
Expand Down
5 changes: 5 additions & 0 deletions data/sigma_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ logsources:
product: windows
conditions:
data_type: "windows:evtx:record"
service_windows_certificate_services:
service: certificateservicesclient-lifecycle-system
conditions:
source_name:
- "Microsoft-Windows-CertificateServicesClient-Lifecycle-System"
service_windows_security:
service: security
conditions:
Expand Down
80 changes: 80 additions & 0 deletions data/tags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,83 @@ yara_match_tagger:
modifiers: ['split']
save_search: true
search_name: 'Yara rule matches'

aws_cloudtrail_readonly_true:
query_string: 'data_type:"aws:cloudtrail:entry" AND cloud_trail_event:"*readOnly\":true*"'
tags: ['readOnly_true']
emojis: ['MAGNIFYING_GLASS']
save_search: true
search_name: 'readOnly_true'

aws_cloudtrail_readonly_false:
query_string: 'data_type:"aws:cloudtrail:entry" AND cloud_trail_event:"*readOnly\":false*"'
tags: ['readOnly_false']
emojis: ['SPARKLES']
save_search: true
search_name: 'readOnly_false'

aws_cloudtrail_unauthorized_api_call:
query_string: 'data_type:"aws:cloudtrail:entry" AND cloud_trail_event: ("*errorCode\":\"AccessDenied*" OR "*errorCode\":\"UnauthorizedOperation*")'
tags: ['UnauthorizedAPICall']
save_search: true
search_name: 'UnauthorizedAPICall'

aws_cloudtrail_failed_login_non_existent_iam_user:
query_string: 'data_type:"aws:cloudtrail:entry" AND cloud_trail_event:"*userIdentity\":\"HIDDEN_DUE_TO_SECURITY_REASONS*" AND cloud_trail_event:"*errorMessage\":\"No username found in supplied account*"'
tags: ['FailedLoginNonExistentIAMUser']
save_search: true
search_name: 'FailedLoginNonExistentIAMUser'

aws_cloudtrail_security_group:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("AuthorizeSecurityGroupEgress" OR "AuthorizeSecurityGroupIngress" OR "CreateSecurityGroup" OR "DeleteSecurityGroup" OR "ModifySecurityGroupRules" OR "RevokeSecurityGroupEgress" OR "RevokeSecurityGroupIngress")'
tags: ['NetworkChanged', 'SG']
save_search: true
search_name: 'NetworkChanged SecurityGroup'

aws_cloudtrail_network_acl:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("CreateNetworkAcl" OR "CreateNetworkAclEntry" OR "DeleteNetworkAcl" OR "DeleteNetworkAclEntry" OR "ReplaceNetworkAclAssociation" OR "ReplaceNetworkAclEntry")'
tags: ['NetworkChanged', 'NACL']
save_search: true
search_name: 'NetworkChanged NetworkACl'

aws_cloudtrail_gateway:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: (Accept* OR Associate* OR Attach* OR Create* OR Delete* OR Replace*) AND event_name:*Gateway'
tags: ['NetworkChanged', 'GW']
save_search: true
search_name: 'NetworkChanged GateWay'

aws_cloudtrail_routetable:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("CreateRoute" OR "CreateRouteTable" OR "DeleteRoute" OR "DeleteRouteTable" OR "DisassociateRouteTable" OR "ReplaceRoute" OR "ReplaceRouteTableAssociation")'
tags: ['NetworkChanged', 'RouteTable']
save_search: true
search_name: 'NetworkChanged RouteTable'

aws_cloudtrail_vpc:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("AcceptVpcPeeringConnection" OR "AttachClassicLinkVpc" OR "CreateVpc" OR "CreateVpcPeeringConnection" OR "DeleteVpc" OR "DeleteVpcPeeringConnection" OR "DetachClassicLinkVpc" OR "DisableVpcClassicLink" OR "EnableVpcClassicLink" OR "ModifyVpcAttribute" OR "RejectVpcPeeringConnection")'
tags: ['NetworkChanged', 'VPC']
save_search: true
search_name: 'NetworkChanged VPC'

aws_cloudtrail_suspicous_iam_activity:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("AddRoleToInstanceProfile" OR "AddUserToGroup" OR "AssumeRole" OR "AttachGroupPolicy" OR "AttachRolePolicy" OR "AttachUserPolicy" OR "CreateAccessKey" OR "CreateLoginProfile" OR "CreatePolicyVersion" OR "CreateRole" OR "PassRole" OR "PutGroupPolicy" OR "PutRolePolicy" OR "PutUserPolicy" OR "SetDefaultPolicyVersion" OR "UpdateAccessKey" OR "UpdateLoginProfile" OR "GetFederationToken" )'
tags: ['SuspicousIAMActivity']
save_search: true
search_name: 'SuspicousIAMActivity'

aws_cloudtrail_suspicous_iam_identity_center_activity:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name: ("StartSSO" OR "CreateUser" OR "CreateGroup" OR "AddMemberToGroup" OR "CreatePermissionSet" OR "CreateAccountAssignment" OR "Authenticate" OR "Federate" OR "AssumeRoleWithSAML")'
tags: ['SuspicousIICActivity']
save_search: true
search_name: 'SuspicousIICActivity'

aws_cloudtrail_console_login:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name:"ConsoleLogin"'
tags: ['ConsoleLogin']
save_search: true
search_name: 'ConsoleLogin'

aws_cloudtrail_get_caller_identity:
query_string: 'data_type:"aws:cloudtrail:entry" AND event_name:"GetCallerIdentity"'
tags: ['GetCallerIdentity']
save_search: true
search_name: 'GetCallerIdentity'
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"axios": "^1.7.7"
}
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
alembic==1.11.1
altair==4.1.0
celery==5.2.7
cryptography==43.0.0
cryptography==43.0.1
datasketch==1.5.0
dfir-unfurl==20240627
opensearch-py==2.6.0
Expand Down
2 changes: 1 addition & 1 deletion timesketch/frontend-ng/dist/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta name=csrf-token content="{{ csrf_token() }}"><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/dist/favicon.ico><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel=stylesheet><title>Timesketch</title><link href=/dist/css/chunk-vendors.f265108c.css rel=preload as=style><link href=/dist/css/index.008f2248.css rel=preload as=style><link href=/dist/js/chunk-vendors.eba39bd6.js rel=preload as=script><link href=/dist/js/index.fbd54591.js rel=preload as=script><link href=/dist/css/chunk-vendors.f265108c.css rel=stylesheet><link href=/dist/css/index.008f2248.css rel=stylesheet></head><body><div id=app></div><script src=/dist/js/chunk-vendors.eba39bd6.js></script><script src=/dist/js/index.fbd54591.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta name=csrf-token content="{{ csrf_token() }}"><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/dist/favicon.ico><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel=stylesheet><title>Timesketch</title><link href=/dist/css/chunk-vendors.f265108c.css rel=preload as=style><link href=/dist/css/index.008f2248.css rel=preload as=style><link href=/dist/js/chunk-vendors.eba39bd6.js rel=preload as=script><link href=/dist/js/index.1ff10a58.js rel=preload as=script><link href=/dist/css/chunk-vendors.f265108c.css rel=stylesheet><link href=/dist/css/index.008f2248.css rel=stylesheet></head><body><div id=app></div><script src=/dist/js/chunk-vendors.eba39bd6.js></script><script src=/dist/js/index.1ff10a58.js></script></body></html>
2 changes: 2 additions & 0 deletions timesketch/frontend-ng/dist/js/index.1ff10a58.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions timesketch/frontend-ng/dist/js/index.1ff10a58.js.map

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions timesketch/frontend-ng/dist/js/index.fbd54591.js

This file was deleted.

1 change: 0 additions & 1 deletion timesketch/frontend-ng/dist/js/index.fbd54591.js.map

This file was deleted.

2 changes: 1 addition & 1 deletion timesketch/frontend-ng/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"eslint": "^5.8.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-vue": "^5.0.0",
"happy-dom": "^12.10.3",
"happy-dom": "^15.10.1",
"node-sass": "^8.0.0",
"sass": "~1.32",
"sass-loader": "^10.1.1",
Expand Down
9 changes: 8 additions & 1 deletion timesketch/frontend-ng/src/components/Explore/EventList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,14 @@ export default {
}
})
.catch((e) => {
this.errorSnackBar('Sorry, there was a problem fetching your search results. Please try again.')
let msg = 'Sorry, there was a problem fetching your search results. Error: "'+ e.response.data.message +'"'
if (e.response.data.message.includes('too_many_nested_clauses')) {
msg = 'Sorry, your query is too complex. Use field-specific search (like "message:(<query terms>)") and try again.'
this.warningSnackBar(msg)
} else {
this.errorSnackBar(msg)
}
console.error('Error message: ' + msg)
console.error(e)
})
},
Expand Down
6 changes: 6 additions & 0 deletions timesketch/frontend-ng/src/mixins/snackBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Vue.mixin({
snackbar.color = "error"
this.$store.dispatch('setSnackBar', snackbar)
},
warningSnackBar(message) {
let snackbar = defaultSnackBar
snackbar.message = message
snackbar.color = "warning"
this.$store.dispatch('setSnackBar', snackbar)
},
infoSnackBar(message) {
let snackbar = defaultSnackBar
snackbar.message = message
Expand Down
Loading

0 comments on commit bc88d60

Please sign in to comment.