Description
I've set up geo-based routing - can you outsmart it? Access to the real service is restricted based on your geographic location. Only requests from a specific region are routed to the server that holds the flag.
Setup
Launch the challenge instance and note the URL.
Get a VPN service with an Iceland server (e.g. ProtonVPN, Mullvad, or a browser extension like Browsec that lets you pick a country). Connect to an Iceland exit before proceeding.
Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Geo-restriction: read the config and bypass with a VPNObservationI noticed the challenge description mentioned geo-based routing that restricts access by geographic location, and the linked Nginx config file explicitly showed 'if ($geoip_country_code = IS)' routing to the flag server, which pointed directly to using a VPN with an Iceland exit node to satisfy that country-code check.The challenge exposes its routing configuration (a config file linked from the instance page). Reading it shows the gate is a literal country-code check -if ($geoip_country_code = IS)routes to the flag server, everyone else goes elsewhere. IS is the ISO code for Iceland. Connect to a VPN server located in Iceland so your requests appear to come from an Icelandic IP. Free options include ProtonVPN, Windscribe, or browser extensions like Browsec where you can select Iceland as the exit country. Tor with ExitNodes {is} also works as an alternative if you prefer not to use a VPN.bash# Read the provided config first - it names the IS gate outright.bash# After connecting your VPN to an Iceland server, verify your apparent IP:bashcurl -s https://ipinfo.io/json # confirm 'country': 'IS'bashbash# Alternative: Tor with Iceland exit nodes (if you prefer not to use a VPN)bash# sudo apt install torbash# echo 'ExitNodes {is}' | sudo tee -a /etc/tor/torrcbash# echo 'StrictNodes 1' | sudo tee -a /etc/tor/torrcbash# sudo systemctl restart torExpected output
{ "ip": "...", "country": "IS", "region": "...", ... }What didn't work first
Tried: Spoof the X-Forwarded-For or X-Real-IP header to an Icelandic IP address in the curl request.
Adding 'X-Forwarded-For: 185.220.101.1' (an Icelandic IP) to the request headers does not fool a server-side GeoIP check. Nginx reads the GeoIP module variable from the actual TCP connection IP, not from forwarded headers unless the config explicitly trusts and reads those headers. The gate checks the real source IP, so the request still comes from your non-Icelandic address and gets blocked.
Tried: Select any European country in the VPN settings instead of specifically Iceland.
The Nginx config checks for the exact ISO country code 'IS' (Iceland), not a regional group. Connecting to a German, Dutch, or Swedish VPN server produces a country code of DE, NL, or SE respectively. The conditional 'if ($geoip_country_code = IS)' does not match any of those, so the geo-gate still blocks the request. Only an Icelandic exit IP satisfies the check.
Learn more
Geo-based routing (also called geolocation-based access control) uses the requester's IP address to determine their geographic location and serve different content or restrict access accordingly. Nginx and other reverse proxies implement this using GeoIP databases like MaxMind's GeoLite2, which map IP ranges to country codes. A simple Nginx config might use
if ($geoip_country_code != IS) { return 403; }to block non-Icelandic traffic.VPNs (Virtual Private Networks) tunnel your traffic through a server in another country, making your requests appear to originate from that server's IP address. This is the most common and accessible way to bypass geo-restrictions. Many VPN providers offer free tiers with limited bandwidth and server selection that are sufficient for CTF challenges. Browser extensions like Browsec provide an even lighter-weight option for browser-based challenges. Tor with
ExitNodes {is}is an alternative that works the same way by routing your traffic through an Icelandic exit relay, though Iceland has fewer Tor exit nodes than larger countries, which can make circuit building slower.In real-world security, geo-blocking is widely used as a coarse access control layer but is considered a weak defense because it is trivially bypassed by VPNs, proxies, and Tor. It has legitimate uses for regulatory compliance (e.g., GDPR geo-restrictions) but should never be relied upon for security-critical access control. This challenge demonstrates exactly why IP-based geolocation is an unreliable trust signal.
Step 2
Request the challenge URL through the Iceland VPNObservationI noticed from the ipinfo.io verification step that the VPN was correctly showing 'country': 'IS', which confirmed the geo-gate would now pass and that sending the request to the challenge URL would route us to the flag server.With your VPN or proxy routing through Iceland, your request appears to originate from an Icelandic IP. The geo-check passes and you are routed to the flag server.bash# With VPN active and connected to Iceland, confirm country first:bashcurl -s https://ipinfo.io/json # should show 'country': 'IS'bashbash# Then hit the challenge URL:bashcurl http://<HOST>:<PORT_FROM_INSTANCE>/bashbash# If using Tor as the alternative proxy:bashcurl --proxy socks5h://localhost:9050 http://<HOST>:<PORT_FROM_INSTANCE>/What didn't work first
Tried: Hit the challenge URL directly without first verifying the VPN is connected and showing an Icelandic IP.
VPN clients sometimes silently fail to connect, connect to a different server than selected, or drop back to the local IP after a timeout. Without running 'curl -s https://ipinfo.io/json' first to confirm 'country': 'IS', you may send the request from your real IP and get a 403 or redirected non-flag response, leaving you unsure whether the bypass worked or the approach is wrong. Always verify the apparent IP before hitting the gate.
Tried: Use 'curl --proxy socks5://localhost:9050' (without the 'h' suffix) for Tor proxying.
The flag '--proxy socks5://localhost:9050' tells curl to resolve the hostname locally before passing the connection through Tor. This leaks DNS and can fail entirely if the challenge host is not resolvable from your machine. The '--proxy socks5h://localhost:9050' flag (note the 'h') delegates hostname resolution to the Tor SOCKS5 proxy itself, which is required for .onion addresses and avoids DNS leaks when routing through Tor exit nodes.
Learn more
Verifying your apparent IP and country before attempting the bypass is good practice. Services like
ipinfo.ioreturn a JSON response with your detected country code, so you can confirm the VPN or proxy is working correctly before hitting the challenge endpoint.This same technique applies in penetration testing scenarios where testers need to simulate traffic from specific geographic regions. Many bug bounty programs require testing from specific regions or networks, and a VPN or Tor exit node selection provides a way to accomplish this. See the networking tools guide for more on proxying and verification patterns.
Flag
Reveal flag
picoCTF{g30_byp4ss_...}
The Nginx config routes Icelandic IPs to the flag server. Connect to a VPN server in Iceland (or use Tor with ExitNodes {is}) so your requests appear to originate from Iceland.