A couple months ago I discovered an unauthenticated Remote Code Execution (RCE) in a relatively popular PHP photo gallery. If the uploading functionality is enabled in the configuration and ffmpeg is in $PATH, it would allow attackers to execute arbitary code on a victim server, thereby compromising it. During my Shodan fingerprinting I have discovered over 100 potentially vulnerable hosts worldwide.

Heatmap of vulnerable hosts.

The vulnerability lies in the video thumbnail generation, which is done with an exec call to ffmpeg.

// ffmpeg command to create video preview in $cache path
$cmd = $ffmpeg_path . ' -ss 3 -t 1 -hide_banner -i "' . str_replace('"', '\"', $this->path) . '" -frames:v 1 -an -vf "thumbnail,scale=480:320:force_original_aspect_ratio=increase,crop=480:320" -r 1 -y -f mjpeg "' . $cache . '" 2>&1';

// attempt to execute FFmpeg command
exec($cmd, $output, $result_code);

On the first line, the command passed to exec is constructed. The construction is done with $this->path, which is the absolute filepath of the video. This variable is (partially) user-controllable, and not properly sanitized. That is, only double quotes are escaped. This means we can construct a filename that contains e.g., a command substitution ($(malicious command here) or `malicious`) and the command inside will be executed by exec. Other than uploading and ffmpeg being enabled, there are two other prerequisites to make the exploit work. The file must end in a video extension (e.g., .mp4) and must contain its respective magic bytes. Otherwise, the call to exec is never reached. For example, the following would construct a valid exploit file.

$ echo "AAAAAGZ0eXBtcDQy" | base64 -d > '$(malicious command).mp4'

Upload this file to the application, and your code gets executed automatically.

The CVE has been assigned to CVE-2024-53615, and the exploit script can be found here.

Until next time!

- Pim