<?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