← All hunts high TLP:CLEAR Part 1 of 2

Exploitation of Web-Facing GitLab and Langflow

An adversary is exploiting GitLab unauthenticated file reads or Langflow authenticated RCE to access repository secrets or execute code on the server host, starting from public-facing assets.

Based on research by Rapid7 2026-09-28 9 steps · 3 queries T1190

Brief

Why now

Rapid7's latest Metasploit Wrap Up: Belgian Waffles, Chocolates, and…Modules-Frites? (https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-belgian-waffles-chocolates-and-modules-frites) includes new modules for GitLab and Langflow. These modules simplify exploitation for attackers looking to read repository secrets or execute code on AI service hosts. While these vulnerabilities are critical, catching them in the wild is difficult because the exploit traffic often mirrors legitimate administrative use.

How the hunt flows

The hunt starts by querying vulnerability management data. It identifies every host in the estate flagged with CVE-2026-85706 or CVE-2026-18729. This step focuses the behavioral search on the most at-risk systems and prevents the hunt from processing logs for patched or non-vulnerable assets.

For GitLab assets, the hunt examines HTTP logs for repository API requests. It calculates the prevalence of requests to specific commit and file paths. High-frequency or rare source IPs requesting these paths suggest a Metasploit module harvesting repository contents rather than a developer performing standard work.

Simultaneously, the hunt monitors Langflow service processes. It looks for common shells like bash or powershell.exe spawned as child processes of the Langflow service. Since Langflow does not typically launch interactive shells for its internal operations, these events indicate successful code execution.

An automated agent then correlates the vulnerability status with any observed network or process anomalies. This step filters out standard administrative activity and provides a per-host verdict. If the agent finds high-confidence evidence of an exploit, it routes the host for immediate isolation and credential revocation.

What the hunt cannot see

If the organization does not decrypt HTTPS traffic at the proxy or log it at the application level, the GitLab API request patterns remain invisible to the HTTP surface. The hunt also faces a challenge with Langflow if a sophisticated attacker executes Python code entirely in-memory within the service process. If no child process spawns, the process-based query will not trigger.

In this series

Steps

  1. Identify vulnerable web assets

    Query · scoping

    Locate hosts with reported vulnerabilities corresponding to the Metasploit module release to prioritize the behavioral search.

    reads hb_vulnerability_findingsql
    SELECT device_uid, resource_uid, cve_uid, severity, title FROM hb_vulnerability_finding WHERE instr(',' || '{{vulnerable_cves}}' || ',', ',' || cve_uid || ',') > 0

    What a hit looks like. A list of device identifiers or resources flagged with the target CVEs. Silence means the vulnerability scanner has not identified these risks in the estate.

  2. GitLab repository API request prevalence

    Query · baseline

    Identify rare or unauthorized access to repository commits and files APIs that suggest an automated gather module is reading files.

    reads hb_http_activitysql
    SELECT src_endpoint_ip, url_path, device_hostname, COUNT(*) as request_count, MIN(time) as first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%/api/v4/projects/%/repository/commits%' OR LOWER(url_path) LIKE '%/api/v4/projects/%/repository/files%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip, url_path, device_hostname

    What a hit looks like. Anomalous requests to specific API paths. Rare combinations of URL paths and source IPs indicate potential exploit attempts.

  3. Langflow anomalous child processes

    Query · detection candidate

    Detect authenticated RCE in Langflow by identifying shells or interpreters spawned by the Langflow service process.

    reads hb_process_activitysql
    SELECT device_hostname, process_name, process_cmd_line, parent_process_name, parent_process_cmd_line, user_name, time FROM hb_process_activity WHERE LOWER(parent_process_cmd_line) LIKE '%langflow%' AND instr(',' || '{{target_shells}}' || ',', ',' || LOWER(process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Shell instances where the parent command line identifies Langflow, indicating code execution.

  4. Triage exploitation signals

    Agent triage

    Synthesize the presence of vulnerable applications with observed HTTP and process anomalies to settle on a verdict.

  5. Route on triage verdict

    Decision

    Determine whether to contain a host, task an analyst, or close the hunt based on the agent findings.

  6. Isolate host and revoke credentials

    Response action

    Immediately contain the breach to prevent further data exfiltration or lateral movement.

  7. Manual forensic validation

    Analyst task

    Review the telemetry to confirm the scope of the compromise and identify any data exfiltrated.

  8. Hunt closure and reporting

    Analyst task

    Document the findings and ensure vulnerable systems are scheduled for patching.

Coverage

Scenario coverage

StageCoveredHow, or why not
GitLab Unauthenticated Arbitrary File Read
T1190
Yes identify-vulnerable-assets, gitlab-api-requests
Langflow AI Authenticated RCE
T1190
Yes identify-vulnerable-assets, langflow-suspicious-children
IPv6 DNS Takeover Coercion
T1190
Out of scope Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates, and…Modules-Frites?' series.
Anomalous RDP Interaction
T1021.001
Out of scope Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates, and…Modules-Frites?' series.
Kate Plugin Persistence
T1190
Out of scope Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates, and…Modules-Frites?' series.

Blind spots

  • Needs TLS decryption at the proxy or application-level logging. If GitLab traffic is not decrypted at a monitoring point, hb_http_activity will not show the URL path, missing the exploit attempts. It would answer whether file read attempts occurred over encrypted HTTPS channels.
  • Needs hb_process_activity and script telemetry. Sophisticated RCE may execute code without spawning a separate shell; if no child process is created, the process-based query will not trigger. It would answer whether Python code executed entirely within the Langflow interpreter process.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
lookback_daysnumber14Days of history to examine.
scope_hostslist[host]—Specific hostnames to narrow the behavioral search; leave empty for fleet-wide.
target_shellslist[string]sh, bash, zsh, cmd.exe, powershell.exe, pwsh.exeExecutables commonly used as shells for RCE persistence or command execution.
vulnerable_cveslist[string]CVE-2026-85706, CVE-2026-18729Targeted CVE identifiers for GitLab and Langflow.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint
Web server / proxy logssiemnetwork

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: A simple detection rule for GitLab API paths would trigger on regular administrative
  activity; this hunt uses prevalence to isolate rare access patterns and correlates
  it with known vulnerable assets and secondary process-level indicators for Langflow.
blind_spots:
- id: gitlab-https-decryption
  question: whether file read attempts occurred over encrypted HTTPS channels
  requires: TLS decryption at the proxy or application-level logging
  risk: If GitLab traffic is not decrypted at a monitoring point, hb_http_activity
    will not show the URL path, missing the exploit attempts.
  stage: gitlab-unauthenticated-file-read
- id: in-memory-python-execution
  question: whether Python code executed entirely within the Langflow interpreter
    process
  requires: hb_process_activity and script telemetry
  risk: Sophisticated RCE may execute code without spawning a separate shell; if no
    child process is created, the process-based query will not trigger.
  stage: langflow-authenticated-rce
coverage:
- stage: gitlab-unauthenticated-file-read
  status: covered
  steps:
  - identify-vulnerable-assets
  - gitlab-api-requests
- stage: langflow-authenticated-rce
  status: covered
  steps:
  - identify-vulnerable-assets
  - langflow-suspicious-children
- reason: "Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates,\
    \ and\u2026Modules-Frites?' series."
  stage: ipv6-dns-takeover-coercion
  status: out_of_scope
- reason: "Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates,\
    \ and\u2026Modules-Frites?' series."
  stage: rdp-anomalous-interaction
  status: out_of_scope
- reason: "Belongs to another part of the 'Metasploit Wrap Up: Belgian Waffles, Chocolates,\
    \ and\u2026Modules-Frites?' series."
  stage: kate-plugin-persistence
  status: out_of_scope
guardrails:
  claims: no_unsupported
  evidence: citation_required
  missing_data: not_benign
  telemetry: untrusted
hunt:
  applicability: campaign-specific
  handoff: keep-as-periodic-hunt
  justification: Metasploit modules for unauthenticated file reads and authenticated
    RCE lower the barrier for attackers to gain initial access to repository secrets
    or server environments; a negative result over vulnerable assets confirms no immediate
    active compromise.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An adversary is exploiting GitLab unauthenticated file reads or Langflow
  authenticated RCE to access repository secrets or execute code on the server host,
  starting from public-facing assets.
labels:
- hunt
- attack.t1190
name: Exploitation of Web-Facing GitLab and Langflow
parameters:
  lookback_days:
    default: '14'
    description: Days of history to examine.
    from:
      kind: manual
      observed: '2026-09-25'
      ref: default
    type: number
  scope_hosts:
    default: []
    description: Specific hostnames to narrow the behavioral search; leave empty for
      fleet-wide.
    from:
      kind: manual
      observed: '2026-09-25'
      ref: analyst-defined
    type: list[host]
  target_shells:
    default:
    - sh
    - bash
    - zsh
    - cmd.exe
    - powershell.exe
    - pwsh.exe
    description: Executables commonly used as shells for RCE persistence or command
      execution.
    from:
      kind: manual
      observed: '2026-09-25'
      ref: standard-tradecraft
    type: list[string]
  vulnerable_cves:
    default:
    - CVE-2026-85706
    - CVE-2026-18729
    description: Targeted CVE identifiers for GitLab and Langflow.
    from:
      kind: article
      observed: '2026-09-25'
      ref: Rapid7 Metasploit Wrap Up
    type: list[string]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-belgian-waffles-chocolates-and-modules-frites
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Start with servers identified in hb_vulnerability_finding with the target
  CVEs. Prioritize internet-facing GitLab instances and Langflow environments used
  for development or production AI workflows.
references:
- name: "Metasploit Wrap Up: Belgian Waffles, Chocolates, and\u2026Modules-Frites?"
  url: https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-belgian-waffles-chocolates-and-modules-frites
related:
- hunt: ipv6-dns-takeover-coercion
  reason: Lateral movement via DHCPv6 and DNS coercion is a distinct technique requiring
    different network and identity telemetry.
  relation: out-of-scope-alternative
scenario:
  stages:
  - name: GitLab Unauthenticated Arbitrary File Read
    observables:
    - CVE-2026-85706
    - HTTP requests to GitLab repository commits APIs
    - HTTP requests to GitLab repository files APIs
    - 'Module: gather/gitlab_file_read_cve_2026_85706'
    - Affected GitLab versions 18.7 up to 19.3.2
    slug: gitlab-unauthenticated-file-read
    tactic: initial-access
    techniques:
    - T1190
  - name: Langflow AI Authenticated RCE
    observables:
    - CVE-2026-18729
    - Authenticated HTTP requests to Langflow custom components
    - Arbitrary Python code execution via Langflow process
    - 'Module: multi/http/langflow_auth_rce_cve_2026_18729'
    - Langflow versions 1.11.1 and below
    slug: langflow-authenticated-rce
    tactic: execution
    techniques:
    - T1190
  - name: IPv6 DNS Takeover Coercion
    observables:
    - CVE-2026-20929
    - Rogue DHCPv6 server activity on UDP port 547
    - Rogue IPv6 Router Advertisements (RA)
    - Kerberos authentication relay attempts
    - 'Module: spoof/dhcp/dhcpv6_dns_takeover'
    - 'Module: spoof/ipv6/ipv6_ra_dns_takeover'
    slug: ipv6-dns-takeover-coercion
    tactic: credential-access
    techniques:
    - T1190
  - name: Anomalous RDP Interaction
    observables:
    - Unexpected size RDP packets and responses
    - Anomalous Remote Interactive logons
    - RDP connections to internal assets on port 3389
    slug: rdp-anomalous-interaction
    tactic: lateral-movement
    techniques:
    - T1021.001
  - name: Kate Plugin Persistence
    observables:
    - Writes to Kate editor plugin directories
    - New plugin configuration files for Kate editor
    - 'Module: multi/persistence/kate_plugin'
    slug: kate-plugin-persistence
    tactic: persistence
    techniques:
    - T1190
  summary: Recent Metasploit updates introduced exploitation modules for unauthenticated
    file read in GitLab (CVE-2026-85706) and authenticated RCE in Langflow AI (CVE-2026-18729).
    The release also features native IPv6 DNS takeover modules for Kerberos relay
    attacks and a new persistence mechanism targeting the Kate text editor.
series:
  index: 1
  slug: metasploit-wrap-up-belgian-waffles-chocolates-and-modules-frites
  title: "Metasploit Wrap Up: Belgian Waffles, Chocolates, and\u2026Modules-Frites?"
  total: 2
severity: high
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
  web:
    category: siem
    name: Web server / proxy logs
    telemetry:
    - network
tlp: clear
type: investigation
---


# Exploitation of Web-Facing GitLab and Langflow

This hunt targets two critical web vulnerabilities recently integrated into Metasploit: an unauthenticated local file read in GitLab (CVE-2026-85706) and an authenticated remote code execution in Langflow (CVE-2026-18729). The hunt begins by identifying vulnerable assets using inventory and vulnerability data, then checks for signs of active exploitation in parallel: it looks for rare GitLab API access patterns that suggest automated file harvesting, and detects anomalous shell processes originating from the Langflow AI service. An agent then triages the evidence per host to decide between containment or manual forensic review.

## identify-vulnerable-assets
<!-- Identify vulnerable web assets -->
Locate hosts with reported vulnerabilities corresponding to the Metasploit module release to prioritize the behavioral search.

```sqlite target=endpoint role=scoping params=(vulnerable_cves=vulnerable_cves)
~~~yaml
expected: A list of device identifiers or resources flagged with the target CVEs.
  Silence means the vulnerability scanner has not identified these risks in the estate.
reads:
- device_uid
- resource_uid
- cve_uid
- severity
- title
silence: not_evidence_of_absence
source: hb_vulnerability_finding
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT device_uid, resource_uid, cve_uid, severity, title FROM hb_vulnerability_finding WHERE instr(',' || '{{vulnerable_cves}}' || ',', ',' || cve_uid || ',') > 0
```

## exploitation-check
<!-- Check for exploitation activity -->
parallel:
- → gitlab-api-requests
- → langflow-suspicious-children
join: → triage-verdict

## gitlab-api-requests
<!-- GitLab repository API request prevalence -->
Identify rare or unauthorized access to repository commits and files APIs that suggest an automated gather module is reading files.

```sqlite target=web role=baseline params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
baseline:
  compare: first_seen
  window: '{{lookback_days}}d'
expected: Anomalous requests to specific API paths. Rare combinations of URL paths
  and source IPs indicate potential exploit attempts.
prevalence:
  by: device_hostname
  key:
  - url_path
  rare_below: 3
reads:
- src_endpoint_ip
- url_path
- device_hostname
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT src_endpoint_ip, url_path, device_hostname, COUNT(*) as request_count, MIN(time) as first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%/api/v4/projects/%/repository/commits%' OR LOWER(url_path) LIKE '%/api/v4/projects/%/repository/files%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip, url_path, device_hostname
```

## langflow-suspicious-children
<!-- Langflow anomalous child processes -->
Detect authenticated RCE in Langflow by identifying shells or interpreters spawned by the Langflow service process.

```sqlite target=endpoint role=detection-candidate params=(scope_hosts=scope_hosts, lookback_days=lookback_days, target_shells=target_shells)
~~~yaml
expected: Shell instances where the parent command line identifies Langflow, indicating
  code execution.
reads:
- device_hostname
- process_name
- process_cmd_line
- parent_process_name
- parent_process_cmd_line
- user_name
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT device_hostname, process_name, process_cmd_line, parent_process_name, parent_process_cmd_line, user_name, time FROM hb_process_activity WHERE LOWER(parent_process_cmd_line) LIKE '%langflow%' AND instr(',' || '{{target_shells}}' || ',', ',' || LOWER(process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## triage-verdict
<!-- Triage exploitation signals -->
```agent target=hunter
cite: required
context:
- identify-vulnerable-assets
- gitlab-api-requests
- langflow-suspicious-children
max_iterations: 5
objective: Determine if any host shows evidence of active exploit attempts in network
  or process telemetry that correlate with identified vulnerabilities.
success_criteria: A verdict for every scoped host citing relevant rows from HTTP or
  process queries.
tools:
- endpoint
- web
```

## route-verdict
<!-- Route on triage verdict -->
if~: "The triage verdict is malicious or suspicious for at least one host based on the correlation of vulnerabilities and exploit indicators." (confidence: high, judge=hunter)
then: → contain-host
indeterminate: → analyst-review
unavailable: → analyst-review (blind_spot: gitlab-https-decryption)
else: → close-out

## contain-host
<!-- Isolate host and revoke credentials -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the compromised host via the EDR console and revoke active GitLab or Langflow authentication tokens for any users identified in the triage context.
```
→ analyst-review

## analyst-review
<!-- Manual forensic validation -->
```manual target=analyst
Review full HTTP logs for the identified server to confirm which repository files were accessed. For Langflow, verify if child processes made any external network connections after spawning.
```
→ close-out

## close-out
<!-- Hunt closure and reporting -->
```manual target=analyst
Record the results of the hunt. If you found vulnerable servers without exploit indicators, ensure they are patched immediately. Record any false positives from the API prevalence query for future tuning.
```
→ end

Run it

Take this hunt into your environment.

Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.

Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.