使用一个堆溢出来写任意数据 [英] Use a heap overflow to write arbitrary data

查看:259
本文介绍了使用一个堆溢出来写任意数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力学习堆溢出攻击的基本知识。我在使用攻击的基础块元数据的损坏或修改最感兴趣,但我也开放给其他建议。我知道我的攻击目标应该是做覆盖的printf()函数的挑战()的指针函数指针,但我似乎无法弄清楚如何做到这一点写。
我有下面这段code,我想利用,这是使用的malloc 的glibc 2.11.2

I've been trying to learn the basics of a heap overflow attack. I'm mostly interested in using a corruption or modification of the chunk metadata for the basis of the attack, but I'm also open to other suggestions. I know that my goal of the exploit should be do overwrite the printf() function pointer with that of the challenge() function pointer, but I can't seem to figure out how to achieve that write. I have the following piece of code which I want to exploit, which is using malloc from glibc 2.11.2 :

void challenge()
{
        puts("you win\n");
}

int main(int argc, char **argv)
{
        char *inputA, *inputB, *inputC;

        inputA = malloc(32);
        inputB = malloc(32);
        inputC = malloc(32);

        strcpy(inputA, argv[1]);
        strcpy(inputB, argv[2]);
        strcpy(inputC, argv[3]);

        free(inputC);
        free(inputB);
        free(inputA);

        printf("execute challenge to win\n");
}

显然,实现分配的块的元数据的实际覆盖实在是微不足道。不过,我一直没能找到一种方法,利用使用任何标准技术这code。
我已阅读并试图从实现技术:

Obviously, achieving an actual overwrite of an allocated chunk's metadata is trivial. However, I have not been able to find a way to exploit this code using any of the standard techniques. I have read and attempted to implement the techniques from:


  • 文章:w00w00在堆溢出

    • 虽然纸张是很清楚,在取消链接技术已经过时了一段时间了。

    • The paper: w00w00 on Heap Overflows
      • Although the paper is very clear, the unlink technique has been obsolete for some time.

      • 本文在从w00w00天利用技术扩大,占glibc的较新版本。但是,我还没有找到,鉴于5技术文件中详述的,即code以上匹配任何prerequisites的那些技术。


      • PDF格式给出了pretty如何堆的作品好好复习,但重点是双重释放技术。

      我最初试图通过操纵块为inputC的大小值,使其指向回inputC块的头,利用此code。如果没有工作,我想指出进一步回inputB的块。这就是当我意识到新的glibc执行的大小值进行仔细的检查。

      I originally tried to exploit this code by manipulating the size value of the chunk for inputC, so that it pointed back to the head of the inputC chunk. When that didn't work, I tried pointing further back to the chunk of inputB. That is when I realized that the new glibc performs a sanity check on the size value.

      用户工艺一个如何可以利用采取自由的优点,假设他要编辑的分配块的元数据为任意值的能力,和用户它在GOT覆盖值或写入任何其他任意地址?

      How can a user craft an exploit to take advantage of a free, assuming he has the ability to edit the allocated chunk's metadata to arbitrary values, and user it to overwrite a value in the GOT or write to any other arbitrary address?

      请注意:当我写任意地址据我所知,内存页面可能是只读或受保护的,我的意思是我可以假设我可以写一个地址

      Note: When I write 'arbitrary address' I understand that memory pages may be read only or protected, I mean an address that I can assume I can write to.

      推荐答案

      请注意:我才回答这纯粹是一个学术的答案,不打算被用于恶意目的,我会说。我知道的练习OP做,他们都是开源的,并非意在鼓励任何用户在未经批准的情况下使用这些技术。

      Note: I will say before I answer that this is purely an academic answer, not intended to be used for malicious purposes. I am aware of the exercises OP is doing and they are open source and not intended to encourage any users to use these techniques in unapproved circumstances.

      我将详细介绍下面的技术,但供大家参考,因为我的概要将是短单我会看一看的Vudo招数的malloc(它在你上面的链接之一引用):<一href=\"http://www.phrack.com/issues.html?issue=57&id=8\">http://www.phrack.com/issues.html?issue=57&id=8

      I will detail the technique below but for your reference I would take a look at the Vudo malloc tricks (It's referenced in one of your links above) because my overview is going to be a short one: http://www.phrack.com/issues.html?issue=57&id=8

      它详细的malloc如何处理创造了内存块,从列表和其他的东西拉内存。特别是取消链接攻击是对这种攻击的兴趣(注:你是正确的,现在的glibc上执行尺寸为这个特别的原因进行仔细的检查,但你应该对这个练习......遗产兄弟一个旧的libc)。

      It details how malloc handles creating blocks of memory, pulling memory from lists and other things. In particular the unlink attack is of interest for this attack (note: you're correct that glibc now performs a sanity check on sizes for this particular reason, but you should be on an older libc for this exercise... legacy bro).

      从纸,分配块和空闲块使用相同的数据结构,但是数据是不同的处理。在这里看到:

      From the paper, an allocated block and a free block use the same data structure, but the data is handled differently. See here:

      chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               | prev_size: size of the previous chunk, in bytes (used   |
               | by dlmalloc only if this previous chunk is free)        |
               +---------------------------------------------------------+
               | size: size of the chunk (the number of bytes between    |
               | "chunk" and "nextchunk") and 2 bits status information  |
        mem -> +---------------------------------------------------------+
               | fd: not used by dlmalloc because "chunk" is allocated   |
               | (user data therefore starts here)                       |
               + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
               | bk: not used by dlmalloc because "chunk" is allocated   |
               | (there may be user data here)                           |
               + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
               |                                                         |
               |                                                         |
               | user data (may be 0 bytes long)                         |
               |                                                         |
               |                                                         |
      next   -> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                | prev_size: not used by dlmalloc because "chunk" is      |
                | allocated (may hold user data, to decrease wastage)     |
                +---------------------------------------------------------+
      

      分配的内存块不使用FD或BK三分球,但自由的意志。这将是重要的后面。你应该知道足够的编程来理解,在Doug Lea的malloc的块被组织成一个双向链表;有一个列表的空闲块,另一个是分配的人(在技术上也有免费的视大小几个列表,但由于code分配相同大小的块是无关紧要这里)。因此,当你释放特定块,你必须修复指针保持在机智的列表中。

      Allocated blocks don't use the fd or bk pointers, but free ones will. This is going to be important later. You should know enough programming to understand that "blocks" in Doug Lea's malloc are organized into a doubly-linked list; there's one list for free blocks and another for allocated ones (technically there are several lists for free depending on sizes but it's irrelevant here since the code allocates blocks of the same size). So when you're freeing a particular block, you have to fix the pointers to keep the list in tact.

      例如。说,你从下面的列表释放块Y:

      e.g. say you're freeing block y from the list below:

      x <-> y <-> z
      

      请注意,该点为BK如上图和FD包含必要的指针沿着列表进行迭代。当malloc的要采取的块p关闭它调用,除其他事项清单,宏修复列表:

      Notice that in the diagram above the spots for bk and fd contain the necessary pointers to iterate along the list. When malloc wants to take a block p off of the list it calls, among other things, a macro to fix the list:

      #define unlink( y, BK, FD ) {            
          BK = P->bk;                          
          FD = P->fd;                          
          FD->bk = BK;                         
          BK->fd = FD;                         
      }
      

      宏本身不难理解,但要注意在旧版本的libc中最重要的是,它不会对大小进行合理性检查或指针被写入。这是什么意思你的情况是,没有任何类型的地址随机化,你可以predictably和可靠地确定堆的状态,并通过(通过strncopy这里)溢出堆重定向任意指向您选择的地址一种特定的方式。

      The macro itself isn't hard to understand, but the important thing to note in older versions of libc is that it doesn't perform sanity checks on the size or the pointers being written to. What it means in your case is that without any sort of address randomization you can predictably and reliably determine the status of the heap and redirect an arbitrary pointer to an address of your choosing by overflowing the heap (via the strncopy here) in a specific way.

      还有让攻击工作所需的几件事情:

      There's a few things required to get the attack to work:


      • 为您块FD指针指向要覆盖减去12字节的地址。偏移具有使用malloc清理对齐时做它修改列表

      • 您块的指针BK是指向你的shell code

      • 的尺寸需要-4。这完成了一些东西,即它设置状态位在块

      所以你必须玩弄你的具体实例的偏移量,但你想在这里与strcpy的传递一般的恶意格式的格式为:

      So you'll have to play around with the offsets in your specific example, but the general malicious format that you're trying to pass with the strcpy here is of the format:

      |垃圾填满的合法缓冲| -4 | -4 |地址要覆盖-12(的0x0C)|地址要改为调用

      | junk to fill up the legitimate buffer | -4 | -4 | addr you want to overwrite -12 (0x0C) | addr you want to call instead

      请注意负数设置prev_size场至-4,这使得自​​由路由认为,prev_size块实际上开始于你控制/是破坏当前块。

      Note the negative number sets the prev_size field to -4, which makes the free routing believe that the prev_size chunk actually starts in the current chunk that you control/are corrupting.

      是的,正确的解释不会没有提的是,这种攻击不会对glibc的当前版本的工作是完整的;大小方面做了全面的检查,并取消链接的方法是行不通的。在与像地址随机化相结合的缓解措施使这种攻击没有什么,但遗留系统是可行的。但这里介绍的方法是我怎么做的挑战;)

      And yes, a proper explanation wouldn't be complete without mentioning that this attack doesn't work on current versions of glibc; the size has a sanity check done and the unlink method just won't work. That in combination with mitigations like address randomization make this attack not viable on anything but legacy systems. But the method described here is how I did that challenge ;)

      这篇关于使用一个堆溢出来写任意数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆