在溢出scanf的(QUOT;%8S&QUOT ;,字符串)? [英] Overflow over scanf("%8s", string)?

查看:154
本文介绍了在溢出scanf的(QUOT;%8S&QUOT ;,字符串)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是可能会超出普通code:

字符字符串[9];

scanf函数(%S,字符串)。

但有可能溢出scanf函数(%8S,字符串)? 8仅仅是一个例子。

我知道8S%就像一个划定的,但我也因注意到,当我输入的字符串超过8个字符长,程序将终止:

*砸检测栈* :./a.out终止

=======回溯:=========

...

显然有检测堆由GCC在默认情况下砸开启的标志。由于这是一个堆栈溢出,那么我的猜测是,它仍然有可能溢出并执行任意code。

相反,正常的溢出轧液scanf函数(%S)的调用者,如果scanf函数(%8S)可能会溢出,它会scanf的函数中,这样,当scanf函数试图返回,控制上涨溢出。

但scanf函数是一个需要模式切换(从用户模式切换到内核模式)系统调用,并在内部它会调用东西,如读取到标准输入等,所以不知道,如果我们能在内核模式或溢出的东西..

评论欢迎!

更新>>

字符串[9],假定在上述的例子。字符字符串[8]在以下实code。

真正的问题是有关安全scanf函数之间的相互冲突似乎故事(%8S)和GCC流产由于堆栈冲击。

简体code:

 无效美孚(通过一些指针){
字符输入[8];
INT input_number = 0;而(1){//循环控制台
   printf的一些信息;
   scanf函数(%8S,输入);   input_number =的atoi(输入);   如果((strlen的(输入)== 1)及及(STRNCMP(输入,Q,1)== 0)){
       input_number = -1;
   }
   开关(input_number){
       案例-1:退出控制台当输入=Q;
       默认:打印信息的指针指到;
       ...
   }}}

请注意:


  1. 富被别人叫。

  2. 尽管字符串是实时的8个字节
    code。与%8S,我不认为这
    导致砸。


解决方案

请参阅http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html:


  

每个指令由下列之一......一个可选的非零十进制整数,指定最大字段宽度。


  
  

取值结果
     匹配不在空白字符的字节序列。申请书应当保证相应的参数是指向字符数组的起始字节,签署char或unsigned char型大到足以接受序列和终止空字符code,应自动添加。


所以不会溢出一个9字节的字符串缓冲区。

I know it's possible to overflow ordinary code:

char string[9];

scanf("%s", string).

But is it possible to overflow scanf("%8s", string)? 8 is just an example.

I know "%8s" works like a delimit, but I also notice when I input string longer than 8 chars, the program will terminate due to:

* stack smashing detected *: ./a.out terminated

======= Backtrace: =========

...

Obviously there's a flag that detects stack smashing turned on by GCC by default. Since this is a stack smashing, then my guess is that it is still possible to overflow and execute arbitrary code.

Contrary to normal overflow that mangles the caller of scanf("%s"), if scanf("%8s") can overflow, it will overflow within scanf function so that when scanf try to return, control is gained.

But scanf is a syscall that requires mode-switch (switching from user mode into kernel mode), and internally it will call stuff like read to the stdin etc. So not sure if we can overflow in kernel mode or something..

Comments are welcome!!

UPDATE >>

char string[9] is assumed in the above example. char string[8] in following real code.

The question is really about the seeming conflicting story between safe scanf("%8s") and GCC abortion due to stack smashing.

Simplified code:

void foo(pass some pointer) {
char input[8];
int input_number = 0;

while (1) { // looping console
   printf some info;
   scanf("%8s", input);

   input_number = atoi(input);

   if ((strlen(input) == 1) && (strncmp(input, "q", 1) == 0)) {
       input_number = -1;
   }
   switch (input_number) {
       case -1: to quit the console if input = 'q';
       default: to print info that pointer refers to;
       ...
   } 

}

}

Note:

  1. foo is called by someone else.
  2. Though string is 8 bytes in real code with "%8s", I don't think this lead to smashing.

解决方案

See http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html:

Each directive is composed of one of the following...An optional non-zero decimal integer that specifies the maximum field width.

s
Matches a sequence of bytes that are not white-space characters. The application shall ensure that the corresponding argument is a pointer to the initial byte of an array of char, signed char, or unsigned char large enough to accept the sequence and a terminating null character code, which shall be added automatically.

So it won't overflow a 9-byte string buffer.

这篇关于在溢出scanf的(QUOT;%8S&QUOT ;,字符串)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆