// HackTricks · Network Services

403 & 401 Bypasses

403 & 401 Bypasses

HTTP Verbs/Methods Fuzzing

Try different methods against the same resource: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH, INVENTED, HACK. Only use state-changing methods when the assessment scope permits them.[3]

  • Check the response headers, maybe some information can be given. For example, a 200 response to HEAD with Content-Length: 55 means that the HEAD verb can access the info. But you still need to find a way to exfiltrate that info.
  • Some frameworks honor headers such as X-HTTP-Method-Override: PUT, causing application routing to treat the request as a different method even though the HTTP request line is unchanged.
  • Use TRACE verb and if you are very lucky maybe in the response you can see also the headers added by intermediate proxies that might be useful.

HTTP Headers Fuzzing

  • Change Host header to some arbitrary value (that worked here)[1]

  • Try other User-Agent values from a maintained fuzzing list.[4]

  • Fuzz HTTP headers: test proxy-origin headers, a small authorized set of Basic/NTLM credentials, and related routing variations. fuzzhttpbypass automates many of these probes.[5]

    • X-Originating-IP: 127.0.0.1
    • X-Forwarded-For: 127.0.0.1
    • X-Forwarded: 127.0.0.1
    • Forwarded-For: 127.0.0.1
    • X-Remote-IP: 127.0.0.1
    • X-Remote-Addr: 127.0.0.1
    • X-ProxyUser-Ip: 127.0.0.1
    • X-Original-URL: 127.0.0.1
    • Client-IP: 127.0.0.1
    • True-Client-IP: 127.0.0.1
    • Cluster-Client-IP: 127.0.0.1
    • Host: localhost

    If the path is protected you can try to bypass the path protection using these other headers:

    • X-Original-URL: /admin/console
    • X-Rewrite-URL: /admin/console
  • If the page is behind a proxy, the proxy may be enforcing the restriction while the backend applies different rules. Test HTTP Request Smuggling or hop-by-hop headers where authorized.

  • Fuzz special HTTP headers looking for different response.

    • Fuzz special HTTP headers while fuzzing HTTP Methods.
  • Remove the Host header and maybe you will be able to bypass the protection.

Path Fuzzing

If /path is blocked:

  • Try using /%2e/path (if the access is blocked by a proxy, this could bypass the protection). Try also /%252e**/path (double URL encode)
  • Try Unicode bypass: /%ef%bc%8fpath (The URL encoded chars are like ”/”) so when encoded back it will be //path and maybe you will have already bypassed the /path name check
  • Other path bypasses:
    • site.com/secret → HTTP 403 Forbidden
    • site.com/SECRET → HTTP 200 OK
    • site.com/secret/ → HTTP 200 OK
    • site.com/secret/. → HTTP 200 OK
    • site.com//secret// → HTTP 200 OK
    • site.com/./secret/.. → HTTP 200 OK
    • site.com/;/secret → HTTP 200 OK
    • site.com/.;/secret → HTTP 200 OK
    • site.com//;//secret → HTTP 200 OK
    • site.com/secret.json → HTTP 200 OK (some Ruby routing stacks)
    • Use all this list in the following situations:
      • /FUZZsecret
      • /FUZZ/secret
      • /secretFUZZ
  • Other API bypasses:
    • /v3/users_data/1234 —> 403 Forbidden
    • /v1/users_data/1234 —> 200 OK
    • {"id":111} → 401 Unauthorized
    • {"id":[111]} → 200 OK
    • {"id":{"id":111}} → 200 OK
    • {“user_id”:“<legit_id>”,“user_id”:“<victims_id>”} (JSON Parameter Pollution)
    • user_id=ATTACKER_ID&user_id=VICTIM_ID (Parameter Pollution)

Parameter Manipulation

  • Change param value: From id=123 —> id=124
  • Add additional parameters to the URL: ?id=124 —-> id=124&isAdmin=true
  • Remove the parameters
  • Re-order parameters
  • Use special characters.
  • Perform boundary testing in the parameters — provide values like -234 or 0 or 99999999 (just some example values).

Protocol version

If the target uses HTTP/1.1, compare HTTP/1.0 and HTTP/2 behavior. Different front-end/backend protocol handling can expose inconsistent authorization or path normalization.[3]

Other Bypasses

  • Get the IP or CNAME of the domain and try contacting it directly.
  • Try to stress the server sending common GET requests (It worked for this guy wit Facebook).[2]
  • Change the protocol: from http to https, or for https to http
  • Go to https://archive.org/web/ and check if in the past that file was worldwide accessible.

Brute Force

  • Guess the password: Test the following common credentials. Do you know something about the victim? Or the CTF challenge name?
  • Brute force: Try basic, digest and NTLM auth.
admin    admin
admin    password
admin    1234
admin    admin1234
admin    123456
root     toor
test     test
guest    guest

Automatic Tools

References

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.