My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

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.

Tags: ,

Leave a Reply

  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby