hacktricks/network-services-pentesting/pentesting-web/imagemagick-security.md
2023-06-06 18:56:34 +00:00

12 KiB

Segurança do ImageMagick

Durante nossas auditorias, ocasionalmente nos deparamos com arquivos de configuração de política de segurança (policy.xml) do ImageMagick, úteis para limitar o comportamento padrão e os recursos consumidos pela biblioteca. Na prática, esses arquivos geralmente contêm uma infinidade de recomendações coletadas de várias fontes na internet. Isso normalmente acontece por duas razões:

  • Suas opções são descritas apenas de forma geral na página de documentação online da biblioteca, sem uma clara explicação do que cada diretiva de segurança permitida pela política está regulando. Embora a complexidade arquitetural e a granularidade das opções definíveis pela política sejam os principais obstáculos para um iniciante, a base de conhecimento correspondente poderia ser mais acolhedora. Por padrão, o ImageMagick vem com uma política irrestrita que deve ser ajustada pelos desenvolvedores dependendo do uso. De acordo com a documentação, "isso oferece a máxima utilidade para instalações do ImageMagick que são executadas em um ambiente isolado, talvez em uma instância do Docker, ou atrás de um firewall onde os riscos de segurança são muito menores em comparação com um site público." Uma política estrita e segura também está disponível, no entanto, como observado no passado, nem sempre está bem configurada.
  • O ImageMagick suporta mais de 100 formatos principais de arquivo (sem incluir subformatos) de tipos de formatos de imagem. As infames vulnerabilidades que afetam a biblioteca ao longo dos anos produziram uma série de correções de segurança urgentes e soluções alternativas envolvendo a adição de itens de política que excluem os formatos e recursos afetados (ImageTragick em 2016, RCE de @taviso via GhostScript em 2018, injeção de shell de @insertScript via senha de PDF em 2020, @alexisdanizan em 2021).

Rumo a políticas mais seguras

Com isso em mente, decidimos estudar os efeitos de todas as opções aceitas pelo analisador de política de segurança do ImageMagick e escrever uma ferramenta para ajudar tanto os desenvolvedores quanto as equipes de segurança a projetar e auditar esses arquivos. Devido ao número de opções disponíveis e à necessidade de negar explicitamente todas as configurações inseguras, isso geralmente é uma tarefa manual, que pode não identificar sutis contornos que comprometem a força de uma política. Também é fácil definir políticas que parecem funcionar, mas não oferecem nenhum benefício real de segurança. As verificações da ferramenta são baseadas em nossa pesquisa com o objetivo de ajudar os desenvolvedores a fortalecer suas políticas e melhorar a segurança de suas aplicações, para garantir que as políticas forneçam um benefício de segurança significativo e não possam ser subvertidas por atacantes.

A ferramenta pode ser encontrada em imagemagick-secevaluator.doyensec.com/.

Abordagem de lista de permissões versus lista de negações

Uma série de políticas aparentemente seguras podem ser encontradas online, especificando uma lista de codificadores inseguros semelhantes a:

  ...
  <policy domain="coder" rights="none" pattern="EPHEMERAL" />
  <policy domain="coder" rights="none" pattern="EPI" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="none" pattern="MSL" />
  <policy domain="coder" rights="none" pattern="MVG" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="PLT" />
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="PS2" />
  <policy domain="coder" rights="none" pattern="PS3" />
  <policy domain="coder" rights="none" pattern="SHOW" />
  <policy domain="coder" rights="none" pattern="TEXT" />
  <policy domain="coder" rights="none" pattern="WIN" />
  <policy domain="coder" rights="none" pattern="XPS" />
  ...

No ImageMagick 6.9.7-7, uma mudança não listada foi implementada. O analisador de políticas mudou o comportamento de proibir o uso de um codificador se houvesse pelo menos uma regra de permissão none na política para respeitar a última regra correspondente na política para o codificador. Isso significa que é possível adotar uma abordagem de lista de permissões em políticas modernas, negando primeiro todos os direitos dos codificadores e habilitando os aprovados. Uma política mais segura especificaria:

  ...
  <policy domain="delegate" rights="none" pattern="*" />
  <policy domain="coder" rights="none" pattern="*" />
  <policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
  ...

Sensibilidade a maiúsculas e minúsculas

Considere a seguinte diretiva:

  ...
  <policy domain="coder" rights="none" pattern="ephemeral,epi,eps,msl,mvg,pdf,plt,ps,ps2,ps3,show,text,win,xps" />
  ...

Com isso, as conversões ainda serão permitidas, já que os padrões de política diferenciam maiúsculas de minúsculas. Os codificadores e módulos devem sempre estar em maiúsculas na política (por exemplo, "EPS" e não "eps").

Limites de recursos

A negação de serviço no ImageMagick é bastante fácil de ser alcançada. Para obter um novo conjunto de payloads, é conveniente pesquisar por palavras-chave como "oom" nas issues recentemente abertas no repositório Github da biblioteca. Isso é um problema, já que uma instância do ImageMagick que aceita entradas potencialmente maliciosas (o que é frequentemente o caso) sempre estará propensa a ser explorada. Por causa disso, a ferramenta também relata se limites razoáveis não são explicitamente definidos pela política.

Fragmentação de política

Uma vez que uma política é definida, é importante garantir que o arquivo de política esteja em vigor. Pacotes do ImageMagick incluídos na distribuição ou instalados como dependências por meio de vários gerenciadores de pacotes podem especificar políticas diferentes que interferem entre si. Um rápido find em sua máquina local identificará várias ocorrências de arquivos policy.xml:

$ find / -iname policy.xml

# Example output on macOS
/usr/local/etc/ImageMagick-7/policy.xml
/usr/local/Cellar/imagemagick@6/6.9.12-60/etc/ImageMagick-6/policy.xml
/usr/local/Cellar/imagemagick@6/6.9.12-60/share/doc/ImageMagick-6/www/source/policy.xml
/usr/local/Cellar/imagemagick/7.1.0-45/etc/ImageMagick-7/policy.xml
/usr/local/Cellar/imagemagick/7.1.0-45/share/doc/ImageMagick-7/www/source/policy.xml

# Example output on Ubuntu
/usr/local/etc/ImageMagick-7/policy.xml
/usr/local/share/doc/ImageMagick-7/www/source/policy.xml
/opt/ImageMagick-7.0.11-5/config/policy.xml
/opt/ImageMagick-7.0.11-5/www/source/policy.xml

As políticas também podem ser configuradas usando o argumento CLI -limit, métodos da API MagickCore ou com variáveis de ambiente.

Uma política restritiva inicial

Começando pela política mais restritiva descrita na documentação oficial, projetamos uma política restritiva que reúne todas as nossas observações:

<policymap xmlns="">
  <policy domain="resource" name="temporary-path" value="/mnt/magick-conversions-with-restrictive-permissions"/> <!-- the location should only be accessible to the low-privileged user running ImageMagick -->
  <policy domain="resource" name="memory" value="256MiB"/>
  <policy domain="resource" name="list-length" value="32"/>
  <policy domain="resource" name="width" value="8KP"/>
  <policy domain="resource" name="height" value="8KP"/>
  <policy domain="resource" name="map" value="512MiB"/>
  <policy domain="resource" name="area" value="16KP"/>
  <policy domain="resource" name="disk" value="1GiB"/>
  <policy domain="resource" name="file" value="768"/>
  <policy domain="resource" name="thread" value="2"/>
  <policy domain="resource" name="time" value="10"/>
  <policy domain="module" rights="none" pattern="*" /> 
  <policy domain="delegate" rights="none" pattern="*" />
  <policy domain="coder" rights="none" pattern="*" /> 
  <policy domain="coder" rights="write" pattern="{PNG,JPG,JPEG}" /> <!-- your restricted set of acceptable formats, set your rights needs -->
  <policy domain="filter" rights="none" pattern="*" />
  <policy domain="path" rights="none" pattern="@*"/>
  <policy domain="cache" name="memory-map" value="anonymous"/>
  <policy domain="cache" name="synchronize" value="true"/>
  <!-- <policy domain="cache" name="shared-secret" value="my-secret-passphrase" stealth="True"/> Only needed for distributed pixel cache spanning multiple servers -->
  <policy domain="system" name="shred" value="2"/>
  <policy domain="system" name="max-memory-request" value="256MiB"/>
  <policy domain="resource" name="throttle" value="1"/> <!-- Periodically yield the CPU for at least the time specified in ms -->
  <policy xmlns="" domain="system" name="precision" value="6"/>
</policymap>

Você pode verificar se uma política de segurança está ativa usando o comando identify:

identify -list policy
Path: ImageMagick/policy.xml
...

Você também pode brincar com a política acima usando nossa ferramenta de avaliação enquanto desenvolve uma personalizada.

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥