<title>XSS post forwarder</title>
<?php
//Get the first bit of the querystring, which is the target of the form
$target = @$_GET['xss_target'];
if (empty(
$target)):
?>
<style type="text/css">
.url { color: green; }
.key { color: blue; }
.value { color: red; }
.xss { color: #88a; }
</style>

<h4>Description:</h4>
<p>
    This page is meant to enable people to easily showcase XSS flaws that use POST instead of GET.
    By linking to this page and providing GETed variables this page will build a form as specified which lets you show users the XSS flaw.
</p>
<h4>Usage:</h4>
<p>
    It should be obvious that the variables are passed in the querystring, any parameters for this script not meant to be used in constructing the form start with <em>xss_</em>.
    The target of the form is supplied via the xss_target variable.
    After that follows an ampersand (&), then the rest of the parameters to create, so for instance the following url:<br />
    ?<span class="xss">xss_target</span>=<span class="url">http://babelfish.altavista.com/tr</span>&<span class="key">doit</span>=<span class="value">done</span>&<span class="key">intl</span>=<span class="value">1</span>&<span class="key">tt</span>=<span class="value">urltext</span>&<span class="key">trtext</span>=<span class="value">This+is+a+test</span>&<span class="key">lp</span>=<span class="value">en_de</span>&<span class="key">btnTrTxt</span>=<span class="value">Translate</span><br />
    would create a form to translate 'This is a test' into german using Altavistas babelfish.<br />
    On that line I've highlighted the xss_target variable in <span class="xss">grey</span>, the url (forms target) in <span class="url">green</span>, keys (form elements names) in <span class="key">blue</span> and values (the values of those elements) in <span class="value">red</span>.<br />
    It should be noted that xss_note can also be supplied as a variable and the value will just be printed on the page into a &lt;p&gt; tag, allowing you to leave a note of any kind to whomever views your showcase XSS.<br />
    If you want an ampersand in the variables without it splitting the variable in two use %26.
</p>
<p>
    Summary:<br />
    xss_target = action attribute of form<br />
    xss_note = optional note to reader<br />
    any variables not starting with xss_ are form element names and their value in the elements value
</p>
<?php
else:
    
?>
    <a href='?'>What is this?</a><br /><br />
    <?php
    
//Before we do anything else we output the optional description by the user
    
if (!empty($_GET['xss_note']))
        echo 
"<h4>Note from XSSer:</h4>\n<p>".htmlentities($_GET['xss_note'])."</p>\n";
    
    
//create a new form, supply target
    
$frm = new form($target);

    
//Get the rest of the GETed vars - I have to do this the long way (not using $_GET) because PHP likes converting . to _ in the query string.
    
$params explode("&",getenv("QUERY_STRING"));
    foreach (
$params as $i => $pair)
    {
        
$pair explode('=',$params[$i]);
        if (
strncmp($pair[0],'xss_',4) !== 0//xss_* variables are reserved for other purposes for this script.
        
{
            
$key $pair[0];
            
array_shift($pair);
            
$value implode('=',$pair); // There can be an = in the value field too
            
$frm->add_input(new input($key,$value));
        }
    }
    
    
//Create the form
    
echo $frm->create_form();
    
//Next we create a textarea so people can easily copy paste the forms code
    
?>
    <hr /><textarea style='width: 80%; height: 50%;'>
<?php
$frm
->escape();
echo 
$frm->create_form()
?>

&lt;script&gt;
document.forms[0].submit()
&lt;/script&gt;
</textarea>
<?php
endif;


//The classes
class form
{
    private 
$target;
    private 
$inputs = array();
    
    public function 
__construct($target)
    {
        
$this->target htmlentities($target,ENT_QUOTES);
    }
    
    public function 
add_input(input $input)
    {
        
array_push($this->inputs,$input);
    }
    
    private function 
create_submit_button()
    {
        return 
"<input type='submit' value='submit' />";
    }
    
    public function 
escape()
    {
        foreach (
$this->inputs as $input)
        {
            
$input->escape();
        }
    }
    
    public function 
create_form()
    {
        
$html "<form method='post' action='{$this->target}'>\n";
        foreach (
$this->inputs as $input)
        {
            
$html .= "\t{$input->create()}<br />\n";
        }
        
$html .= "\t{$this->create_submit_button()}<br />\n";
        
$html .= "</form>";
        return 
$html;
    }
}

class 
input
{
    private 
$name;
    private 
$value;
    private 
$type;

    
//A constant for the width of the elements, they're just wide so people can easily read everything in them.
    
private $element_width '80%';
    
    public function 
__construct($name,$value,$type='text')
    {
        
$this->name htmlentities(urldecode($name),ENT_QUOTES);
        
$this->value htmlentities(urldecode($value),ENT_QUOTES);
        
$this->type htmlentities(urldecode($type),ENT_QUOTES);
    }
    
    public function 
escape()
    {
        
$this->value htmlentities($this->value,ENT_QUOTES);
        
$this->name htmlentities($this->name,ENT_QUOTES);
        
$this->type htmlentities($this->type,ENT_QUOTES);
    }
    
    public function 
create()
    {
        return 
"{$this->name}:<input input='{$this->type}' value='{$this->value}' name='{$this->name}' style='width:{$this->element_width}' />";
    }
}
?>