绕过堆栈保护-缓冲区溢出

Bypassing stack guard- Buffer overflow

我正在学习安全计算机系统课程,我对这个主题还很陌生。我在分配时遇到问题,我需要通过溢出目标程序 (target.cc) 中的缓冲区来获得 shell。我无法在 target.cc 中进行任何更改,但我可以将参数发送到目标文件。

这是代码。

#include <cstdio>
#include <cstring>
#include <cstdlib>
class SubStringReference
{
    const char *start;
    size_t len;

public:
    SubStringReference(const char *s, size_t l) : start(s), len(l) { }
    virtual ~SubStringReference() { }
    virtual const char *getStart() const { return start; }
    virtual int getLen() const { return len; }
};

void print_sub_string(const SubStringReference& str)
{
    char buf[252];
    if (str.getLen() >= sizeof buf)
    {
        // Only copy sizeof(buf) - 1 bytes plus a null
        memcpy(buf, str.getStart(), sizeof(buf) - 1);
        buf[sizeof(buf) - 1] = '[=10=]'; // null-terminate
    }
    else
    {   
        printf("by passed mem check\n");
        // The length is less than the size of buf so just string copy.
        strcpy(buf, str.getStart());
        buf[str.getLen()] = '[=10=]'; // null-terminate to get just the substring
    }
    puts(buf);
}

int main(int argc, char **argv)
{
    if (argc != 4)
    {
        fprintf(stderr, "Usage: %s STRING START LENGTH\n", argv[0]);
        return 1;
    }
    const char *s = argv[1];
    int total_len = strlen(s);
    int start = atoi(argv[2]);
    int len = atoi(argv[3]);
    if (start < 0 || start >= total_len)
    {
        fputs("start is out of range!\n", stderr);
        return 1;
    }
    if (len < 0 || start + len > total_len)
    {
        fputs("length is out of range!\n", stderr);
        return 1;
    }
    SubStringReference str(s + start, len);
    print_sub_string(str);
    return 0;
}

由于此程序受堆栈保护保护,因此程序在返回前被中止。有没有其他方法可以溢出缓冲区并获得 shell??

谢谢。

编辑 - 我 运行 这是在带有 g++ 编译器的 Qemu arm 模拟器上

该漏洞可以通过溢出缓冲区并覆盖str.getLen()函数的地址来指向shell代码来利用。由于金丝雀检查是在函数末尾完成的,因此在检查金丝雀之前获取 shell。