Como um primeiro passo rápido, o comando file
pode detectar rapidamente cabeçalhos de imagem:
if file "$FILE" |grep -qE 'image|bitmap'; then
echo "File '$FILE' has the headers of an image"
fi
(A segunda alternação para bitmap
é necessária se você quiser reconhecer arquivos BMP do Windows , já que a libmagic não usa a palavra "imagem" para descrever imagens de bitmap.)
No entanto , podemos enganar file
com a imagem falsa baseada em PHP de Resposta de Bruce Ediger :
$ echo 'GIF87a<?php echo "Hello from PHP!"; ?>' > fake.gif
$ file fake.gif && echo image detected || echo no image detected
fake.gif: GIF image data, version 87a, 16188 x 26736
image detected
Usando o Imagemagick, identifique
A suíte ImageMagick tem um identifique o script com um frontend da CLI que retornará alguns metadados em uma determinada imagem. Ele falha quando os metadados esperados não estão presentes, por isso é ideal para essa finalidade:
$ identify fake.gif && echo image detected || echo no image detected
identify-im6.q16: negative or zero image size 'fake.gif' @ error/gif.c/ReadGIFImage/1402.
no image detected
Para uma digitalização mais rápida de uma grande coleção de arquivos, recomendo colocar os dois juntos:
if file "$FILE" |grep -qE 'image|bitmap' \
&& ! identify "$FILE" >/dev/null 2>&1; then
echo "File '$FILE' is a fake image!"
fi
(Isso redireciona a saída de identify
para o esquecimento, já que apenas nos preocupamos se foi capaz de concluir com sucesso, o que é capturado pelo seu código de saída.)
Mesmo isso ainda pode ser enganado
O exemplo a seguir usa um simples GIF branco 1x1 com o mesmo código PHP adicionado ao final. Eu não sei PHP e não tenho certeza se isso realmente será executado, mas como o PHP é uma linguagem de template que imprime o literal "text" para qualquer coisa fora de sua tag <?php … ?>
, eu assumo que isto irá rodar o código como -é com apenas algum lixo antes da carga útil.
$ { echo 'R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBAD'
echo 's8P3BocCBlY2hvICJIZWxsbyBmcm9tIFBIUCEiOyA/Pgo='
} | base64 -d > fake2.gif
$ strings fake2.gif
GIF87a
;<?php echo "Hello from PHP!"; ?>
$ file fake2.gif
fake2.gif: GIF image data, version 87a, 1 x 1
$ identify fake2.gif
fake2.gif GIF 1x1 1x1+0+0 8-bit sRGB 2c 68B 0.000u 0:00.000
Isso também pode ser feito com um comentário GIF para ser totalmente válido como uma imagem:
$ hd fake3.gif
00000000 47 49 46 38 39 61 01 00 01 00 80 00 00 ff ff ff |GIF89a..........|
00000010 ff ff ff 21 fe 20 3c 3f 70 68 70 20 65 63 68 6f |...!. <?php echo|
00000020 20 22 48 65 6c 6c 6f 20 66 72 6f 6d 20 50 48 50 | "Hello from PHP|
00000030 21 22 3b 20 3f 3e 00 2c 00 00 00 00 01 00 01 00 |!"; ?>.,........|
00000040 00 02 02 44 01 00 3b |...D..;|
00000047
Escolhi o GIF e aproveitei o sistema de comentários, mas apenas concatenar uma carga útil depois de qualquer imagem também deve funcionar para contornar essa técnica de detecção. É apenas mais difícil do que enganar file
e (dependendo da implementação) que pode deixar alguma evidência para trás (o lixo da imagem).