The U.S. Cybersecurity and Infrastructure Security Agency (CISA) has added a new batch of vulnerabilities affecting GitLab and Cisco products to its Known Exploited Vulnerabilities (KEV) catalog. Among them is CVE-2026-97229, a critical flaw that could allow attackers to execute arbitrary code on vulnerable systems.
For defenders, a KEV listing is not an advisory — it is a confirmation. A vulnerability only lands in the KEV catalog when CISA has reliable evidence of active, in-the-wild exploitation. That means threat actors are already weaponizing these flaws against real targets, and any unpatched GitLab instance or Cisco device exposed to the internet should be treated as a probable target — or a probable victim.
If you operate self-managed GitLab (which stores your source code, CI/CD secrets, and signing keys) or Cisco network infrastructure (which sits at the trust boundary of your environment), this KEV update demands immediate triage. A compromised CI/CD platform is a supply-chain incident waiting to happen; a compromised edge device is a beachhead for everything that follows.
Technical Analysis
What Was Added to the KEV Catalog
CISA's latest KEV update covers vulnerabilities in two product families that are perennially high-value targets:
- GitLab — the widely deployed DevOps platform used for source code management, CI/CD pipelines, and package registries. GitLab flaws have historically attracted both ransomware affiliates and nation-state actors because a single compromised instance exposes repositories, pipeline variables, cloud credentials, and deployment keys.
- Cisco — networking and security appliances that form the backbone of enterprise perimeter infrastructure. Cisco device exploitation is a hallmark of sophisticated espionage campaigns (e.g., ARCANE DOOR-style activity against edge appliances) because network devices often lack EDR coverage and persist undetected for months.
CVE-2026-97229 — Critical Remote Code Execution
The headline flaw in this KEV update is CVE-2026-97229, rated critical, which allows attackers to run arbitrary code on affected systems. Remote code execution at the application or appliance layer is the worst-case scenario for defenders: it gives the attacker code execution in the context of the service, from which they can pivot to credential theft, lateral movement, persistence, and data exfiltration.
From a defender's perspective, the exploitation chain for flaws of this class typically follows a predictable pattern:
- Reconnaissance — internet-wide scanning (Shodan, Censys, attacker-operated scanners) identifies exposed, unpatched instances.
- Initial exploitation — a crafted request to the vulnerable component triggers code execution, often as the service account (e.g.,
giton GitLab systems or the appliance OS context on network devices). - Post-exploitation — web shells or scheduled tasks are dropped for persistence; service accounts spawn anomalous child processes (
bash,curl,wget, reverse shells); outbound connections to attacker infrastructure begin. - Expansion — harvested CI/CD tokens, SSH keys, or device configurations are used for lateral movement or supply-chain poisoning.
Exploitation Status
- CISA KEV: Confirmed. Inclusion in the catalog means these vulnerabilities are being actively exploited in the wild.
- Federal mandate: Under Binding Operational Directive (BOD) 22-01, U.S. federal civilian agencies must remediate KEV-listed vulnerabilities within the deadline CISA assigns — typically within three weeks of catalog addition. Private-sector organizations should treat that same window as their service-level target; attackers do not distinguish between government and enterprise targets when scanning.
Why These Two Product Families Matter
- GitLab sits at the center of your software supply chain. An RCE on GitLab is not just a server compromise — it is potential access to every repository, every pipeline secret, and every artifact your developers ship. Treat GitLab exploitation as a supply-chain risk event, not a single-host incident.
- Cisco appliances are edge devices: VPN concentrators, firewalls, routers, and management interfaces. They rarely have endpoint agents, their logs are often not centralized, and adversaries exploit them specifically because detection coverage is thin. Persistent implants on network devices have survived full workstation reimaging in real intrusions.
Detection & Response
A KEV listing means exploitation is already happening, so patching alone is insufficient. You must assume possible pre-patch compromise and hunt accordingly. The detections below focus on the highest-fidelity post-exploitation behaviors: service accounts spawning shells, web shell deployment, unexpected outbound connections from servers and appliances, and anomalous GitLab authentication/configuration activity.
Sigma Rules
---
title: GitLab Service Account Spawning Suspicious Shell or Downloader
id: 8f2c1d4e-6a3b-4c5d-9e7f-2a1b3c4d5e6f
status: experimental
description: Detects the git or gitlab service accounts spawning interactive shells or download utilities, consistent with post-exploitation of a GitLab RCE vulnerability such as CVE-2026-97229.
references:
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.execution
- attack.t1059.004
- attack.t1105
logsource:
category: process_creation
product: linux
detection:
selection_user:
User:
- 'git'
- 'gitlab-www'
- 'gitlab-redis'
- 'gitlab-psql'
selection_image:
Image|endswith:
- '/bash'
- '/sh'
- '/dash'
- '/curl'
- '/wget'
- '/python'
- '/python3'
- '/perl'
- '/nc'
- '/ncat'
condition: selection_user and selection_image
falsepositives:
- GitLab CI runners executing pipeline jobs (restrict scope to the GitLab host itself, not runner hosts)
- Rare administrative maintenance via service account
level: high
---
title: Web Server or Application Process Writing Executable to Web-Accessible Directory
id: 3b7e9f12-4c8a-4d6e-8f1a-5b2c3d4e5f6a
status: experimental
description: Detects web-facing service processes writing script or executable files into web-accessible or temporary directories, a common web shell deployment pattern following exploitation of internet-facing applications such as GitLab.
references:
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection_path:
TargetFilename|contains:
- '/var/opt/gitlab/gitlab-rails/uploads/'
- '/opt/gitlab/embedded/service/gitlab-rails/public/'
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
selection_ext:
TargetFilename|endswith:
- '.php'
- '.jsp'
- '.sh'
- '.elf'
filter_legit_tmp:
TargetFilename|contains:
- '/tmp/ruby'
- '/tmp/passenger'
condition: selection_path and selection_ext and not filter_legit_tmp
falsepositives:
- Legitimate GitLab upgrades writing to application directories (correlate with maintenance windows)
- CI artifacts staged in /tmp on runner hosts
level: high
---
title: Unexpected Outbound Connection from GitLab Server Process
id: 5d1a8c36-7e2b-4f49-9a3c-6d5e4f3a2b1c
status: experimental
description: Detects GitLab application processes initiating outbound connections to rare external destinations, potentially indicating reverse shell or data exfiltration activity after RCE exploitation.
references:
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- https://attack.mitre.org/techniques/T1071/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.command_and_control
- attack.t1071.001
logsource:
category: network_connection
product: linux
detection:
selection:
Image|contains:
- 'puma'
- 'sidekiq'
- 'gitaly'
- 'gitlab-workhorse'
filter_known:
DestinationIp|startswith:
- '10.'
- '172.16.'
- '192.168.'
- '127.'
condition: selection and not filter_known
falsepositives:
- GitLab outbound webhooks, package registry sync, and license checks (baseline known destinations and alert only on new ones)
level: medium
KQL (Microsoft Sentinel / Defender)
The following hunt queries assume Syslog/CEF ingestion from GitLab hosts and network devices into Sentinel, plus Defender/MDE coverage where available. Run these over at least the last 30 days to catch pre-patch compromise.
// Hunt 1: GitLab service accounts spawning shells or downloaders (Linux Syslog ingestion)
Syslog
| where TimeGenerated > ago(30d)
| where ProcessName in~ ("bash", "sh", "dash", "curl", "wget", "python", "python3", "perl", "nc", "ncat")
| where SyslogMessage has_any ("git", "gitlab")
| project TimeGenerated, Computer, ProcessName, SyslogMessage, HostIP
| order by TimeGenerated desc
;
// Hunt 2: Rare outbound connections from GitLab application processes (CEF/syslog firewall or host logs)
CommonSecurityLog
| where TimeGenerated > ago(30d)
| where DeviceProduct has_any ("gitlab", "paloalto", "fortinet", "cisco")
| where ApplicationProtocol in~ ("puma", "sidekiq", "gitlab-workhorse")
or SourceHostName has "gitlab"
| where DestinationIP !startswith "10." and DestinationIP !startswith "192.168." and DestinationIP !startswith "172."
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by SourceHostName, DestinationIP, DestinationPort
| where ConnectionCount < 50
| order by FirstSeen asc
;
// Hunt 3: Suspicious process execution on Cisco management hosts and network device logins (Syslog from IOS/ASA)
Syslog
| where TimeGenerated > ago(30d)
| where SyslogMessage has_any ("%SEC_LOGIN-5-LOGIN_SUCCESS", "configured from", "Added user", "NEW_USER")
or SyslogMessage has_any ("copy tftp", "copy ftp", "write memory")
| where SyslogMessage !has "known-admin-source-ip"
| project TimeGenerated, Computer, SeverityLevel, SyslogMessage
| order by TimeGenerated desc
;
// Hunt 4: Web shell staging — script files written to temp or web dirs (Defender for Endpoint on Linux)
DeviceFileEvents
| where TimeGenerated > ago(30d)
| where FolderPath has_any ("/tmp/", "/dev/shm/", "/var/tmp/", "/var/opt/gitlab/gitlab-rails/uploads/")
| where FileName endswith ".sh" or FileName endswith ".php" or FileName endswith ".elf"
| where InitiatingProcessAccountName in~ ("git", "gitlab-www", "www-data", "nginx")
| project TimeGenerated, DeviceName, FileName, FolderPath, InitiatingProcessAccountName, SHA256
| order by TimeGenerated desc
Tune Hunt 2 against a known-destination baseline (GitLab webhook targets, package registries, license servers) or it will be noisy; Hunts 1, 3, and 4 are high-fidelity on a properly scoped GitLab host.
Velociraptor VQL
Use this artifact for a fleet-wide sweep of GitLab hosts (and Linux jump boxes used to administer Cisco gear) to identify service-account shell execution, staged payloads in temp directories, and suspicious outbound connections in one pass.
-- Hunt GitLab post-exploitation artifacts: service account shells,
-- staged payloads in temp directories, and unexpected outbound connections
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Username =~ 'git|gitlab'
AND (Name =~ '(?i)bash|sh|dash|curl|wget|python|perl|nc|ncat'
OR CommandLine =~ '(?i)bash -i|/dev/tcp|nc -e|curl .*\| *(bash|sh)|wget -qO')
UNION
SELECT
NULL AS Pid,
B.Name AS Name,
B.FullPath AS CommandLine,
NULL AS Exe,
NULL AS Username,
B.Mtime AS CreateTime
FROM glob(globs=['/tmp/*.sh', '/tmp/*.elf', '/dev/shm/*', '/var/tmp/*.sh',
'/var/opt/gitlab/gitlab-rails/uploads/**/*.php'])
AS B
WHERE B.Mtime > now() - 2592000
UNION
SELECT
C.Pid AS Pid,
C.Name AS Name,
format(format='%v:%v', args=[C.Raddr.IP, C.Raddr.Port]) AS CommandLine,
NULL AS Exe,
NULL AS Username,
NULL AS CreateTime
FROM netstat() AS C
WHERE C.Name =~ '(?i)puma|sidekiq|gitaly|gitlab-workhorse|ruby'
AND C.Status = 'ESTABLISHED'
AND NOT C.Raddr.IP =~ '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)'
Remediation & Verification Script
Run the following on self-managed GitLab Linux hosts to check the installed version against the vendor's fixed releases, and to surface common post-exploitation artifacts for triage. For Cisco devices, the equivalent actions are comparing running software against the fixed releases in the relevant Cisco Security Advisory and auditing local accounts and configuration history via the device CLI and your config management backups.
#!/bin/bash
# GitLab KEV triage: version verification + compromise indicators
# Run as root on self-managed GitLab (Omnibus) hosts. Review output before remediating.
echo "=== [1] Installed GitLab version ==="
gitlab-rake gitlab:env:info 2>/dev/null | head -20
cat /opt/gitlab/version-manifest.txt 2>/dev/null | head -5
echo "=== [2] Check for pending OS/GitLab updates ==="
apt list --upgradable 2>/dev/null | grep -i gitlab || yum check-update gitlab-ce gitlab-ee 2>/dev/null
echo "=== [3] Shells/downloaders spawned by service accounts (last 7 days) ==="
ausearch -ts recent -k exec_log 2>/dev/null | grep -Ei 'uid=(git|gitlab-www)' | grep -Ei 'bash|/sh|curl|wget|python|nc ' | tail -30 || \
journalctl --since "7 days ago" | grep -Ei 'sudo.*(git|gitlab-www).*(bash|sh|curl|wget|python)' | tail -30
echo "=== [4] Recently modified files in temp and web-accessible dirs ==="
find /tmp /var/tmp /dev/shm -type f -mtime -7 2>/dev/null | head -40
find /var/opt/gitlab/gitlab-rails/uploads /opt/gitlab/embedded/service/gitlab-rails/public \
-type f \( -name '*.php' -o -name '*.sh' -o -name '*.jsp' \) -mtime -30 2>/dev/null
echo "=== [5] Unexpected established outbound connections from GitLab processes ==="
ss -tupn 2>/dev/null | grep -Ei 'puma|sidekiq|gitaly|ruby|workhorse' | grep ESTAB | \
grep -Ev '127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.'
echo "=== [6] New or modified local users and SSH authorized_keys (last 30 days) ==="
find /home /root /var/opt/gitlab -name 'authorized_keys' -mtime -30 2>/dev/null
awk -F: '$3 >= 1000 {print $1}' /etc/passwd
echo "=== [7] Persistence mechanisms modified recently ==="
find /etc/cron* /var/spool/cron /etc/systemd/system -type f -mtime -30 2>/dev/null
echo ""
echo "=== ACTION: If GitLab version is below the fixed release in the vendor advisory, ==="
echo "=== patch immediately: apt update && apt install gitlab-ee (or gitlab-ce) ==="
echo "=== Then re-run sections 3-7 after patching and treat any hits as IR triggers. ==="
Remediation
- Confirm your exposure immediately. Inventory every self-managed GitLab instance (including forgotten staging servers and runners) and every Cisco appliance with the affected software trains. Internet-facing instances are priority zero — that is where the active exploitation CISA confirmed is concentrated.
- Patch against the vendor advisories, not just the CVE list. Pull the fixed version numbers directly from the official sources:
- CISA KEV catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- GitLab security releases: https://about.gitlab.com/security-releases/
- Cisco Security Advisories: https://sec.cloudapps.cisco.com/security/center/publicationListing.x Verify the exact fixed release for your version train — GitLab backports fixes across multiple branches, and Cisco fixes are train-specific.
- Meet the BOD 22-01 clock. Federal civilian agencies must remediate within CISA's assigned KEV due date (typically three weeks from catalog addition). Treat that same deadline as your internal SLA regardless of sector — the exploitation CISA documented does not wait for your change window.
- Hunt before you patch, patch before you trust. Active exploitation means some percentage of unpatched systems are already compromised. Run the detection content above against at least 30 days of telemetry before and after patching. A clean patch on a compromised host changes nothing.
- If compromise indicators surface on GitLab, rotate everything. Pipeline variables, deploy tokens, SSH keys, OAuth application secrets, Personal Access Tokens, and any cloud credentials stored in CI/CD configuration. Assume secrets on an exploited GitLab host are burned.
- If compromise indicators surface on Cisco devices, treat it as an IR engagement. Review local accounts, AAA/TACACS+ logs, configuration diffs against known-good backups, firmware integrity (verify image hashes against Cisco-published values), and any unexpected GRE tunnels, NAT rules, or added management ACLs. Edge device implants are designed to survive reboots and partial remediation.
- Reduce future exposure. Remove GitLab and Cisco management interfaces from direct internet exposure behind VPN/ZTNA, enforce central log forwarding from all network devices (they have no EDR — your SIEM is their only telemetry), and subscribe to CISA KEV feeds so your vulnerability scanner automatically reprioritizes KEV-listed CVEs above CVSS-only scoring.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.