在了解幽灵漏洞的时候看到了这个词, 查了一下原来就是恶意控制程序执行流.
正好有个朋友也在研究这些东西, 如果我不知道岂不是连人家的博客都看不懂
本文仅用作个人大概了解,可能有误.参考资料主要来源于wiki,gpt和下文中的链接.

词典

  • gadgets: 以ret结尾的指令序列.
  • payload: 攻击者在溢出缓冲区时注入的恶意代码或数据.

分类

  • ret2text
  • ret2shellcode
  • ret2syscall
  • ret2libc
  • ret2dl_resolve
  • ret2VDSO
  • SROP
  • BROP
如何绕过canary

^参考
ret是在canary之后的. 如果绕不过canary, 修改返回地址就免谈了.

  • 泄漏canary:
    正常是读不到canary的.
    并且每次运行程序 canary都不一样.
    有时canary低字节部分为0, 我们可以稍微溢出一点缓冲区, 正好覆盖掉canary低字节为0的部分而不覆盖其全部, 这样就能读取到canary了.
  • 爆破canary
    令覆盖的值随机(或者遍历),一步步覆盖canary,如果正确就进一步覆盖,不正确就重开. (不过因为重开的是fork程序, 不管fork多少次 canary都是和原程序一致的. 所以不用担心canary变动的问题)
    (原文给出的示例是仅限于fork时,canary不变才能得到的,不知道有没有其他适用条件)
  • ssp leak(Stack Smashing Protect Leak)
    glibc2.27以上已经修复了这个方法,这里简单了解一下吧.
    “通过输入足够长的字符串覆盖掉argv[0],这样就能让canary保护输出我们想要地址上的值”
    更详细一点的过程是,当覆盖了canary引发stack_chk_fail时, 会执行fortify_fail(), 这个函数会打印启动参数argv[0].
    而argv[0]是在canary后面的. 如果我们覆盖的足够长, 覆盖掉argv[0], 也就可以打印我们修改过的argv[0]的值.
    再深入一点涉及到smashes和exp什么的??这里不再细说了. ^原文链接
  • 劫持__stack_chk_fail
    通过修改got表实现. 这里涉及到格式化字符串漏洞. 关于这个漏洞,我觉得暂时没必要再往深看了,不然好像没有尽头的样子
    大概过程是, 修改__stack_chk_fail在got表中指向的函数, 从而在触发的时候 执行其他函数(比如一个空函数.)

好了,现在终于可以看看怎么ret2xxx了!

ret2text:

也就是返回到程序原有的代码段.
不需要关nx, 毕竟这是程序本身的代码段.
(感觉没什么用啊 哪个攻击者能直接获取二进制程序并且知道ret到哪里可以有效攻击啊)
后来想想 好像ctf比赛是不是会直接给二进制程序?
^示例

ret2shellcode

返回到自己覆盖的缓冲区上的代码.
需要关NX保护.
覆盖返回地址到栈上, 具体是返回到我们写入的缓冲区中的shellcode.
(仍然感觉没什么用, 除了打比赛.)

ret2syscall

返回到系统调用. 和ret2text差不多,只不过要指定寄存器.
amd64调用系统调用需要这几个寄存器:eax, ebx, ecx, edx和syscall指令. riscv是用的x10, x11, x12和x17, 这里先看看amd64的吧.

ret2libc

这里复习一下got表和plt的知识.
动态链接库中的函数, 在我们的程序的函数中调用时, 访问的是全局符号. got表记录了这些符号到 动态链接库中实际函数地址 的映射.
当第一次调用动态链接库中的函数时, 会先访问plt. plt负责调用动态链接器, 找到相应的真实的链接库中的函数地址, 然后放到got表中.
可以将plt看成一种懒加载的实现.

返回到libc或者其他的外部链接库(不过一般是返回到libc).

ret2csu

就是调用任意函数.
相应的, ret2csu的额外工作是拟造目标函数需要的参数.

需要的参数很多时怎么办?
当传入多个参数时, 程序将先前的参数压到栈中, 然后再读剩下的参数.
等需要某个参数时, 再将栈中的参数放到寄存器中.

程序中,一般有一段万能的控制参数的gatget, 可以控制用于传参的寄存器(比如__libc_csu__init), 这样就可以进行传参调用了.

more

还有其他的rop方法,不细看了,放个链接在这里吧.
https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/medium-rop/

总结

栈溢出真的能引发很多问题.
但貌似也是很低级的问题.
关于逆向方面的知识先看到这里. 下一次学习可能会了解^这个东西.
但是现在我该ret2幽灵漏洞了.