{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":133453229,"defaultBranch":"main","name":"kibana","ownerLogin":"mistic","currentUserCanPush":false,"isFork":true,"isEmpty":false,"createdAt":"2018-05-15T03:20:14.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/4440734?v=4","public":true,"private":false,"isOrgOwned":false},"refInfo":{"name":"","listCacheKey":"v0:1721496347.0","currentOid":""},"activityList":{"items":[{"before":"1458ac2e67b1020596471624d23f2e8248a11e06","after":"754e86fddffe73b4973a17748f8658ce70fe1f5d","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-22T13:58:54.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"janmonschke","name":"Jan Monschke","path":"/janmonschke","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/68591?s=80&v=4"},"commit":{"message":"make sure we're comparing numbers","shortMessageHtmlLink":"make sure we're comparing numbers"}},{"before":"fccb5768f6d13f6c068d60600f5fb56c9a9d1f1d","after":"c3deae9e18c723b34f6dafd843089c0c444052b3","ref":"refs/heads/revert-org-wide-pr-bot-7.17","pushedAt":"2024-07-22T13:17:09.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jbudz","name":"Jon","path":"/jbudz","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/3143860?s=80&v=4"},"commit":{"message":"update lockfile","shortMessageHtmlLink":"update lockfile"}},{"before":"0e7a5da4eaca564f94c7b676513a064bb845bf77","after":"fccb5768f6d13f6c068d60600f5fb56c9a9d1f1d","ref":"refs/heads/revert-org-wide-pr-bot-7.17","pushedAt":"2024-07-22T13:06:05.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jbudz","name":"Jon","path":"/jbudz","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/3143860?s=80&v=4"},"commit":{"message":"rebuild buildkite-library","shortMessageHtmlLink":"rebuild buildkite-library"}},{"before":"812d7012b16fc517b74921d9196bfd5777daffbe","after":"0e7a5da4eaca564f94c7b676513a064bb845bf77","ref":"refs/heads/revert-org-wide-pr-bot-7.17","pushedAt":"2024-07-22T13:03:21.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"jbudz","name":"Jon","path":"/jbudz","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/3143860?s=80&v=4"},"commit":{"message":"update buildkite-library","shortMessageHtmlLink":"update buildkite-library"}},{"before":null,"after":"812d7012b16fc517b74921d9196bfd5777daffbe","ref":"refs/heads/revert-org-wide-pr-bot-7.17","pushedAt":"2024-07-20T17:25:47.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"backport revert org wide pr bot #188771","shortMessageHtmlLink":"backport revert org wide pr bot elastic#188771"}},{"before":null,"after":"3295157a0a905ca3cf811d498f735931fadee599","ref":"refs/heads/revert-org-wide-pr-bot-8.14","pushedAt":"2024-07-20T17:22:34.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"backport revert org wide pr bot #188771","shortMessageHtmlLink":"backport revert org wide pr bot elastic#188771"}},{"before":null,"after":"6721109519c3845733ef2babeac1ef7e392aebae","ref":"refs/heads/revert-org-wide-pr-bot-8.15","pushedAt":"2024-07-20T17:20:59.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"backport revert org wide pr bot #188771","shortMessageHtmlLink":"backport revert org wide pr bot elastic#188771"}},{"before":null,"after":"19bcc82a5c628fdbbca343bb078a7f020417b2d2","ref":"refs/heads/backport/8.15/pr-187386","pushedAt":"2024-07-20T17:14:15.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[8.15] [integration automatic-import] Small bugfixes (#188778) (#188785)\n\n# Backport\n\nThis will backport the following commits from `main` to `8.15`:\n- [[integration automatic-import] Small bugfixes\n(#188778)](https://github.com/elastic/kibana/pull/188778)\n\n\n\n### Questions ?\nPlease refer to the [Backport tool\ndocumentation](https://github.com/sqren/backport)\n\n\n\nCo-authored-by: Kylie Meli ","shortMessageHtmlLink":"[8.15] [integration automatic-import] Small bugfixes (elastic#188778) ("}},{"before":"74ebee00f6bc5a27cc4665ad3bc01b89db40d8d1","after":"1458ac2e67b1020596471624d23f2e8248a11e06","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-19T18:24:33.000Z","pushType":"push","commitsCount":52,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"chore(NA): merge and solve conflicts with main","shortMessageHtmlLink":"chore(NA): merge and solve conflicts with main"}},{"before":"6c053fa3588f3bf528c5dc9a3cf2e8ab6e7ee75a","after":"74ebee00f6bc5a27cc4665ad3bc01b89db40d8d1","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-18T15:24:26.000Z","pushType":"push","commitsCount":54,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch 'main' into upgrade-ts-v5.1","shortMessageHtmlLink":"Merge branch 'main' into upgrade-ts-v5.1"}},{"before":"545b8eecbb20530cf64ec36f0b908201c81ace14","after":"9a383fdfb16206c3d243c6094a2264d96064bed5","ref":"refs/heads/backport/8.15/pr-188492","pushedAt":"2024-07-17T20:37:12.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[Security Assistant] Updates ESQL example queries used in ESQL Query Generation (#188492)\n\n## Summary\n\nThis PR updates the pre-packaged ESQL examples used by the ESQL Query\nGeneration tool as provided by @jamesspi. The number of examples have\nstayed the same, as have the file names -- so I've only updated the raw\ncontent here.\n\n> [!NOTE]\n> Since we're enabling the new `kbDataClient` with\nhttps://github.com/elastic/kibana/pull/188168 for `8.15`, there is no\nneed for a delete/re-install for pre-existing deployments to use these\nnew example queries, as the Knowledge Base will be rebuilt on an upgrade\nto `8.15`.\n\nToken length changes as calculated using the [GPT-4\nTokenizer](https://platform.openai.com/tokenizer):\n\n
Existing Example Queries / Tokens: 1,108 / Characters:\n4151\n

\n\n```\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE NOT CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\",\n\"192.168.0.0/16\")\n| STATS destcount = COUNT(destination.ip) by user.name, host.name\n| ENRICH ldap_lookup_new ON user.name\n| WHERE group.name IS NOT NULL\n| EVAL follow_up = CASE(\n destcount >= 100, \"true\",\n \"false\")\n| SORT destcount desc\n| KEEP destcount, host.name, user.name, group.name, follow_up\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| grok dns.question.name\n\"%{DATA}\\\\.%{GREEDYDATA:dns.question.registered_domain:string}\"\n| stats unique_queries = count_distinct(dns.question.name) by\ndns.question.registered_domain, process.name\n| where unique_queries > 5\n| sort unique_queries desc\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.code is not null\n| stats event_code_count = count(event.code) by event.code,host.name\n| enrich win_events on event.code with EVENT_DESCRIPTION\n| where EVENT_DESCRIPTION is not null and host.name is not null\n| rename EVENT_DESCRIPTION as event.description\n| sort event_code_count desc\n| keep event_code_count,event.code,host.name,event.description\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.category == \"file\" and event.action == \"creation\"\n| stats filecount = count(file.name) by process.name,host.name\n| dissect process.name \"%{process}.%{extension}\"\n| eval proclength = length(process.name)\n| where proclength > 10\n| sort filecount,proclength desc\n| limit 10\n| keep\nhost.name,process.name,filecount,process,extension,fullproc,proclength\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where process.name == \"curl.exe\"\n| stats bytes = sum(destination.bytes) by destination.address\n| eval kb = bytes/1024\n| sort kb desc\n| limit 10\n| keep kb,destination.address\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metrics-apm*\n| WHERE metricset.name == \"transaction\" AND metricset.interval == \"1m\"\n| EVAL bucket = AUTO_BUCKET(transaction.duration.histogram, 50,\n, )\n| STATS avg_duration = AVG(transaction.duration.histogram) BY bucket\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM packetbeat-*\n| STATS doc_count = COUNT(destination.domain) BY destination.domain\n| SORT doc_count DESC\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM employees\n| EVAL hire_date_formatted = DATE_FORMAT(hire_date, \"MMMM yyyy\")\n| SORT hire_date\n| KEEP emp_no, hire_date_formatted\n| LIMIT 5\n```\n\n[[esql-example-queries]]\n\nThe following is NOT an example of an ES|QL query:\n\n```\nPagination is not supported\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE @timestamp >= NOW() - 15 minutes\n| EVAL bucket = DATE_TRUNC(1 minute, @timestamp)\n| STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY bucket, host.name\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM traces-apm*\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL successful = CASE(event.outcome == \"success\", 1, 0),\n failed = CASE(event.outcome == \"failure\", 1, 0)\n| STATS success_rate = AVG(successful),\n avg_duration = AVG(transaction.duration),\n total_requests = COUNT(transaction.id) BY service.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metricbeat*\n| EVAL cpu_pct_normalized = (system.cpu.user.pct +\nsystem.cpu.system.pct) / system.cpu.cores\n| STATS AVG(cpu_pct_normalized) BY host.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM postgres-logs\n| DISSECT message \"%{} duration: %{query_duration} ms\"\n| EVAL query_duration_num = TO_DOUBLE(query_duration)\n| STATS avg_duration = AVG(query_duration_num)\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM nyc_taxis\n| WHERE DATE_EXTRACT(drop_off_time, \"hour\") >= 6 AND\nDATE_EXTRACT(drop_off_time, \"hour\") < 10\n| LIMIT 10\n```\n\n```\n

\n
\n\n
8.15 Example Queries / Tokens: 4,847 /\nCharacters:16671\n

\n\n```\n// 1. regex to extract from dns.question.registered_domain\n// Helpful when asking how to use GROK to extract values via REGEX\nfrom logs-*\n| where dns.question.name like \"?*\"\n| grok dns.question.name \"\"\"(?[a-zA-Z0-9]+\\.[a-z-A-Z]{2,3}$)\"\"\"\n| keep dns_registered_domain\n| limit 10\n\n// 2. hunting scheduled task with suspicious actions via registry.data.bytes\n// Helpful when answering questions on regex based searches and replacements (RLIKE and REPLACE), base64 conversions, and dealing with case sensitivity\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"registry\" and event.action == \"modification\" and\n registry.path like \"\"\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*Actions*\"\"\"\n| eval scheduled_task_action = replace(TO_LOWER(FROM_BASE64(registry.data.bytes)), \"\"\"\\u0000\"\"\", \"\")\n| eval scheduled_task_action = replace(scheduled_task_action, \"\"\"(\\u0003\\fauthorfff|\\u0003\\fauthorff\\u000e)\"\"\", \"\")\n| where scheduled_task_action rlike \"\"\".*(users\\\\public\\\\|\\\\appdata\\\\roaming|programdata|powershell|rundll32|regsvr32|mshta.exe|cscript.exe|wscript.exe|cmd.exe|forfiles|msiexec).*\"\"\" and not scheduled_task_action like \"localsystem*\"\n| keep scheduled_task_action, registry.path, agent.id\n| stats count_agents = count_distinct(agent.id) by scheduled_task_action | where count_agents == 1\n\n// 3. suspicious powershell cmds from base64 encoded cmdline\n// Helpful when answering questions on regex based searches and replacements, base64 conversions, and dealing with case sensitivity (TO_LOWER and TO_UPPER commands)\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"process\" and event.action == \"start\" and TO_LOWER(process.name) == \"powershell.exe\" and process.command_line rlike \".+ -(e|E).*\"\n| keep agent.id, process.command_line\n| grok process.command_line \"\"\"(?([A-Za-z0-9+/]+={1,2}$|[A-Za-z0-9+/]{100,}))\"\"\"\n| where base64_data is not null\n| eval decoded_base64_cmdline = replace(TO_LOWER(FROM_BASE64(base64_data)), \"\"\"\\u0000\"\"\", \"\")\n| where decoded_base64_cmdline rlike \"\"\".*(http|webclient|download|mppreference|sockets|bxor|.replace|reflection|assembly|load|bits|start-proc|iwr|frombase64).*\"\"\"\n| keep agent.id, process.command_line, decoded_base64_cmdline\n\n//4. Detect masquerading attempts as native Windows binaries\n//MITRE Tactics: \"Defense Evasion\"\nfrom logs-*\n| where event.type == \"start\" and event.action == \"start\" and host.os.name == \"Windows\" and not starts_with(process.executable, \"C:\\\\Program Files\\\\WindowsApps\\\\\") and not starts_with(process.executable, \"C:\\\\Windows\\\\System32\\\\DriverStore\\\\\") and process.name != \"setup.exe\"\n| keep process.name.caseless, process.executable.caseless, process.code_signature.subject_name, process.code_signature.trusted, process.code_signature.exists, host.id\n| eval system_bin = case(starts_with(process.executable.caseless, \"c:\\\\windows\\\\system32\") and starts_with(process.code_signature.subject_name, \"Microsoft\") and process.code_signature.trusted == true, process.name.caseless, null), non_system_bin = case(process.code_signature.exists == false or process.code_signature.trusted != true or not starts_with(process.code_signature.subject_name, \"Microsoft\"), process.name.caseless, null)\n| stats count_system_bin = count(system_bin), count_non_system_bin = count(non_system_bin) by process.name.caseless, host.id\n| where count_system_bin >= 1 and count_non_system_bin >= 1\n\n//5. Detect DLL Hijack via Masquerading as Microsoft Native Libraries\n// Helpful when asking how to use ENRICH query results with enrich policies\nfrom logs-*\n| where host.os.family == \"windows\" and event.action == \"load\" and process.code_signature.status == \"trusted\" and dll.code_signature.status != \"trusted\" and\n not dll.path rlike \"\"\"[c-fC-F]:\\\\(Windows|windows|WINDOWS)\\\\(System32|SysWOW64|system32|syswow64)\\\\[a-zA-Z0-9_]+.dll\"\"\"\n| keep dll.name, dll.path, dll.hash.sha256, process.executable, host.id\n| ENRICH libs-policy-defend\n| where native == \"yes\" and not starts_with(dll.path, \"C:\\\\Windows\\\\assembly\\\\NativeImages\")\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\"),\n dll_path = replace(dll.path, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| stats host_count = count_distinct(host.id) by dll.name, dll_path, process_path, dll.hash.sha256\n| sort host_count asc\n\n//6. Potential Exfiltration by process total egress bytes\n// Helpful when asking how to filter/search on IP address (CIDR_MATCH) fields and aggregating/grouping\n//MITRE Tactics: \"Command and Control\", \"Exfiltration\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n event.action == \"disconnect_received\" and\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.executable, process.entity_id\n| stats total_bytes_out = sum(source.bytes) by process.entity_id, destination.address, process.executable\n /* more than 1GB out by same process.pid in 8 hours */\n| where total_bytes_out >= 1073741824\n\n//7. Windows logon activity by source IP\n// Helpful when answering questions about the CASE command (as well as conditional outputs/if statements)\n//MITRE Tactics: \"Credential Access\"\nfrom logs-*\n| where host.os.family == \"windows\" and\n event.category == \"authentication\" and event.action in (\"logon-failed\", \"logged-in\") and winlog.logon.type == \"Network\" and\n source.ip is not null and\n /* noisy failure status codes often associated to authentication misconfiguration */\n not (event.action == \"logon-failed\" and winlog.event_data.Status in (\"0xC000015B\", \"0XC000005E\", \"0XC0000133\", \"0XC0000192\"))\n| eval failed = case(event.action == \"logon-failed\", source.ip, null), success = case(event.action == \"logged-in\", source.ip, null)\n| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(winlog.event_data.TargetUserName) by source.ip\n /* below threshold should be adjusted to your env logon patterns */\n| where count_failed >= 100 and count_success <= 10 and count_user >= 20\n\n//8. High count of network connection over extended period by process\n//Helpful when answering questions about IP searches/filters, field converstions(to_double, to_int), and running multiple aggregations\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and (process.executable like \"C:\\\\\\\\Windows\\\\\\\\System32*\" or process.executable like \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\*\") and not user.id in (\"S-1-5-19\", \"S-1-5-20\") and\n/* multiple Windows svchost services perform long term connection to MS ASN, can be covered in a dedicated hunt */\nnot (process.name == \"svchost.exe\" and user.id == \"S-1-5-18\") and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 1 and number_of_con_per_hour >= 120\n\n//9. Persistence via Suspicious Launch Agent or Launch Daemon with low occurrence\n//Helpful when answering questions on concatenating fields, dealing with time based searches\n//MITRE Tactics: \"Persistence\"\nfrom logs-*\n| where @timestamp > now() - 7 day\n| where host.os.family == \"macos\" and event.category == \"file\" and event.action == \"launch_daemon\" and\n (Persistence.runatload == true or Persistence.keepalive == true) and process.executable is not null\n| eval args = MV_CONCAT(Persistence.args, \",\")\n /* normalizing users home profile */\n| eval args = replace(args, \"\"\"/Users/[a-zA-Z0-9ñ\\.\\-\\_\\$~ ]+/\"\"\", \"/Users/user/\")\n| stats agents = count_distinct(host.id), total = count(*) by process.name, Persistence.name, args\n| where starts_with(args, \"/\") and agents == 1 and total == 1\n\n//10. Suspicious Network Connections by unsigned macO\n//Helpful when answering questions on IP filtering, calculating the time difference between timestamps, aggregations, and field conversions\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"macos\" and event.category == \"network\" and\n (process.code_signature.exists == false or process.code_signature.trusted != true) and\n /* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 8 and number_of_con_per_hour >= 120\n\n//11. Unusual file creations by web server user\n//Helpful when answering questions on using the LIKE command (wildcard searches) and aggregations\nFROM logs-*\n| WHERE @timestamp > NOW() - 50 day\n| WHERE host.os.type == \"linux\" and event.type == \"creation\" and user.name in (\"www-data\", \"apache\", \"nginx\", \"httpd\", \"tomcat\", \"lighttpd\", \"glassfish\", \"weblogic\") and (\n file.path like \"/var/www/*\" or\n file.path like \"/var/tmp/*\" or\n file.path like \"/tmp/*\" or\n file.path like \"/dev/shm/*\"\n)\n| STATS file_count = COUNT(file.path), host_count = COUNT(host.name) by file.path, host.name, process.name, user.name\n// Alter this threshold to make sense for your environment\n| WHERE file_count <= 5\n| SORT file_count asc\n| LIMIT 100\n\n//12. Segmentation Fault & Potential Buffer Overflow Hunting\n//Helpful when answering questions on extractions with GROK\nFROM logs-*\n| WHERE host.os.type == \"linux\" and process.name == \"kernel\" and message like \"*segfault*\"\n| GROK message \"\\\\[%{NUMBER:timestamp}\\\\] %{WORD:process}\\\\[%{NUMBER:pid}\\\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\\\[%{BASE16NUM:so_base_address}\\\\+%{BASE16NUM:so_offset}\\\\]\"\n| KEEP timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset\n\n//13. Persistence via Systemd (timers)\n//Helpful when answering questions on using the CASE command (conditional statements), searching lists using the IN command, wildcard searches with the LIKE command and aggregations\nFROM logs-*\n| WHERE host.os.type == \"linux\" and event.type in (\"creation\", \"change\") and (\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\"\n\n) and not (\n process.name in (\n \"dpkg\", \"dockerd\", \"yum\", \"dnf\", \"snapd\", \"pacman\", \"pamac-daemon\",\n \"netplan\", \"systemd\", \"generate\"\n ) or\n process.executable == \"/proc/self/exe\" or\n process.executable like \"/dev/fd/*\" or\n file.extension in (\"dpkg-remove\", \"swx\", \"swp\")\n)\n| EVAL persistence = CASE(\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\",\n process.name,\n null\n)\n| STATS cc = COUNT(*), pers_count = COUNT(persistence), agent_count = COUNT(agent.id) by process.executable, file.path, host.name, user.name\n| WHERE pers_count > 0 and pers_count <= 20 and agent_count <= 3\n| SORT cc asc\n| LIMIT 100\n\n//14. Low Frequency AWS EC2 Admin Password Retrieval Attempts from Unusual ARNs\n//Helpful when answering questions on extracting fields with the dissect command and aggregations. Also an example for hunting for cloud threats\nfrom logs-*\n| where event.provider == \"ec2.amazonaws.com\" and event.action == \"GetPasswordData\"\nand aws.cloudtrail.error_code == \"Client.UnauthorizedOperation\" and aws.cloudtrail.user_identity.type == \"AssumedRole\"\n| dissect aws.cloudtrail.request_parameters \"{%{key}=%{instance_id}}\"\n| dissect aws.cloudtrail.user_identity.session_context.session_issuer.arn \"%{?keyword1}:%{?keyword2}:%{?keyword3}::%{account_id}:%{keyword4}/%{arn_name}\"\n| dissect user.id \"%{principal_id}:%{session_name}\"\n| keep aws.cloudtrail.user_identity.session_context.session_issuer.principal_id, instance_id, account_id, arn_name, source.ip, principal_id, session_name, user.name\n| stats instance_counts = count_distinct(arn_name) by instance_id, user.name, source.ip, session_name\n| where instance_counts < 5\n| sort instance_counts desc\n```\n

\n
\n\n(cherry picked from commit 6137f8185c01a923213de41d7de6337deb21a382)","shortMessageHtmlLink":"[Security Assistant] Updates ESQL example queries used in ESQL Query …"}},{"before":"16f26993320c9fb6070acc270675440bd061d5cc","after":"545b8eecbb20530cf64ec36f0b908201c81ace14","ref":"refs/heads/backport/8.15/pr-188492","pushedAt":"2024-07-17T20:36:29.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[Security Assistant] Updates ESQL example queries used in ESQL Query Generation (#188492)\n\n## Summary\n\nThis PR updates the pre-packaged ESQL examples used by the ESQL Query\nGeneration tool as provided by @jamesspi. The number of examples have\nstayed the same, as have the file names -- so I've only updated the raw\ncontent here.\n\n> [!NOTE]\n> Since we're enabling the new `kbDataClient` with\nhttps://github.com/elastic/kibana/pull/188168 for `8.15`, there is no\nneed for a delete/re-install for pre-existing deployments to use these\nnew example queries, as the Knowledge Base will be rebuilt on an upgrade\nto `8.15`.\n\nToken length changes as calculated using the [GPT-4\nTokenizer](https://platform.openai.com/tokenizer):\n\n
Existing Example Queries / Tokens: 1,108 / Characters:\n4151\n

\n\n```\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE NOT CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\",\n\"192.168.0.0/16\")\n| STATS destcount = COUNT(destination.ip) by user.name, host.name\n| ENRICH ldap_lookup_new ON user.name\n| WHERE group.name IS NOT NULL\n| EVAL follow_up = CASE(\n destcount >= 100, \"true\",\n \"false\")\n| SORT destcount desc\n| KEEP destcount, host.name, user.name, group.name, follow_up\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| grok dns.question.name\n\"%{DATA}\\\\.%{GREEDYDATA:dns.question.registered_domain:string}\"\n| stats unique_queries = count_distinct(dns.question.name) by\ndns.question.registered_domain, process.name\n| where unique_queries > 5\n| sort unique_queries desc\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.code is not null\n| stats event_code_count = count(event.code) by event.code,host.name\n| enrich win_events on event.code with EVENT_DESCRIPTION\n| where EVENT_DESCRIPTION is not null and host.name is not null\n| rename EVENT_DESCRIPTION as event.description\n| sort event_code_count desc\n| keep event_code_count,event.code,host.name,event.description\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.category == \"file\" and event.action == \"creation\"\n| stats filecount = count(file.name) by process.name,host.name\n| dissect process.name \"%{process}.%{extension}\"\n| eval proclength = length(process.name)\n| where proclength > 10\n| sort filecount,proclength desc\n| limit 10\n| keep\nhost.name,process.name,filecount,process,extension,fullproc,proclength\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where process.name == \"curl.exe\"\n| stats bytes = sum(destination.bytes) by destination.address\n| eval kb = bytes/1024\n| sort kb desc\n| limit 10\n| keep kb,destination.address\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metrics-apm*\n| WHERE metricset.name == \"transaction\" AND metricset.interval == \"1m\"\n| EVAL bucket = AUTO_BUCKET(transaction.duration.histogram, 50,\n, )\n| STATS avg_duration = AVG(transaction.duration.histogram) BY bucket\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM packetbeat-*\n| STATS doc_count = COUNT(destination.domain) BY destination.domain\n| SORT doc_count DESC\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM employees\n| EVAL hire_date_formatted = DATE_FORMAT(hire_date, \"MMMM yyyy\")\n| SORT hire_date\n| KEEP emp_no, hire_date_formatted\n| LIMIT 5\n```\n\n[[esql-example-queries]]\n\nThe following is NOT an example of an ES|QL query:\n\n```\nPagination is not supported\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE @timestamp >= NOW() - 15 minutes\n| EVAL bucket = DATE_TRUNC(1 minute, @timestamp)\n| STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY bucket, host.name\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM traces-apm*\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL successful = CASE(event.outcome == \"success\", 1, 0),\n failed = CASE(event.outcome == \"failure\", 1, 0)\n| STATS success_rate = AVG(successful),\n avg_duration = AVG(transaction.duration),\n total_requests = COUNT(transaction.id) BY service.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metricbeat*\n| EVAL cpu_pct_normalized = (system.cpu.user.pct +\nsystem.cpu.system.pct) / system.cpu.cores\n| STATS AVG(cpu_pct_normalized) BY host.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM postgres-logs\n| DISSECT message \"%{} duration: %{query_duration} ms\"\n| EVAL query_duration_num = TO_DOUBLE(query_duration)\n| STATS avg_duration = AVG(query_duration_num)\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM nyc_taxis\n| WHERE DATE_EXTRACT(drop_off_time, \"hour\") >= 6 AND\nDATE_EXTRACT(drop_off_time, \"hour\") < 10\n| LIMIT 10\n```\n\n```\n

\n
\n\n
8.15 Example Queries / Tokens: 4,847 /\nCharacters:16671\n

\n\n```\n// 1. regex to extract from dns.question.registered_domain\n// Helpful when asking how to use GROK to extract values via REGEX\nfrom logs-*\n| where dns.question.name like \"?*\"\n| grok dns.question.name \"\"\"(?[a-zA-Z0-9]+\\.[a-z-A-Z]{2,3}$)\"\"\"\n| keep dns_registered_domain\n| limit 10\n\n// 2. hunting scheduled task with suspicious actions via registry.data.bytes\n// Helpful when answering questions on regex based searches and replacements (RLIKE and REPLACE), base64 conversions, and dealing with case sensitivity\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"registry\" and event.action == \"modification\" and\n registry.path like \"\"\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*Actions*\"\"\"\n| eval scheduled_task_action = replace(TO_LOWER(FROM_BASE64(registry.data.bytes)), \"\"\"\\u0000\"\"\", \"\")\n| eval scheduled_task_action = replace(scheduled_task_action, \"\"\"(\\u0003\\fauthorfff|\\u0003\\fauthorff\\u000e)\"\"\", \"\")\n| where scheduled_task_action rlike \"\"\".*(users\\\\public\\\\|\\\\appdata\\\\roaming|programdata|powershell|rundll32|regsvr32|mshta.exe|cscript.exe|wscript.exe|cmd.exe|forfiles|msiexec).*\"\"\" and not scheduled_task_action like \"localsystem*\"\n| keep scheduled_task_action, registry.path, agent.id\n| stats count_agents = count_distinct(agent.id) by scheduled_task_action | where count_agents == 1\n\n// 3. suspicious powershell cmds from base64 encoded cmdline\n// Helpful when answering questions on regex based searches and replacements, base64 conversions, and dealing with case sensitivity (TO_LOWER and TO_UPPER commands)\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"process\" and event.action == \"start\" and TO_LOWER(process.name) == \"powershell.exe\" and process.command_line rlike \".+ -(e|E).*\"\n| keep agent.id, process.command_line\n| grok process.command_line \"\"\"(?([A-Za-z0-9+/]+={1,2}$|[A-Za-z0-9+/]{100,}))\"\"\"\n| where base64_data is not null\n| eval decoded_base64_cmdline = replace(TO_LOWER(FROM_BASE64(base64_data)), \"\"\"\\u0000\"\"\", \"\")\n| where decoded_base64_cmdline rlike \"\"\".*(http|webclient|download|mppreference|sockets|bxor|.replace|reflection|assembly|load|bits|start-proc|iwr|frombase64).*\"\"\"\n| keep agent.id, process.command_line, decoded_base64_cmdline\n\n//4. Detect masquerading attempts as native Windows binaries\n//MITRE Tactics: \"Defense Evasion\"\nfrom logs-*\n| where event.type == \"start\" and event.action == \"start\" and host.os.name == \"Windows\" and not starts_with(process.executable, \"C:\\\\Program Files\\\\WindowsApps\\\\\") and not starts_with(process.executable, \"C:\\\\Windows\\\\System32\\\\DriverStore\\\\\") and process.name != \"setup.exe\"\n| keep process.name.caseless, process.executable.caseless, process.code_signature.subject_name, process.code_signature.trusted, process.code_signature.exists, host.id\n| eval system_bin = case(starts_with(process.executable.caseless, \"c:\\\\windows\\\\system32\") and starts_with(process.code_signature.subject_name, \"Microsoft\") and process.code_signature.trusted == true, process.name.caseless, null), non_system_bin = case(process.code_signature.exists == false or process.code_signature.trusted != true or not starts_with(process.code_signature.subject_name, \"Microsoft\"), process.name.caseless, null)\n| stats count_system_bin = count(system_bin), count_non_system_bin = count(non_system_bin) by process.name.caseless, host.id\n| where count_system_bin >= 1 and count_non_system_bin >= 1\n\n//5. Detect DLL Hijack via Masquerading as Microsoft Native Libraries\n// Helpful when asking how to use ENRICH query results with enrich policies\nfrom logs-*\n| where host.os.family == \"windows\" and event.action == \"load\" and process.code_signature.status == \"trusted\" and dll.code_signature.status != \"trusted\" and\n not dll.path rlike \"\"\"[c-fC-F]:\\\\(Windows|windows|WINDOWS)\\\\(System32|SysWOW64|system32|syswow64)\\\\[a-zA-Z0-9_]+.dll\"\"\"\n| keep dll.name, dll.path, dll.hash.sha256, process.executable, host.id\n| ENRICH libs-policy-defend\n| where native == \"yes\" and not starts_with(dll.path, \"C:\\\\Windows\\\\assembly\\\\NativeImages\")\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\"),\n dll_path = replace(dll.path, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| stats host_count = count_distinct(host.id) by dll.name, dll_path, process_path, dll.hash.sha256\n| sort host_count asc\n\n//6. Potential Exfiltration by process total egress bytes\n// Helpful when asking how to filter/search on IP address (CIDR_MATCH) fields and aggregating/grouping\n//MITRE Tactics: \"Command and Control\", \"Exfiltration\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n event.action == \"disconnect_received\" and\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.executable, process.entity_id\n| stats total_bytes_out = sum(source.bytes) by process.entity_id, destination.address, process.executable\n /* more than 1GB out by same process.pid in 8 hours */\n| where total_bytes_out >= 1073741824\n\n//7. Windows logon activity by source IP\n// Helpful when answering questions about the CASE command (as well as conditional outputs/if statements)\n//MITRE Tactics: \"Credential Access\"\nfrom logs-*\n| where host.os.family == \"windows\" and\n event.category == \"authentication\" and event.action in (\"logon-failed\", \"logged-in\") and winlog.logon.type == \"Network\" and\n source.ip is not null and\n /* noisy failure status codes often associated to authentication misconfiguration */\n not (event.action == \"logon-failed\" and winlog.event_data.Status in (\"0xC000015B\", \"0XC000005E\", \"0XC0000133\", \"0XC0000192\"))\n| eval failed = case(event.action == \"logon-failed\", source.ip, null), success = case(event.action == \"logged-in\", source.ip, null)\n| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(winlog.event_data.TargetUserName) by source.ip\n /* below threshold should be adjusted to your env logon patterns */\n| where count_failed >= 100 and count_success <= 10 and count_user >= 20\n\n//8. High count of network connection over extended period by process\n//Helpful when answering questions about IP searches/filters, field converstions(to_double, to_int), and running multiple aggregations\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and (process.executable like \"C:\\\\\\\\Windows\\\\\\\\System32*\" or process.executable like \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\*\") and not user.id in (\"S-1-5-19\", \"S-1-5-20\") and\n/* multiple Windows svchost services perform long term connection to MS ASN, can be covered in a dedicated hunt */\nnot (process.name == \"svchost.exe\" and user.id == \"S-1-5-18\") and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 1 and number_of_con_per_hour >= 120\n\n//9. Persistence via Suspicious Launch Agent or Launch Daemon with low occurrence\n//Helpful when answering questions on concatenating fields, dealing with time based searches\n//MITRE Tactics: \"Persistence\"\nfrom logs-*\n| where @timestamp > now() - 7 day\n| where host.os.family == \"macos\" and event.category == \"file\" and event.action == \"launch_daemon\" and\n (Persistence.runatload == true or Persistence.keepalive == true) and process.executable is not null\n| eval args = MV_CONCAT(Persistence.args, \",\")\n /* normalizing users home profile */\n| eval args = replace(args, \"\"\"/Users/[a-zA-Z0-9ñ\\.\\-\\_\\$~ ]+/\"\"\", \"/Users/user/\")\n| stats agents = count_distinct(host.id), total = count(*) by process.name, Persistence.name, args\n| where starts_with(args, \"/\") and agents == 1 and total == 1\n\n//10. Suspicious Network Connections by unsigned macO\n//Helpful when answering questions on IP filtering, calculating the time difference between timestamps, aggregations, and field conversions\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"macos\" and event.category == \"network\" and\n (process.code_signature.exists == false or process.code_signature.trusted != true) and\n /* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 8 and number_of_con_per_hour >= 120\n\n//11. Unusual file creations by web server user\n//Helpful when answering questions on using the LIKE command (wildcard searches) and aggregations\nFROM logs-*\n| WHERE @timestamp > NOW() - 50 day\n| WHERE host.os.type == \"linux\" and event.type == \"creation\" and user.name in (\"www-data\", \"apache\", \"nginx\", \"httpd\", \"tomcat\", \"lighttpd\", \"glassfish\", \"weblogic\") and (\n file.path like \"/var/www/*\" or\n file.path like \"/var/tmp/*\" or\n file.path like \"/tmp/*\" or\n file.path like \"/dev/shm/*\"\n)\n| STATS file_count = COUNT(file.path), host_count = COUNT(host.name) by file.path, host.name, process.name, user.name\n// Alter this threshold to make sense for your environment\n| WHERE file_count <= 5\n| SORT file_count asc\n| LIMIT 100\n\n//12. Segmentation Fault & Potential Buffer Overflow Hunting\n//Helpful when answering questions on extractions with GROK\nFROM logs-*\n| WHERE host.os.type == \"linux\" and process.name == \"kernel\" and message like \"*segfault*\"\n| GROK message \"\\\\[%{NUMBER:timestamp}\\\\] %{WORD:process}\\\\[%{NUMBER:pid}\\\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\\\[%{BASE16NUM:so_base_address}\\\\+%{BASE16NUM:so_offset}\\\\]\"\n| KEEP timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset\n\n//13. Persistence via Systemd (timers)\n//Helpful when answering questions on using the CASE command (conditional statements), searching lists using the IN command, wildcard searches with the LIKE command and aggregations\nFROM logs-*\n| WHERE host.os.type == \"linux\" and event.type in (\"creation\", \"change\") and (\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\"\n\n) and not (\n process.name in (\n \"dpkg\", \"dockerd\", \"yum\", \"dnf\", \"snapd\", \"pacman\", \"pamac-daemon\",\n \"netplan\", \"systemd\", \"generate\"\n ) or\n process.executable == \"/proc/self/exe\" or\n process.executable like \"/dev/fd/*\" or\n file.extension in (\"dpkg-remove\", \"swx\", \"swp\")\n)\n| EVAL persistence = CASE(\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\",\n process.name,\n null\n)\n| STATS cc = COUNT(*), pers_count = COUNT(persistence), agent_count = COUNT(agent.id) by process.executable, file.path, host.name, user.name\n| WHERE pers_count > 0 and pers_count <= 20 and agent_count <= 3\n| SORT cc asc\n| LIMIT 100\n\n//14. Low Frequency AWS EC2 Admin Password Retrieval Attempts from Unusual ARNs\n//Helpful when answering questions on extracting fields with the dissect command and aggregations. Also an example for hunting for cloud threats\nfrom logs-*\n| where event.provider == \"ec2.amazonaws.com\" and event.action == \"GetPasswordData\"\nand aws.cloudtrail.error_code == \"Client.UnauthorizedOperation\" and aws.cloudtrail.user_identity.type == \"AssumedRole\"\n| dissect aws.cloudtrail.request_parameters \"{%{key}=%{instance_id}}\"\n| dissect aws.cloudtrail.user_identity.session_context.session_issuer.arn \"%{?keyword1}:%{?keyword2}:%{?keyword3}::%{account_id}:%{keyword4}/%{arn_name}\"\n| dissect user.id \"%{principal_id}:%{session_name}\"\n| keep aws.cloudtrail.user_identity.session_context.session_issuer.principal_id, instance_id, account_id, arn_name, source.ip, principal_id, session_name, user.name\n| stats instance_counts = count_distinct(arn_name) by instance_id, user.name, source.ip, session_name\n| where instance_counts < 5\n| sort instance_counts desc\n```\n

\n
\n\n(cherry picked from commit 6137f8185c01a923213de41d7de6337deb21a382)","shortMessageHtmlLink":"[Security Assistant] Updates ESQL example queries used in ESQL Query …"}},{"before":"5d572a96114172a818a50354d2856f1866a839f9","after":"16f26993320c9fb6070acc270675440bd061d5cc","ref":"refs/heads/backport/8.15/pr-188492","pushedAt":"2024-07-17T20:33:23.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[Security Assistant] Updates ESQL example queries used in ESQL Query Generation (#188492)\n\n## Summary\n\nThis PR updates the pre-packaged ESQL examples used by the ESQL Query\nGeneration tool as provided by @jamesspi. The number of examples have\nstayed the same, as have the file names -- so I've only updated the raw\ncontent here.\n\n> [!NOTE]\n> Since we're enabling the new `kbDataClient` with\nhttps://github.com/elastic/kibana/pull/188168 for `8.15`, there is no\nneed for a delete/re-install for pre-existing deployments to use these\nnew example queries, as the Knowledge Base will be rebuilt on an upgrade\nto `8.15`.\n\nToken length changes as calculated using the [GPT-4\nTokenizer](https://platform.openai.com/tokenizer):\n\n
Existing Example Queries / Tokens: 1,108 / Characters:\n4151\n

\n\n```\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE NOT CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\",\n\"192.168.0.0/16\")\n| STATS destcount = COUNT(destination.ip) by user.name, host.name\n| ENRICH ldap_lookup_new ON user.name\n| WHERE group.name IS NOT NULL\n| EVAL follow_up = CASE(\n destcount >= 100, \"true\",\n \"false\")\n| SORT destcount desc\n| KEEP destcount, host.name, user.name, group.name, follow_up\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| grok dns.question.name\n\"%{DATA}\\\\.%{GREEDYDATA:dns.question.registered_domain:string}\"\n| stats unique_queries = count_distinct(dns.question.name) by\ndns.question.registered_domain, process.name\n| where unique_queries > 5\n| sort unique_queries desc\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.code is not null\n| stats event_code_count = count(event.code) by event.code,host.name\n| enrich win_events on event.code with EVENT_DESCRIPTION\n| where EVENT_DESCRIPTION is not null and host.name is not null\n| rename EVENT_DESCRIPTION as event.description\n| sort event_code_count desc\n| keep event_code_count,event.code,host.name,event.description\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.category == \"file\" and event.action == \"creation\"\n| stats filecount = count(file.name) by process.name,host.name\n| dissect process.name \"%{process}.%{extension}\"\n| eval proclength = length(process.name)\n| where proclength > 10\n| sort filecount,proclength desc\n| limit 10\n| keep\nhost.name,process.name,filecount,process,extension,fullproc,proclength\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where process.name == \"curl.exe\"\n| stats bytes = sum(destination.bytes) by destination.address\n| eval kb = bytes/1024\n| sort kb desc\n| limit 10\n| keep kb,destination.address\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metrics-apm*\n| WHERE metricset.name == \"transaction\" AND metricset.interval == \"1m\"\n| EVAL bucket = AUTO_BUCKET(transaction.duration.histogram, 50,\n, )\n| STATS avg_duration = AVG(transaction.duration.histogram) BY bucket\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM packetbeat-*\n| STATS doc_count = COUNT(destination.domain) BY destination.domain\n| SORT doc_count DESC\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM employees\n| EVAL hire_date_formatted = DATE_FORMAT(hire_date, \"MMMM yyyy\")\n| SORT hire_date\n| KEEP emp_no, hire_date_formatted\n| LIMIT 5\n```\n\n[[esql-example-queries]]\n\nThe following is NOT an example of an ES|QL query:\n\n```\nPagination is not supported\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE @timestamp >= NOW() - 15 minutes\n| EVAL bucket = DATE_TRUNC(1 minute, @timestamp)\n| STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY bucket, host.name\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM traces-apm*\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL successful = CASE(event.outcome == \"success\", 1, 0),\n failed = CASE(event.outcome == \"failure\", 1, 0)\n| STATS success_rate = AVG(successful),\n avg_duration = AVG(transaction.duration),\n total_requests = COUNT(transaction.id) BY service.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metricbeat*\n| EVAL cpu_pct_normalized = (system.cpu.user.pct +\nsystem.cpu.system.pct) / system.cpu.cores\n| STATS AVG(cpu_pct_normalized) BY host.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM postgres-logs\n| DISSECT message \"%{} duration: %{query_duration} ms\"\n| EVAL query_duration_num = TO_DOUBLE(query_duration)\n| STATS avg_duration = AVG(query_duration_num)\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM nyc_taxis\n| WHERE DATE_EXTRACT(drop_off_time, \"hour\") >= 6 AND\nDATE_EXTRACT(drop_off_time, \"hour\") < 10\n| LIMIT 10\n```\n\n```\n

\n
\n\n
8.15 Example Queries / Tokens: 4,847 /\nCharacters:16671\n

\n\n```\n// 1. regex to extract from dns.question.registered_domain\n// Helpful when asking how to use GROK to extract values via REGEX\nfrom logs-*\n| where dns.question.name like \"?*\"\n| grok dns.question.name \"\"\"(?[a-zA-Z0-9]+\\.[a-z-A-Z]{2,3}$)\"\"\"\n| keep dns_registered_domain\n| limit 10\n\n// 2. hunting scheduled task with suspicious actions via registry.data.bytes\n// Helpful when answering questions on regex based searches and replacements (RLIKE and REPLACE), base64 conversions, and dealing with case sensitivity\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"registry\" and event.action == \"modification\" and\n registry.path like \"\"\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*Actions*\"\"\"\n| eval scheduled_task_action = replace(TO_LOWER(FROM_BASE64(registry.data.bytes)), \"\"\"\\u0000\"\"\", \"\")\n| eval scheduled_task_action = replace(scheduled_task_action, \"\"\"(\\u0003\\fauthorfff|\\u0003\\fauthorff\\u000e)\"\"\", \"\")\n| where scheduled_task_action rlike \"\"\".*(users\\\\public\\\\|\\\\appdata\\\\roaming|programdata|powershell|rundll32|regsvr32|mshta.exe|cscript.exe|wscript.exe|cmd.exe|forfiles|msiexec).*\"\"\" and not scheduled_task_action like \"localsystem*\"\n| keep scheduled_task_action, registry.path, agent.id\n| stats count_agents = count_distinct(agent.id) by scheduled_task_action | where count_agents == 1\n\n// 3. suspicious powershell cmds from base64 encoded cmdline\n// Helpful when answering questions on regex based searches and replacements, base64 conversions, and dealing with case sensitivity (TO_LOWER and TO_UPPER commands)\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"process\" and event.action == \"start\" and TO_LOWER(process.name) == \"powershell.exe\" and process.command_line rlike \".+ -(e|E).*\"\n| keep agent.id, process.command_line\n| grok process.command_line \"\"\"(?([A-Za-z0-9+/]+={1,2}$|[A-Za-z0-9+/]{100,}))\"\"\"\n| where base64_data is not null\n| eval decoded_base64_cmdline = replace(TO_LOWER(FROM_BASE64(base64_data)), \"\"\"\\u0000\"\"\", \"\")\n| where decoded_base64_cmdline rlike \"\"\".*(http|webclient|download|mppreference|sockets|bxor|.replace|reflection|assembly|load|bits|start-proc|iwr|frombase64).*\"\"\"\n| keep agent.id, process.command_line, decoded_base64_cmdline\n\n//4. Detect masquerading attempts as native Windows binaries\n//MITRE Tactics: \"Defense Evasion\"\nfrom logs-*\n| where event.type == \"start\" and event.action == \"start\" and host.os.name == \"Windows\" and not starts_with(process.executable, \"C:\\\\Program Files\\\\WindowsApps\\\\\") and not starts_with(process.executable, \"C:\\\\Windows\\\\System32\\\\DriverStore\\\\\") and process.name != \"setup.exe\"\n| keep process.name.caseless, process.executable.caseless, process.code_signature.subject_name, process.code_signature.trusted, process.code_signature.exists, host.id\n| eval system_bin = case(starts_with(process.executable.caseless, \"c:\\\\windows\\\\system32\") and starts_with(process.code_signature.subject_name, \"Microsoft\") and process.code_signature.trusted == true, process.name.caseless, null), non_system_bin = case(process.code_signature.exists == false or process.code_signature.trusted != true or not starts_with(process.code_signature.subject_name, \"Microsoft\"), process.name.caseless, null)\n| stats count_system_bin = count(system_bin), count_non_system_bin = count(non_system_bin) by process.name.caseless, host.id\n| where count_system_bin >= 1 and count_non_system_bin >= 1\n\n//5. Detect DLL Hijack via Masquerading as Microsoft Native Libraries\n// Helpful when asking how to use ENRICH query results with enrich policies\nfrom logs-*\n| where host.os.family == \"windows\" and event.action == \"load\" and process.code_signature.status == \"trusted\" and dll.code_signature.status != \"trusted\" and\n not dll.path rlike \"\"\"[c-fC-F]:\\\\(Windows|windows|WINDOWS)\\\\(System32|SysWOW64|system32|syswow64)\\\\[a-zA-Z0-9_]+.dll\"\"\"\n| keep dll.name, dll.path, dll.hash.sha256, process.executable, host.id\n| ENRICH libs-policy-defend\n| where native == \"yes\" and not starts_with(dll.path, \"C:\\\\Windows\\\\assembly\\\\NativeImages\")\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\"),\n dll_path = replace(dll.path, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| stats host_count = count_distinct(host.id) by dll.name, dll_path, process_path, dll.hash.sha256\n| sort host_count asc\n\n//6. Potential Exfiltration by process total egress bytes\n// Helpful when asking how to filter/search on IP address (CIDR_MATCH) fields and aggregating/grouping\n//MITRE Tactics: \"Command and Control\", \"Exfiltration\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n event.action == \"disconnect_received\" and\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.executable, process.entity_id\n| stats total_bytes_out = sum(source.bytes) by process.entity_id, destination.address, process.executable\n /* more than 1GB out by same process.pid in 8 hours */\n| where total_bytes_out >= 1073741824\n\n//7. Windows logon activity by source IP\n// Helpful when answering questions about the CASE command (as well as conditional outputs/if statements)\n//MITRE Tactics: \"Credential Access\"\nfrom logs-*\n| where host.os.family == \"windows\" and\n event.category == \"authentication\" and event.action in (\"logon-failed\", \"logged-in\") and winlog.logon.type == \"Network\" and\n source.ip is not null and\n /* noisy failure status codes often associated to authentication misconfiguration */\n not (event.action == \"logon-failed\" and winlog.event_data.Status in (\"0xC000015B\", \"0XC000005E\", \"0XC0000133\", \"0XC0000192\"))\n| eval failed = case(event.action == \"logon-failed\", source.ip, null), success = case(event.action == \"logged-in\", source.ip, null)\n| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(winlog.event_data.TargetUserName) by source.ip\n /* below threshold should be adjusted to your env logon patterns */\n| where count_failed >= 100 and count_success <= 10 and count_user >= 20\n\n//8. High count of network connection over extended period by process\n//Helpful when answering questions about IP searches/filters, field converstions(to_double, to_int), and running multiple aggregations\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and (process.executable like \"C:\\\\\\\\Windows\\\\\\\\System32*\" or process.executable like \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\*\") and not user.id in (\"S-1-5-19\", \"S-1-5-20\") and\n/* multiple Windows svchost services perform long term connection to MS ASN, can be covered in a dedicated hunt */\nnot (process.name == \"svchost.exe\" and user.id == \"S-1-5-18\") and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 1 and number_of_con_per_hour >= 120\n\n//9. Persistence via Suspicious Launch Agent or Launch Daemon with low occurrence\n//Helpful when answering questions on concatenating fields, dealing with time based searches\n//MITRE Tactics: \"Persistence\"\nfrom logs-*\n| where @timestamp > now() - 7 day\n| where host.os.family == \"macos\" and event.category == \"file\" and event.action == \"launch_daemon\" and\n (Persistence.runatload == true or Persistence.keepalive == true) and process.executable is not null\n| eval args = MV_CONCAT(Persistence.args, \",\")\n /* normalizing users home profile */\n| eval args = replace(args, \"\"\"/Users/[a-zA-Z0-9ñ\\.\\-\\_\\$~ ]+/\"\"\", \"/Users/user/\")\n| stats agents = count_distinct(host.id), total = count(*) by process.name, Persistence.name, args\n| where starts_with(args, \"/\") and agents == 1 and total == 1\n\n//10. Suspicious Network Connections by unsigned macO\n//Helpful when answering questions on IP filtering, calculating the time difference between timestamps, aggregations, and field conversions\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"macos\" and event.category == \"network\" and\n (process.code_signature.exists == false or process.code_signature.trusted != true) and\n /* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 8 and number_of_con_per_hour >= 120\n\n//11. Unusual file creations by web server user\n//Helpful when answering questions on using the LIKE command (wildcard searches) and aggregations\nFROM logs-*\n| WHERE @timestamp > NOW() - 50 day\n| WHERE host.os.type == \"linux\" and event.type == \"creation\" and user.name in (\"www-data\", \"apache\", \"nginx\", \"httpd\", \"tomcat\", \"lighttpd\", \"glassfish\", \"weblogic\") and (\n file.path like \"/var/www/*\" or\n file.path like \"/var/tmp/*\" or\n file.path like \"/tmp/*\" or\n file.path like \"/dev/shm/*\"\n)\n| STATS file_count = COUNT(file.path), host_count = COUNT(host.name) by file.path, host.name, process.name, user.name\n// Alter this threshold to make sense for your environment\n| WHERE file_count <= 5\n| SORT file_count asc\n| LIMIT 100\n\n//12. Segmentation Fault & Potential Buffer Overflow Hunting\n//Helpful when answering questions on extractions with GROK\nFROM logs-*\n| WHERE host.os.type == \"linux\" and process.name == \"kernel\" and message like \"*segfault*\"\n| GROK message \"\\\\[%{NUMBER:timestamp}\\\\] %{WORD:process}\\\\[%{NUMBER:pid}\\\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\\\[%{BASE16NUM:so_base_address}\\\\+%{BASE16NUM:so_offset}\\\\]\"\n| KEEP timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset\n\n//13. Persistence via Systemd (timers)\n//Helpful when answering questions on using the CASE command (conditional statements), searching lists using the IN command, wildcard searches with the LIKE command and aggregations\nFROM logs-*\n| WHERE host.os.type == \"linux\" and event.type in (\"creation\", \"change\") and (\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\"\n\n) and not (\n process.name in (\n \"dpkg\", \"dockerd\", \"yum\", \"dnf\", \"snapd\", \"pacman\", \"pamac-daemon\",\n \"netplan\", \"systemd\", \"generate\"\n ) or\n process.executable == \"/proc/self/exe\" or\n process.executable like \"/dev/fd/*\" or\n file.extension in (\"dpkg-remove\", \"swx\", \"swp\")\n)\n| EVAL persistence = CASE(\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\",\n process.name,\n null\n)\n| STATS cc = COUNT(*), pers_count = COUNT(persistence), agent_count = COUNT(agent.id) by process.executable, file.path, host.name, user.name\n| WHERE pers_count > 0 and pers_count <= 20 and agent_count <= 3\n| SORT cc asc\n| LIMIT 100\n\n//14. Low Frequency AWS EC2 Admin Password Retrieval Attempts from Unusual ARNs\n//Helpful when answering questions on extracting fields with the dissect command and aggregations. Also an example for hunting for cloud threats\nfrom logs-*\n| where event.provider == \"ec2.amazonaws.com\" and event.action == \"GetPasswordData\"\nand aws.cloudtrail.error_code == \"Client.UnauthorizedOperation\" and aws.cloudtrail.user_identity.type == \"AssumedRole\"\n| dissect aws.cloudtrail.request_parameters \"{%{key}=%{instance_id}}\"\n| dissect aws.cloudtrail.user_identity.session_context.session_issuer.arn \"%{?keyword1}:%{?keyword2}:%{?keyword3}::%{account_id}:%{keyword4}/%{arn_name}\"\n| dissect user.id \"%{principal_id}:%{session_name}\"\n| keep aws.cloudtrail.user_identity.session_context.session_issuer.principal_id, instance_id, account_id, arn_name, source.ip, principal_id, session_name, user.name\n| stats instance_counts = count_distinct(arn_name) by instance_id, user.name, source.ip, session_name\n| where instance_counts < 5\n| sort instance_counts desc\n```\n

\n
\n\n(cherry picked from commit 6137f8185c01a923213de41d7de6337deb21a382)","shortMessageHtmlLink":"[Security Assistant] Updates ESQL example queries used in ESQL Query …"}},{"before":"fc50cb808f8cc9f31279a12fd2dfb04a17b8d3d5","after":"5d572a96114172a818a50354d2856f1866a839f9","ref":"refs/heads/backport/8.15/pr-188492","pushedAt":"2024-07-17T20:32:34.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[Security Assistant] Updates ESQL example queries used in ESQL Query Generation (#188492)\n\n## Summary\n\nThis PR updates the pre-packaged ESQL examples used by the ESQL Query\nGeneration tool as provided by @jamesspi. The number of examples have\nstayed the same, as have the file names -- so I've only updated the raw\ncontent here.\n\n> [!NOTE]\n> Since we're enabling the new `kbDataClient` with\nhttps://github.com/elastic/kibana/pull/188168 for `8.15`, there is no\nneed for a delete/re-install for pre-existing deployments to use these\nnew example queries, as the Knowledge Base will be rebuilt on an upgrade\nto `8.15`.\n\nToken length changes as calculated using the [GPT-4\nTokenizer](https://platform.openai.com/tokenizer):\n\n
Existing Example Queries / Tokens: 1,108 / Characters:\n4151\n

\n\n```\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE NOT CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\",\n\"192.168.0.0/16\")\n| STATS destcount = COUNT(destination.ip) by user.name, host.name\n| ENRICH ldap_lookup_new ON user.name\n| WHERE group.name IS NOT NULL\n| EVAL follow_up = CASE(\n destcount >= 100, \"true\",\n \"false\")\n| SORT destcount desc\n| KEEP destcount, host.name, user.name, group.name, follow_up\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| grok dns.question.name\n\"%{DATA}\\\\.%{GREEDYDATA:dns.question.registered_domain:string}\"\n| stats unique_queries = count_distinct(dns.question.name) by\ndns.question.registered_domain, process.name\n| where unique_queries > 5\n| sort unique_queries desc\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.code is not null\n| stats event_code_count = count(event.code) by event.code,host.name\n| enrich win_events on event.code with EVENT_DESCRIPTION\n| where EVENT_DESCRIPTION is not null and host.name is not null\n| rename EVENT_DESCRIPTION as event.description\n| sort event_code_count desc\n| keep event_code_count,event.code,host.name,event.description\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.category == \"file\" and event.action == \"creation\"\n| stats filecount = count(file.name) by process.name,host.name\n| dissect process.name \"%{process}.%{extension}\"\n| eval proclength = length(process.name)\n| where proclength > 10\n| sort filecount,proclength desc\n| limit 10\n| keep\nhost.name,process.name,filecount,process,extension,fullproc,proclength\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where process.name == \"curl.exe\"\n| stats bytes = sum(destination.bytes) by destination.address\n| eval kb = bytes/1024\n| sort kb desc\n| limit 10\n| keep kb,destination.address\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metrics-apm*\n| WHERE metricset.name == \"transaction\" AND metricset.interval == \"1m\"\n| EVAL bucket = AUTO_BUCKET(transaction.duration.histogram, 50,\n, )\n| STATS avg_duration = AVG(transaction.duration.histogram) BY bucket\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM packetbeat-*\n| STATS doc_count = COUNT(destination.domain) BY destination.domain\n| SORT doc_count DESC\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM employees\n| EVAL hire_date_formatted = DATE_FORMAT(hire_date, \"MMMM yyyy\")\n| SORT hire_date\n| KEEP emp_no, hire_date_formatted\n| LIMIT 5\n```\n\n[[esql-example-queries]]\n\nThe following is NOT an example of an ES|QL query:\n\n```\nPagination is not supported\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE @timestamp >= NOW() - 15 minutes\n| EVAL bucket = DATE_TRUNC(1 minute, @timestamp)\n| STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY bucket, host.name\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM traces-apm*\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL successful = CASE(event.outcome == \"success\", 1, 0),\n failed = CASE(event.outcome == \"failure\", 1, 0)\n| STATS success_rate = AVG(successful),\n avg_duration = AVG(transaction.duration),\n total_requests = COUNT(transaction.id) BY service.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metricbeat*\n| EVAL cpu_pct_normalized = (system.cpu.user.pct +\nsystem.cpu.system.pct) / system.cpu.cores\n| STATS AVG(cpu_pct_normalized) BY host.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM postgres-logs\n| DISSECT message \"%{} duration: %{query_duration} ms\"\n| EVAL query_duration_num = TO_DOUBLE(query_duration)\n| STATS avg_duration = AVG(query_duration_num)\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM nyc_taxis\n| WHERE DATE_EXTRACT(drop_off_time, \"hour\") >= 6 AND\nDATE_EXTRACT(drop_off_time, \"hour\") < 10\n| LIMIT 10\n```\n\n```\n

\n
\n\n
8.15 Example Queries / Tokens: 4,847 /\nCharacters:16671\n

\n\n```\n// 1. regex to extract from dns.question.registered_domain\n// Helpful when asking how to use GROK to extract values via REGEX\nfrom logs-*\n| where dns.question.name like \"?*\"\n| grok dns.question.name \"\"\"(?[a-zA-Z0-9]+\\.[a-z-A-Z]{2,3}$)\"\"\"\n| keep dns_registered_domain\n| limit 10\n\n// 2. hunting scheduled task with suspicious actions via registry.data.bytes\n// Helpful when answering questions on regex based searches and replacements (RLIKE and REPLACE), base64 conversions, and dealing with case sensitivity\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"registry\" and event.action == \"modification\" and\n registry.path like \"\"\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*Actions*\"\"\"\n| eval scheduled_task_action = replace(TO_LOWER(FROM_BASE64(registry.data.bytes)), \"\"\"\\u0000\"\"\", \"\")\n| eval scheduled_task_action = replace(scheduled_task_action, \"\"\"(\\u0003\\fauthorfff|\\u0003\\fauthorff\\u000e)\"\"\", \"\")\n| where scheduled_task_action rlike \"\"\".*(users\\\\public\\\\|\\\\appdata\\\\roaming|programdata|powershell|rundll32|regsvr32|mshta.exe|cscript.exe|wscript.exe|cmd.exe|forfiles|msiexec).*\"\"\" and not scheduled_task_action like \"localsystem*\"\n| keep scheduled_task_action, registry.path, agent.id\n| stats count_agents = count_distinct(agent.id) by scheduled_task_action | where count_agents == 1\n\n// 3. suspicious powershell cmds from base64 encoded cmdline\n// Helpful when answering questions on regex based searches and replacements, base64 conversions, and dealing with case sensitivity (TO_LOWER and TO_UPPER commands)\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"process\" and event.action == \"start\" and TO_LOWER(process.name) == \"powershell.exe\" and process.command_line rlike \".+ -(e|E).*\"\n| keep agent.id, process.command_line\n| grok process.command_line \"\"\"(?([A-Za-z0-9+/]+={1,2}$|[A-Za-z0-9+/]{100,}))\"\"\"\n| where base64_data is not null\n| eval decoded_base64_cmdline = replace(TO_LOWER(FROM_BASE64(base64_data)), \"\"\"\\u0000\"\"\", \"\")\n| where decoded_base64_cmdline rlike \"\"\".*(http|webclient|download|mppreference|sockets|bxor|.replace|reflection|assembly|load|bits|start-proc|iwr|frombase64).*\"\"\"\n| keep agent.id, process.command_line, decoded_base64_cmdline\n\n//4. Detect masquerading attempts as native Windows binaries\n//MITRE Tactics: \"Defense Evasion\"\nfrom logs-*\n| where event.type == \"start\" and event.action == \"start\" and host.os.name == \"Windows\" and not starts_with(process.executable, \"C:\\\\Program Files\\\\WindowsApps\\\\\") and not starts_with(process.executable, \"C:\\\\Windows\\\\System32\\\\DriverStore\\\\\") and process.name != \"setup.exe\"\n| keep process.name.caseless, process.executable.caseless, process.code_signature.subject_name, process.code_signature.trusted, process.code_signature.exists, host.id\n| eval system_bin = case(starts_with(process.executable.caseless, \"c:\\\\windows\\\\system32\") and starts_with(process.code_signature.subject_name, \"Microsoft\") and process.code_signature.trusted == true, process.name.caseless, null), non_system_bin = case(process.code_signature.exists == false or process.code_signature.trusted != true or not starts_with(process.code_signature.subject_name, \"Microsoft\"), process.name.caseless, null)\n| stats count_system_bin = count(system_bin), count_non_system_bin = count(non_system_bin) by process.name.caseless, host.id\n| where count_system_bin >= 1 and count_non_system_bin >= 1\n\n//5. Detect DLL Hijack via Masquerading as Microsoft Native Libraries\n// Helpful when asking how to use ENRICH query results with enrich policies\nfrom logs-*\n| where host.os.family == \"windows\" and event.action == \"load\" and process.code_signature.status == \"trusted\" and dll.code_signature.status != \"trusted\" and\n not dll.path rlike \"\"\"[c-fC-F]:\\\\(Windows|windows|WINDOWS)\\\\(System32|SysWOW64|system32|syswow64)\\\\[a-zA-Z0-9_]+.dll\"\"\"\n| keep dll.name, dll.path, dll.hash.sha256, process.executable, host.id\n| ENRICH libs-policy-defend\n| where native == \"yes\" and not starts_with(dll.path, \"C:\\\\Windows\\\\assembly\\\\NativeImages\")\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\"),\n dll_path = replace(dll.path, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| stats host_count = count_distinct(host.id) by dll.name, dll_path, process_path, dll.hash.sha256\n| sort host_count asc\n\n//6. Potential Exfiltration by process total egress bytes\n// Helpful when asking how to filter/search on IP address (CIDR_MATCH) fields and aggregating/grouping\n//MITRE Tactics: \"Command and Control\", \"Exfiltration\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n event.action == \"disconnect_received\" and\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.executable, process.entity_id\n| stats total_bytes_out = sum(source.bytes) by process.entity_id, destination.address, process.executable\n /* more than 1GB out by same process.pid in 8 hours */\n| where total_bytes_out >= 1073741824\n\n//7. Windows logon activity by source IP\n// Helpful when answering questions about the CASE command (as well as conditional outputs/if statements)\n//MITRE Tactics: \"Credential Access\"\nfrom logs-*\n| where host.os.family == \"windows\" and\n event.category == \"authentication\" and event.action in (\"logon-failed\", \"logged-in\") and winlog.logon.type == \"Network\" and\n source.ip is not null and\n /* noisy failure status codes often associated to authentication misconfiguration */\n not (event.action == \"logon-failed\" and winlog.event_data.Status in (\"0xC000015B\", \"0XC000005E\", \"0XC0000133\", \"0XC0000192\"))\n| eval failed = case(event.action == \"logon-failed\", source.ip, null), success = case(event.action == \"logged-in\", source.ip, null)\n| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(winlog.event_data.TargetUserName) by source.ip\n /* below threshold should be adjusted to your env logon patterns */\n| where count_failed >= 100 and count_success <= 10 and count_user >= 20\n\n//8. High count of network connection over extended period by process\n//Helpful when answering questions about IP searches/filters, field converstions(to_double, to_int), and running multiple aggregations\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and (process.executable like \"C:\\\\\\\\Windows\\\\\\\\System32*\" or process.executable like \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\*\") and not user.id in (\"S-1-5-19\", \"S-1-5-20\") and\n/* multiple Windows svchost services perform long term connection to MS ASN, can be covered in a dedicated hunt */\nnot (process.name == \"svchost.exe\" and user.id == \"S-1-5-18\") and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 1 and number_of_con_per_hour >= 120\n\n//9. Persistence via Suspicious Launch Agent or Launch Daemon with low occurrence\n//Helpful when answering questions on concatenating fields, dealing with time based searches\n//MITRE Tactics: \"Persistence\"\nfrom logs-*\n| where @timestamp > now() - 7 day\n| where host.os.family == \"macos\" and event.category == \"file\" and event.action == \"launch_daemon\" and\n (Persistence.runatload == true or Persistence.keepalive == true) and process.executable is not null\n| eval args = MV_CONCAT(Persistence.args, \",\")\n /* normalizing users home profile */\n| eval args = replace(args, \"\"\"/Users/[a-zA-Z0-9ñ\\.\\-\\_\\$~ ]+/\"\"\", \"/Users/user/\")\n| stats agents = count_distinct(host.id), total = count(*) by process.name, Persistence.name, args\n| where starts_with(args, \"/\") and agents == 1 and total == 1\n\n//10. Suspicious Network Connections by unsigned macO\n//Helpful when answering questions on IP filtering, calculating the time difference between timestamps, aggregations, and field conversions\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"macos\" and event.category == \"network\" and\n (process.code_signature.exists == false or process.code_signature.trusted != true) and\n /* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 8 and number_of_con_per_hour >= 120\n\n//11. Unusual file creations by web server user\n//Helpful when answering questions on using the LIKE command (wildcard searches) and aggregations\nFROM logs-*\n| WHERE @timestamp > NOW() - 50 day\n| WHERE host.os.type == \"linux\" and event.type == \"creation\" and user.name in (\"www-data\", \"apache\", \"nginx\", \"httpd\", \"tomcat\", \"lighttpd\", \"glassfish\", \"weblogic\") and (\n file.path like \"/var/www/*\" or\n file.path like \"/var/tmp/*\" or\n file.path like \"/tmp/*\" or\n file.path like \"/dev/shm/*\"\n)\n| STATS file_count = COUNT(file.path), host_count = COUNT(host.name) by file.path, host.name, process.name, user.name\n// Alter this threshold to make sense for your environment\n| WHERE file_count <= 5\n| SORT file_count asc\n| LIMIT 100\n\n//12. Segmentation Fault & Potential Buffer Overflow Hunting\n//Helpful when answering questions on extractions with GROK\nFROM logs-*\n| WHERE host.os.type == \"linux\" and process.name == \"kernel\" and message like \"*segfault*\"\n| GROK message \"\\\\[%{NUMBER:timestamp}\\\\] %{WORD:process}\\\\[%{NUMBER:pid}\\\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\\\[%{BASE16NUM:so_base_address}\\\\+%{BASE16NUM:so_offset}\\\\]\"\n| KEEP timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset\n\n//13. Persistence via Systemd (timers)\n//Helpful when answering questions on using the CASE command (conditional statements), searching lists using the IN command, wildcard searches with the LIKE command and aggregations\nFROM logs-*\n| WHERE host.os.type == \"linux\" and event.type in (\"creation\", \"change\") and (\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\"\n\n) and not (\n process.name in (\n \"dpkg\", \"dockerd\", \"yum\", \"dnf\", \"snapd\", \"pacman\", \"pamac-daemon\",\n \"netplan\", \"systemd\", \"generate\"\n ) or\n process.executable == \"/proc/self/exe\" or\n process.executable like \"/dev/fd/*\" or\n file.extension in (\"dpkg-remove\", \"swx\", \"swp\")\n)\n| EVAL persistence = CASE(\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\",\n process.name,\n null\n)\n| STATS cc = COUNT(*), pers_count = COUNT(persistence), agent_count = COUNT(agent.id) by process.executable, file.path, host.name, user.name\n| WHERE pers_count > 0 and pers_count <= 20 and agent_count <= 3\n| SORT cc asc\n| LIMIT 100\n\n//14. Low Frequency AWS EC2 Admin Password Retrieval Attempts from Unusual ARNs\n//Helpful when answering questions on extracting fields with the dissect command and aggregations. Also an example for hunting for cloud threats\nfrom logs-*\n| where event.provider == \"ec2.amazonaws.com\" and event.action == \"GetPasswordData\"\nand aws.cloudtrail.error_code == \"Client.UnauthorizedOperation\" and aws.cloudtrail.user_identity.type == \"AssumedRole\"\n| dissect aws.cloudtrail.request_parameters \"{%{key}=%{instance_id}}\"\n| dissect aws.cloudtrail.user_identity.session_context.session_issuer.arn \"%{?keyword1}:%{?keyword2}:%{?keyword3}::%{account_id}:%{keyword4}/%{arn_name}\"\n| dissect user.id \"%{principal_id}:%{session_name}\"\n| keep aws.cloudtrail.user_identity.session_context.session_issuer.principal_id, instance_id, account_id, arn_name, source.ip, principal_id, session_name, user.name\n| stats instance_counts = count_distinct(arn_name) by instance_id, user.name, source.ip, session_name\n| where instance_counts < 5\n| sort instance_counts desc\n```\n

\n
\n\n(cherry picked from commit 6137f8185c01a923213de41d7de6337deb21a382)","shortMessageHtmlLink":"[Security Assistant] Updates ESQL example queries used in ESQL Query …"}},{"before":null,"after":"fc50cb808f8cc9f31279a12fd2dfb04a17b8d3d5","ref":"refs/heads/backport/8.15/pr-188492","pushedAt":"2024-07-17T20:30:40.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[Security Assistant] Updates ESQL example queries used in ESQL Query Generation (#188492)\n\n## Summary\n\nThis PR updates the pre-packaged ESQL examples used by the ESQL Query\nGeneration tool as provided by @jamesspi. The number of examples have\nstayed the same, as have the file names -- so I've only updated the raw\ncontent here.\n\n> [!NOTE]\n> Since we're enabling the new `kbDataClient` with\nhttps://github.com/elastic/kibana/pull/188168 for `8.15`, there is no\nneed for a delete/re-install for pre-existing deployments to use these\nnew example queries, as the Knowledge Base will be rebuilt on an upgrade\nto `8.15`.\n\nToken length changes as calculated using the [GPT-4\nTokenizer](https://platform.openai.com/tokenizer):\n\n
Existing Example Queries / Tokens: 1,108 / Characters:\n4151\n

\n\n```\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE NOT CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"172.16.0.0/12\",\n\"192.168.0.0/16\")\n| STATS destcount = COUNT(destination.ip) by user.name, host.name\n| ENRICH ldap_lookup_new ON user.name\n| WHERE group.name IS NOT NULL\n| EVAL follow_up = CASE(\n destcount >= 100, \"true\",\n \"false\")\n| SORT destcount desc\n| KEEP destcount, host.name, user.name, group.name, follow_up\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| grok dns.question.name\n\"%{DATA}\\\\.%{GREEDYDATA:dns.question.registered_domain:string}\"\n| stats unique_queries = count_distinct(dns.question.name) by\ndns.question.registered_domain, process.name\n| where unique_queries > 5\n| sort unique_queries desc\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.code is not null\n| stats event_code_count = count(event.code) by event.code,host.name\n| enrich win_events on event.code with EVENT_DESCRIPTION\n| where EVENT_DESCRIPTION is not null and host.name is not null\n| rename EVENT_DESCRIPTION as event.description\n| sort event_code_count desc\n| keep event_code_count,event.code,host.name,event.description\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where event.category == \"file\" and event.action == \"creation\"\n| stats filecount = count(file.name) by process.name,host.name\n| dissect process.name \"%{process}.%{extension}\"\n| eval proclength = length(process.name)\n| where proclength > 10\n| sort filecount,proclength desc\n| limit 10\n| keep\nhost.name,process.name,filecount,process,extension,fullproc,proclength\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nfrom logs-*\n| where process.name == \"curl.exe\"\n| stats bytes = sum(destination.bytes) by destination.address\n| eval kb = bytes/1024\n| sort kb desc\n| limit 10\n| keep kb,destination.address\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metrics-apm*\n| WHERE metricset.name == \"transaction\" AND metricset.interval == \"1m\"\n| EVAL bucket = AUTO_BUCKET(transaction.duration.histogram, 50,\n, )\n| STATS avg_duration = AVG(transaction.duration.histogram) BY bucket\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM packetbeat-*\n| STATS doc_count = COUNT(destination.domain) BY destination.domain\n| SORT doc_count DESC\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM employees\n| EVAL hire_date_formatted = DATE_FORMAT(hire_date, \"MMMM yyyy\")\n| SORT hire_date\n| KEEP emp_no, hire_date_formatted\n| LIMIT 5\n```\n\n[[esql-example-queries]]\n\nThe following is NOT an example of an ES|QL query:\n\n```\nPagination is not supported\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM logs-*\n| WHERE @timestamp >= NOW() - 15 minutes\n| EVAL bucket = DATE_TRUNC(1 minute, @timestamp)\n| STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY bucket, host.name\n| LIMIT 10\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM traces-apm*\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL successful = CASE(event.outcome == \"success\", 1, 0),\n failed = CASE(event.outcome == \"failure\", 1, 0)\n| STATS success_rate = AVG(successful),\n avg_duration = AVG(transaction.duration),\n total_requests = COUNT(transaction.id) BY service.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM metricbeat*\n| EVAL cpu_pct_normalized = (system.cpu.user.pct +\nsystem.cpu.system.pct) / system.cpu.cores\n| STATS AVG(cpu_pct_normalized) BY host.name\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM postgres-logs\n| DISSECT message \"%{} duration: %{query_duration} ms\"\n| EVAL query_duration_num = TO_DOUBLE(query_duration)\n| STATS avg_duration = AVG(query_duration_num)\n```\n\n[[esql-example-queries]]\n\nThe following is an example ES|QL query:\n\n```\nFROM nyc_taxis\n| WHERE DATE_EXTRACT(drop_off_time, \"hour\") >= 6 AND\nDATE_EXTRACT(drop_off_time, \"hour\") < 10\n| LIMIT 10\n```\n\n```\n

\n
\n\n
8.15 Example Queries / Tokens: 4,847 /\nCharacters:16671\n

\n\n```\n// 1. regex to extract from dns.question.registered_domain\n// Helpful when asking how to use GROK to extract values via REGEX\nfrom logs-*\n| where dns.question.name like \"?*\"\n| grok dns.question.name \"\"\"(?[a-zA-Z0-9]+\\.[a-z-A-Z]{2,3}$)\"\"\"\n| keep dns_registered_domain\n| limit 10\n\n// 2. hunting scheduled task with suspicious actions via registry.data.bytes\n// Helpful when answering questions on regex based searches and replacements (RLIKE and REPLACE), base64 conversions, and dealing with case sensitivity\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"registry\" and event.action == \"modification\" and\n registry.path like \"\"\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Schedule\\\\TaskCache\\\\Tasks\\\\*Actions*\"\"\"\n| eval scheduled_task_action = replace(TO_LOWER(FROM_BASE64(registry.data.bytes)), \"\"\"\\u0000\"\"\", \"\")\n| eval scheduled_task_action = replace(scheduled_task_action, \"\"\"(\\u0003\\fauthorfff|\\u0003\\fauthorff\\u000e)\"\"\", \"\")\n| where scheduled_task_action rlike \"\"\".*(users\\\\public\\\\|\\\\appdata\\\\roaming|programdata|powershell|rundll32|regsvr32|mshta.exe|cscript.exe|wscript.exe|cmd.exe|forfiles|msiexec).*\"\"\" and not scheduled_task_action like \"localsystem*\"\n| keep scheduled_task_action, registry.path, agent.id\n| stats count_agents = count_distinct(agent.id) by scheduled_task_action | where count_agents == 1\n\n// 3. suspicious powershell cmds from base64 encoded cmdline\n// Helpful when answering questions on regex based searches and replacements, base64 conversions, and dealing with case sensitivity (TO_LOWER and TO_UPPER commands)\nfrom logs-*\n| where host.os.type == \"windows\" and event.category == \"process\" and event.action == \"start\" and TO_LOWER(process.name) == \"powershell.exe\" and process.command_line rlike \".+ -(e|E).*\"\n| keep agent.id, process.command_line\n| grok process.command_line \"\"\"(?([A-Za-z0-9+/]+={1,2}$|[A-Za-z0-9+/]{100,}))\"\"\"\n| where base64_data is not null\n| eval decoded_base64_cmdline = replace(TO_LOWER(FROM_BASE64(base64_data)), \"\"\"\\u0000\"\"\", \"\")\n| where decoded_base64_cmdline rlike \"\"\".*(http|webclient|download|mppreference|sockets|bxor|.replace|reflection|assembly|load|bits|start-proc|iwr|frombase64).*\"\"\"\n| keep agent.id, process.command_line, decoded_base64_cmdline\n\n//4. Detect masquerading attempts as native Windows binaries\n//MITRE Tactics: \"Defense Evasion\"\nfrom logs-*\n| where event.type == \"start\" and event.action == \"start\" and host.os.name == \"Windows\" and not starts_with(process.executable, \"C:\\\\Program Files\\\\WindowsApps\\\\\") and not starts_with(process.executable, \"C:\\\\Windows\\\\System32\\\\DriverStore\\\\\") and process.name != \"setup.exe\"\n| keep process.name.caseless, process.executable.caseless, process.code_signature.subject_name, process.code_signature.trusted, process.code_signature.exists, host.id\n| eval system_bin = case(starts_with(process.executable.caseless, \"c:\\\\windows\\\\system32\") and starts_with(process.code_signature.subject_name, \"Microsoft\") and process.code_signature.trusted == true, process.name.caseless, null), non_system_bin = case(process.code_signature.exists == false or process.code_signature.trusted != true or not starts_with(process.code_signature.subject_name, \"Microsoft\"), process.name.caseless, null)\n| stats count_system_bin = count(system_bin), count_non_system_bin = count(non_system_bin) by process.name.caseless, host.id\n| where count_system_bin >= 1 and count_non_system_bin >= 1\n\n//5. Detect DLL Hijack via Masquerading as Microsoft Native Libraries\n// Helpful when asking how to use ENRICH query results with enrich policies\nfrom logs-*\n| where host.os.family == \"windows\" and event.action == \"load\" and process.code_signature.status == \"trusted\" and dll.code_signature.status != \"trusted\" and\n not dll.path rlike \"\"\"[c-fC-F]:\\\\(Windows|windows|WINDOWS)\\\\(System32|SysWOW64|system32|syswow64)\\\\[a-zA-Z0-9_]+.dll\"\"\"\n| keep dll.name, dll.path, dll.hash.sha256, process.executable, host.id\n| ENRICH libs-policy-defend\n| where native == \"yes\" and not starts_with(dll.path, \"C:\\\\Windows\\\\assembly\\\\NativeImages\")\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\"),\n dll_path = replace(dll.path, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| stats host_count = count_distinct(host.id) by dll.name, dll_path, process_path, dll.hash.sha256\n| sort host_count asc\n\n//6. Potential Exfiltration by process total egress bytes\n// Helpful when asking how to filter/search on IP address (CIDR_MATCH) fields and aggregating/grouping\n//MITRE Tactics: \"Command and Control\", \"Exfiltration\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n event.action == \"disconnect_received\" and\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.executable, process.entity_id\n| stats total_bytes_out = sum(source.bytes) by process.entity_id, destination.address, process.executable\n /* more than 1GB out by same process.pid in 8 hours */\n| where total_bytes_out >= 1073741824\n\n//7. Windows logon activity by source IP\n// Helpful when answering questions about the CASE command (as well as conditional outputs/if statements)\n//MITRE Tactics: \"Credential Access\"\nfrom logs-*\n| where host.os.family == \"windows\" and\n event.category == \"authentication\" and event.action in (\"logon-failed\", \"logged-in\") and winlog.logon.type == \"Network\" and\n source.ip is not null and\n /* noisy failure status codes often associated to authentication misconfiguration */\n not (event.action == \"logon-failed\" and winlog.event_data.Status in (\"0xC000015B\", \"0XC000005E\", \"0XC0000133\", \"0XC0000192\"))\n| eval failed = case(event.action == \"logon-failed\", source.ip, null), success = case(event.action == \"logged-in\", source.ip, null)\n| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(winlog.event_data.TargetUserName) by source.ip\n /* below threshold should be adjusted to your env logon patterns */\n| where count_failed >= 100 and count_success <= 10 and count_user >= 20\n\n//8. High count of network connection over extended period by process\n//Helpful when answering questions about IP searches/filters, field converstions(to_double, to_int), and running multiple aggregations\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and (process.executable like \"C:\\\\\\\\Windows\\\\\\\\System32*\" or process.executable like \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\*\") and not user.id in (\"S-1-5-19\", \"S-1-5-20\") and\n/* multiple Windows svchost services perform long term connection to MS ASN, can be covered in a dedicated hunt */\nnot (process.name == \"svchost.exe\" and user.id == \"S-1-5-18\") and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 1 and number_of_con_per_hour >= 120\n\n//9. Persistence via Suspicious Launch Agent or Launch Daemon with low occurrence\n//Helpful when answering questions on concatenating fields, dealing with time based searches\n//MITRE Tactics: \"Persistence\"\nfrom logs-*\n| where @timestamp > now() - 7 day\n| where host.os.family == \"macos\" and event.category == \"file\" and event.action == \"launch_daemon\" and\n (Persistence.runatload == true or Persistence.keepalive == true) and process.executable is not null\n| eval args = MV_CONCAT(Persistence.args, \",\")\n /* normalizing users home profile */\n| eval args = replace(args, \"\"\"/Users/[a-zA-Z0-9ñ\\.\\-\\_\\$~ ]+/\"\"\", \"/Users/user/\")\n| stats agents = count_distinct(host.id), total = count(*) by process.name, Persistence.name, args\n| where starts_with(args, \"/\") and agents == 1 and total == 1\n\n//10. Suspicious Network Connections by unsigned macO\n//Helpful when answering questions on IP filtering, calculating the time difference between timestamps, aggregations, and field conversions\n//MITRE Tactics: \"Command and Control\"\nfrom logs-*\n| where host.os.family == \"macos\" and event.category == \"network\" and\n (process.code_signature.exists == false or process.code_signature.trusted != true) and\n /* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, @timestamp\n /* calc total duration , total MB out and the number of connections per hour */\n| stats total_bytes_out = sum(source.bytes), count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, destination.address, process.name\n| eval dur = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(dur/3600000), MB_out=TO_DOUBLE(total_bytes_out) / (1024*1024), number_of_con_per_hour = (count_connections / duration_hours)\n| keep process.entity_id, process.name, duration_hours, destination.address, MB_out, count_connections, number_of_con_per_hour\n/* threshold is set to 120 connections per minute , you can adjust it to your env/FP rate */\n| where duration_hours >= 8 and number_of_con_per_hour >= 120\n\n//11. Unusual file creations by web server user\n//Helpful when answering questions on using the LIKE command (wildcard searches) and aggregations\nFROM logs-*\n| WHERE @timestamp > NOW() - 50 day\n| WHERE host.os.type == \"linux\" and event.type == \"creation\" and user.name in (\"www-data\", \"apache\", \"nginx\", \"httpd\", \"tomcat\", \"lighttpd\", \"glassfish\", \"weblogic\") and (\n file.path like \"/var/www/*\" or\n file.path like \"/var/tmp/*\" or\n file.path like \"/tmp/*\" or\n file.path like \"/dev/shm/*\"\n)\n| STATS file_count = COUNT(file.path), host_count = COUNT(host.name) by file.path, host.name, process.name, user.name\n// Alter this threshold to make sense for your environment\n| WHERE file_count <= 5\n| SORT file_count asc\n| LIMIT 100\n\n//12. Segmentation Fault & Potential Buffer Overflow Hunting\n//Helpful when answering questions on extractions with GROK\nFROM logs-*\n| WHERE host.os.type == \"linux\" and process.name == \"kernel\" and message like \"*segfault*\"\n| GROK message \"\\\\[%{NUMBER:timestamp}\\\\] %{WORD:process}\\\\[%{NUMBER:pid}\\\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\\\[%{BASE16NUM:so_base_address}\\\\+%{BASE16NUM:so_offset}\\\\]\"\n| KEEP timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset\n\n//13. Persistence via Systemd (timers)\n//Helpful when answering questions on using the CASE command (conditional statements), searching lists using the IN command, wildcard searches with the LIKE command and aggregations\nFROM logs-*\n| WHERE host.os.type == \"linux\" and event.type in (\"creation\", \"change\") and (\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\"\n\n) and not (\n process.name in (\n \"dpkg\", \"dockerd\", \"yum\", \"dnf\", \"snapd\", \"pacman\", \"pamac-daemon\",\n \"netplan\", \"systemd\", \"generate\"\n ) or\n process.executable == \"/proc/self/exe\" or\n process.executable like \"/dev/fd/*\" or\n file.extension in (\"dpkg-remove\", \"swx\", \"swp\")\n)\n| EVAL persistence = CASE(\n\n // System-wide/user-specific services/timers (root permissions required)\n file.path like \"/run/systemd/system/*\" or\n file.path like \"/etc/systemd/system/*\" or\n file.path like \"/etc/systemd/user/*\" or\n file.path like \"/usr/local/lib/systemd/system/*\" or\n file.path like \"/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/system/*\" or\n file.path like \"/usr/lib/systemd/user/*\" or\n\n // user-specific services/timers (user permissions required)\n file.path like \"/home/*/.config/systemd/user/*\" or\n file.path like \"/home/*/.local/share/systemd/user/*\" or\n\n // System-wide generators (root permissions required)\n file.path like \"/etc/systemd/system-generators/*\" or\n file.path like \"/usr/local/lib/systemd/system-generators/*\" or\n file.path like \"/lib/systemd/system-generators/*\" or\n file.path like \"/etc/systemd/user-generators/*\" or\n file.path like \"/usr/local/lib/systemd/user-generators/*\" or\n file.path like \"/usr/lib/systemd/user-generators/*\",\n process.name,\n null\n)\n| STATS cc = COUNT(*), pers_count = COUNT(persistence), agent_count = COUNT(agent.id) by process.executable, file.path, host.name, user.name\n| WHERE pers_count > 0 and pers_count <= 20 and agent_count <= 3\n| SORT cc asc\n| LIMIT 100\n\n//14. Low Frequency AWS EC2 Admin Password Retrieval Attempts from Unusual ARNs\n//Helpful when answering questions on extracting fields with the dissect command and aggregations. Also an example for hunting for cloud threats\nfrom logs-*\n| where event.provider == \"ec2.amazonaws.com\" and event.action == \"GetPasswordData\"\nand aws.cloudtrail.error_code == \"Client.UnauthorizedOperation\" and aws.cloudtrail.user_identity.type == \"AssumedRole\"\n| dissect aws.cloudtrail.request_parameters \"{%{key}=%{instance_id}}\"\n| dissect aws.cloudtrail.user_identity.session_context.session_issuer.arn \"%{?keyword1}:%{?keyword2}:%{?keyword3}::%{account_id}:%{keyword4}/%{arn_name}\"\n| dissect user.id \"%{principal_id}:%{session_name}\"\n| keep aws.cloudtrail.user_identity.session_context.session_issuer.principal_id, instance_id, account_id, arn_name, source.ip, principal_id, session_name, user.name\n| stats instance_counts = count_distinct(arn_name) by instance_id, user.name, source.ip, session_name\n| where instance_counts < 5\n| sort instance_counts desc\n```\n

\n
\n\n(cherry picked from commit 6137f8185c01a923213de41d7de6337deb21a382)","shortMessageHtmlLink":"[Security Assistant] Updates ESQL example queries used in ESQL Query …"}},{"before":"bf0422ac9759d79abfc7eee004035a90403d1d8d","after":"6c053fa3588f3bf528c5dc9a3cf2e8ab6e7ee75a","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-17T15:16:30.000Z","pushType":"push","commitsCount":48,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch 'main' into upgrade-ts-v5.1","shortMessageHtmlLink":"Merge branch 'main' into upgrade-ts-v5.1"}},{"before":null,"after":"f7b4489d38ea7ef0cb41a81feb82752d06a6d67c","ref":"refs/heads/backport/8.14/pr-188313","pushedAt":"2024-07-16T23:05:01.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[ci] skip flaky test (#188313)\n\n## Summary\nRe: https://github.com/elastic/kibana/issues/188234\n(cherry picked from commit d5345e442dce28b0ee5ef057988b156ba78784ad)","shortMessageHtmlLink":"[ci] skip flaky test (elastic#188313)"}},{"before":"d3568ce8197ba7e5599e18907acdc9de61744e7a","after":"bf0422ac9759d79abfc7eee004035a90403d1d8d","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-16T17:08:02.000Z","pushType":"push","commitsCount":44,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch 'main' into upgrade-ts-v5.1","shortMessageHtmlLink":"Merge branch 'main' into upgrade-ts-v5.1"}},{"before":"9078959f7f6775f748a956938858e19499e113c7","after":"a1a26573af813daf8fcf4bedddd5f48e28274f4a","ref":"refs/heads/backport/7.17/pr-188134","pushedAt":"2024-07-16T16:43:22.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"fix(NA): eslint","shortMessageHtmlLink":"fix(NA): eslint"}},{"before":"d1ac060f74b15f35a44ca9ef4c09c162eb70ba09","after":"399ccc4de784732209f41cb8b485a303bc2f0528","ref":"refs/heads/backport/8.14/pr-188134","pushedAt":"2024-07-16T16:36:55.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"fix(NA): yarn duplicates","shortMessageHtmlLink":"fix(NA): yarn duplicates"}},{"before":"5b3963e90ab31972fbae612585968a17ea2d85c3","after":"9078959f7f6775f748a956938858e19499e113c7","ref":"refs/heads/backport/7.17/pr-188134","pushedAt":"2024-07-16T13:39:28.000Z","pushType":"push","commitsCount":7,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch '7.17' into backport/7.17/pr-188134","shortMessageHtmlLink":"Merge branch '7.17' into backport/7.17/pr-188134"}},{"before":"98e000bc72376be6e33dec67879a0aee89c8c85b","after":"d1ac060f74b15f35a44ca9ef4c09c162eb70ba09","ref":"refs/heads/backport/8.14/pr-188134","pushedAt":"2024-07-16T13:39:25.000Z","pushType":"push","commitsCount":4,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch '8.14' into backport/8.14/pr-188134","shortMessageHtmlLink":"Merge branch '8.14' into backport/8.14/pr-188134"}},{"before":"1d9dc61fc6f240426fe6043f71179800c68ea1b5","after":"ea3dcfc37a3eaf5a12ca0f1512c5e0cab640c565","ref":"refs/heads/backport/7.17/pr-186104","pushedAt":"2024-07-15T20:31:52.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"fix(NA): eslint","shortMessageHtmlLink":"fix(NA): eslint"}},{"before":null,"after":"1d9dc61fc6f240426fe6043f71179800c68ea1b5","ref":"refs/heads/backport/7.17/pr-186104","pushedAt":"2024-07-15T20:09:02.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[ML] Removing use of re2 library (#186104)\n\nWe no longer need to use `re2` over the standard regex library.\n\n(cherry picked from commit ed70d4c6ffb77324f9c6e74e26ed559303ae6c3f)\n\n# Conflicts:\n#\tx-pack/plugins/ml/server/saved_objects/initialization/space_overrides/logs.ts\n#\tx-pack/plugins/ml/server/saved_objects/initialization/space_overrides/metrics.ts\n#\tx-pack/plugins/ml/server/saved_objects/service.ts","shortMessageHtmlLink":"[ML] Removing use of re2 library (elastic#186104)"}},{"before":null,"after":"b613ee70bdc59681427ecacdfd1cf4124d059bdf","ref":"refs/heads/backport/8.14/pr-186104","pushedAt":"2024-07-15T20:02:55.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"[ML] Removing use of re2 library (#186104)\n\nWe no longer need to use `re2` over the standard regex library.\n\n(cherry picked from commit ed70d4c6ffb77324f9c6e74e26ed559303ae6c3f)","shortMessageHtmlLink":"[ML] Removing use of re2 library (elastic#186104)"}},{"before":null,"after":"98e000bc72376be6e33dec67879a0aee89c8c85b","ref":"refs/heads/backport/8.14/pr-188134","pushedAt":"2024-07-15T20:02:06.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"chore(NA): remove usage of re2 and replace it with a non native module (#188134)\n\nThis PR removes the usage of the native module version of `re2` and\nreplaces it with a js port called `re2js`.\nIt also ends our usage of native node modules in production and it\nremoves the task from the build as well. Further steps will be taken\nalong our strategy to avoid future usages of native node modules in prod\nenvironments.\n\n(cherry picked from commit 3c338a82c2d6d59c91f0f3b74f725231c69c5b13)\n\n# Conflicts:\n#\tyarn.lock","shortMessageHtmlLink":"chore(NA): remove usage of re2 and replace it with a non native module ("}},{"before":null,"after":"5b3963e90ab31972fbae612585968a17ea2d85c3","ref":"refs/heads/backport/7.17/pr-188134","pushedAt":"2024-07-15T19:58:24.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"chore(NA): remove usage of re2 and replace it with a non native module (#188134)\n\nThis PR removes the usage of the native module version of `re2` and\nreplaces it with a js port called `re2js`.\nIt also ends our usage of native node modules in production and it\nremoves the task from the build as well. Further steps will be taken\nalong our strategy to avoid future usages of native node modules in prod\nenvironments.\n\n(cherry picked from commit 3c338a82c2d6d59c91f0f3b74f725231c69c5b13)\n\n# Conflicts:\n#\tkbn_pm/src/lib/bazel.mjs\n#\tpackage.json\n#\trenovate.json\n#\tsrc/dev/build/tasks/install_dependencies_task.ts\n#\tsrc/dev/build/tasks/patch_native_modules_task.ts\n#\tyarn.lock","shortMessageHtmlLink":"chore(NA): remove usage of re2 and replace it with a non native module ("}},{"before":"a5678cd0f1a8a796217e1b5cec6708628d103b03","after":"d3568ce8197ba7e5599e18907acdc9de61744e7a","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-15T19:34:24.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch 'main' into upgrade-ts-v5.1","shortMessageHtmlLink":"Merge branch 'main' into upgrade-ts-v5.1"}},{"before":"2fe3946aa5cdc9b04f8c5e38c03ce496f3f01ca9","after":"a5678cd0f1a8a796217e1b5cec6708628d103b03","ref":"refs/heads/upgrade-ts-v5.1","pushedAt":"2024-07-15T19:32:48.000Z","pushType":"push","commitsCount":19,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"fix(NA): eslint","shortMessageHtmlLink":"fix(NA): eslint"}},{"before":"077d61dbe3f08fabaf78f6211ec118fc857d6c76","after":"87f09bf74b2359c35bba070d9681a8acfa760867","ref":"refs/heads/remove-native-re2","pushedAt":"2024-07-15T14:15:52.000Z","pushType":"push","commitsCount":25,"pusher":{"login":"mistic","name":"Tiago Costa","path":"/mistic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/4440734?s=80&v=4"},"commit":{"message":"Merge branch 'main' into remove-native-re2","shortMessageHtmlLink":"Merge branch 'main' into remove-native-re2"}}],"hasNextPage":true,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"djE6ks8AAAAEhdgK8gA","startCursor":null,"endCursor":null}},"title":"Activity · mistic/kibana"}