%00 is the URL-encoded version of a null byte character. In some applications you can inject a null byte to prematurely terminate a string. An attacker may take advantage of this to cut the end of a string that they can't control.
Here is pseudocode for how the affected code may look like:
print(readfile("./" + $name + ".txt"))
In this example, any user-supplied value for $name would be automatically appended with a .txt extension, stopping you from choosing arbitrary file names. To be able to still supply your own path, you can use the 0x00 byte to terminate the string immediately after the payload.
Hence, these paths would be treated equally by the affected system:
./../../../../../../../../windows/PFRO.log
./../../../../../../../../windows/PFRO.log%00.txt
Null byte injection flaws are common because many higher-level languages are based on C, where a null byte is used to indicate the end of a string. E.g., here is an example of a vulnerable PHP script, taken from the PHP docs:
<?php
$file = $_GET['file']; // "../../etc/passwd\0"
if (file_exists('/home/wwwrun/'.$file.'.php')) {
// file_exists will return true as the file /home/wwwrun/../../etc/passwd exists
include '/home/wwwrun/'.$file.'.php';
// the file /etc/passwd will be included
}
?>
Also see: Embedding Null Code on OWASP.