Skip to content

Instantly share code, notes, and snippets.

@henryci
Created May 10, 2018 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henryci/d42183edf8f461d81e4625df5b5ffbae to your computer and use it in GitHub Desktop.
Save henryci/d42183edf8f461d81e4625df5b5ffbae to your computer and use it in GitHub Desktop.
<?php
# I ran this on a virtualized server, so accessing the filesystem directly wasn't a risk.
# I would not recommend this any other way.
$basedir = "/home/henryci/posttestserver.com/data/";
$filedir = "/home/henryci/posttestserver.com/files/";
# Enable CORS
header('Access-Control-Allow-Origin: *');
# Creates a local directory
function makeDir($dir)
{
if(file_exists($dir) == false) {
mkdir($dir);
}
}
# Creates the path for today's uploads
function dir_with_date($startDir)
{
$dir = $startDir . date("Y");
makeDir($dir);
$dir = "$dir/".date("m");
makeDir($dir);
$dir = "$dir/".date("d");
makeDir($dir);
return $dir;
}
# use &status_code to force the server to return a specific status code
if (isset($_GET['status_code']))
{
$status = $_GET['status_code'];
header("HTTP/1.0 $status Custom Status", true, $status);
}
# use &sleep to delay the input. Set a max on this to avoid all threads getting tied up
if(isset($_GET['sleep']))
{
$sleep_count = $_GET['sleep'];
if($sleep_count > 30) { $sleep_count = 30; }
sleep($sleep_count);
}
$output = "Time: " . date(DATE_RFC822) . "\n";
$output .= "Source ip: " . getenv('REMOTE_ADDR') . "\n";
# Grab the headers present in the upload
$output .= "\nHeaders (Some may be inserted by server)\n";
foreach ($_SERVER as $name => $content) {
# ignore server specific content (confuses people)
if(preg_match("/^PATH/", $name) ||
preg_match("/^RAILS/", $name) ||
preg_match("/^FCGI/", $name) ||
preg_match("/^SCRIPT_URL/", $name) ||
preg_match("/^SCRIPT_URI/", $name) ||
preg_match("/^dsid/", $name) ||
preg_match("/^ds_id/", $name) ||
preg_match("/^DH_USER/", $name) ||
preg_match("/^DOCUMENT/", $name) ||
preg_match("/^SERVER/", $name) ||
preg_match("/^SCRIPT/", $name) ||
preg_match("/^argv/", $name) ||
preg_match("/^argc/", $name) ||
preg_match("/^PHP/", $name) ||
preg_match("/^SCRIPT/", $name) ) {
continue;
}
}
$output .= "\n";
# Avoid writing huge files
$totalsize = (int) $_SERVER['CONTENT_LENGTH'];
if($totalsize > 537387 ) { # Honestly, I have no idea where I got this magic number from. :)
echo "Posted message too large. :(";
exit;
}
# Parse the post parameters
if($_POST && count($_POST) > 0 )
{
$output .= "Post Params:\n";
foreach ($_POST as $key => $value) {
$output .= "key: '$key' value: '$value'\n";
}
}
else
{
$output .= "No Post Params.\n";
}
# If the post contains a raw data block
if($HTTP_RAW_POST_DATA)
{
$output .= "\n== Begin post body ==\n";
$output .= $HTTP_RAW_POST_DATA;
$output .= "\n== End post body ==\n";
}
else
{
$output .= "Empty post body.\n";
}
# Handle multipart/form-data
# $_FILES is a hash of hashes, one for each uploaded file
if(isset($_SERVER["CONTENT_TYPE"]) &&
preg_match("/multipart\/form-data/i", $_SERVER["CONTENT_TYPE"] )
)
{
$output .= "\n== Multipart File upload. ==\n";
$output .= "Received " . count($_FILES) . " file(s)\n";
$count = 0;
foreach($_FILES as $key => $value)
{
$output .= " $count: posted name=$key\n";
foreach($_FILES[$key] as $key2 => $value2)
{
if(!strcmp($key2, "tmp_name")) {
continue;
}
$output .= " $key2: $value2\n";
}
# move the file from temp storage to the actual destination
$uploaded = $_FILES[$key]['tmp_name'];
$target_filename = "f_" . date("H.i.s") . rand();
$target_path = dir_with_date($filedir) . "/$target_filename";
$target_url = "/files/".date("Y/m/d")."/$target_filename";
if(is_uploaded_file($uploaded))
{
if(copy($uploaded, $target_path)) {
$output .= "Uploaded File: http://posttestserver.com$target_url\n";
}
else {
$output .= "File uploaded successfully but could not be copied.\n";
}
}
else {
$output .= "File specified was not uploaded. Possible file upload attack.\n";
}
}
}
# read in any data uploaded via a PUT
$putdata = fopen("php://input", "r");
$didit = false;
while ($data = fread($putdata, 1024)) {
if(!$didit) {
$output .= "\nUpload contains PUT data:\n";
$didit = true;
}
$output .= $data;
}
fclose($putdata);
$dir = dir_with_date($basedir);
# Allowing the end user to name the file is a risk.
if(! empty($_GET) && isset($_GET["dir"])) {
$target = str_replace(".", "", $_GET["dir"]);
$target = str_replace("/", "", $target);
$target = str_replace(";", "", $target);
if(strlen($target) > 1) {
$dir = "$dir/$target";
makeDir($dir);
}
}
# Name the upload w/ a timestamp and random number
$filename = date("H.i.s") . rand();
$file = $dir . "/$filename";
$fh = fopen($file, 'w');
fwrite($fh, $output);
fclose($fh);
# Allow the user to specify a custom response
if (isset($_GET['response_body']))
{
echo $_GET['response_body'];
}
else # or else output the results.
{
if (isset($_GET['dump']) == false )
{
echo "Successfully dumped " . count($_POST) . " post variables.\n";
$path = date("Y/m/d") . "/";
if(isset($_GET["dir"])) {
$path .= $_GET["dir"] . "/";
}
$path .= "$filename\n";
echo "View it at http://www.posttestserver.com/data/$path";
echo "Post body was " . strlen($HTTP_RAW_POST_DATA) . " chars long.";
}
if (isset($_GET['dump']))
{
if(isset($_GET['html']))
{
echo '<html><head><title>Post test</title></head><body>';
echo str_replace("\n", "<br />", $output);
echo '</body></html>';
}
else {
echo $output;
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment