We can view below that verification of malicious file upload is made using ExifTool to check file extension. But the raw variable target_file is concatenated with a string in exec() function, resulting in a blind command injection.
As you can see in the code snippet, to understand the injection point and the payload were be used is generated in 4 steps:
$target_dir: constant variable with the value /tmp
$filename: array of strings generated using explode function, that split the name of the file uploaded by dot. So, position
$filename[0]: filename, (string before the dot)
$filename[1]: extension (string after the dot)
md5($filename[0] + timestamp): md5 hash of the name of file + timestamp
$target_file: concatenation of two variables explained plus $filename[1], that is the injection point.
The exec() is a built-in function in PHP to execute OS commands, manipulating the extension of the file we can inject a command before the ExifTool command.
Exploitation
To execute another command at the same function call we can put a || to start a payload. This operator acts like a or condition in bash, so if the first command returns a 0 (False) the second command will be executed.
PoC
Injecting the payload before we can confirm that the POC is working because the server is wait 5 seconds to respond.
||sleep 5
The result in the code is the following:
exiftool --ext php ||sleep 5
To retrieve the flag we can get the content /flag and put it in the server directory, to simply GET the file using the website. To do that I used this final payload: