栈溢出攻击及其对抗机制

目录

什么是栈溢出

查找 Stack Overflow 偏移量 

Stack Overflow运用 

Ret2win 

Shellcode

ROP & Ret2...  

防御方式 

启用Core Files

启用核心转储生成 

使用 GDB 分析核心文件 


什么是栈溢出

堆栈溢出是一种漏洞,当程序向堆栈写入的数据多于分配给堆栈的数据时,就会发生这种情况。这些多余的数据将覆盖相邻的内存空间,从而导致有效数据损坏、控制流中断,甚至可能执行恶意代码。此问题通常是由于使用不对输入执行边界检查的不安全函数而引起的。

这种覆盖的主要问题是,保存的指令指针(EIP/RIP)和返回上一个函数的保存的基指针(EBP/RBP)存储在堆栈中。因此,攻击者将能够覆盖它们并控制程序的执行流程

该漏洞通常是因为函数在堆栈内复制的字节数多于为其分配的数量,因此能够覆盖堆栈的其他部分。

一些常见的易受此影响的函数包括:strcpy,,, ...此外,如果指定的长度大于分配的长度,则接受长度参数的函数(如strcat &)可能会以易受攻击sprintf方式使用getsfgetsreadmemcpy

例如,以下功能可能存在漏洞:

void vulnerable() {
    char buffer[128];
    printf("Enter some text: ");
    gets(buffer); // This is where the vulnerability lies
    printf("You entered: %s\n", buffer);
}

查找 Stack Overflow 偏移量 

查找堆栈溢出的最常见方式是给出一个非常大的输入As (例如python3 -c 'print("A"*1000)'),并期望 表示试图访问Segmentation Fault地址0x41414141

此外,一旦发现存在 Stack Overflow 漏洞,你将需要找到偏移量,直到可以覆盖返回地址,为此通常使用De Bruijn 序列。对于给定的大小为k的字母表和长度为n的子序列,它是一个循环序列,其中长度为 _n _** 的每个可能子序列都作为连续子序列出现一次**。

这样,就不需要手动确定需要哪个偏移量来控制 EIP,而是可以使用其中一个序列作为填充,然后找到结束覆盖它的字节的偏移量。

可以使用pwntools来实现这一点:

from pwn import *

# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)

# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value)  # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")

或者GEF :

#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp

Stack Overflow运用 

在溢出期间(假设溢出大小足够大),您将能够覆盖堆栈内的局部变量的值,直到到达保存的EBP/RBP 和 EIP/RIP(甚至更多)。滥用此类漏洞的最常见方式是修改返回地址,因此当函数结束时,控制流将被重定向到用户在此指针中指定的任何地方。

然而,在其他情况下,可能只需覆盖堆栈中的某些变量值就足以进行利用(例如在简单的 CTF 挑战中)。

Ret2win 

在这种类型的 CTF 挑战中,二进制文件中有一个从未被调用的函数,你需要调用该函数才能获胜。对于这些挑战,你只需要找到偏移量来覆盖返回地址并找到要调用的函数的地址(通常会禁用 ASLR),因此当易受攻击的函数返回时,将调用隐藏函数。

Shellcode

在这种情况下,攻击者可以在堆栈中放置一个 shellcode,并滥用受控的 EIP/RIP 跳转到 shellcode 并执行任意代码。 

ROP & Ret2...  

该技术是绕过上一个技术的主要保护措施的基本框架:无可执行堆栈 (NX)。它还允许执行其他几种技术(ret2lib、ret2syscall……),这些技术将通过滥用二进制文件中的现有指令来终止执行任意命令。 

防御方式 

启用Core Files

核心文件是进程崩溃时操作系统生成的一种文件。这些文件捕获崩溃进程终止时的内存映像,包括进程的内存、寄存器和程序计数器状态等详细信息。此快照对于调试和了解崩溃原因非常有用。 

启用核心转储生成 

默认情况下,许多系统将核心文件的大小限制为 0(即不生成核心文件)以节省磁盘空间。要启用核心文件的生成,你可以使用命令ulimit(在 bash 或类似的 shell 中)或配置系统范围的设置。 

  • 使用 ulimit:该命令ulimit -c unlimited允许当前 shell 会话创建无限大小的核心文件。这对于调试会话很有用,但在重新启动或新会话后不会持久。 
ulimit -c unlimited
  •  持久配置:对于更永久的解决方案,你可以编辑/etc/security/limits.conf文件以包含类似的行* soft core unlimited,这允许所有用户生成无限大小的核心文件,而不必在其会话中手动设置 ulimit。
* soft core unlimited

使用 GDB 分析核心文件 

要分析核心文件,您可以使用 GDB(GNU 调试器)等调试工具。假设你有一个生成核心转储的可执行文件,并且核心文件名为core_file,你可以使用以下命令开始分析:  

gdb /path/to/executable /path/to/core_file

此命令将可执行文件和核心文件加载到 GDB 中,让您可以检查崩溃时程序的状态。您可以使用 GDB 命令探索堆栈、检查变量并了解崩溃的原因。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值