.. | ||
ret2lib | ||
ebp2ret-ebp-chaining.md | ||
pointer-redirecting.md | ||
README.md | ||
ret2csu.md | ||
ret2dlresolve.md | ||
ret2esp-ret2reg.md | ||
ret2ret.md | ||
ret2shellcode.md | ||
ret2win.md | ||
rop-return-oriented-programing.md | ||
rop-syscall-execv.md | ||
srop-sigreturn-oriented-programming.md | ||
stack-pivoting-ebp2ret-ebp-chaining.md | ||
stack-shellcode.md |
Stack Overflow
{% hint style="success" %}
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
什么是栈溢出
栈溢出是一种漏洞,当程序向栈写入的数据超过其分配的容量时就会发生。这些多余的数据将覆盖相邻的内存空间,导致有效数据的损坏、控制流的中断,以及潜在的恶意代码执行。这个问题通常是由于使用不安全的函数而引起的,这些函数不对输入进行边界检查。
这个覆盖的主要问题是保存的指令指针 (EIP/RIP) 和保存的基指针 (EBP/RBP) 用于返回到上一个函数,这些信息是存储在栈上的。因此,攻击者将能够覆盖这些信息并控制程序的执行流。
该漏洞通常是因为一个函数在栈中复制的字节数超过了为其分配的数量,因此能够覆盖栈的其他部分。
一些常见的易受攻击的函数包括:strcpy
、strcat
、sprintf
、gets
... 此外,像 fgets
或 read
这样的函数,如果指定的长度大于分配的长度,也可能以脆弱的方式使用。
例如,以下函数可能是易受攻击的:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
寻找栈溢出
寻找栈溢出的最常见方法是输入非常大的 A
(例如 python3 -c 'print("A"*1000)'
),并期待出现 Segmentation Fault
,这表明 尝试访问了地址 0x41414141
。
此外,一旦发现存在栈溢出漏洞,您需要找到偏移量,以便能够 覆盖返回地址,通常使用 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
利用栈溢出
在溢出期间(假设溢出大小足够大),您将能够覆盖栈内局部变量的值,直到达到保存的 EBP/RBP 和 EIP/RIP(甚至更多)。
滥用这种类型漏洞的最常见方法是修改返回地址,这样当函数结束时,控制流将被重定向到用户在此指针中指定的任何位置。
然而,在其他场景中,仅仅覆盖栈中某些变量的值可能就足以进行利用(例如在简单的 CTF 挑战中)。
Ret2win
在这种类型的 CTF 挑战中,二进制文件中有一个从未被调用的函数,而且您需要调用它才能获胜。对于这些挑战,您只需找到覆盖返回地址的偏移量并找到要调用的函数的地址(通常ASLR会被禁用),这样当易受攻击的函数返回时,隐藏的函数将被调用:
{% content-ref url="ret2win.md" %} ret2win.md {% endcontent-ref %}
栈 Shellcode
在这种情况下,攻击者可以将 shellcode 放置在栈中,并利用受控的 EIP/RIP 跳转到 shellcode 并执行任意代码:
{% content-ref url="stack-shellcode.md" %} stack-shellcode.md {% endcontent-ref %}
ROP
该技术是绕过前一种技术主要保护的基本框架:不可执行栈(NX)。它允许执行其他几种技术(ret2lib、ret2syscall...),通过滥用二进制文件中现有的指令来最终执行任意命令:
{% content-ref url="rop-return-oriented-programing.md" %} rop-return-oriented-programing.md {% endcontent-ref %}
保护类型
有几种保护措施试图防止漏洞的利用,请查看它们:
{% content-ref url="../common-binary-protections-and-bypasses/" %} common-binary-protections-and-bypasses {% endcontent-ref %}
{% hint style="success" %}
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 电报群组 或 在 Twitter 上关注 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享黑客技巧。