diff --git a/rules/network/collection_fortigate_config_download.toml b/rules/network/collection_fortigate_config_download.toml new file mode 100644 index 000000000..eaca75f0e --- /dev/null +++ b/rules/network/collection_fortigate_config_download.toml @@ -0,0 +1,91 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects the download of a FortiGate device configuration file. Configuration exports contain sensitive data +including administrator password hashes, LDAP bind credentials, VPN pre-shared keys, routing tables, and firewall +policies. Threat actors exploiting CVE-2026-24858 have been observed exporting the full device configuration +immediately after gaining access to harvest credentials and map the internal network. +""" +from = "now-9m" +interval = "5m" +index = ["logs-fortinet_fortigate.*"] +language = "eql" +license = "Elastic License v2" +name = "FortiGate Configuration File Downloaded" +note = """## Triage and analysis + +### Investigating FortiGate Configuration File Downloaded + +This alert indicates that a FortiGate device configuration file was downloaded. Configuration files contain highly sensitive information including administrator credentials, LDAP/RADIUS secrets, VPN pre-shared keys, certificate private keys, and the complete network topology. + +In the FG-IR-26-060 campaign, threat actors exported the full device configuration shortly after creating rogue administrator accounts, using the harvested credentials for lateral movement and to maintain access through alternative channels. + +### Possible investigation steps + +- Review `source.user.name` to determine which account initiated the download and `fortinet.firewall.ui` for the source interface and IP address (e.g., GUI, CLI, or API). Verify whether this administrator is authorized to export device configurations. +- Check whether a scheduled backup process or configuration management tool performed this action. Look for preceding SSO login events or administrator account creation events on the same device and determine whether the downloading account was recently created. +- Check `observer.name` to identify which device had its configuration exported and search for configuration download events across other FortiGate devices in the fleet. +- Check for firewall policy changes, VPN configuration modifications, or additional admin account creation after the download. Determine whether any credentials from the configuration have been used for lateral movement. + +### False positive analysis + +- Scheduled configuration backups performed by FortiManager, Ansible, or other automation tools. +- Administrator-initiated backups during planned maintenance or before firmware upgrades. +- Configuration audits or compliance checks that require config export. + +### Response and remediation + +- If unauthorized, treat all credentials in the configuration as compromised. Rotate all passwords, pre-shared keys, LDAP bind credentials, and RADIUS secrets contained in the configuration. +- Revoke and reissue any certificates whose private keys were included in the export. +- Audit the administrator account that performed the download for compromise and check for other indicators of compromise on the device (rogue admins, policy changes). +- If the activity is expected, document the backup activity and verify it was performed through an authorized process. Ensure configuration backups are stored securely with appropriate access controls.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 47 +rule_id = "b7e2a04d-4f8a-4e12-8c9a-1d5e6f7a8b9c" +severity = "medium" +tags = [ + "Use Case: Threat Detection", + "Tactic: Collection", + "Resources: Investigation Guide", + "Domain: Network", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "eql" + +query = ''' +any where event.dataset == "fortinet_fortigate.log" and + event.code == "0100032095" and + fortinet.firewall.action == "download" +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1602" +name = "Data from Configuration Repository" +reference = "https://attack.mitre.org/techniques/T1602/" +[[rule.threat.technique.subtechnique]] +id = "T1602.002" +name = "Network Device Configuration Dump" +reference = "https://attack.mitre.org/techniques/T1602/002/" + + + +[rule.threat.tactic] +id = "TA0009" +name = "Collection" +reference = "https://attack.mitre.org/tactics/TA0009/" diff --git a/rules/network/defense_evasion_fortigate_overly_permissive_firewall_policy.toml b/rules/network/defense_evasion_fortigate_overly_permissive_firewall_policy.toml new file mode 100644 index 000000000..d86d0f462 --- /dev/null +++ b/rules/network/defense_evasion_fortigate_overly_permissive_firewall_policy.toml @@ -0,0 +1,96 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects the creation or modification of a FortiGate firewall policy that permits all sources, all +destinations, and all services. An overly permissive policy effectively bypasses all firewall protections. Threat actors +exploiting CVE-2026-24858 have been observed creating such policies to allow unrestricted traffic flow through +compromised FortiGate devices. +""" +from = "now-9m" +interval = "5m" +index = ["logs-fortinet_fortigate.*"] +language = "eql" +license = "Elastic License v2" +name = "FortiGate Overly Permissive Firewall Policy Created" +note = """## Triage and analysis + +### Investigating FortiGate Overly Permissive Firewall Policy Created + +This alert indicates that a firewall policy was created or modified on a FortiGate device with source address `all`, destination address `all`, and service `ALL`. This configuration effectively disables firewall enforcement for traffic matching the policy. + +In the FG-IR-26-060 campaign, threat actors created these permissive policies to ensure their traffic could traverse the firewall without restriction. + +### Possible investigation steps + +- Review `source.user.name` to determine which account created or modified the policy and `fortinet.firewall.ui` for the source interface and IP address. Verify whether this administrator is authorized to make firewall policy changes. +- Examine `fortinet.firewall.cfgattr` for the full policy configuration including interfaces, NAT settings, and scheduling. Check `fortinet.firewall.cfgobj` for the affected policy ID and determine whether the policy is positioned to intercept traffic (policy ordering matters). +- Look for administrator account creation, SSO login events, or configuration exports preceding this change. Determine whether the administrator account itself was recently created. +- Identify which interfaces the policy applies to (srcintf/dstintf in cfgattr) and determine whether the policy enables inbound, outbound, or both directions of unrestricted traffic. + +### False positive analysis + +- Temporary troubleshooting policies created during network diagnostics (should be time-limited and removed). +- Initial device setup or lab environments where broad policies are intentionally configured. +- Migration or cutover scenarios where temporary permissive rules are needed. + +### Response and remediation + +- If unauthorized, immediately delete the permissive firewall policy and audit the administrator account that created it for compromise. +- Review all other firewall policies for unauthorized modifications and check for other indicators of compromise on the device (rogue admins, VPN users). +- Restore the policy configuration from a known-clean backup. +- If the activity is expected, document the business justification and ensure a removal timeline is defined. Replace with specific source/destination/service rules as soon as possible.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 73 +rule_id = "896a0a38-eaa0-42e9-be35-dfcc3e3e90ae" +severity = "high" +tags = [ + "Use Case: Threat Detection", + "Tactic: Defense Evasion", + "Resources: Investigation Guide", + "Domain: Network", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "eql" + +query = ''' +any where event.dataset == "fortinet_fortigate.log" and + event.code == "0100044547" and + fortinet.firewall.cfgpath == "firewall.policy" and + fortinet.firewall.action in ("Add", "Edit") and + fortinet.firewall.cfgattr like~ "*srcaddr[all]*" and + fortinet.firewall.cfgattr like~ "*dstaddr[all]*" and + fortinet.firewall.cfgattr like~ "*service[all]*" +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1562" +name = "Impair Defenses" +reference = "https://attack.mitre.org/techniques/T1562/" +[[rule.threat.technique.subtechnique]] +id = "T1562.004" +name = "Disable or Modify System Firewall" +reference = "https://attack.mitre.org/techniques/T1562/004/" + + + +[rule.threat.tactic] +id = "TA0005" +name = "Defense Evasion" +reference = "https://attack.mitre.org/tactics/TA0005/" + diff --git a/rules/network/initial_access_fortigate_admin_login_multi_srcip.toml b/rules/network/initial_access_fortigate_admin_login_multi_srcip.toml index dc0b16165..79cbe5309 100644 --- a/rules/network/initial_access_fortigate_admin_login_multi_srcip.toml +++ b/rules/network/initial_access_fortigate_admin_login_multi_srcip.toml @@ -2,49 +2,20 @@ creation_date = "2026/01/28" integration = ["fortinet_fortigate"] maturity = "production" -updated_date = "2026/01/28" +updated_date = "2026/01/29" [rule] author = ["Elastic"] description = """ -This rule detects successful logins to the FortiGate management interface using the same Administrator account from multiple distinct source IP addresses within an 24-hour period. -Administrator logins from multiple locations in a short time window may indicate credential sharing, compromised credentials, or unauthorized access and should be investigated. +This rule detects successful logins to the FortiGate management interface using the same Administrator account from +multiple distinct source IP addresses within an 24-hour period. Administrator logins from multiple locations in a short +time window may indicate credential sharing, compromised credentials, or unauthorized access and should be investigated. """ from = "now-24h" interval = "5m" language = "esql" license = "Elastic License v2" name = "FortiGate Administrator Login from Multiple IP Addresses" -risk_score = 73 -rule_id = "8a556117-3f05-430e-b2eb-7df0100b4e3b" -severity = "high" -tags = ["Use Case: Threat Detection", "Tactic: Initial Access", "Resources: Investigation Guide", "Domain: Network", "Domain: Identity", "Data Source: Fortinet"] -timestamp_override = "event.ingested" -type = "esql" - -query = ''' -FROM logs-fortinet_fortigate.*, filebeat-* metadata _id - -| WHERE event.dataset == "fortinet_fortigate.log" and - event.category == "authentication" and event.action == "login" and - event.outcome == "success" and source.user.roles == "Administrator" and - source.user.name is not null and source.ip is not null -| stats Esql.logon_count = count(*), - Esql.source_ip_count_distinct = COUNT_DISTINCT(source.ip), - Esql.max_timestamp = MAX(@timestamp), - Esql.source_ip_values = VALUES(source.ip), - Esql.message_values = VALUES(message), - Esql.source_geo_country_name_values = VALUES(source.geo.country_name) by source.user.name - -// last logon event timestamp is within 6m of the rule execution time to avoid duplicates -| eval Esql.recent = DATE_DIFF("minute", Esql.max_timestamp, now()) -| where Esql.recent <= 6 and Esql.logon_count >= 2 and Esql.source_ip_count_distinct >= 2 - -// move dynamic fields to ECS equivalent for rule exceptions -| eval source.ip = MV_FIRST(Esql.source_ip_values) - -| keep source.ip, source.user.name, Esql.* -''' note = """## ## Triage and Analysis ### Investigating FortiGate Administrator Login from Multiple IP Addresses @@ -96,7 +67,48 @@ Because FortiGate administrator credentials grant full control over network secu - Restrict administrative access to trusted IP ranges. - Enforce MFA for administrative logins if not already enabled. - Monitor for additional signs of lateral movement or persistence.""" -references = ["https://www.elastic.co/docs/reference/integrations/fortinet_fortigate"] +references = [ + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 73 +rule_id = "8a556117-3f05-430e-b2eb-7df0100b4e3b" +severity = "high" +tags = [ + "Use Case: Threat Detection", + "Tactic: Initial Access", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "esql" + +query = ''' +FROM logs-fortinet_fortigate.*, filebeat-* metadata _id + +| WHERE event.dataset == "fortinet_fortigate.log" and + event.category == "authentication" and event.action == "login" and + event.outcome == "success" and source.user.roles == "Administrator" and + source.user.name is not null and source.ip is not null +| stats Esql.logon_count = count(*), + Esql.source_ip_count_distinct = COUNT_DISTINCT(source.ip), + Esql.max_timestamp = MAX(@timestamp), + Esql.source_ip_values = VALUES(source.ip), + Esql.message_values = VALUES(message), + Esql.source_geo_country_name_values = VALUES(source.geo.country_name) by source.user.name + +// last logon event timestamp is within 6m of the rule execution time to avoid duplicates +| eval Esql.recent = DATE_DIFF("minute", Esql.max_timestamp, now()) +| where Esql.recent <= 6 and Esql.logon_count >= 2 and Esql.source_ip_count_distinct >= 2 + +// move dynamic fields to ECS equivalent for rule exceptions +| eval source.ip = MV_FIRST(Esql.source_ip_values) + +| keep source.ip, source.user.name, Esql.* +''' [[rule.threat]] @@ -111,3 +123,4 @@ reference = "https://attack.mitre.org/techniques/T1078/" id = "TA0001" name = "Initial Access" reference = "https://attack.mitre.org/tactics/TA0001/" + diff --git a/rules/network/initial_access_fortigate_sso_login_from_unusual_source.toml b/rules/network/initial_access_fortigate_sso_login_from_unusual_source.toml new file mode 100644 index 000000000..83e4f3cdf --- /dev/null +++ b/rules/network/initial_access_fortigate_sso_login_from_unusual_source.toml @@ -0,0 +1,113 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects the first successful FortiCloud SSO login from a previously unseen source IP address to a FortiGate +device within the last 5 days. FortiCloud SSO logins from new source IPs may indicate exploitation of SAML-based +authentication bypass vulnerabilities such as CVE-2026-24858, where crafted SAML assertions allow unauthorized access to +FortiGate devices registered to other accounts. Environments that regularly use FortiCloud SSO will only alert on new +source IPs not seen in the lookback window. +""" +from = "now-7205m" +interval = "5m" +language = "esql" +license = "Elastic License v2" +name = "FortiGate FortiCloud SSO Login from Unusual Source" +note = """## Triage and analysis + +### Investigating FortiGate FortiCloud SSO Login from Unusual Source + +This alert indicates that a FortiCloud SSO login was observed from a source IP address not previously seen authenticating via SSO in the last 5 days. This is a high-value signal because it filters out routine SSO access from known management IPs and only fires on novel source addresses. + +CVE-2026-24858 (FG-IR-26-060) allows attackers with a FortiCloud account and a registered device to craft SAML assertions that authenticate them as administrators on other FortiGate devices when FortiCloud SSO is enabled. This vulnerability has been actively exploited in the wild. + +### Possible investigation steps + +- Check `source.ip` against known corporate management networks, VPN egress points, and jump hosts. Investigate the IP's ASN and geolocation, as attacker IPs have been observed from The Constant Company LLC, BL Networks, Kaopu Cloud HK Limited, and Cloudflare-protected ranges. +- Determine whether this IP has been seen in any other authentication context across the environment. +- Check `Esql.user_values` for the SSO account name (typically an email address) and verify the account belongs to the organization. Compare against known attacker email IOCs: cloud-noc@mail.io, cloud-init@mail.io, heltaylor.12@tutamail.com, support@openmail.pro. +- Check `Esql.observer_name_values` to identify which FortiGate device was accessed and confirm whether FortiCloud SSO is intentionally enabled on the device. +- Look for local administrator account creation, configuration exports, firewall policy changes, or VPN user/group creation immediately following the SSO login. The observed attack pattern involves rogue admin creation within seconds of login. + +### False positive analysis + +- Administrators connecting from a new office location, hotel, or home network for the first time may trigger this alert. +- FortiCloud SSO access after IP address changes such as ISP rotation or VPN egress changes can appear as a new source IP. +- First login after FortiCloud SSO is initially enabled on a device will fire since no historical SSO logins exist. + +### Response and remediation + +- If the activity is unauthorized, disable FortiCloud SSO immediately using `config system global` > `set admin-forticloud-sso-login disable`. +- Audit all administrator accounts for unauthorized additions and review and restore configuration from a known-clean backup. +- Rotate all credentials including any LDAP/AD accounts connected to the device. +- Upgrade FortiOS to a patched version. +- If the activity is expected, document the new source IP and consider adding an exception if it represents a new management location.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 47 +rule_id = "618a219d-a363-4ab1-ba30-870d7c22facd" +severity = "medium" +tags = [ + "Use Case: Threat Detection", + "Tactic: Initial Access", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "esql" + +query = ''' +FROM logs-fortinet_fortigate.* metadata _id, _version, _index + +| WHERE event.dataset == "fortinet_fortigate.log" and + event.category == "authentication" and event.action == "login" and + event.outcome == "success" and + (fortinet.firewall.method == "sso" or fortinet.firewall.ui like "sso*") and + source.ip is not null +| STATS Esql.logon_count = COUNT(*), + Esql.first_time_seen = MIN(@timestamp), + Esql.user_values = VALUES(source.user.name), + Esql.observer_name_values = VALUES(observer.name), + Esql.message_values = VALUES(message) BY source.ip + +// first time seen is within 6m of the rule execution time and for the last 5d of events history +| EVAL Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now()) +| WHERE Esql.recent <= 6 AND Esql.logon_count == 1 + +// move dynamic fields to ECS equivalent for rule exceptions +| EVAL source.user.name = MV_FIRST(Esql.user_values) + +| KEEP source.ip, source.user.name, Esql.* +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1078" +name = "Valid Accounts" +reference = "https://attack.mitre.org/techniques/T1078/" +[[rule.threat.technique.subtechnique]] +id = "T1078.004" +name = "Cloud Accounts" +reference = "https://attack.mitre.org/techniques/T1078/004/" + + + +[rule.threat.tactic] +id = "TA0001" +name = "Initial Access" +reference = "https://attack.mitre.org/tactics/TA0001/" + diff --git a/rules/network/initial_access_newly_observed_fortigate_admin_logon.toml b/rules/network/initial_access_newly_observed_fortigate_admin_logon.toml index 5b6bd9639..abd746f9f 100644 --- a/rules/network/initial_access_newly_observed_fortigate_admin_logon.toml +++ b/rules/network/initial_access_newly_observed_fortigate_admin_logon.toml @@ -2,46 +2,20 @@ creation_date = "2026/01/28" integration = ["fortinet_fortigate"] maturity = "production" -updated_date = "2026/01/28" +updated_date = "2026/01/29" [rule] author = ["Elastic"] description = """ -This rule detects the first observed successful login of a user with the Administrator role to the FortiGate management interface within the last 5 days. -First-time administrator logins can indicate newly provisioned accounts, misconfigurations, or unauthorized access using valid credentials and should be reviewed promptly. +This rule detects the first observed successful login of a user with the Administrator role to the FortiGate management +interface within the last 5 days. First-time administrator logins can indicate newly provisioned accounts, +misconfigurations, or unauthorized access using valid credentials and should be reviewed promptly. """ from = "now-7205m" interval = "5m" language = "esql" license = "Elastic License v2" name = "First-Time FortiGate Administrator Login" -risk_score = 73 -rule_id = "55a372b9-f5b6-4069-a089-8637c00609a2" -severity = "high" -tags = ["Use Case: Threat Detection", "Tactic: Initial Access", "Resources: Investigation Guide", "Domain: Network", "Domain: Identity", "Data Source: Fortinet"] -timestamp_override = "event.ingested" -type = "esql" - -query = ''' -FROM logs-fortinet_fortigate.*, filebeat-* metadata _id - -| WHERE event.dataset == "fortinet_fortigate.log" and - event.category == "authentication" and event.action == "login" and - event.outcome == "success" and source.user.roles == "Administrator" and source.user.name is not null -| stats Esql.logon_count = count(*), - Esql.first_time_seen = MIN(@timestamp), - Esql.source_ip_values = VALUES(source.ip), - Esql.message_values = VALUES(message) by source.user.name - -// first time seen is within 6m of the rule execution time and for the last 5d of events history -| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now()) -| where Esql.recent <= 6 and Esql.logon_count == 1 - -// move dynamic fields to ECS equivalent for rule exceptions -| eval source.ip = MV_FIRST(Esql.source_ip_values) - -| keep source.ip, source.user.name, Esql.* -''' note = """## Triage and Analysis ### Investigating First-Time FortiGate Administrator Login @@ -86,7 +60,45 @@ Because administrator access provides full control over network security devices - Rotate credentials and review authentication sources. - Audit recent FortiGate configuration changes. - Review surrounding network activity for lateral movement or persistence attempts.""" -references = ["https://www.elastic.co/docs/reference/integrations/fortinet_fortigate"] +references = [ + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 73 +rule_id = "55a372b9-f5b6-4069-a089-8637c00609a2" +severity = "high" +tags = [ + "Use Case: Threat Detection", + "Tactic: Initial Access", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "esql" + +query = ''' +FROM logs-fortinet_fortigate.*, filebeat-* metadata _id + +| WHERE event.dataset == "fortinet_fortigate.log" and + event.category == "authentication" and event.action == "login" and + event.outcome == "success" and source.user.roles == "Administrator" and source.user.name is not null +| stats Esql.logon_count = count(*), + Esql.first_time_seen = MIN(@timestamp), + Esql.source_ip_values = VALUES(source.ip), + Esql.message_values = VALUES(message) by source.user.name + +// first time seen is within 6m of the rule execution time and for the last 5d of events history +| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now()) +| where Esql.recent <= 6 and Esql.logon_count == 1 + +// move dynamic fields to ECS equivalent for rule exceptions +| eval source.ip = MV_FIRST(Esql.source_ip_values) + +| keep source.ip, source.user.name, Esql.* +''' [[rule.threat]] @@ -101,3 +113,4 @@ reference = "https://attack.mitre.org/techniques/T1078/" id = "TA0001" name = "Initial Access" reference = "https://attack.mitre.org/tactics/TA0001/" + diff --git a/rules/network/persistence_fortigate_admin_creation_unusual_source.toml b/rules/network/persistence_fortigate_admin_creation_unusual_source.toml new file mode 100644 index 000000000..bf11e09db --- /dev/null +++ b/rules/network/persistence_fortigate_admin_creation_unusual_source.toml @@ -0,0 +1,100 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects FortiGate administrator account creation from a source IP address not previously seen performing +admin operations on the device. Threat actors exploiting CVE-2026-24858 (FG-IR-26-060) authenticate via FortiCloud +SSO bypass and immediately create local administrator accounts for persistence, typically from infrastructure not +associated with normal administrative activity. +""" +from = "now-9m" +index = ["logs-fortinet_fortigate.*"] +interval = "5m" +language = "kuery" +license = "Elastic License v2" +name = "FortiGate Administrator Account Creation from Unusual Source" +note = """## Triage and analysis + +### Investigating FortiGate Administrator Account Creation from Unusual Source + +This alert indicates that an administrator account was created on a FortiGate device from a source IP address that has not been observed performing configuration changes in the recent history window. This is a behavioral indicator of compromise, as threat actors exploiting SSO bypass vulnerabilities typically operate from infrastructure not previously associated with the device. + +### Possible investigation steps + +- Review `source.ip` to determine whether the IP address belongs to a known management network or authorized administrator location. Check against known threat infrastructure from The Constant Company LLC, BL Networks, and Kaopu Cloud HK Limited. +- Examine `fortinet.firewall.cfgobj` for the name of the newly created account and `fortinet.firewall.cfgattr` for the access profile assigned (especially super_admin). +- Check `source.user.name` to identify the account that performed the creation and verify whether it was recently created itself or accessed via SSO. +- Look for other configuration changes from the same source IP, including firewall policy modifications, configuration exports, or VPN user creation. +- Run `get system admin` on the affected FortiGate to list all current administrator accounts and compare against the authorized list. + +### False positive analysis + +- Authorized administrators connecting from a new location (VPN, travel, new office). +- Initial device setup or migration where configuration changes come from temporary infrastructure. +- Managed service providers performing authorized administration from rotating IP addresses. + +### Response and remediation + +- If unauthorized, immediately delete the newly created administrator account and audit the source account for compromise. +- Block the source IP at the perimeter and check other FortiGate devices for activity from the same IP. +- Restore configuration from a known-clean backup and rotate all credentials including LDAP/AD accounts connected to the device. +- Upgrade FortiOS to a patched version and disable FortiCloud SSO if not required.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 47 +rule_id = "d08ba1ed-a0a3-4fe0-9c02-e643b9a25a03" +severity = "medium" +tags = [ + "Use Case: Threat Detection", + "Tactic: Persistence", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "new_terms" + +query = ''' +event.dataset: "fortinet_fortigate.log" and + event.code: "0100044547" and + fortinet.firewall.cfgpath: "system.admin" and + fortinet.firewall.action: "Add" and + fortinet.firewall.ui: (* and not "") +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1136" +name = "Create Account" +reference = "https://attack.mitre.org/techniques/T1136/" +[[rule.threat.technique.subtechnique]] +id = "T1136.001" +name = "Local Account" +reference = "https://attack.mitre.org/techniques/T1136/001/" + + + +[rule.threat.tactic] +id = "TA0003" +name = "Persistence" +reference = "https://attack.mitre.org/tactics/TA0003/" + +[rule.new_terms] +field = "new_terms_fields" +value = ["fortinet.firewall.ui"] +[[rule.new_terms.history_window_start]] +field = "history_window_start" +value = "now-5d" diff --git a/rules/network/persistence_fortigate_sso_login_followed_by_admin_creation.toml b/rules/network/persistence_fortigate_sso_login_followed_by_admin_creation.toml new file mode 100644 index 000000000..432f9d326 --- /dev/null +++ b/rules/network/persistence_fortigate_sso_login_followed_by_admin_creation.toml @@ -0,0 +1,96 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects a FortiCloud SSO login followed by administrator account creation on the same FortiGate device +within 15 minutes. This sequence is a high-confidence indicator of the FG-IR-26-060 attack pattern, where threat +actors authenticate via SAML-based SSO bypass and immediately create local administrator accounts for persistence. +""" +from = "now-30m" +index = ["logs-fortinet_fortigate.*"] +interval = "10m" +language = "eql" +license = "Elastic License v2" +name = "FortiGate SSO Login Followed by Administrator Account Creation" +note = """## Triage and analysis + +### Investigating FortiGate SSO Login Followed by Administrator Account Creation + +This alert indicates that a FortiCloud SSO login was followed by an administrator account creation event on the same FortiGate device within 15 minutes. This two-event sequence is the core attack pattern observed in the FG-IR-26-060 campaign. + +The attack flow is: authenticate via FortiCloud SSO using a crafted SAML assertion, then immediately create local administrator accounts to maintain access even after the SSO vulnerability is patched. + +### Possible investigation steps + +- Review the SSO login event for the FortiCloud account used and the source IP. Determine whether the SSO account belongs to the organization. +- Check the admin creation event for the names of accounts created and the access profiles assigned (especially super_admin). +- Assess the timing between events. In the observed campaign, admin creation occurs within seconds of SSO login. A tight time correlation is a strong indicator of compromise. +- Review `observer.name` to identify the targeted device and verify whether FortiCloud SSO is intentionally enabled. Run `get system admin` to list all current administrator accounts. +- Check whether the same SSO account or source IP targeted other devices. Look for configuration exports, firewall policy changes, or VPN modifications following the admin creation. + +### False positive analysis + +- An authorized administrator logging in via FortiCloud SSO and creating a new admin account as part of normal operations. +- Initial device onboarding where SSO login and account setup occur in the same session. + +### Response and remediation + +- If unauthorized, delete all administrator accounts created during the session and disable FortiCloud SSO immediately. +- Restore configuration from a known-clean backup and rotate all credentials including LDAP/AD accounts connected to the device. +- Upgrade FortiOS to a patched version and engage incident response for the affected device and any downstream systems. +- If the activity is expected, document the administrative session and verify it was authorized. Consider creating accounts through a separate session to avoid triggering this correlation.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 73 +rule_id = "e3a7b1c2-5d9f-4e8a-b6c3-2f1d4e5a6b7c" +severity = "high" +tags = [ + "Use Case: Threat Detection", + "Tactic: Persistence", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "eql" + +query = ''' +sequence by observer.name with maxspan=15m + [authentication where event.dataset == "fortinet_fortigate.log" and + event.action == "login" and event.outcome == "success" and + (fortinet.firewall.method == "sso" or fortinet.firewall.ui like~ "sso*")] + [any where event.dataset == "fortinet_fortigate.log" and + event.code == "0100044547" and + fortinet.firewall.cfgpath == "system.admin" and + fortinet.firewall.action == "Add"] +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1136" +name = "Create Account" +reference = "https://attack.mitre.org/techniques/T1136/" +[[rule.threat.technique.subtechnique]] +id = "T1136.001" +name = "Local Account" +reference = "https://attack.mitre.org/techniques/T1136/001/" + + + +[rule.threat.tactic] +id = "TA0003" +name = "Persistence" +reference = "https://attack.mitre.org/tactics/TA0003/" diff --git a/rules/network/persistence_fortigate_super_admin_account_creation.toml b/rules/network/persistence_fortigate_super_admin_account_creation.toml new file mode 100644 index 000000000..95436b332 --- /dev/null +++ b/rules/network/persistence_fortigate_super_admin_account_creation.toml @@ -0,0 +1,93 @@ +[metadata] +creation_date = "2026/01/28" +integration = ["fortinet_fortigate"] +maturity = "production" +updated_date = "2026/01/28" + +[rule] +author = ["Elastic"] +description = """ +This rule detects the creation of an administrator account on a FortiGate device. Administrator account creation on +these devices should be infrequent and tightly controlled. In the FG-IR-26-060 campaign, threat actors created +super_admin accounts immediately after gaining initial access via FortiCloud SSO bypass to establish persistence. +""" +from = "now-9m" +interval = "5m" +index = ["logs-fortinet_fortigate.*"] +language = "eql" +license = "Elastic License v2" +name = "FortiGate Super Admin Account Creation" +note = """## Triage and analysis + +### Investigating FortiGate Super Admin Account Creation + +This alert indicates that an administrator account was created on a FortiGate device. Administrator creation events on these devices are generally rare and should be closely scrutinized, as they are a key persistence mechanism used in the FG-IR-26-060 campaign. + +In the observed campaign, threat actors created multiple super_admin accounts (audit, backup, support, itadmin, secadmin, remoteadmin) within seconds of initial access to ensure persistent control even if individual accounts are discovered and removed. + +### Possible investigation steps + +- Review `fortinet.firewall.cfgobj` for the name of the newly created account and examine `fortinet.firewall.cfgattr` to determine the access profile assigned to the account (especially super_admin). +- Review `source.user.name` to determine which account performed the creation and `fortinet.firewall.ui` for the source interface and IP address. Verify whether this administrator is authorized to provision accounts. +- Check whether a login event (especially via SSO) occurred shortly before the account creation. Analyze the timing between events. +- Check `observer.name` to identify the FortiGate device and run `get system admin` to get the current administrator list. Check other FortiGate devices in the fleet for the same account name. + +### False positive analysis + +- Authorized provisioning of a new administrator account through an approved change management process. +- Initial device setup where administrator accounts are created as part of deployment. +- Migration or device replacement scenarios where accounts are replicated from another device. + +### Response and remediation + +- If unauthorized, delete the administrator account immediately and audit the creating account for compromise. +- Treat the device configuration as compromised and restore from a known-clean backup. +- Check all FortiGate devices for similar account creation and upgrade FortiOS to a patched version. +- If the activity is expected, document the provisioning activity and the business justification.""" +references = [ + "https://www.fortiguard.com/psirt/FG-IR-26-060", + "https://www.fortinet.com/blog/psirt-blogs/analysis-of-sso-abuse-on-fortios", + "https://www.elastic.co/docs/reference/integrations/fortinet_fortigate", + "https://www.cisa.gov/news-events/alerts/2026/01/28/fortinet-releases-guidance-address-ongoing-exploitation-authentication-bypass-vulnerability-cve-2026", +] +risk_score = 47 +rule_id = "cbbe0523-33f3-4420-b88d-5c940d9e72c1" +severity = "medium" +tags = [ + "Use Case: Threat Detection", + "Tactic: Persistence", + "Resources: Investigation Guide", + "Domain: Network", + "Domain: Identity", + "Data Source: Fortinet", + "Data Source: Fortinet FortiGate", +] +timestamp_override = "event.ingested" +type = "eql" + +query = ''' +any where event.dataset == "fortinet_fortigate.log" and + event.code == "0100044547" and + fortinet.firewall.cfgpath == "system.admin" and + fortinet.firewall.action == "Add" and + fortinet.firewall.cfgattr like~ "*accprofile[super_admin]*" +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1136" +name = "Create Account" +reference = "https://attack.mitre.org/techniques/T1136/" +[[rule.threat.technique.subtechnique]] +id = "T1136.001" +name = "Local Account" +reference = "https://attack.mitre.org/techniques/T1136/001/" + + + +[rule.threat.tactic] +id = "TA0003" +name = "Persistence" +reference = "https://attack.mitre.org/tactics/TA0003/"