3

【prompt(1) to win】 Level 6 - Action

 2 years ago
source link: https://exp-blog.com/safe/ctf/prompt/level-6-action/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【prompt(1) to win】 Level 6



javascript
function escape(input) {
    // let's do a post redirection
    try {
        // pass in formURL#formDataJSON
        // e.g. http://httpbin.org/post#{"name":"Matt"}
        var segments = input.split('#');
        var formURL = segments[0];
        var formData = JSON.parse(segments[1]);

        var form = document.createElement('form');
        form.action = formURL;
        form.method = 'post';

        for (var i in formData) {
            var input = form.appendChild(document.createElement('input'));
            input.name = i;
            input.setAttribute('value', formData[i]);
        }

        return form.outerHTML + '                         \n\
<script>                                                  \n\
    // forbid javascript: or vbscript: and data: stuff    \n\
    if (!/script:|data:/i.test(document.forms[0].action)) \n\
        document.forms[0].submit();                       \n\
    else                                                  \n\
        document.write("Action forbidden.")               \n\
</script>                                                 \n\
        ';
    } catch (e) {
        return 'Invalid form data.';
    }
}

题目代码还是挺好理解的:

  • 输入内容以 # 分隔
  • 左侧内容放入 <form>action 属性
  • 右侧内容是 json 格式,每一对 key-val 构造成 <form> 内的一个 <input> 子标签,其中 key 作为 <input>name 属性值、val 作为 <input>value 属性值
  • 只要 <form>action 属性值通过正则校验,则会调用 <form>submit() 函数触发 action 行为
01.png

要在 <form>action 属性执行 javascript 代码,可以构造这样的 payload:

javascript:alert(1)#{"EXP":"M02"}

但是由于 document.forms[0].action 的内容被正则过滤了,导致 javascript:alert(1) 无法执行:

02.png

但是这个过滤是不完善的,可以绕过。关键在于 document.forms[0].action 的指向。

<forms> 的子标签中没有任何名为 <action> 的子标签时, document.forms[0].action 指向的就是 <forms> 自身的 action 属性。

但若 <forms> 的子标签中,有任一子标签名为 <action> 时, document.forms[0].action 会优先指向该子标签。这样,正则过滤所校验的值就是子标签 <action> 的值,而非 <forms> 标签自身的 action 属性。


回到此题,虽然题目会把我们输入的 json 构造成 <form> 内的 <input> 子标签,但是我们无法直接构造标签名为 <action> 。不过 json 的 key 会作为 <action> 标签的 name 属性值,而我们恰恰可以通过 name 属性为标签更名。

例如 <input name="action"> 的名字实际是 action ,而非 input 。


于是我们可以构造这样的 payload 绕过针对 action 的正则过滤:javascript:alert(1)#{"action":"EXP"}

显然成功触发了 alert 事件:

03.png

至此,只需要把 alert 改成 prompt 即可完成挑战,最终 payload 为:javascript:prompt(1)#{"action":"EXP"}

04.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK