简体   繁体   English

为什么此代码易受缓冲区溢出的影响?

[英]Why is this code vulnerable to buffer overflow?

void cpy(char* b) {
    char values[1024];
    strcpy(b, values);
    fprint(values);
}

int main(int argc, char** argv){
    if(argc == 1 || strlen(argv[1]) > 1024) {
        fprint("Nope!\n");
        return 1;
}
    cpy(argv[1]);
    return 0;
}

Why is this code vulnerable to buffer overflow? 为什么此代码易受缓冲区溢出的影响? I think it has something to do with the "strcpy" part but I'm not sure... 我认为这与“ strcpy”部分有关,但我不确定...

Any ideas? 有任何想法吗?

Short story: The arguments on strcpy are switched. 简短的故事: strcpy的参数已切换。

Long story: strcpy copies from the second to the first argument. strcpystrcpy 从第二个参数复制到第一个参数。

Let us make a quick analysis. 让我们进行快速分析。 In main , the code checks that argv[1] is at most 1023+1 (NUL byte) characters long. main ,代码检查argv[1]长度最多为1023 + 1(NUL字节)个字符。 argv[1] is then passed to cpy as first and only argument and is available there as b . 然后将argv[1]作为第一个也是唯一的参数传递给cpy ,并在那里以b

In cpy , there's also an uninitialised array of char called values , which is allocated to be 1024 characters long. cpy ,还有一个未初始化的char数组,称为values ,分配给它的长度为1024个字符。

Now, strcpy is instructed to copy from values into b . 现在,指示strcpyvalues复制到b As we know, b is the pointer obtained from argv[1] , and thus has at most 1024 chars of space. 众所周知, b是从argv[1]获得的指针,因此最多具有1024个字符的空间。 values is reserved for 1024 characters, but uninitialised. values保留1024个字符,但未初始化。 Thus, it may or may not contain a NUL byte in those 1024 characters. 因此,它可能包含也可能不包含这1024个字符中的NUL字节。

If it happens to contain a NUL byte before the bounds of argv[1] are reached, everything is fine. 如果在到达argv[1]的边界之前碰巧包含一个NUL字节,则一切正常。 If it does not, two things can happen: 如果不这样做,可能会发生两件事:

  • if argv[1] is exactly 1023 characters long (+ terminating NUL byte), out of bounds reads (on values ) and writes (on argv[1] ) will happen. 如果argv[1]长度恰好是1023个字符(+终止NUL字节),则将超出范围(对values )进行读取和写入(针对argv[1] )。

  • if argv[1] is less than 1023 characters long, out of bounds writes on argv[1] will happen, and by extension there may also happen out of bounds reads on values , if the program survives the out of bounds writes. 如果argv[1]长度小于1023个字符,则会对argv[1]进行越界写入,并且通过扩展,如果程序在越界写入中幸存下来,则可能还会对values进行越界读取。

Depending on what fprint is (I don't have a manpage for it on my system), there may be other issues in the code. 根据fprint是什么(我的系统上没有它的联机帮助页),代码中可能还有其他问题。

我认为您使用char数组,因为没有运算符来标记数组的结尾。

The problem is the fprint, it does not know when your string ends. 问题是fprint,它不知道字符串何时结束。 It should end with a '\\0'. 它应以“ \\ 0”结尾。 So if you write something in your array with all the 1024 bytes set. 因此,如果您在数组中写了所有1024字节的内容。 The fprint command will read out of the memory to check if there is a '\\0'... It will continue to read until it finds the end mark. fprint命令将从内存中读出,以检查是否存在'\\ 0'...它将继续读取,直到找到结束标记为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM