Maxton‘s Blog

Back

Notes compiled by a beginner for learning and reference. I am not a professional; please forgive any oversights. Acknowledgments to others and AI assistance where applicable.

I chose to present the source code directly (normally you cannot see the full backend source, only the page source). On one hand, this saves space used by trial-and-error payloads; on the other hand, it makes it more intuitive for future review without needing to run other tools. I believe most filtering methods can be discovered through testing—just try a few more times. (Okay, actually, I don’t think anyone else will read this; it’s mostly for my own review)

Level 11#

Source Code Presentation

1.Judging from the source code analysis, this level is full of smoke screens (it’s really impressive if you can solve this without seeing source code; I certainly couldn’t guess it).

<input name="t_link"  value="'.'" type="hidden">
<input name="t_history"  value="'.'" type="hidden">
<input name="t_sort"  value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref"  value="'.$str33.'" type="hidden">
php

No matter what you pass to the four variables given in the problem, it’s useless…

2.The entry point of the problem lies in the HTTP request header.

$str11=$_SERVER['HTTP_REFERER'];
php

Following this, we can see simple filtering for < and >. So we need some auxiliary tools, such as Hackbar, BurpSuite, etc.

3.For example, use BurpSuite to capture the packet and add directly to the end:

Referer: " onclick = alert(1) type="text
plaintext

Level 12#

Source Code Presentation

1.Very similar to the previous level, just changed Referer to User-Agent.

2.Still use BurpSuite to capture packets, find User-Agent and construct:

User-Agent:" onclick = alert(1) type="text
plaintext

Level 13#

Source Code Presentation

1.No difference from the previous two levels, this time it changed to cookie.

2.The source code writes as follows. Even without seeing source code, capturing packets via BP (BurpSuite) reveals clear clues.

setcookie("user", "call me maybe?", time()+3600);
php
Cookie: user=call+me+maybe%3F  
plaintext

The problem hints at modifying the user value to achieve injection.

3.The rest is no different from the above levels.

Cookie: user=" onclick = alert(1) type="text
plaintext

HTTP Header Injection#

LevelInjection Point (HTTP Header)PHP Receiver Code (Vulnerability Source)Filtering StatusCore Payload (General)
Level 11Referer$_SERVER['HTTP_REFERER']Filters < >
Does not filter "
" onclick=alert(1) type="text
Level 12User-Agent$_SERVER['HTTP_USER_AGENT']Filters < >
Does not filter "
" onclick=alert(1) type="text
Level 13Cookie$_COOKIE['user']Filters < >
Does not filter "
" onclick=alert(1) type="text

Level 14#

Source Code Presentation

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>欢迎来到level14</title>
</head>
<body>
<h1 align=center>欢迎来到level14</h1>
<center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xss/level15.php?src=1.gif>点我进level15</a></center>
</body>
</html>
html

1.XSS Labs Level 14 is often considered “broken” or “impossible to complete”.

2.We can modify it locally to run it. Since I am in a docker environment, I directly went in and modified level14.php.

For convenience, I didn’t write other filters. You can add them if you want. The ultimate method is roughly the same as previous levels.

3.Then we might as well construct a python script to implement it.

Exif Injection#

    • Core Concepts

      • What is Exif: “Hidden notes” (metadata) of an image, containing camera model, shooting time, GPS, etc. Stored in the JPG file header.

      • Injection Principle: Exif is essentially text. Attackers use tools to modify fields like “Camera Model” into malicious code (like XSS Payload).

      • Trigger Condition: Server-side reads image Exif info (e.g., exif_read_data()) and displays it on the page or stores it in database without filtering.

    • Attack Flow

    • Creation: Use ExifTool or Python script to write Payload into image fields.

    • Upload: Upload the “poisoned” image to the target website.

    • Execution:

      • Stored XSS: Triggered when user/admin views image details page.

      • SQL Injection: Triggered when backend stores Exif info into database (less common).

Injection Field (Tag Name)MeaningRatingReason
ModelCamera Model⭐⭐⭐⭐⭐Most commonly read and displayed, Level 14 test point
MakeCamera Manufacturer⭐⭐⭐⭐⭐Often displayed together with Model
ImageDescriptionImage Description⭐⭐⭐⭐Allows longer characters, suitable for long Payloads
UserCommentUser Comment⭐⭐⭐⭐Specifically for user writing, large capacity
ArtistPhotographer/Author⭐⭐⭐Some album programs display author name
CopyrightCopyright Info⭐⭐⭐Usually displayed at page bottom

Level 15#

Source Code Presentation

1.The core technology of this level is AngularJS frontend inclusion vulnerability.

Of course, looking at the page source makes it obvious.

2.What is ng-include? This is an AngularJS directive. It acts similarly to PHP’s include, used to fetch an external HTML file and display it inside the current tag. Original Design Intent: This level was originally supposed to follow Level 14. The author wanted you to upload an image containing a Payload in Level 14 (e.g., 1.jpg), then reference it in Level 15 (?src='1.jpg'). AngularJS would execute the image as HTML code. But regrettably, Level 14 is broken.

3.However, we can change our approach and start from Level 1. We can construct:

level15.php?src='level1.php?name=<img src=1 onerror=alert(1)>'
html

Why not use <script>? Because HTML loaded via ng-include in AngularJS generally won’t execute direct <script> tags unless specially handled, but the onerror event of <img> tags will definitely trigger.

The reason it works even after passing through htmlspecialchars() via ng-include is because the browser automatically handles entity encoding &lt; restoring it to characters for JS use, or sending it as a URL parameter.

AngularJS#

Knowledge PointKey Directives/SymbolsFunction (Normal)CTF/Security Point (Hacker View)Typical Payload / Scenario
Startup Directiveng-appDefines root element of Angular app, tells framework to start parsing here.If the page hasn’t enabled Angular, you can inject this attribute to force it on for subsequent attacks.<html ng-app>
File Inclusionng-includeLoads external HTML fragments and compiles execution.Bypass Local Filters. Hide XSS Payload in another file or URL, utilizing this directive to “borrow a knife to kill”.<div ng-include="'level1.php?x=payload'"></div>
Template Expression{{ }}Outputs variables or simple calculation results in HTML.CSTI (Client-Side Template Injection). Use special constructions to bypass sandbox and execute arbitrary JS code.{{constructor.constructor('alert(1)')()}}
Event Directivesng-click
ng-mouseover
Binds mouse click, hover, etc. events.Similar to native onclick, but belongs to Angular system, sometimes bypasses filters for standard HTML events.<div ng-mouseover="x=1">
Unsafe HTMLng-bind-htmlBinds HTML content to element.If not used with $sce (Strict Contextual Escaping), leads to DOM XSS.<div ng-bind-html="user_input">
Filters|| (Pipe)Format data (like case conversion, sorting).Sometimes used to obfuscate Payload, or in old versions utilize orderBy filters for sandbox escape.
No-Executeng-non-bindableTells Angular NOT to parse content of this element.Defense Measure. If you see this, it means your injection in this area will be ineffective.<span ng-non-bindable>{{1+1}}</span>
Xss-labs Full Walkthrough & XSS Notes03
https://en.maxtonniu.com/blog/xsslabs03
Author Maxton Niu
Published at December 26, 2025