首页 > 系统相关 >内存对齐和缓冲区溢出攻击

内存对齐和缓冲区溢出攻击

时间:2024-09-16 15:35:09浏览次数:9  
标签:字节 内存 缓冲区 对齐 buf 溢出

一、问候语

客!

二、什么是内存对齐

  计算机中内存空间都是按照字节(byte)进行划分的,所以从理论上讲对于任何类型的变量访问都可以从任意地址开始,但是在实际情况中,在访问特定类型变量的时候经常在特定的内存地址访问,所以这就需要把各种类型数据按照一定的规则在空间上排列,而不是按照顺序一个接一个的排放,这种就称为内存对齐,内存对齐是指首地址对齐,而不是说每个变量大小对齐。通俗一点讲话内存对齐的目的是为了提高CPU读写内存里数据的速度。现代的CPU读取内存并不是一个一个字节挨着读取,这样做的效率非常低。现代的CPU一般以4个字节(32bit数据总线)或者8个字节(64bit数据总线)为一组,一组一组地读写内存里的数据。

  在该图示意的例子中,一个栈空间4个字节,一个char字符占1个字节,每4个字符占一个栈空间,由于内存对齐的原因,不满4个字符也占用1个栈空间,即4个字节。故当字符数组大小为1或者为4时候,都占用1个栈空间,即4个字节。当字符数组大小为5或者为8时候,都占用2个栈空间,即8个字节.在结构体中a变量和c变量均为int型,b变量为char型,int型为4字节,char型为1字节,在不了解内存对齐的原理前,我们计算它们所占字节一般会直接将它们的字节大小加起来,即4+1+4=9字节,但这样的计算是错误的。考虑到内存对齐,实际占用字节应为4+4+4=12个字节。

三、缓冲区溢出攻击原理

  缓冲区溢出攻击是一种常见的安全漏洞,也被称为缓冲区溢出。它发生在程序尝试向缓冲区写入数据时,超过了缓冲区的容量,导致数据溢出到相邻的内存区域。这种溢出可能破坏程序的堆栈,使程序转而执行其它指令,从而达到攻击的目的。缓冲区溢出攻击的原理主要是利用程序中存在的缓冲区溢出漏洞。当程序没有仔细检查用户输入的参数时,攻击者可以通过输入超出缓冲区边界的恶意数据来破坏程序的正常执行流程。这些数据可以覆盖程序中的其他数据或函数返回地址,导致程序执行攻击者指定的恶意代码。例如,在一个简单的C语言程序中,如果程序使用固定大小的缓冲区来接收用户输入,而攻击者输入的数据超过该缓冲区的容量,就会发生缓冲区溢出。攻击者可以构造恶意输入,覆盖函数返回地址,使程序在执行完毕后跳转到攻击者指定的恶意代码处执行。

  在该图示意的c语言代码例子中,字符数组buf的大小为4,调用strcpy函数将src的值传递给buf,此时存在缓冲区溢出漏洞,如果src的大小超过了buf已规定的大小,将会发生缓冲区溢出。

1、当字符数组buf空间大小为2时


  当buf的空间大小为2时候,由于内存对齐,此时在栈中占用4个字节,即要想实现缓冲区溢出攻击,需要4+4+4+1=13个内存空间大小的gbuf

2、当字符数组buf空间大小为4时


  当buf的空间大小为4时候,由于内存对齐,此时在栈中占用4个字节,即要想实现缓冲区溢出攻击,需要4+4+4+1=13个内存空间大小的gbuf

3、当字符数组buf空间大小为5时


  当buf的空间大小为5时候,由于内存对齐,此时在栈中占用8个字节,即要想实现缓冲区溢出攻击,需要8+4+4+1=17个内存空间大小的gbuf,1的数量也应从8个改为12个。故原先13个内存空间大小的gubf无法实现缓冲区溢出攻击

4、当字符数组buf空间大小为22时


  当buf的空间大小为22时候,由于内存对齐,此时在栈中占用24个字节,即要想实现缓冲区溢出攻击,需要24+4+4+1=33个内存空间大小的gbuf,1的数量也应为28个

5、缓冲区溢出攻击相关计算


  以当字符数组buf空间大小为2时的情况为例子。gbuf的大小应为4+4+4+1=13即可实现缓冲区溢出攻击。1的数量为8。1的数量大小4+4=8主要是为了覆盖局部数组buf和栈基址指针ebp。即((void**)(gbuf + 8)) = exploit;中的+8。后面的+4是为了覆盖原先返回地址,将我们要跳转的目的地址替换掉原先的地址。最后的+1是空字符\0。((void**)(gbuf + 8)) = exploit;其中exploit为我们要跳转的目的地址

四、预防缓冲区溢出攻击

1、输入验证和长度检查

  最基本的防护方法是进行输入验证和长度检查。程序员应该在编写代码时,对所有的输入数据进行严格的验证和长度检查,确保输入数据不会超过缓冲区的容量。这可以通过使用安全的库函数或者自定义的函数来实现。例如,使用strncpy函数代替strcpy函数可以避免缓冲区溢出的问题,因为strncpy函数允许指定目标缓冲区的大小。

2、使用安全的库函数

  使用安全的库函数也是防止缓冲区溢出攻击的防护方法之一。程序员应该尽可能使用安全的库函数,例如strncpy、snprintf等,这些函数在处理输入数据时会自动进行长度检查,避免了缓冲区溢出的问题。此外,程序员还应该了解并避免使用不安全的库函数,例如strcpy、sprintf等。

3、栈保护

  栈保护是一种有效的缓冲区溢出攻击防护方法。它通过在栈上添加保护机制,防止攻击者利用缓冲区溢出漏洞覆盖栈上的返回地址或者其他重要数据。常见的栈保护技术包括:1.栈随机化:通过随机化栈的基地址,使得攻击者无法准确地预测栈的布局,从而增加了攻击的难度。2.栈保护:通过在栈上添加保护机制,例如Canary值或者GS标志位,检测栈是否被篡改,从而防止攻击者利用缓冲区溢出漏洞进行攻击。

4、地址空间布局随机化(ASLR)

  地址空间布局随机化(ASLR)是一种有效的缓冲区溢出攻击防护方法。它通过随机化程序的内存布局,使得攻击者无法准确地预测内存地址,从而增加了攻击的难度。ASLR可以通过操作系统或者编译器来实现,程序员只需要在编写代码时开启相应的选项即可。

5、数据执行保护(DEP)

  数据执行保护(DEP)也是一种有效的缓冲区溢出攻击防护方法。它防止程序在内存中执行恶意代码,从而防止了缓冲区溢出攻击。DEP可以通过操作系统或者编译器来实现,程序员只需要在编写代码时开启相应的选项即可。

五、结束语

此随笔内容仅为学习缓冲区溢出攻击的一些感悟、想法与总结,由于本人能力有限,如随笔内容有错误希望能见谅并加指出。--------------------------------------------------------------------------------------------------------如果感兴趣的话可以点击页面下方的关注感谢你的支持!

标签:字节,内存,缓冲区,对齐,buf,溢出
From: https://www.cnblogs.com/Qing1024/p/18416319

相关文章

  • ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)
    名词缩写ASID:AddressSpaceID地址空间标识符CD:ContextDescriptor;上下文描述符;CTP:Context-tablepointer上下文表指针EPT:ExtendedPageTable扩展页表GPA:GuestPhyicalAddress客人的实际地址GVA:GuestVirtualAddress访客虚拟地址HPA:HostPhyicalAddress......
  • 掌握C语言动态内存分配:从入门到精通,一次搞定!
    在C语言开发中,内存管理是一个非常重要但常被忽略的话题。与一些高级语言(如Java或Python)不同,C语言不会自动管理内存,开发者需要自己处理内存的分配和释放。虽然这种灵活性为程序的优化提供了巨大的可能性,但它也意味着更高的风险:如果不小心,就容易引发内存泄漏、空指针错误、内存越......
  • 小林coding学习笔记(内存页面置换算法)
    缺页中断示意图1在CPU里执行一条查找某个页面A的指令,首先是虚拟内存,会到虚拟内存和物理内存的映射关系的页表中查询。2页表中不存在需要查找的页面A的有效信息。3则触发缺页中断信号给操作系统,操作系统收到缺页中断信号后,就会去磁盘里面查找该页面。4操作系统在磁盘中查......
  • 使用 O(1) 额外内存删除二叉树
    这是一个naive的做法:voiddeleteTreeRec(TreeNode*root){if(root==NULL)return;deleteTreeRec(root->left);deleteTreeRec(root->right);cout<<"Deletingnode"<<root->data<<endl;deleteroot;}O(1)空......
  • 共享内存的理解
     目录直接原理原理图​编辑直接代码创建唯一键值代码 创建共享内存代码 共享内存的指令操作  简单封装补充指令集系统设计的只能本地进行通信;直接原理共享内存也是进程间通信的方案原理图理解:1.  所有图中所说的操作都是os所做的 2.  os必须提......
  • Linux内存管理知识-一篇文章了解堆和栈区别(进阶篇)
    前面已经介绍过,栈是由编译器在需要时分配的,不需要时自动清除的变量存储区。里面的变量通常是局部变量、函数参数等。堆是由malloc()函数分配的内存块,内存释放由程序员手动控制,在C语言为free函数完成。栈和堆的主要区别有以下几点:(1)管理方式不同栈编译器自动管理,无需程序员手......
  • C++入门基础知识69(高级)——【关于C++ 动态内存】
    成长路上不孤单......
  • 内存管理-35-内存统计-1-各成员含义
    基于msm-5.4一、vm_zone_stat[]基础调用路径:clear_page_mlock//mlock.c传参(..,NR_MLOCK,..)mlock_vma_page//mlock.c传参(..,NR_MLOCK,..)account_kernel_stack//fork.c传参(..,NR_KERNEL_STACK_KB,..)scs_account//scs.c传参(..,NR_K......
  • Python中的内存池机制
    在Python中,内存管理是一个复杂但至关重要的主题,它直接关系到程序的性能和稳定性。Python的内存管理机制包括对象的分配、追踪以及回收,其中内存池(MemoryPool)是这一机制中的一个重要组成部分。内存池机制通过预先分配和重用小块内存来减少内存分配和释放的开销,从而提高程序的执......
  • Git缓冲区理解:`index`,`add`和`reset`,`staged`和`unstaged`
    在git里面,有一个叫index的区域,你把东西加到那里叫add,把东西再从哪里撤回来叫reset;已经在里面的我们形容它是staged,还没有加进去的我们形容它是unstaged。其实index区就是一个纯粹的缓冲区,也叫stagingarea,是正式提交之前给我们的一个缓冲,还有犹豫的余地。因为一旦正式commit提交......