C 缓冲区溢出导致终端以shell命令的形式执行额外字符
我开始考虑缓冲区溢出风险,特别是在涉及低级C库输入/输出函数时,并试图了解它与内存利用和代码注入的关系 我正在考虑以下代码块及其执行所产生的奇怪行为:C 缓冲区溢出导致终端以shell命令的形式执行额外字符,c,security,io,limit,buffer-overflow,C,Security,Io,Limit,Buffer Overflow,我开始考虑缓冲区溢出风险,特别是在涉及低级C库输入/输出函数时,并试图了解它与内存利用和代码注入的关系 我正在考虑以下代码块及其执行所产生的奇怪行为: int main () { char buffer[10]; int r = read (STDIN_FILENO, buffer, 14); puts(buffer); return EXIT_SUCCESS; } 现在,当给出以下17个大小的输入时 你好,世界!pwd 我得到以下输出: Hello
int main ()
{
char buffer[10];
int r = read (STDIN_FILENO, buffer, 14);
puts(buffer);
return EXIT_SUCCESS;
}
现在,当给出以下17个大小的输入时
你好,世界!pwd
我得到以下输出:
Hello, Wor
> pwd
/media/...<current working directory path>
你好,沃尔
>pwd
/媒体/。。。
如输出所示,3个额外字符(此处为演示目的故意pwd
)超出了read
函数的指定限制,被终端接收并作为shell命令执行
从低层次的角度来看,是什么导致了这种行为?可以用来执行代码注入吗 如输出所示,3个额外字符(此处为
pwd
为了演示的目的)-这是不允许的
读取
功能的指定限制-被终端接管
并作为shell命令执行
从低层次的角度来看,这怎么可能
正如@ChrisTurner在评论中首先观察到的那样,pwd
在程序退出后被解释为启动程序的shell的输入,这并不奇怪。虽然每个程序都有自己的句柄,但它们都在读取同一个文件,可能连接到终端
不过,通过使用低级I/O函数,read
,您的程序会有所帮助,它不会从该文件中消耗超出您请求的任何字节。对比基于流的函数,如fread
、fgets
和scanf
,它们通常执行缓冲读取(这是它们操作的流的特征,而不是函数本身)。在您的特定情况下,其中任何一个都将消耗第一个换行之前(包括第一个换行)的所有输入
您的程序中确实存在潜在的缓冲区溢出,但这是一种危险的做法。您描述的行为确实取决于读取请求的全部14个字节,但不保证这样做,但无论出于何种目的,当标准输入连接到终端时,您都可以依靠它来执行。如果这样做了,您的程序确实会表现出未定义的行为,但是UB的显示可能会被限制到程序的输出(注意它是如何被截断的?),甚至对您来说是不可见的。它不负责父shell将“pwd”读取为输入
那怎么办
非控制台程序执行,如GUI应用程序、web应用程序等。。。
在这种情况下他们会怎么做?最重要的是,什么
从二进制角度来看,这种情况会带来安全问题吗
利用漏洞和代码注入,可能还有其他安全方面
我不知道是什么
只有直接访问程序的父shell(如果有)或该shell的控制终端的人员或程序才能向其提供输入。你没有表现出其他方面。没有特别的安全考虑需要讨论。堆栈溢出不是一个教程站点,这一点非常广泛(请参阅和)。找一本好书或一个教程网站。@Someprogrammerdude关于堆栈溢出的问题有很多非常相似的问题,甚至比这个问题更广泛、更技术。为什么会有这种奇怪的行为?您的代码读取14个字节,剩下的由shell读取,processUB代表未定义的行为。在这种情况下,通过溢出数组的边界(假设
读取
确实读取了完整的14个字节,这似乎是事实,但不能保证)。@JohnBollinger我想这是因为r
在缓冲区
之后声明,并设置为14Thanx以获得详细答案。因此,它与代码注入或内存利用几乎没有关系,如果我理解得很好的话?@programmersn,shell读取并执行程序输入端的“pwd”的结果与代码注入或内存利用无关。