puts中调用的got表
去千岛湖团建的时候和男孩聊起上次强网杯中_exit
的题中用到了puts@got@libc
,
当时不是很理解,于是就提起了这件事,然后发现,这个类似于got表一样的东西与puts
没啥关系,
倒是与strlen
有关系
省流:看下文粗体结论
先是在nameless师傅的博客里找到的灵感:
cyberprinter
于是我就在本地调了一下,也是类似有个跳表存在,不过Arch的libc不能改这一项(因为开了Full RELRO)
可以看到出现跳表的位置对应源码是在strlen
的位置,在elixir中,
原始的puts
函数是这样的:
1 | int |
检查strlen
的交叉引用,在string.h
里只有一个声明
1 | /* Return the length of S. */ |
那么真正调用的是什么函数呢?在文件sysdeps/x86_64/multiarch/strlen.c
中,有一些提示:
1 | /* Define multiple versions only for the definition in libc. */ |
接着跟进到ifunc-avx2.h
,其针对经常调用的函数做了cpu针对性的优化。回到gdb,
跟进strlen
,实际调用的函数是__strlen_avx2
,对应的文件是sysdeps/x86_64/multiarch/strlen-avx2.S
,
这下答案已经呼之欲出了:glibc通过ifunc将优化版本的strlen
嵌入到库中,
方便后期绑定优化版本,而这个跳表*ABS*
就是在libc的got中,在一些Ubuntu的libc中,只启用了Partial
RELRO,就可以通过修改这一项,达到执行libc中的puts
时,从跳表中运行任意代码
这也让我想起了前不久刚过去的xz风波,xz同样是借助了glibc的ifunc机制来修改了
liblzma
中的函数, 达到嵌入代码的目的
在源码中,除了strlen
以外,strcpy
等函数都有其对应的优化版本,调用到这些函数的库函数同样应该会被插入跳表,
存在利用的可能性。但要注意的是,直接调用strcpy
是不会有跳表的,经过dl_runtime_resolve
会直接解析成
__strcpy_avx2
- 标题: puts中调用的got表
- 作者: RocketDev
- 创建于 : 2024-04-15 23:48:00
- 更新于 : 2024-07-25 12:34:56
- 链接: https://rocketmadev.github.io/2024/04/15/ifuncInPuts/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。