使用LD_PRELOAD方法注入printf的问题

时间:2009-10-16 07:51:05

标签: hook code-injection glibc

我在我的一个项目中攻击了glibc的printf()并遇到了一些问题。你能提一些线索吗?我担心的一个原因是为什么malloc / free的相同解决方案完美无缺!

如附带的那样,“PrintfHank.c”包含我自己的printf()解决方案,它将在标准库之前预先加载;和“main.c”只使用printf()输出一个句子。编辑完两个文件后,我发出了以下命令:

  1. 编译main.c          gcc -Wall -o main main.c
  2. 创建我自己的库          gcc -Wall -fPIC -shared -o PrintfHank.so PrintfHank.c -ldl
  3. 测试新库          LD_PRELOAD =“$ mypath / PrintfHank.so”$ mypath / main
  4. 但是我在控制台中收到了“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");
    }
    

3 个答案:

答案 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]

并没有实际提到printfputs基本上是没有格式化的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");