Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 格式化字符串漏洞以segfault结束_C_Path_Formatting_Environment Variables_Exploit - Fatal编程技术网

C 格式化字符串漏洞以segfault结束

C 格式化字符串漏洞以segfault结束,c,path,formatting,environment-variables,exploit,C,Path,Formatting,Environment Variables,Exploit,我现在正在读《黑客——剥削的艺术》一书 这是我开发格式字符串代码的简化版本 /* fmt_vuln.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main (int argc, char *argv[]){ char text [1024]; if (argc < 2){ printf ("Usage: %s <text to print

我现在正在读《黑客——剥削的艺术》一书

这是我开发格式字符串代码的简化版本

/* fmt_vuln.c */

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

int main (int argc, char *argv[]){
  char text [1024];

  if (argc < 2){
    printf ("Usage: %s <text to print>\n", argv[0]);
    exit (0);
  }
  strcpy (text, argv[1]);
  printf ("The wrong way to print user-controlled input:\n");
  printf (text);
  printf ("\n");
  return 0;
}
我得到:

The wrong way to print user-controlled input:
AAAA59055000.58e347a0.58b68620.ffffffff.00000000.fba56ac8.58a9fc58.41414141
The wrong way to print user-controlled input:
Segmentation fault
所以,我看到第8个format参数是从format字符串的开头读取的

然后,当我运行命令时:

./getenv PATH ./fmt_vuln
我得到了地址:

0x7ffe2a673d84
所以我试着运行:(为了打印PATH变量)

我得到:

The wrong way to print user-controlled input:
AAAA59055000.58e347a0.58b68620.ffffffff.00000000.fba56ac8.58a9fc58.41414141
The wrong way to print user-controlled input:
Segmentation fault
为什么我会有错?从getenv程序中我得到了路径的地址,但程序仍然崩溃


感谢您的帮助。

出于安全原因,并非计算机中的所有进程都共享同一个进程。当我谈论不同的内存空间时,我是什么意思?考虑以下2个程序:

//program 1
int main(int argc, char** argv){
    printf("%02x", *((uint8_t*)0xf00fba11));
    return 0;
}

//program 2
int main(int argc, char** argv){
    printf("%02x", *((uint8_t*)0xf00fba11));
    return 0;
}
如果这些程序同时运行(并且假设它们不发生segfault(它们几乎肯定会发生segfault)),它们将打印不同的值。怎么可能呢??它们都访问内存位置0xf00fba11!。。。还是他们

为了理解这里发生了什么,我们首先需要了解cpu从内存加载值时发生了什么。要从内存加载值,cpu向RAM发送一个请求,如下所示:

 cpu
|-------------|                                           |---------|
| read        |-------address out to RAM (0xf00fba11)---->|  RAM    |
|             |                                           |         |
| *0xf00fba11 |<---------data coming back to CPU----------|         |
|-------------|                                           |---------|
因此,如果在进程1中在内存地址0x7ffe2a673d84处加载环境变量,则它可能会转换为物理地址0x63002a673d84。此外,当进程2尝试访问*0x7ff32a673d84时,它将被映射到一个完全不同的地址,或者,在您的情况下,它可能被进程2取消映射,从而导致一个segfult。

所以坏消息是,我认为没有任何方法可以用代码“修复”这个问题。做你想做的事情会给你一个错误或者随机的,无用的数据。要获取您感兴趣的数据,您需要查看MMU配置设置并修改它们,除非您以提升的权限级别运行,否则不允许这样做

在我们分开之前,值得注意的是,为了在两个进程之间来回传递数据或访问共享软件库,进程之间可能存在一些共享的地址。也就是说,对于几个不同的进程,0x1000将转换为0x5000


或者我不知道你在说什么。我没有真正遵循关于
/getenv PATH./fmt\u vuln

的行,因为您使用64位系统,所以您的地址有8个字节

看看这个地址,它只有6个字节。这意味着较高的两个字节为零。但您不能简单地将零字节作为十六进制字符串提供,如
\xff\xaa\xbb\x00
,因为程序会将该零字节解释为字符串的结尾


您需要使用32位系统来进行试验,x64体系结构将不允许您利用该漏洞。

偶然发现了相同的东西(阅读同一本书)

getenv_addr
不是超级可靠的。我在
fmt_vuln.c
中显示了
PATH
的确切地址,并添加了:

printf("[*] %s is at %p\n", "PATH", getenv("PATH"));
这将为您提供一个应该可以工作的地址,并且与
getenv_addr
给出的地址不应太远

此外,请确保禁用ASLR(地址空间布局随机化-基本上随机化地址空间位置):


并确保编译一个32位程序(
gcc-m32
)。

您提到的这一行实际上是程序getenvaddr,可以在这里找到:。其次,您知道为什么在书中他们也这么做并得到PATH的值吗?他们从上一条评论中查找程序的地址,并完全按照我所做的做了(当然是他们得到的地址)。这段代码高度依赖于系统。我不确定你的系统,但在我的系统上,如果我运行几次get_env,每次我都会得到不同的地址。这听起来可能像是逃避回答,但我怀疑如果你使用的是这本书的第一版(写于2003年),那么写这本书的原始系统可能与你的不同。是的,同样在我的电脑上,我每次在get_env上都得到不同的结果。正如你所说,我认为它实际上是依赖于系统的。无论如何,谢谢你的帮助和详细的解释!
Process 1
asks for          | gets physical address
------------------------------------
 0x0000 - 0x0fff  | ERROR SEGFAULT
 0x1000 - 0x1fff  | 0x70000 - 0x70fff
 0x2000 - 0x2fff  | 0x30000 - 0x30fff
 0x3000 - 0x3fff  | 0xa7000 - 0xa7fff
      etc....     | etc.....


Process 2
asks for          | gets physical address
------------------------------------
 0x0000 - 0x0fff  | ERROR SEGFAULT
 0x1000 - 0x1fff  | 0xb1000 - 0xb1fff
 0x2000 - 0x2fff  | 0x40000 - 0x40fff
 0x3000 - 0x3fff  | 0x1c000 - 0x1cfff
      etc....     | etc.....
printf("[*] %s is at %p\n", "PATH", getenv("PATH"));
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space