You can use various tools:
FileInfo
You can use FileInfo directly from PHP:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, 'the_file_to_check.ico');
// Should print something like 'image/x-icon'
finfo_close($finfo);
If FileInfo is setup on your system, this is probably the easiest way to go.
ImageMagick
ImageMagick goes a step further by actually decoding the content of the file, listing the embedded images:
$ identify favicon.ico
favicon.ico[0] ICO 16x16 16x16+0+0 32-bit sRGB 15.1KB 0.000u 0:00.000
favicon.ico[1] ICO 32x32 32x32+0+0 32-bit sRGB 15.1KB 0.000u 0:00.000
favicon.ico[2] ICO 48x48 48x48+0+0 32-bit sRGB 15.1KB 0.000u 0:00.000
(called from the command line in this example)
I don't know how FileInfo works with ICO files, but ImageMagick is probably safer as it really has to decode a significant part of the file.
As ImageMagick supports a lot of formats, it's important to check its output and not simply its return code (it also succeeds with JPG, SVG, etc).
IcoUtils
As a lightweight alternative to ImageMagick, IcoUtils can do the trick:
$ icotool -l favicon.ico
--icon --index=1 --width=16 --height=16 --bit-depth=32 --palette-size=0
--icon --index=2 --width=32 --height=32 --bit-depth=32 --palette-size=0
--icon --index=3 --width=48 --height=48 --bit-depth=32 --palette-size=0
$ icotool -l not_a_favicon.svg
favicon.svg: not an icon or cursor file (reserved non-zero)
Unfortunately its return code is always 0, forcing you to actually check its output.
It can be installed on Ubuntu with:
sudo apt-get install icoutils