精华内容
下载资源
问答
  • 栈溢出攻击
    2021-02-12 07:14:44

    我们先来看下面的一个例子:

    ~~~

    #include

    int main(){

    char str[10] = {0};

    gets(str);

    printf("str: %s\n", str);

    return 0;

    }

    ~~~

    在 main() 函数内部定义一个字符数组,并通过 gets() 为它赋值。

    在VS2010 Debug模式下运行程序,当输入的字符不超过10个时,可以正确输出,但是当输入的字符过多时,就会出现运行时错误。例如输入"12345678901234567890",就会出现下面的错误:

    ![](https://box.kancloud.cn/9d939f22fab553d3bf701939f3c78ac8_623x154.png)

    这是为什么呢?我们不妨先来看一下 main() 函数的栈:

    ![](https://box.kancloud.cn/94fc205f6aa42915645de5807db261e8_181x300.png)

    局部数组也是在栈上分配内存,当输入"12345678901234567890" 时,会发生数组溢出,占用“4字节空白内存”、“old ebp”和“返回地址”所在的内存,并将原有的数据覆盖掉,这样当 main() 函数执行完成后,会取得一个错误的返回地址,该地址上的指令是不确定的,或者根本就没有指令,所以程序在返回时出错。

    C语言不会对数组溢出做检测,这是一个典型的由于数组溢出导致覆盖了函数返回地址的例子,我们将这样的错误称为“栈溢出错误”。

    > 注意:这里所说的“栈溢出”是指栈上的某个数据过大,覆盖了其他的数据

    局部数组在栈上分配内存,并且不对数组溢出做检测,这是导致栈溢出的根源。除了上面讲到的 gets() 函数,strcpy()、scanf() 等能够向数组写入数据的函数都有导致栈溢出的风险。

    下面是使用 strcpy() 函数导致栈溢出的例子:

    ~~~

    #include

    #include

    int main(){

    char *str1 = "sfsdffffffffaeggggggg3r4t4nihfgi23ufhbu4bgui3beugb";

    char str2[6] = {0};

    strcpy(str2, str1);

    printf("str: %s\n", str2);

    return 0;

    }

    ~~~

    将 str1 复制到 str2,显然超出了 str2 的接受范围,会发生溢出,覆盖返回地址,导致 main() 函数返回时出错。

    栈溢出一般不会产生严重的后果,但是如果有用户精心构造栈溢出,让返回地址指向恶意代码,那就比较危险了,这就是常说的栈溢出攻击

    更多相关内容
  • 主要介绍了java内存溢出示例(堆溢出、栈溢出),需要的朋友可以参考下
  • 栈溢出漏洞

    2017-03-30 18:32:11
    湖湘杯2016网络安全技能大赛pwnme
  • 基本的栈溢出攻击,是最早产生的一种缓冲区溢出攻击方法,它是所有其他缓冲区溢出攻击的基础。但是,由于这种攻击方法产生的时间比较长,故而GCC编译器、Linux操作系统提供了一些机制来阻止这种攻击方法对系统产生...
  • 栈溢出crash小合集

    2018-11-15 10:06:18
    自己收集的一些栈溢出可执行程序,自己通过AFL fuzz出大量的crash,是做漏洞挖掘实验验证所需的。
  • 详解栈溢出

    2021-05-28 11:31:14
    在我们平时开发的过程中,经常会出现stack overflow的情况导致程序崩溃,通常的原因都是无限的递归调用导致的,也就是无限的调用函数,导致空间用完,可是为什么非要使用呢,它内部是怎么运行的,的空间一共有多...

    前言

    在我们平时开发的过程中,经常会出现stack overflow的情况导致程序崩溃,通常的原因都是无限的递归调用导致的,也就是无限的调用函数,导致空间用完,可是为什么非要使用栈呢,它内部是怎么运行的,栈的空间一共有多大呢,在下面会一一的详解

    为什么要使用程序栈?

    我们先来看一段代码

    
    // function_example.c
    #include <stdio.h>
    int static add(int a, int b)
    {
        return a+b;
    }
    
    
    int main()
    {
        int x = 5;
        int y = 10;
        int u = add(x, y);
    }
    

    是一个函数调用

    $ gcc -g -c function_example.c
    $ objdump -d -M intel -S function_example.o
    

    我们将这个程序反汇编

    
    int static add(int a, int b)
    {
       0:   55                      push   rbp
       1:   48 89 e5                mov    rbp,rsp
       4:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
       7:   89 75 f8                mov    DWORD PTR [rbp-0x8],esi
        return a+b;
       a:   8b 55 fc                mov    edx,DWORD PTR [rbp-0x4]
       d:   8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
      10:   01 d0                   add    eax,edx
    }
      12:   5d                      pop    rbp
      13:   c3                      ret    
    0000000000000014 <main>:
    int main()
    {
      14:   55                      push   rbp
      15:   48 89 e5                mov    rbp,rsp
      18:   48 83 ec 10             sub    rsp,0x10
        int x = 5;
      1c:   c7 45 fc 05 00 00 00    mov    DWORD PTR [rbp-0x4],0x5
        int y = 10;
      23:   c7 45 f8 0a 00 00 00    mov    DWORD PTR [rbp-0x8],0xa
        int u = add(x, y);
      2a:   8b 55 f8                mov    edx,DWORD PTR [rbp-0x8]
      2d:   8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
      30:   89 d6                   mov    esi,edx
      32:   89 c7                   mov    edi,eax
      34:   e8 c7 ff ff ff          call   0 <add>
      39:   89 45 f4                mov    DWORD PTR [rbp-0xc],eax
      3c:   b8 00 00 00 00          mov    eax,0x0
    }
      41:   c9                      leave  
      42:   c3                      ret    
    

    我们查看程序,他和上面指令的跳转查不多,但是他将上面的jump转换为了call指令,call跳转后仍是程序的地址,但值得注意的是,在add函数调用的时候,程序是先执行力一句push命令和mov命令,后来又执行了一条pop和ret命令,这其实就是我们要说的压栈和出栈

    可以发现他和if else的命令有一点像,但是又完成不一致,在if else 中程序完成一次跳转,他的命令类似于goto,而函数是要回到原来执行的地方。

    可是为什么非要跳转呢,我们为什么不将函数中的内容直接替换到这个地方,其实道理很简单,就是如果两个函数之间互相包含,那就会出现无限替换的情况,这样会导致程序的奔溃,就像向下的镜子
    在这里插入图片描述
    说到这里你可能想到了,我们可以去使用一个类似于pc寄存器的东西去记录这个地址,但是我们计算机中的寄存器单元是有限的,在函数调用过多的情况下是无法完成记录的,这时候科学家就想到了我们想到了我们经常使用的的数据结构,,利用他的先进后出这个特性,每一次函数调用都是一次压栈,而每个函数的结束就是一次出栈的过程,这样子程序的调用也就是按照规则来

    就例如一个直直的乒乓球桶,第一个程序调用的时候,就将第一个乒乓球放入,如果第一个乒乓球内调用了第二个乒乓球,就继续向里面加球,反之则取出第一个乒乓球
    在这里插入图片描述
    在真实的程序中,压栈不只用函数的地址和返回值,还会有一些参数,在寄存器不够的时候,这些参数也会被放入内存中,这个就叫做函数的栈帧(stack Frame),在中文里是相框的意思,就是将函数的所有框了起来

    在实际的内存布局中,底和顶是倒过来的,我们的桶也是倒过来的,这样的布局是因为内存地址一开始就是固定的,而一层层压栈后,程序的地址是在逐渐变小,而不是逐渐变大。因为逐渐变大的话有可能内存地址超出最大限制

    我们在调用第 34 行的 call 指令时,会把当前的 PC 寄存器里的下一条指令的地址压栈,保留函数调用结束后要执行的指令地址。而 add 函数的第 0 行,push rbp 这个指令,就是在进行压栈。这里的 rbp 又叫栈帧指针(Frame Pointer),是一个存放了当前栈帧位置的寄存器。push rbp 就把之前调用函数,也就是 main 函数的栈帧的栈底地址,压到栈顶。

    接着,第 1 行的一条命令 mov rbp, rsp 里,则是把 rsp 这个栈指针(Stack Pointer)的值复制到 rbp 里,而 rsp 始终会指向栈顶。这个命令意味着,rbp 这个栈帧指针指向的地址,变成当前最新的栈顶,也就是 add 函数的栈帧的栈底地址了。

    而在函数 add 执行完成之后,又会分别调用第 12 行的 pop rbp 来将当前的栈顶出栈,这部分操作维护好了我们整个栈帧。然后,我们可以调用第 13 行的 ret 指令,这时候同时要把 call 调用的时候压入的 PC 寄存器里的下一条指令出栈,更新到 PC 寄存器中,将程序的控制权返回到出栈后的栈顶。

    栈溢出

    所以什么是栈溢出,就是我们无限的向这个栈中输入数据,导致栈的内存被用完,就是出现栈溢出现象学,通常会出现在无限的递归,或者递归的层数过深,又或者在栈区存放了大量的数据,都会导致栈溢出,下面程序为无限递归出口递归

    int a()
    {
      return a();
    }
    
    
    int main()
    {
      a();
      return 0;
    }
    

    如何使用内联优化

    我们在前面说过,如果一个函数中存在另一个函数,就会出现无限的替换的情况,但是当我们的程序中没有那些调用的时候,我们就可以去使用内敛优化的方式,这样就可以减少一些程序的出栈和压栈的内耗,我们在GCC编译的时候,加上一个-O,编译器就会在可行的地方进行优化

    内联带来的优化是,CPU 需要执行的指令数变少了,根据地址跳转的过程不需要了,压栈和出栈的过程也不用了。

    但是内敛也是会有代价的,我们在程序指令的地方完成展开了,程序占用的空间就会变大

    展开全文
  • V5-305_FreeRTOS实验_任务栈溢出检测方式一 (模拟栈溢出
  • MSP430 数组填充越界引起的栈溢出 导致程序跑飞。
  • 简单实现栈溢出实验(IDA)

    千次阅读 多人点赞 2020-10-10 13:53:22
    有关栈溢出的相关知识 最近学校讲到了栈溢出,并有一道很基础的题,在此可以记录一下,感兴趣的人可以了解了解

    有关栈溢出的相关知识

    最近学校讲到了栈溢出,并有一道很基础的题,在此可以记录一下,感兴趣的人可以了解了解.
    /
    栈溢出:
    /
    首先谈到栈溢出,要先说windows系统典型漏洞分析。
    /
    栈溢出也是其中的一种。
    /
    要了解栈溢出,要先了解:

    1.主角:栈 与 栈帧

    栈(音:zhan四声)是一种特殊的线性计算机内部存储结构,服从先进后出的一种特殊线性结构,如同弹夹里的子弹,先放入的子弹,在最下面。栈的结构使其只能在栈的顶端进行增加数据和删除数据的操作,压入数据称为(push),弹出数据称为(pop).
    /

    2.内存结构

    在win32环境下,由高级语言生成的可执行文件,即PE文件,(Portable Executable)文件。在运行可执行文件时,系统会将其加载到内存,并映射出4GB的虚拟存储空间,然后继续运行,形成所谓的进程空间。(教材原话)
    /
    在win32中将进程使用的内存按功能可以分为4个区域,如下图:
    /

    名称作用
    栈区(stack)用于动态存储函数之间的调用关系低地址
    堆区该内存区域由进程利用相关函数和运算符动态申请
    代码区存放程序汇编之后的机械代码和只读程序,计算机运行程序,会在该区域读取命令并执行。
    数据区用于存储全局变量和静态变量高地址

    /
    其在计算机内存中的结构也如下图:

    栈区↑栈增长方向
    堆区↓堆增长方向
    代码区
    数据区

    代码实现

    /

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void attack()
    {
    	printf("TRY IT!.\n");       //attack函数
    }
    void func()                     //func函数
    {
    	char password[6] = "ABCDEF";
    	char str[6];
    	FILE *fp;
    	if(!(fp=fopen("D:\\password.txt","r"))) //打开D盘的password.txt文件
    		exit(0);
    	fscanf(fp,"%s",str);           //将str的内容写入fp
    	str[5]='\0';
    	if(strcmp(str,password)==0)    //判断str是否与password相同
    		printf("OK.\n");
    	else
    		printf("NO.\n");            
    }
    int main()
    {
    	func();          //运行func函数
    	return 0;
    }
    

    /

    用软件IDA实现栈溢出实验(步骤)

    /在这里入图片描述
    在D盘的password.txt中输入一定量的字符串,运行程序,AAAAA…与指定的password并不相同,所以返回了“NO”。

    现在打开IDA.

    1.打开

    可以将exe文件拖入其中
    得到如下:
    /在这里插入图片描述
    /
    现在展示的IDA适用静态调试,左边可以清晰地看到函数体,这是IDA比较清晰简便的一个优点。

    2.寻找函数名称

    在这里插入图片描述
    点击左侧的函数名可以进入。右侧也可以查看十六进制视图:在这里插入图片描述
    IDA快捷键,按F5可以查看伪代码。伪代码可以让人较为清晰地了解函数的部分构造,但不是能运行的代码。在这里,用鼠标左键双击左侧函数名称中的func(),再按F5可以进入func函数查看伪代码:

    3. F5查看伪代码

    在这里插入图片描述

    在这里插入图片描述
    在上图中点击各个变量,可以查看栈。

    4.查看栈

    在这里插入图片描述

    查看到str,password,fp在栈中的位置

    /

    注意到最下面有一个"r"

    /

    这里"r"指的是return adress,这里简述为ret,ret指的是返回地址,ret在汇编中也有涉及。
    这里的ret主要功能是返回下一个函数的地址,用于在一个函数运行完后跳转到下一个函数,栈溢出攻击在这里运行的原理是,通过文本中读入过量的数据,从而,是数据在栈上溢出,使其覆盖正常的数据,从而引起漏洞与异常。

    /

    如果,溢出的数据覆盖了ret地址,那么函数可以跳转到一个指定的函数,即上文的“attack”函数。

    /

    所以在这里开始,找到attack函数的地址:

    在这里插入图片描述
    然后,只要将attack()的地址,输入到文本的末尾即可。但是,要满足其刚好能将ret的地址覆盖,使函数跳转异常,从而跳转到指定的攻击函数。
    /

    那么,来计算一下,在文本中输入多少个字符会刚刚覆盖到“r”,处:

    /

    这里查看到这个信息: [esp+10h] [ebp-18h] (如下图)
    /

    5.分析怎么实现栈溢出

    在这里插入图片描述

    由于内存栈区的地址由高地址向低地址增长,当4个字节压入栈帧时,即为 ESP=ESP-4, 有4个字节弹出栈帧时, ESP=ESP+4.

    ESP(extended stack point)是扩展栈指针寄存器,其存放地址指向这个栈帧的栈顶
    /
    EBP(extended base point)是扩展基址指针寄存器,其存放地址指向这个栈帧的栈底。

    /
    ESP与EBP之间是当前栈帧的空间。

    上图意为,从前栈底到str存放的位置还有18个字节。即[ebp-18h]的含义。

    其实从IDA中也能清晰看出来:

    在这里插入图片描述
    上图中,可以看到变量str,password,fp存放在栈中的位置,可以看到上图用红色框框选的,有18个字节,也就是上文的[ebp-18h],下面蓝色框有10个字节,即到r为止。
    /
    数据从上方加入,那我们只要在文本前加入(10+18)=28个字节,就可以刚刚覆盖到r处,r是运行完后要跳转的函数地址,那我们在28个直接之后加入,攻击函数attack()的地址即可。
    /

    在这里插入图片描述
    将D盘的password.txt文件拖入软件“HxD”中,一种文本编辑软件,notepad++也可。
    输入28个字母,之后将attack()的地址加入,即"00 40 13 50",但这里是小端序。

    这里讲一讲:

    6.小端序和大端序

    字节序即为多字节对象存储在内存中的字节顺序,有两种不同的存储方案:大端法和小端法。现代的处理器大多为双端法,大小端都支持,可以配置称大端法或者小端法。
    /
    大端序:(Big-endian):高位字节存入低地址,低位字节存入高地址
    小端序:(Little-endian):低位字节存入低地址,高位字节存入高地址

    7.继续,运行结果,原理

    一般x86位的CPU都为小端序:所以在编辑时将地址反着写,写作"50 13 40 00",
    然后,点击“保存”文件。
    /
    再打开编译器,运行:
    /
    在这里插入图片描述
    运行结果出现了TRY IT!,明显这是attack()函数的内容,已经完成了栈溢出,使函数运行出了指定的内容,这就是用IDA实现的简单的栈溢出攻击实验。
    /
    通过栈上数据的溢出,覆盖了,正确的r返回地址,从而使函数跳转出现失误,或指向性的跳转。可以加以利用。

    展开全文
  • 栈溢出攻击技术

    2018-03-13 15:16:13
    缓冲区溢出攻击技术-栈溢出攻击技术。网络安全相关。
  • 经典栈溢出PPT

    2018-11-28 21:04:23
    比较简洁的栈溢出的PPT,适合新手入门使用的教程,作用相当于一篇较简短的博客!
  • 栈溢出原理

    2021-05-16 14:47:40
    栈溢出原理¶介绍¶栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出...

    栈溢出原理¶

    介绍¶

    栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式。栈溢出漏洞轻则可以使程序崩溃,重则可以使攻击者控制程序执行流程。此外,我们也不难发现,发生栈溢出的基本前提是 程序必须向栈上写入数据。

    写入的数据大小没有被良好地控制。

    基本示例¶

    最典型的栈溢出利用是覆盖程序的返回地址为攻击者所控制的地址,当然需要确保这个地址所在的段具有可执行权限。下面,我们举一个简单的例子:

    #include

    #include

    void success() { puts("You Hava already controlled it."); }

    void vulnerable() {

    char s[12];

    gets(s);

    puts(s);

    return;

    }

    int main(int argc, char **argv) {

    vulnerable();

    return 0;

    }

    这个程序的主要目的读取一个字符串,并将其输出。我们希望可以控制程序执行 success 函数。

    我们利用如下命令对其进行编译

    ➜ stack-example gcc -m32 -fno-stack-protector stack_example.c -o stack_example

    stack_example.c: In function ‘vulnerable’:

    stack_example.c:6:3: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]

    gets(s);

    ^

    /tmp/ccPU8rRA.o:在函数‘vulnerable’中:

    stack_example.c:(.text+0x27): 警告: the `gets' function is dangerous and should not be used.

    可以看出 gets 本身是一个危险函数。它从不检查输入字符串的长度,而是以回车来判断输入是否结束,所以很容易可以导致栈溢出, 历史上,莫里斯蠕虫第一种蠕虫病毒就利用了 gets 这个危险函数实现了栈溢出。

    gcc 编译指令中,-m32 指的是生成 32 位程序; -fno-stack-protector 指的是不开启堆栈溢出保护,即不生成 canary。 此外,为了更加方便地介绍栈溢出的基本利用方式,这里还需要关闭 PIE(Position Independent Executable),避免加载基址被打乱。不同 gcc 版本对于 PIE 的默认配置不同,我们可以使用命令gcc -v查看gcc 默认的开关情况。如果含有--enable-default-pie参数则代表 PIE 默认已开启,需要在编译指令中添加参数-no-pie。

    编译成功后,可以使用 checksec 工具检查编译出的文件:

    ➜ stack-example checksec stack_example

    Arch: i386-32-little

    RELRO: Partial RELRO

    Stack: No canary found

    NX: NX enabled

    PIE: No PIE (0x8048000) 提到编译时的 PIE 保护,Linux平台下还有地址空间分布随机化(ASLR)的机制。简单来说即使可执行文件开启了 PIE 保护,还需要系统开启 ASLR 才会真正打乱基址,否则程序运行时依旧会在加载一个固定的基址上(不过和 No PIE 时基址不同)。我们可以通过修改 /proc/sys/kernel/randomize_va_space 来控制 ASLR 启动与否,具体的选项有 0,关闭 ASLR,没有随机化。栈、堆、.so 的基地址每次都相同。

    1,普通的 ASLR。栈基地址、mmap基地址、.so加载基地址都将被随机化,但是堆基地址没有随机化。

    2,增强的ASLR,在 1 的基础上,增加了堆基地址随机化。

    我们可以使用echo 0 > /proc/sys/kernel/randomize_va_space关闭 Linux 系统的 ASLR,类似的,也可以配置相应的参数。

    为了降低后续漏洞利用复杂度,我们这里关闭 ASLR,在编译时关闭 PIE。当然读者也可以尝试 ASLR、PIE 开关的不同组合,配合 IDA 及其动态调试功能观察程序地址变化情况(在 ASLR 关闭、PIE 开启时也可以攻击成功)。

    确认栈溢出和 PIE 保护关闭后,我们利用 IDA 来反编译一下二进制程序并查看 vulnerable 函数 。可以看到

    int vulnerable()

    {

    char s; // [sp+4h] [bp-14h]@1

    gets(&s);

    return puts(&s);

    }

    该字符串距离 ebp 的长度为 0x14,那么相应的栈结构为

    +-----------------+

    | retaddr |

    +-----------------+

    | saved ebp |

    ebp--->+-----------------+

    | |

    | |

    | |

    | |

    | |

    | |

    s,ebp-0x14-->+-----------------+

    并且,我们可以通过 IDA 获得 success 的地址,其地址为 0x0804843B。

    .text:0804843B success proc near

    .text:0804843B push ebp

    .text:0804843C mov ebp, esp

    .text:0804843E sub esp, 8

    .text:08048441 sub esp, 0Ch

    .text:08048444 push offset s ; "You Hava already controlled it."

    .text:08048449 call _puts

    .text:0804844E add esp, 10h

    .text:08048451 nop

    .text:08048452 leave

    .text:08048453 retn

    .text:08048453 success endp

    那么如果我们读取的字符串为

    0x14*'a'+'bbbb'+success_addr

    那么,由于 gets 会读到回车才算结束,所以我们可以直接读取所有的字符串,并且将 saved ebp 覆盖为 bbbb,将 retaddr 覆盖为 success_addr,即,此时的栈结构为

    +-----------------+

    | 0x0804843B |

    +-----------------+

    | bbbb |

    ebp--->+-----------------+

    | |

    | |

    | |

    | |

    | |

    | |

    s,ebp-0x14-->+-----------------+

    但是需要注意的是,由于在计算机内存中,每个值都是按照字节存储的。一般情况下都是采用小端存储,即0x0804843B 在内存中的形式是

    \x3b\x84\x04\x08

    但是,我们又不能直接在终端将这些字符给输入进去,在终端输入的时候\,x等也算一个单独的字符。。所以我们需要想办法将 \x3b 作为一个字符输入进去。那么此时我们就需要使用一波 pwntools 了(关于如何安装以及基本用法,请自行 github),这里利用 pwntools 的代码如下:

    ##coding=utf8

    from pwn import *

    ## 构造与程序交互的对象

    sh = process('./stack_example')

    success_addr = 0x0804843b

    ## 构造payload

    payload = 'a' * 0x14 + 'bbbb' + p32(success_addr)

    print p32(success_addr)

    ## 向程序发送字符串

    sh.sendline(payload)

    ## 将代码交互转换为手工交互

    sh.interactive()

    执行一波代码,可以得到

    ➜ stack-example python exp.py

    [+] Starting local process './stack_example': pid 61936

    ;\x84\x0

    [*] Switching to interactive mode

    aaaaaaaaaaaaaaaaaaaabbbb;\x84\x0

    You Hava already controlled it.

    [*] Got EOF while reading in interactive

    $

    [*] Process './stack_example' stopped with exit code -11 (SIGSEGV) (pid 61936)

    [*] Got EOF while sending in interactive

    可以看到我们确实已经执行 success 函数。

    小总结¶

    上面的示例其实也展示了栈溢出中比较重要的几个步骤。

    寻找危险函数¶

    通过寻找危险函数,我们快速确定程序是否可能有栈溢出,以及有的话,栈溢出的位置在哪里。常见的危险函数如下 输入gets,直接读取一行,忽略'\x00'

    scanf

    vscanf

    输出sprintf

    字符串strcpy,字符串复制,遇到'\x00'停止

    strcat,字符串拼接,遇到'\x00'停止

    bcopy

    确定填充长度¶

    这一部分主要是计算我们所要操作的地址与我们所要覆盖的地址的距离。常见的操作方法就是打开 IDA,根据其给定的地址计算偏移。一般变量会有以下几种索引模式 相对于栈基地址的的索引,可以直接通过查看EBP相对偏移获得

    相对应栈顶指针的索引,一般需要进行调试,之后还是会转换到第一种类型。

    直接地址索引,就相当于直接给定了地址。

    一般来说,我们会有如下的覆盖需求 覆盖函数返回地址,这时候就是直接看 EBP 即可。

    覆盖栈上某个变量的内容,这时候就需要更加精细的计算了。

    覆盖 bss 段某个变量的内容。

    根据现实执行情况,覆盖特定的变量或地址的内容。

    之所以我们想要覆盖某个地址,是因为我们想通过覆盖地址的方法来直接或者间接地控制程序执行流程。

    参考阅读¶

    展开全文
  • V5-306_FreeRTOS实验_任务栈溢出检测方式二 (模拟栈溢出
  • java内存溢出和栈溢出

    2018-06-08 00:54:27
     * 栈溢出    * @author feizi    * @time 2015-1-23上午9:13:11    */   public   class  SOFTest {      public   void  stackOverFlowMethod(){   stackOverFlowMethod();   }      ...
  • 栈溢出基础

    2021-01-17 16:14:06
    基础知识什么是缓冲区溢出在深入探讨技术之前, 我们先了解一下缓冲区溢出的实际内容.想象一个非常简单的程序, 要求你输入你的用户名, 然后返回到它在做什么.从视觉上看, 如下所示注意到括号之间的空格是输入...
  • linux栈溢出

    千次阅读 2022-02-01 20:57:06
    基础知识 结构 函数调用过程 32位为例: KaTeX parse error: No such environment: align* at position 8: \begin{̲a̲l̲i̲g̲n̲*̲}̲ & \text{push a… 函数参数传递 32位程序 普通函数传参:参数...
  • 64位Linux下的栈溢出

    2014-10-05 11:43:55
    0x01 x86和x86_64的区别 0x02 漏洞代码片段 0x03 触发溢出 0x04 控制RIP 0x05 跳入用户控制的缓冲区 0x06 执行shellcode 0x07 GDB vs 现实 0x08 结语
  • 栈溢出和堆溢出

    2021-06-07 21:19:59
    1. 栈溢出StackOverflowError 栈是线程私有的,生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。 栈溢出:方法执行时创建的栈帧个数超过了栈...
  • 我用递归大概试了一下,大概在4100多一点的时候,会溢出,可是用try 和catch 方法如何才能找到f(i)中的i 到底是多少呢?求代码。。。
  • 怎样解决栈溢出

    千次阅读 2021-03-13 15:46:44
    1,什么是栈溢出?由于栈一般默觉得1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。2,解决方式:方法一:用栈把递归转换成非递归通常,一个函数在调用还有一个函数...
  • Linux 内核栈溢出分析

    2021-05-11 04:59:33
    本文分析内核栈溢出。Linux 系统进程运行分为 用户态 和 内核态,进入内核态之后使用的是内核栈,作为基本的安全机制,用户程序不能直接访问内核栈,所以尽管内核栈属于进程的地址空间,但与用户栈是分开的。内核栈...
  • 如何解决栈溢出

    千次阅读 2021-03-13 15:47:06
    1,什么是栈溢出?因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。2,解决方案:方法一:用栈把递归转换成非递归通常,一个函数在调用另一个函数之前,...
  • 栈溢出 本质: 混淆了用户输入与栈上的元数据 产生原因: 用户输入的数据大小超过了程序预留的空间大小 利用: 覆盖返回地址 覆盖栈上的变量,例如函数指针或对象指针 基本栈溢出漏洞实例:实际演示 stack_shellcode 以...
  • 递归调用栈溢出

    千次阅读 2021-06-06 17:23:29
    1. 嵌套深度上会存在一定风险,递归层数过多,不断压栈,可能会引起栈溢出的问题; 2. 代码可读性,不太容易被后面维护的人理解; 但是,凡事总有例外。 比如要有一种需求场景,需要遍历一个目录下的所有文件,...
  • 目前大部分的缓冲区溢出的攻击都是...作者针对Windows操作系统,对栈溢出的原理进行了相关分析,并通过实例完成了一个溢出的攻击验证.实验结果表明,针对有漏洞的代码可以进行漏洞攻击,并给出了防止漏洞攻击的几点建议.
  • 概述: 在程序开发中,我们可能会遇到一些莫名的死机或者程序错误的执行。如果是死机我们可以看coredump,但是有时候coredump可能是死在C库,我们看不出来啥。这时我们可以加打印,打印出相关变量...如果数组越界或
  • GDB调试之二栈溢出

    2021-03-07 21:00:02
    若是需要配置一直生效并指定core文件生成路径和一些其他的信息可以用如下命令 在etc/sysctl.conf目录中添加 kernel.core_pattern=/var/coredump/%t-%e-%p-%c.core kernel.core_uses_pid=0 #sysctl -p 1、栈溢出 在...
  • 1、 内存溢出的原因是什么?内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc ...
  • 栈及栈溢出

    千次阅读 2020-07-05 14:51:14
    } } 3、栈攻击 假如一个应用程序如下,根据栈溢出漏洞攻击。 #include int main() { char name[64]; printf("What's your name?"); scanf("%s", name); printf("Hello, %s!\n", name); return 0; } gcc victim.c -o...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 163,122
精华内容 65,248
关键字:

如何让栈溢出