绕过堆栈保护-缓冲区溢出
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。
我正在学习安全计算机系统课程,我对这个主题还很陌生。我在分配时遇到问题,我需要通过溢出目标程序 (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。