C Printf将%p视为系统()

时间:2015-09-28 18:32:34

标签: c pointers

我在基于堆的溢出教程中看到了这一点:

printf("System: %p", system);

该地址是什么,它是什么意思?每次运行时,打印值都保持不变。 这是所有程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define ERROR -1
#define BUFSIZE 64

int goodfunc(const char *str); /* funcptr starts out as this */

int main(int argc, char **argv)
{
   static char buf[BUFSIZE];
   static int (*funcptr)(const char *str);

   if (argc <= 2)
   {
      fprintf(stderr, "Usage: %s <buf> <goodfunc arg>\n", argv[0]);
      exit(ERROR);
   }

   printf("(for 1st exploit) system() = %p\n", system);
   printf("(for 2nd exploit, stack method) argv[2] = %p\n", argv[2]);
   printf("(for 2nd exploit, heap offset method) buf = %p\n\n", buf);

   funcptr = (int (*)(const char *str))goodfunc;
   printf("before overflow: funcptr points to %p\n", funcptr);

   memset(buf, 0, sizeof(buf));
   strncpy(buf, argv[1], strlen(argv[1]));
   printf("after overflow: funcptr points to %p\n", funcptr);

   (void)(*funcptr)(argv[2]);
   return 0;
}

/* ---------------------------------------------- */

/* This is what funcptr would point to if we didn't overflow it */
int goodfunc(const char *str)
{
   printf("\nHi, I'm a good function.  I was passed: %s\n", str);
   return 0;
}

据我所知,我们指出并将参数“bash”传递给system()。

2 个答案:

答案 0 :(得分:2)

system is a function from stdlib开始,代码具有未定义的行为,因为%p需要void*指针。此代码正在传递一个指向函数的指针,它与void*指针不兼容。

您无法通过插入强制转换来修复此程序,即

printf("System: %p", (void*)system);

因为ISO C标准 * 不允许这样做。

由于行为未定义,语句可以打印它想要的任何内容,崩溃或做任何其他事情。但是,最可能的行为是,表示system地址的某个数字会被重新解释为void*指针,从而导致您观察到的行为,即打印的数字相同。

* C99指向函数的唯一转换是转换到函数的其他指针,如6.3.2.3.8节所述。根据J.5.7.2节,将函数指针转换为void*指针是该语言的通用扩展,旨在用于调试器。

答案 1 :(得分:0)

来自man system

  

system()通过调用/ bin / sh -c命令执行命令中指定的命令,并在命令完成后返回。在执行命令期间,SIGCHLD将被阻止,SIGINT和SIGQUIT将被忽略。

因此,使用system()执行任意代码。

%p打印作为内存地址传递的值。

这个想法是你想利用这些知识通过某种内存溢出使易受攻击的程序执行system("NotAVirus.exe")