Aaron Saray

open source programmer,
web developer

entrepreneur, author
and musician

My Blog

contains PHP, Web and business/entrepreneurial related content. Please join in the conversation!

Scanning for Unfiltered Content Automatically with PHP

A friend of mine posed a question: Do you know of any good PHP based vulnerability scanners? I told him I did not (add any in the comments, if you know! :) ) – but it wouldn’t be that hard to build one. He asked me to give him a code example, so here goes:

The Goals

I have only 2 goals to accomplish with this quick script:

  • Should handle multiple forms on a web page
  • Should be able to submit a payload and automatically review if it is shown unfiltered.

Since this is just a quick script, we do know a few things however:

  • It will not handle javascript based forms that set the action to something different.
  • It doesn’t specifically help identify which form field is the vulnerable one.

But with that, its not that bad.

The example website we’re reviewing

I have two really simple pages for our test site, the form itself and the ‘login’ page.

testform.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
    <head>
        <title>Test Login Form, yo</title>
    </head>
    <body>
        <h1>Oh HAI!</h1>
        <p>Login or no?</p>
        <form action='http://localhost/testsubmit.php' method='post' name='login'>
            Username: <input type="text" name="username" /><br />
            Password: <input type="password" name="password" /><br />
            <input type="submit" />
        </form>
    </body>
</html>

testsubmit.php

1
2
3
4
5
6
7
8
<?php
if ($_POST['username'] == 'MYUSER' && $_POST['password'] == 'MYPASS') {
    print 'you have logged in';
}
else {
    print "{$_POST['username']} did not authenticate correctly.";
}
?>

As you can see, if the login credentials are not correct, it prints the unfiltered username onto the screen. Obviously, this is a very simple example.

The PHP Script

The comments should help the interpretation of this script, so I won’t ramble…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
/** set target, payload **/
$target = 'http://localhost/testform.html';
$payload = '<script>alert("word!");</script>';

/** get content, create dom document with it **/
$targetContent = file_get_contents($target);
$doc = new DomDocument();
$doc->loadHTML($targetContent);

/** get all the forms, iterate through each **/
$forms = $doc->getElementsByTagName('form');

foreach ($forms as $form) {
    $submitInputs = array();
    $submitTo = $form->getAttribute('action') ? $form->getAttribute('action') : $target;
    $submitMethod = $form->getAttribute('method') ? $form->getAttribute('method') : 'GET';

    /** get all inputs so we can set the values **/
    $tagsToParse = array('input', 'textarea');
    foreach ($tagsToParse as $tag) {
        $retrieved = $form->getElementsByTagName($tag);
        foreach ($retrieved as $item) {
            /** get the value - we want to retain whats in there just in case... **/
            $value = $item->getAttribute('value') ? $item->getAttribute('value') : '';
            $value .= $payload;
            $submitInputs[$item->getAttribute('name')] = $value;
        }
    }

    print '<h2>Submitting payload to form: ' . $form->getAttribute('name') . '</h2>';

    /** got our content, prepare for submission, get submitted content **/
    $opts = array('http'=>array('method'=>strtoupper($submitMethod),
                                'header'=>'Content-Type: application/x-www-form-urlencoded',
                                'content'=>http_build_query($submitInputs)));
    $context = stream_context_create($opts);
    $submittedFormContents = file_get_contents($submitTo, false, $context);

    /** find the payload ? **/
    $count = substr_count($submittedFormContents, $payload);
    print "Times payload found: {$count}<br />";
}

As you can see, still very simple, but it lays the groundwork. Combine this with my link checking code and you could make a pretty decent start on a PHP vulnerability scanner.

This entry was posted in PHP, security and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>