Step 102. Natas 0~5 — Opening the Door to Web Wargames
Level 2 — Introduction to Security and Attack Skill Basics | Difficulty ★★☆☆☆ | Estimated time: 3 hours
Prerequisites: you’ll use the knowledge from Step 71 (HTML), 73 (HTTP), 94 (the server’s perspective), plus the wargame cycle trained in Bandit.
- What you need: a browser, developer tools (F12), curl or Python requests, and the notebook where you’ve been managing Bandit’s password chain.
- ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.
- Note: Natas is a legal learning platform officially operated by OverTheWire, the same as Bandit — a practice ground opened on the premise of attacks. Viewing another website’s source is legal, but attempting access by manipulating headers and cookies is unauthorized intrusion.
If Bandit was the Linux server game, Natas is the web game. Same organizer (OverTheWire), same goal — find the next level’s password. Only this time the secret hides not in server files but in and around web pages. Here’s today’s key sentence up front — a web page is not all that you see. The browser screen is merely a pretty rendering of the original document the server sent; traveling along with that original are comments, hidden links, robots.txt, headers, and cookies. The HTTP knowledge you learned in Level 1 gets translated into attack technique here.
1. Learning Objectives
By the end of this chapter, you will be able to:
- Perform the reconnaissance routine — view source → search comments → robots.txt → guess paths — when you meet a new site
- Find comments and hidden paths in HTML source
- Explain the paradox of robots.txt (a forbidden list = a map of hidden paths)
- Send requests with manipulated authentication, Referer, and cookies using curl and Python requests
- Explain web security’s First Principle — "everything coming from the client can be manipulated" — with examples
2. Background Knowledge — Today’s Tools and Concepts
Today’s Tools at a Glance
| Category | Details |
|---|---|
| Language/environment | Browser + developer tools (F12), curl, Python requests (local experiments) |
| Today’s commands | curl -u (authentication), curl -e (Referer), curl -b (cookies), curl -v (view the whole conversation), grep -n "<!--" (search comments) |
| Concepts needed | HTML comments, directory listing, robots.txt, HTTP headers (Referer), cookies, Basic authentication |
| Today’s artifact | natas_mini/ — a Natas-style mini page; cookie_server.py + cookie_client.py — a cookie-tampering experiment set |
2-1. View Source — The Document Behind the Picture
In the browser, Ctrl+U (Cmd+Option+U on macOS) shows the current page’s HTML original. <!-- ... --> inside HTML is a comment — a developer’s memo: invisible on screen, but present in the document. What a developer wrote down "to look at later" is a signpost for an attacker.
Developer tools (F12) go one step further — the Elements tab shows the currently rendered document, the Network tab shows every request and response exchanged, and the Application (Storage) tab shows stored cookies. The three great windows of web hacking.
2-2. robots.txt — A Map of the Forbidden Zones
A website’s root often holds a file called robots.txt. Its original purpose is a sign telling search engines "please don’t scrape these paths."
User-agent: *
Disallow: /secret-folder/
See the paradox — a file listing, in writing, the paths it wants to hide. It’s not a device that blocks access; it’s a notice, so anyone can read it and visit those paths directly. To an attacker, robots.txt is "a map of the paths this site cares about."
2-3. Headers and Cookies — Notes Attached to Requests
The HTTP requests you learned in Step 73 carry extra information besides the body.
- Referer — "which page this request came from." Some sites use it to check whether you’re "someone who came through our page."
- Cookie — a marker the server planted. It might hold a value like
loggedin=0.
The important fact: both are sent by the client, so the client can alter them at will. The browser fills them in honestly, but there’s no promise to keep.
2-4. Basic Authentication — The True Nature of the Gray Login Box
Natas’s login box is the gray dialog the browser pops up — HTTP Basic authentication. The structure is simple: convert username:password to Base64 and place it in the Authorization header. As you learned in Step 50, Base64 is an encoding, not encryption — so over plaintext HTTP the password effectively travels in the clear. curl’s -u builds exactly this header for you. Seeing the header’s substance rather than the login box’s appearance — that’s today’s hidden harvest.
3. Follow Along
3-1. Natas 0 → 1: The First Discovery from View Source
Input: in the browser, go to http://natas0.natas.labs.overthewire.org → username and password are both natas0.
Screen example: a notice saying "the password is hidden somewhere on this page."
Input: open the source with Ctrl+U, and search for password with Ctrl+F.
Screen example: inside an HTML comment — <!-- The password for natas1 is ... -->.
How to read it: a sentence that wasn’t on the screen exists in the original. A developer’s memo is the loot, as-is.
Why: this is the opening move of every level — on connecting, look at the source first. Repeat until it’s a habit.
3-2. Reproduce It in Your Lab — Rummaging Through a Mini Page’s Source (Local Measurement)
"Finding hidden values in source" reproduces completely without a server. Let’s make a Natas-style mini page in a working folder.
Input (save as natas_mini/index.html):
<!DOCTYPE html>
<html>
<head><title>Mini Wargame Level 0</title></head>
<body>
<h1>Find the password</h1>
<p>The next level's password is hidden somewhere on this page.</p>
<!-- developer memo: next level password is miniwargame_level1_pass_777 — must delete later -->
<img src="files/pixel.png" alt="a single dot">
</body>
</html>
Open this file in a browser and the comment does not appear on screen. Now rummage through the original like an attacker (measured 2026-09-09):
$ grep -n "<!--" natas_mini/index.html
7:<!-- developer memo: next level password is miniwargame_level1_pass_777 — must delete later -->
How to read it: the password came out of the comment on line 7. The screen the browser paints and the original document are different — an attacker always looks at the original side. In a browser, Ctrl+U followed by Ctrl+F does the same job as this one line of grep.
3-3. Natas 1 → 2: Same Technique, Different Face
The notice says "this time right-click is blocked." But we don’t view source through the right-click menu.
Input: Ctrl+U isn’t blocked. Repeat the same search.
How to read it: blocking on-screen manipulation and hiding the document are different things. Touch the browser’s decorations all you like — the document that was sent stays as it is.
Why: the first case of the illusion that "blocking the surface means safety." On the web, every surface decoration can be bypassed.
3-4. Natas 2 → 3: Walking the Path Yourself
This time the password isn’t visible in the source. Instead there’s a suspicious image tag — our mini page in 3-2 also had <img src="files/pixel.png">.
Input: take interest not in the image but in where the image lives (the folder). Type it directly into the address bar.
http://natas2.natas.labs.overthewire.org/files/
Screen example: the folder’s file listing (directory listing) appears, with a file like users.txt sitting inside.
How to read it: typing a path directly into the address bar is "walking the site’s map yourself." "If there’s no link, I can’t get there" is a user’s thought; "guess the path and type it" is an attacker’s thought.
Why: servers with directory listing enabled really are a common configuration mistake.
3-5. Natas 3 → 4: The robots.txt Paradox
Input: append /robots.txt in the address bar.
Screen example:
User-agent: *
Disallow: /s3cr3t/
Input: go to that path directly.
Screen example: a file inside the hidden folder holds the next password.
Local measurement (2026-09-09): we built the same structure into the mini site too.
$ cat natas_mini/robots.txt
User-agent: *
Disallow: /s3cr3t/
$ cat natas_mini/s3cr3t/users.txt
mini_level2_password=robots_treasure_map_1234
How to read it: the paradox from 2-2 — the forbidden list is the treasure map — has been confirmed in physical form.
Why: in real site assessments, robots.txt is always one of the first files checked.
3-6. Natas 4 → 5: Manipulating the Referer Header
This page says — "this page can only be viewed by people coming from a designated other page."
Input: there’s no way with a browser — you must craft the header yourself. Bring out curl (on the server, Screen example).
curl -u natas4:previous-password -e "http://natas5.natas.labs.overthewire.org/" http://natas4.natas.labs.overthewire.org/
Screen example: HTML containing "Access granted" and the next password.
How to read it: -u is Basic authentication (username:password); -e sets the Referer header. We hand-wrote a note saying "I came from natas5" and attached it. The server has no way to check whether that note is genuine — because it’s a value the client sent.
Why: the moment you see the flaw in the idea of "controlling entry with a header check." Checks must happen on the server, using information the server controls.
3-7. Natas 5 → 6: Cookie Tampering — Local Measurement First
This time you’ve logged in, yet it says "You are not logged in." This level’s core (tampering with a cookie value) reproduces completely on your own computer. Let’s build a mini server that checks a cookie.
Input (cookie_server.py):
"""A mini server that checks a cookie — for the Natas 5 style experiment."""
from http.server import BaseHTTPRequestHandler, HTTPServer
SECRET = "cookie_lab_level3_pass_5555"
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
cookie = self.headers.get("Cookie", "")
if "loggedin=1" in cookie:
body = f"Access granted. The password is {SECRET}\n".encode()
else:
body = b"You are not logged in\n"
self.send_response(200)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.send_header("Set-Cookie", "loggedin=0")
self.end_headers()
self.wfile.write(body)
HTTPServer(("127.0.0.1", 8123), Handler).serve_forever()
Launch the server in Terminal 1 with python cookie_server.py, then run the client (cookie_client.py) in Terminal 2:
"""Cookie-tampering experiment client — targets the local server (8123)."""
import requests
URL = "http://127.0.0.1:8123/"
print("=== 1) Connect with no cookie ===")
r = requests.get(URL)
print(r.text.strip())
print("Cookie the server planted:", r.headers.get("Set-Cookie"))
print()
print("=== 2) The received cookie as-is (loggedin=0) ===")
r = requests.get(URL, cookies={"loggedin": "0"})
print(r.text.strip())
print()
print("=== 3) Tamper the cookie value to 1 ===")
r = requests.get(URL, cookies={"loggedin": "1"})
print(r.text.strip())
Output (measured 2026-09-09):
=== 1) Connect with no cookie ===
You are not logged in
Cookie the server planted: loggedin=0
=== 2) The received cookie as-is (loggedin=0) ===
You are not logged in
=== 3) Tamper the cookie value to 1 ===
Access granted. The password is cookie_lab_level3_pass_5555
curl produces the same result (measured 2026-09-09):
$ curl -s -b "loggedin=0" http://127.0.0.1:8123/
You are not logged in
$ curl -s -b "loggedin=1" http://127.0.0.1:8123/
Access granted. The password is cookie_lab_level3_pass_5555
How to read it: the server trusts that anyone arriving with loggedin=1 is logged in. A cookie is a value stored on my computer, so it’s mine to control — and the server’s trust becomes the door. When the experiment is over, stop the server with Ctrl+C in Terminal 1.
Why: the danger of a design that relies solely on a client-side value for authentication state — the prototype of a real web vulnerability (broken session management).
3-8. Cookie Tampering on the Natas Server
Now the actual level. Open developer tools (F12) → Application (Storage) tab → Cookies.
Input: the loggedin cookie’s value is 0. Double-click it, change it to 1, and refresh the page.
Screen example: "Access granted" — you’ve become a logged-in person.
How to read it: exactly the same action you performed on your lab server in 3-7. Only the tool changed, from Python to developer tools.
curl Options Card — Today’s Alphabet
Web vulnerability experiments ultimately repeat the question "which piece of the request do I change, and how?" — and these four options are the alphabet of that repetition.
| Option | What it does | Example |
|---|---|---|
-u user:pass |
build a Basic authentication header | curl -u natas4:... |
-e address |
set the Referer header | curl -e "http://..." |
-b "name=value" |
send a cookie along | curl -b "loggedin=1" |
-v |
view all request/response headers | curl -v http://... |
4. Missions & Exercises
Mission — Establishing the Web Reconnaissance Routine and Completing the Cookie Experiment
- Clear all of natas0~5 and record the password chain in your notes
- Build the mini page from 3-2, confirm that the browser screen and the source (
Ctrl+U) differ, and find the password in the comment - Run the cookie server and client from 3-7 yourself and reproduce "loggedin=0 is rejected, 1 passes"
- Write
web-recon-routine.mdin your wiki — on meeting a new site: ① view source ② search comments ③ robots.txt ④ guess paths ⑤ check developer tools Network & Application - For each level, write one line on "what configuration mistake this would be if it were a real service"
Exercises
Exercise 1. Explain why robots.txt is not "a hiding device" but "a map of hidden paths."
Exercise 2. Explain, from the perspective of "the document that was sent," why view source still works even when right-click is blocked.
Exercise 3. State in one sentence the fundamental problem with a design that controls entry via a Referer check.
Exercise 4. What is the mistake of a server that falls for loggedin=1 cookie tampering, and what should a correct design look like?
5. Model Answers & Completion Criteria
Mission Model Answer
Per-level solution summary (server solutions based on the Screen examples):
natas0→1: view source (Ctrl+U) → password in a comment
natas1→2: ignore the right-click block, repeat the same technique with Ctrl+U
natas2→3: guess the folder from the image path in source, go directly to /files/ → users.txt
natas3→4: check /robots.txt → go directly to the Disallow path
natas4→5: forge the Referer with curl -u natas4:pass -e "http://natas5..."
natas5→6: developer tools Application → edit loggedin cookie 0→1 and refresh
The local experiment’s pass criterion: the client output from 3-7 comes out in the same order as the measured result (reject → reject → pass). The single curl line (curl -s -b "loggedin=1" http://127.0.0.1:8123/) must also yield "Access granted."
How to verify: ① is the password chain six links long? ② did you find, in the source, a comment that wasn’t visible on the mini page’s screen? ③ did you reproduce the cookie-tampering experiment with your own hands? ④ did the five-step reconnaissance routine remain as a document? All "yes" means complete.
Exercise Answers
Answer 1. Because robots.txt is not a technical device that blocks access — it’s merely a "request document" addressed to search engines. Anyone can open the file, and anyone can go directly to the paths written in it. A list that says "don’t scrape these" is, in effect, a list of "the paths this site cares about" (in the 3-5 measurement, a real file existed at the Disallow path).
Answer 2. Because the right-click menu is a decoration on the browser’s screen, while the original HTML document has already been fully downloaded to my computer. Block the decoration and the document itself is unchanged — you can get the original with Ctrl+U, developer tools, or even curl.
Answer 3. The problem is that Referer is a value the client crafts and sends — freely manipulable — yet the server trusted it without verification. It directly violates the First Principle: "everything coming from the client can be manipulated."
Answer 4. The mistake is entrusting login state to a single cookie value the client can change (in the 3-7 measurement, one value decided pass or fail). The correct design: the server manages login state, and the cookie holds only an unguessable session token, checked against server-side storage. "A cookie is merely the number of a claim ticket, not identity itself."
Completion Criteria Checklist
- [ ] I can make view source and comment search my first move on a new site
- [ ] I can explain the robots.txt paradox (forbidden list = map)
- [ ] I can find hidden resources by typing paths directly into the address bar
- [ ] I can craft requests precisely with curl’s
-u,-e, and-b - [ ] I reproduced cookie tampering myself on a local server
- [ ] I can explain "client values are all manipulable" with two of today’s examples
- [ ] I can recite the five steps of the web reconnaissance routine in order
6. Common Pitfalls & Fixes
Wall 1. The login box keeps popping up
Symptom: you type the username and password, and it asks again.
Cause: the level number in the address and the number in the username don’t match (e.g., natas2’s password on the natas3 page). Or whitespace rode along when you copied the password.
Fix: check the number in the address bar, the number in the username, and the password’s source level — make sure none of the three is shifted by one. The chain must be exact.
Wall 2. View source won’t open
Symptom: Ctrl+U does nothing.
Cause: browser or shortcut-setting differences.
Fix: type view-source:http://address directly into the address bar, or use F12 → the Elements tab. Even if blocked, you can always fetch the document itself with curl -u user:pass address.
Wall 3. I typed a folder path and got 403/404
Symptom: a path like /files/ is refused.
Cause: directory listing depends on server configuration. It’s open on Natas, but most real sites have it disabled.
Fix: even with listing disabled, the method of guessing file paths directly remains (/files/users.txt, etc.).
Wall 4. curl throws an authentication error (401)
Symptom: curl’s connection is refused.
Cause: a malformed -u (missing colon) or a password typo.
Fix: start from the simplest form, curl -u natas4:password address, and once it works, add options one at a time. The more options you stack, the harder it is to isolate the cause.
Wall 5. I changed the cookie but it reverts
Symptom: you changed the value in developer tools, but refreshing puts it back.
Cause: the server re-overwrites it with Set-Cookie on every response (our mini server in 3-7 also plants loggedin=0 every time — see the Set-Cookie in measurement output 1).
Fix: re-check the value right before refreshing after editing it, or skip the browser entirely and craft the request itself with curl/requests — no browser storage means no chance to be overwritten.
7. Summary
Today’s Concepts
| Concept | One-line explanation |
|---|---|
| HTML comment | <!-- ... --> — a developer memo absent from the screen but present in the original |
| Directory listing | a setting where typing a folder path shows its file list — a common misconfiguration |
| robots.txt | a request document for search engines — its forbidden list is a map of hidden paths |
| Referer | a request header noting "where you came from" — client-made, so freely forged |
| Cookie | a marker the server plants and my computer stores — I can change it at will |
| Basic authentication | sends username:password as Base64 — an encoding, not encryption |
| First Principle | everything coming from the client can be manipulated |
Today’s Commands
| Command | What it does |
|---|---|
Ctrl+U / F12 |
view source / developer tools (Elements·Network·Application) |
grep -n "<!--" file |
find comments in HTML source |
curl -u user:pass address |
request with Basic authentication |
curl -e "address" |
manipulate the Referer header |
curl -b "name=value" |
send a cookie value along |
curl -v address |
observe all request/response headers |
An Instinct More Important Than Commands
You now have an order your hands should follow when meeting a new site — ① view source, ② search comments, ③ robots.txt, ④ guess paths, ⑤ developer tools Network & Application. These five steps are the habit of seeing not "the visible page" but "the entire document that was sent." On sites you visit every day, try only reading the source and robots.txt (changing requests or probing hidden paths is absolutely forbidden). A reconnaissance eye is trained in daily life.
And the one sentence threading all of today’s techniques — everything coming from the client can be manipulated. Referer, cookies, hidden form fields — until they reach the server, they’re values in my hand. This single principle runs through all of Natas, and indeed all of web security. The web attacker’s eye has opened.
Once every box is checked, Step 102 is complete. Click the checkbox in the sidebar to save your progress.