Heartwood Outfitters
Heartwood's site was built in a long weekend by a co-founder who reads more about fly-fishing than web security. The reset flow uses a 4-digit numeric code; the verify endpoint has no rate-limit, no captcha, and no lockout — so the 10,000-code space is fully enumerable.
Room Description

https://dashboard.webverselabs-pro.com/challenges/spare-key
Scenario
Heartwood's site was built in a long weekend by a co-founder who reads more about fly-fishing than web security. The reset flow uses a short numeric code (because the previous one with hex tokens "confused a few customers"). The verify endpoint has no rate-limit, no captcha, and no lockout — so the 10000-code space is fully enumerable.
Objective
A small outdoor-gear brand's customer portal. The forgot-password flow emails you a 4-digit reset code — and the verify endpoint will cheerfully accept as many guesses as you can fire at it.
Initial Analysis
Okay, we have an outdoorsy web application with a couple of endpoints:

We have several endpoints from the navigation menu and an account endpoint:
<nav class="nav">
<div class="container">
<div class="nav__inner">
<a href="/" class="nav__brand">
<span class="nav__brand-mark">H</span>
<span class="nav__brand-text">
<span class="nav__brand-name">Heartwood</span>
<span class="nav__brand-tag">Outfitters · est. 2014</span>
</span>
</a>
<ul class="nav__menu">
<li><a href="/" class="nav__link nav__link--active">Home</a></li>
<li><a href="/shop" class="nav__link ">Shop</a></li>
<li><a href="/about" class="nav__link ">Our story</a></li>
<li><a href="/about#repair" class="nav__link">Repair</a></li>
</ul>
<div class="nav__icons">
<a href="/account/login">Account</a>
<a href="#" aria-label="Cart">Bag · 0</a>
</div>
</div>
</div>
</nav>
Finding the bug
The shop endpoint doesn't give us much, as we can't really add things into our bag.

The abous us page holds information on who the shop creators are as well as e-mail addresses that we might need for tinkering with the login.

Creating an account is a disabled option so all we have is the login page and the forget password segment:

We have 3 e-mail addresses from the about page:
[email protected]
[email protected]
[email protected]

We follow the flow and we end up on this page:

That seems pretty unreasonable, considering if we do land on the reset code, we have account takeover without knowing the previous password.
Exploitation

We have the following POST request when we try to reset the password, we could use Burp Intruder or FFUF or cURL or anything to go through the 10000 possible reset codes.
We will go with FFUF:
ffuf -u https://379bcc26-3970-spare-key-76e47.challenges.webverselabs-pro.com/account/reset \
-X POST -H "Content-Type: application/x-www-form-urlencoded" -d "[email protected]&code=FUZZ&password=minatour" -w <(seq -w 0000 9999) -fr "Invalid email or code" -t 50 -v
And we just wait it out until we hit something:

Since we have sent the request with the correct reset code, we have already set the account password to minatour. Now we just have to login with the credentials:
[email protected]:minatour

And on the logged in dashboard, we have the flag:
