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

时间:2017-09-27 01:35:24

标签: c++ security 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] = '\0'; // 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()] = '\0'; // 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;
}

由于此程序受stackguard保护,程序在返回之前会中止。有没有其他方法可以溢出缓冲区并获得一个shell ??

感谢。

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

1 个答案:

答案 0 :(得分:0)

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