我让自己开始承担缓冲区溢出的风险,尤其是涉及低级C库输入/输出功能并试图了解它与内存利用之间的关系和代码注入。
我正在考虑以下代码块及其执行所产生的怪异行为:
int main ()
{
char buffer[10];
int r = read (STDIN_FILENO, buffer, 14);
puts(buffer);
return EXIT_SUCCESS;
}
现在提供以下17尺寸输入
Hello, World !pwd
我得到以下输出:
Hello, Wor
> pwd
/media/...<current working directory path>
如输出所示,3个多余的字符(在此处为演示目的pwd
)超出了read
函数指定限制的范围-由终端接管并作为shell命令执行。
从低级别的角度来看,是什么导致了此行为?
可以用来执行代码注入吗?
答案 0 :(得分:1)
如输出所示,额外的3个字符(此处为
pwd
出于演示目的)-超出了read
函数的指定限制-已由终端接管 并作为shell命令执行。从低级别的角度来看,这怎么可能?
正如@ChrisTurner在评论中首先看到的那样,在程序退出后,pwd
被解释为启动程序的shell的输入就不足为奇了。尽管每个程序都有其自己的句柄,但它们是从同一个文件读取的,该文件可能已连接到终端。
但是,您的程序通过使用低级I / O函数read
来提供帮助,该函数不会消耗该文件中的字节数超出您的请求。诸如fread
,fgets
和scanf
之类的基于流的对比函数,它们通常执行缓冲读取(这是它们所操作的流的特征,而不是功能本身)。在您的特定情况下,任何这些都会消耗掉直到第一个换行符的所有输入。
您的程序中确实存在潜在的缓冲区溢出,但这是一个红色鲱鱼。您描述的行为确实取决于read
读取请求的全部14个字节,虽然不能保证做到这一点,但是出于所有目的和目的,当标准输入连接到终端时,您可以依靠它来执行。这样,您的程序确实会表现出未定义的行为,但是该UB的表现很可能会受限于程序的输出(注意它是如何被截断的?)甚至对您而言是不可见的。它不负责由父shell读取“ pwd”作为输入。
那 非控制台程序执行,例如 GUI应用,网络应用,等等... 在这种情况下,他们将如何表现?最重要的是 就 binary而言,这种情况是否会引发安全问题 开发和代码注入,以及可能在其他安全方面 我不知道吗?
只有直接访问该程序的父shell(如果有)或该shell的控制终端的人或程序都可以向其输入输入。您没有另外证明。没有特别的安全考虑要讨论。