Step 199. Webhacking.kr 1–15 — The Korean Wargame Sampler Pack
Level 3 — Real-World CTF & Advanced Attack Skills | Difficulty ★★★☆☆ | Estimated time: 6 hours (two days recommended)
Prerequisites: you’ve learned the web techniques from the Steps 132–150 range (SQLi, XSS, cookies & sessions, Burp Suite) and solved Dreamhack’s introductory web problems.
- What you need: a web browser and developer tools (F12), Burp Suite (or the browser’s cookie-editing features), Python for encoding conversion, a notepad for recording attempts.
- ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.
- Legal practice grounds: today’s stage, Webhacking.kr (
webhacking.kr), is Korea’s oldest and finest web wargame, whose operators have officially opened it for solving. Do not use today’s techniques anywhere outside this site’s challenge servers.
If you’ve learned web techniques one at a time until now, it’s time to open the sampler pack. Webhacking.kr is a wargame famous for hiding a "yes, this is it" trick in every challenge. The 1–15 range is beginner-to-intermediate, so it’s within reach of your current skills, but it’s mixed with problems demanding one twist beyond common sense — great for training your sense of direction.
Today’s goal isn’t points. It’s building a common routine that doesn’t waver even before a problem you’ve never seen — view source, check comments & hidden files, manipulate parameters, experiment with filter bypasses. Because this is an external platform, server screens are marked as screen examples, and parts of the learned techniques that can be reviewed locally are confirmed with hands-on measurements.
1. Learning Objectives
By the end of this chapter, you will be able to:
- Read Webhacking.kr’s challenge list structure (points, solve counts) and gauge difficulty
- Apply the common web-challenge routine (view source → comments/hidden files → parameter manipulation → filter bypass) in order
- Classify the representative types of the 1–15 range — cookie tampering, encoding-chain untangling, and more — and set an approach strategy
- Keep the rhythm of leaving a "list of attempted payloads" on stuck problems and moving to the next one
- Write a one-line takeaway for each solved problem and keep your technique list updated
2. Background Knowledge — Today’s Tools and Concepts
Today’s Tools at a Glance
| Category | Details |
|---|---|
| Language/environment | Web browser + developer tools, Burp Suite, Python (encoding conversion) |
| Today’s techniques | View source, finding comments & hidden files, cookie/parameter tampering, decoding encoding chains, filter bypass |
| Concepts needed | Distinguishing base64/URL/hex encodings, cookie structure (name=value), the limits of client-side checks |
| Today’s deliverables | 1–15 solve log + one-line takeaways per challenge |
2-1. Reading Webhacking.kr’s Structure
Webhacking.kr is numbered challenges. Each challenge carries points and a solve count, and these two numbers are difficulty signals. Low points and many solves mean an introductory problem; high points and few solves mean a problem with a twisted trick.
Solving a challenge earns points by submitting an answer in the form of an auth key. What you record today is not the answer string itself but "how you reached that string."
2-2. The Common Web-Challenge Routine — Four Beats
Whatever the number, your path the moment you first open it is fixed.
① View source — read the whole HTML with Ctrl+U (comments, hidden inputs, JS links)
② Check hidden resources — the usual paths: robots.txt, .git, backup files (.bak, ~)
③ Manipulate parameters — change values like ?id=1 in the URL
④ Filter bypass experiments — if a blocked character appears, try five or more bypass candidates
It’s the web version of Bandit’s "read → explore → verify → record." The habit of typing commands before hints makes your attempts a scattershot here too.
2-3. A Type Map of the 1–15 Range
If you pre-classify the types typically met in this range, you can quickly judge "which drawer does this problem belong to" when you open it.
| Type | Signal | First attempt |
|---|---|---|
| Reading source/comments | Simple screen, but comments in the source | Find hints and hidden fields in comments |
| Cookie tampering | An "admins only" message without login | Change cookie values and re-request |
| Encoding chains | An unknown string as answer material | Identify base64/hex/URL, then decode |
| Client-side checks | JS blocks you saying "not allowed" | The check lives in your browser, so it’s bypassable — send directly via Burp |
| Basic SQLi | id parameter, login form | Try the ', ' OR 1=1-- family |
| Filter bypass | Certain characters get stripped or blocked | Case mixing, double typing, encoding bypass |
2-4. A Client-Side Check Is Not a Check
Problems where JavaScript blocks you with "admins only" are staples of this range. That check code runs in your browser. A check running on my computer can be turned off by me — disable JS in dev tools, or send a request directly through Burp Suite that never passes through the check.
The key eye is seeing not "the screen blocked me" but "at which layer did it block me?" Blocked at the server (a 403 response) and blocked in the browser (an alert) are entirely different walls.
3. Follow Along
3-1. Sign Up and Survey the Challenge List
Go to webhacking.kr, register, and open the challenge list (server screens are screen examples — you do the visiting yourself):
[Screen example — what the challenge list looks like]
Challenge 01 100 pts solved by 5,xxx
Challenge 02 150 pts solved by 2,xxx
...
Challenge 15 300 pts solved by 8xx
How to read it: solve counts in the thousands mean problems solvable within common sense; dropping to the hundreds means problems with a trick. Go in order from 1, but set a cap of 30 minutes to 1 hour per challenge. In this range, two laps around fifteen problems beats burning half a day on one.
3-2. Type A — Reading Source and Comments (Screen Example)
The moment you open a problem, view the source with Ctrl+U. The first problems in this range often have answer clues lying in the source.
<!-- Screen example — clues found in a challenge's source -->
<!-- TODO: delete the temporary admin page admin_temp.php later -->
<input type="hidden" name="debug" value="0">
How to read it: filenames in comments, value of hidden inputs, commented-out links — the three staple clues of the source-reading type. Changing debug=0 to 1 becomes your first experiment.
3-3. Type B — Cookie Value Tampering
In "admins only" style problems, open the cookies via dev tools (Application tab) or Burp, and the values are often in plain text. Cookie structure and tampering review cleanly locally (measured 2026-09-09, Python 3.12.14):
cookie = "user=guest; role=user; time=1700000000"
kv = dict(p.split("=", 1) for p in cookie.split("; "))
kv["role"] = "admin"
forged = "; ".join(f"{k}={v}" for k, v in kv.items())
print(forged)
Original cookie: user=guest; role=user; time=1700000000
Forged cookie: user=guest; role=admin; time=1700000000
How to read it: a cookie is just a string of name=value joined by semicolons. If the server trusts this string as-is, swapping in a changed value changes your identity. In wargames, when you see cookies named role, admin, level, changing the value and resending is the standard move.
Why: a cookie is data the client keeps and the client sends. "A certificate kept by the user" can be forged by the user — this proposition is the root of all session attacks (Step 134 review).
3-4. Type C — Untangling Encoding Chains
A type where an unfamiliar string is given as answer material. The first job is identification. base64 is upper+lowercase letters+digits++/ with trailing = padding; hex is only 0–9 and a–f; URL encoding signals itself with %. Confirm with a local measurement (measured 2026-09-09, Python 3.12.14):
import base64, urllib.parse
double = "Wm14aFp5MXNhV3RsTFhSbGVIUT0=" # double-encoding example
once = base64.b64decode(double).decode()
twice = base64.b64decode(once).decode()
print(once) # ZmxhZy1saWtlLXRleHQ=
print(twice) # flag-like-text
Decoded once: ZmxhZy1saWtlLXRleHQ=
Decoded twice: flag-like-text
When identification is ambiguous, actually decode and verify by "does a readable string come out?" (measured 2026-09-09):
'aGVsbG8=': base64-decodable -> b'hello' (readable string: True)
'hello123': base64-decodable -> b'\x85\xe9e\xa3]\xb7' (readable string: False)
'68656c6c6f': not base64 — read as hex, it's b'hello'
How to read it: strings like 'hello123' that "can be decoded" as base64 are the trap. The criterion isn’t whether it decoded but whether it’s readable. If you decode once and another =-terminated string appears, it’s double encoding — repeat until it ends.
3-5. Type D — The Thought Process of Filter Bypass (Screen Example)
A problem where a payload put into a SQLi or command input comes back partially stripped. The key is securing the "list of blocked characters" first.
[Screen example — filter detection process]
Input: ' OR 1=1-- → result: 11 (spaces, OR, quotes suspected stripped)
Input: '||1=1# → result: reflected normally (|| and # pass)
How to read it: when a filter appears, write five or more bypass candidates in a table and eliminate them one by one. Case mixing (Or), doubling the same string (OORR → if only the inner OR is stripped, OR remains), URL double-encoding, and comment substitution (# instead of -- ) are the staple candidates. And on this site, the challenge title or number itself is sometimes the hint — when one twist beyond common sense blocks you, look again at the information outside the screen.
3-6. The Rhythm for When You’re Stuck — Attempt Lists and Time Caps
Two devices for not clinging to one problem.
First, leave a list of attempted payloads.
[Challenge 07 attempt log]
- ' OR 1=1-- → caught by filter
- ' || 1=1# → passes, but no result
- Source re-review → found a separate JS file, examining (stopped here, 1 hour elapsed)
Second, when the cap (30 minutes–1 hour) arrives, move to the next problem without regret. With an attempt log, when you come back later you won’t re-walk the same path.
3-7. One-Line Takeaways
Write one line per solved problem.
[Screen example — takeaway format]
01: temp page path in a source comment — view source is the first command
02: tampering the cookie's time value — a cookie is a string I write
05: double base64 — the decode result is another encoded string
09: JS check bypass — the blocking code lives in my browser
As this table piles up, "which types eat my time" becomes visible. That’s the material that connects to Step 200’s weakness analysis.
4. Missions & Exercises
Mission — Conquer 1–15 and Build the Takeaway Table
- Register on Webhacking.kr and draw a difficulty map from points and solve counts on the challenge list
- Attempt in order from 1, keeping the 30-minute–1-hour cap per challenge
- Apply the common routine’s four beats to every problem; on stuck problems, leave your attempted-payload list and move on
- Solve 12 or more of 1–15, and complete a table with a one-line takeaway for each solved problem
Exercises
Exercise 1. Recite the common web-challenge routine’s four beats in order, and name one "clue that, if found, is promising" at each stage.
Exercise 2. You’re given the string 68656c6c6f. Should it be read as base64 or hex, and what’s the basis for that judgment?
Exercise 3. In a problem where JavaScript blocks you with an "admins only" alert, explain why a bypass is possible from the perspective of "where the check code runs."
Exercise 4. You’re told to leave a "list of attempted payloads" when passing on a stuck problem. Without this record, what waste occurs on a retry?
5. Model Answers & Completion Criteria
Mission Model Answer
An example of a completed takeaway table (fill in the actual per-problem answers with your own solutions):
[Webhacking.kr 1–15 takeaway table — example format]
No. | Result | Type | One-line takeaway
01 | solved | source/comments | temp path in a comment is the entrance
02 | solved | cookie | tamper the time value into the future
03 | solved | encoding | double base64, decode twice
...
07 | on hold | filter bypass | confirmed || and # pass; retry planned
How to verify: ① Are there 12 or more solved entries? ② Is each line’s takeaway written as "technique name + core trick," reproducible by a reader? ③ Do on-hold problems have attempt lists attached? ④ Did you leave the answer strings themselves out of the record (wargame etiquette — only the thought process is kept)?
Exercise Answers
Answer 1. ① View source (comments, hidden fields), ② check hidden resources (robots.txt, .bak), ③ manipulate parameters (change URL id values), ④ filter bypass experiments (write the blocked-character list, then eliminate candidates). Each stage narrows down using the previous stage’s information.
Answer 2. Hex. It’s composed only of 0–9 and a–f, its length is even, and bytes.fromhex reads it as hello (confirmed in the 3-4 measurement). base64 usually mixes upper/lowercase and carries = padding, so it looks different from the start. If the appearance is ambiguous, decode it yourself and verify by "is it a readable string?"
Answer 3. That check code runs in your browser. Code running on my computer is under my control, so disabling JS via dev tools or sending a request directly through Burp Suite that skips the check bypasses it. Unless the server checks for itself, a client-side check is just a signboard.
Answer 4. The waste of re-trying the same payloads. Unless it’s a race, a payload that failed yesterday fails today too. With an attempt list, you can see "up to where is confirmed failure," so you stack only new attempts — and even if you end up looking at a hint, you can compare where your own thinking broke.
Completion Criteria Checklist
- [ ] I can gauge difficulty from points and solve counts on the Webhacking.kr challenge list
- [ ] I apply the common routine’s four beats (view source → hidden resources → parameter tampering → filter bypass) in order
- [ ] I can explain that a cookie is a
name=valuestring and is tamperable - [ ] I can identify base64/hex/URL encodings by appearance and decode them with Python
- [ ] I can distinguish and explain client-side vs server-side checks
- [ ] I left attempt lists on stuck problems and moved on within the cap
- [ ] Mission: solved 12+ of 1–15 + completed the takeaway table
6. Common Pitfalls & Fixes
Wall 1. Registration or access itself doesn’t work
Symptom: the site won’t open, or the signup email never arrives.
Cause: it’s an old wargame, so it may be under maintenance, the mail may have gone to spam, or your company/school network may be blocking it.
Fix: try from another network (tethering, etc.) and check your spam folder. If the site itself is down for maintenance, substitute the same type of training on Dreamhack or PortSwigger during that period — today’s goal is the routine, not the numbers.
Wall 2. I’m sure the answer is right but it says wrong
Symptom: you submitted the auth key and it keeps grading as incorrect.
Cause: leading/trailing whitespace from copying, case mistakes, or included line breaks — most of the time.
Fix: paste the key into a notepad and inspect it visually before submitting. If whitespace seems mixed in, clean it with Python strip() and resubmit.
Wall 3. My filter-bypass candidates dry up after two or three
Symptom: you try case mixing and one round of encoding, then give up.
Cause: your drawer of bypass candidates is shallow.
Fix: build the candidates as a table. Split into three layers — character level (case mixing, double typing, encoding), syntax level (||, #, /**/ space substitution), transport level (URL double-encoding, parameter position changes) — and you get three or four per layer, over ten candidates. Giving up below five candidates is premature in this range.
Wall 4. Burning half a day on one problem
Symptom: you spend a whole day on number 7 and progress halts.
Cause: the "this time it’ll work" trap — repeating retries without basis.
Fix: materialize the cap with a timer (30 minutes–1 hour). When passing, always leave an attempt list. This site’s problems are often answered by "one twist beyond common sense" — what solves them isn’t the time you cling but the angle you change.
Wall 5. After reading a solution, only "oh, it was that?" remains
Symptom: you read a solution you searched for when stuck and moved on, but nothing stays in your hands.
Cause: you saw only the answer and didn’t replay the thought path.
Fix: if you read a solution, always write one line of "why couldn’t I think of this," and re-solve that problem a week later. Only succeeding at the re-solve makes the problem yours.
7. Summary
Today’s Concepts
| Concept | One-line explanation |
|---|---|
| Webhacking.kr | Korea’s web wargame, officially opened by its operators — numbered challenges + auth key submission |
| Common routine | View source → hidden resources → parameter tampering → filter bypass |
| Cookie tampering | Identity forgery by swapping a client-held string |
| Encoding chains | Answer material with base64/hex/URL layered — identify, then decode to the end |
| Client-side checks | Checks running in my browser — can be disabled or bypassed |
| Attempt list | A map of confirmed failures — the starting line for retries |
Today’s Techniques & Tools
| Technique/tool | What it does |
|---|---|
Ctrl+U / developer tools |
Reading source, cookies, network requests |
| Burp Suite Repeater | Sending requests directly, bypassing checks |
base64.b64decode() |
Decoding base64 (trailing = is the signal) |
bytes.fromhex() |
Decoding hex strings (composed only of 0–9, a–f) |
urllib.parse.unquote() |
Restoring URL encoding (%27, etc.) |
| Bypass-candidate table | A ledger eliminating candidates across the three layers: character, syntax, transport |
The Instinct That Matters More Than Commands
This site’s problems sometimes demand "one twist beyond common sense," apart from honest skill. When a filter appears, try five or more bypasses; if it still fails, suspect even the challenge title, the number, and the text in the corner of the screen. And when the answer won’t come — what solves it isn’t the time you cling but the angle you change. The rhythm of setting a cap, leaving records, and moving on is itself a skill. The takeaway table you pile up becomes your map for Step 200’s advanced range.
Once every box is checked, Step 199 is complete. Click the checkbox in the sidebar to save your progress.