---
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
