吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 19286|回复: 49
收起左侧

[漏洞分析] 初步认识栈溢出漏洞

  [复制链接]
Martin 发表于 2015-4-8 13:29
本帖最后由 Martin 于 2015-4-8 13:56 编辑

初步认识栈溢出漏洞
1.   什么是栈?
栈是一种机制,计算机用它来将参数传递给函数,也可以用于放入局部函数变量,函数返回地址,它的目的是赋予程序一个方便的途径来访问特定函数的局部数据,并从函数调用者那边传递信息。栈的作用如同一个缓冲区,保存着函数所需的所有信息。在函数的开始时候产生栈,并在函数的结束时候释放它。栈一般是静态的,也意味着一旦在函数的开始创建一个栈,那么栈就是不可以改变的。栈所有保存的数据是可以改变的,但是栈的本身一般是不可以改变的。
2.   缓冲溢出分为两种,一种是栈溢出,一种是堆溢出。
3.   如何找到栈?
EIP:扩展指令指针。在调用函数时,这个指针被存储在栈中,用于后面的使用。在函数返回时,这个被存储的地址被用于决定下一个将被执行的指令的地址。
ESP:扩展栈指针。这个寄存器指向栈的当前位置,并允许通过使用push和pop操纵或者直接的指针操作来对栈中的内容进行添加和移除。
EBP:扩展基指针。这个寄存器在函数的执行过程中通常是保持不变的。它作为一个静态指针使用,用于只想基本栈的信息,例如,使用了偏移量的函数的数据和变量。这个指针通常指向函数使用栈底部。
4.   通过实践来进行处理
首先演示一下栈的形成:下面是以下代码;
[C] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main()
{
    _asm
   {
        push 0x12345678
        pop eax
   }
}
我们可以在VC++6.0 进行调试来观察一下esp和eip以及ebp的状态变化;

1

1

我们F11来进行跟进下,就会发现esp栈顶指针会跟随变化,因为我们向栈中压人了12345678这样四个字节的数据,指针会减小4个字节的。

2

2

而我们pop的时候就会发现栈顶指针就变大成为了原来的样子。这就告诉我们一个道理栈中压人数据的时候栈顶指针是变小的,而弹出栈的时候栈顶指针是变大的。也就是栈底地址高于栈顶地址。
接下来演示函数内栈的调用过程。

3

3

首先没有进入到overflow函数里面的的时候ebp和esp都是有值得,说明外面的main函数也有栈的实现。我们反汇编看一下具体栈的实现。F11单步走一下就会发现一个跳转jmp跳转到函数overflow。

4

4

这时候后我们单步运行F11。
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
5:        int our=0;
00401038   mov         dword ptr [ebp-4],0
6:        return;
      就会看到如上代码,这时候我们来进一步分析一下。首先它将ebp指针压人栈内,将当前的esp指向的地址给了ebp,这时候esp减小了44h,这时候在堆栈中又开辟了一个长度为44h的一个新的栈空间。从我们分析可以得出dwordptr[ebp-4]0这个局部变量是存放在新的栈空间里面的。ebp-4远远小于44h空间大小。局部变量是存放在栈中的。
通过这个例子我们可以得出一个结论就是:
栈中存放的数据是什么?
      如果程序要调用某个函数,那么计算机就会自动将函数返回后执行的指令地址先压入栈里,等函数调用完之后再从中取出,跳转到该处执行。
溢出的原因?
      正式因为先放入栈的地址在前,而后放入栈的数据一旦过长,就会覆盖到前面的地址这就会导致程序发生错误。
下面来看一下如下的例子来演示栈溢出现象;
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
#include<stdio.h>
#include<string.h>
#include<windows.h>
void overflow(char *buf)
 {
        char des[5]="";
        strcpy(des,buf);
        return;
}
 
void main(int argc,char *argc[])
{
     LoadLibrary("user32.dll");
     char longbuf[100]="aaaaaaaaaaaabbbbcccccccccccc";
     overflow(longbuf);
     return;
}

程序一运行就会停止工作:

5

5

下面我们来但不跟踪一下程序:

6

6

首先先把函数下一个地址以及参数压入栈中:

7

7

这时候但不运行到了strcopy这里:这是我们会发现将参数的值出来放在寄存器edx里面了,请看下面图:48 FF 18 00

8

8

这时候将程序运行到了ret的时候发现程序被strcopy给覆盖了。

9

9

返回地址变成了62626262
这是返回地址是错误的所以就会爆出该内存不可读之类的错误提示。
接下来的操作就是将溢出的地址跳转到一个地方然后对让它执行我们要执行的操作,执行完之后再跳转回真实的返回地址就达到了我们想要的目的。
我们分两个环节来讲。上面讲述的是栈溢出的原理,下面的一个章节用来将栈溢出的利用。

http://www.52pojie.cn/thread-349488-1-1.html     第二篇地址在这里
很久没有写东西了。今天更新下东西希望大家能喜欢。


免费评分

参与人数 20威望 +2 吾爱币 +4 热心值 +20 收起 理由
hpsales + 1 + 1 我很赞同!
孑遗1 + 1 + 1 谢谢@Thanks!
为了部落 + 1 + 1 我很赞同!
吴小凡 + 1 已答复!
猫捉老虎 + 1 + 1 用心讨论,共获提升!
KaQqi + 1 已答复!
sy888 + 1 谢谢@Thanks!
30岁的处女座 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
devillhb5975 + 1 更新下去
Lnairan + 1 谢谢@Thanks!
东吴周郎 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
森屿海港@ + 1 热心回复!
daohang + 1 谢谢@Thanks!
wpf飞鱼 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
ghostfish + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
Double_Z + 1 谢谢@Thanks!
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
寒枫雨雪 + 1 谢谢@Thanks!
LoongKing + 1 更新下去
trustguan + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

王毛 发表于 2016-11-16 14:44
看懂一点点,感觉算是自己没看懂吧,想问一下原因是因为没有具备什么基础知识?呃......看的一头雾水.
Dustin 发表于 2015-4-8 13:33
LoongKing 发表于 2015-4-8 13:54
ablack 发表于 2015-4-8 14:53
看不懂,小白路过
WorldElite丶 发表于 2015-4-8 21:13
给力,支持
xugong 发表于 2015-4-8 21:24
路过支持一下
Jr丶新一 发表于 2015-4-8 21:24
前排 。 希望多出此类教程。
kanxue2018 发表于 2015-4-15 14:15
给力,支持!
actinen 发表于 2015-7-21 16:45
虽然看不懂,但是还是要顶
正经不老实 发表于 2015-7-21 18:13
新手学习了。多多指教
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-19 04:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表