我在我的一个项目中攻击了glibc的printf()并遇到了一些问题。你能提一些线索吗?我担心的一个原因是为什么malloc / free的相同解决方案完美无缺!
如附带的那样,“PrintfHank.c”包含我自己的printf()解决方案,它将在标准库之前预先加载;和“main.c”只使用printf()输出一个句子。编辑完两个文件后,我发出了以下命令:
但是我在控制台中收到了“hello world”而不是“在我自己的printf中”。当攻击malloc / free函数时,没关系。
我以“root”身份登录我的系统,并使用2.6.23.1-42.fc8-i686。任何评论都将受到高度赞赏!!
的main.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
PrintfHank.c
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <dlfcn.h>
static int (*orig_printf)(const char *format, ...) = NULL;
int printf(const char *format, ...)
{
if (orig_printf == NULL)
{
orig_printf = (int (*)(const char *format, ...))dlsym(RTLD_NEXT, "printf");
}
// TODO: print desired message from caller.
return orig_printf("within my own printf\n");
}
答案 0 :(得分:3)
这个问题很古老,但是:
在main.c
中,您在结尾处有换行符,并且未使用printf
的任何格式化功能。
如果我查看LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1
的输出(我已经稍微重命名了您的文件),那么靠近底部我可以看到
17246: transferring control: ./hello
17246:
17246: symbol=puts; lookup in file=./hello [0]
17246: symbol=puts; lookup in file=./printhack.so [0]
17246: symbol=puts; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17246: binding file ./hello [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `puts' [GLIBC_2.2.5]
并没有实际提到printf
。 puts
基本上是没有格式化的printf,最后是自动换行符,所以这显然是gcc的结果&#34;有用的&#34;将printf
替换为puts
。
为了让您的示例正常运行,我从\n
中删除了printf
,这样可以输出如下内容:
17114: transferring control: ./hello
17114:
17114: symbol=printf; lookup in file=./hello [0]
17114: symbol=printf; lookup in file=./printhack.so [0]
17114: binding file ./hello [0] to ./printhack.so [0]: normal symbol `printf' [GLIBC_2.2.5]
现在我可以看到printhack.so
确实被其自定义printf
拖入。
或者,您也可以定义自定义puts
功能:
static int (*orig_puts)(const char *str) = NULL;
int puts(const char *str)
{
if (orig_puts == NULL)
{
orig_puts = (int (*)(const char *str))dlsym(RTLD_NEXT, "puts");
}
// TODO: print desired message from caller.
return orig_puts("within my own puts");
}
答案 1 :(得分:1)
检查 1)预处理器输出。 printf可以更改为smth else
gcc -E main.c
2)关于printf符号和预加载的ld_debug信息
LD_DEBUG=help LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
LD_DEBUG=all LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
答案 2 :(得分:0)
更改
return orig_printf("within my own printf\n");
到
return (*orig_printf)("within my own printf\n");