在从函数A()调用函数B()期间,B()分配一个100-char数组并多次填充,包括一次使用101个字符的字符串,一次使用110个字符的字符串.这是一个明显的错误.
之后,函数A()尝试访问完全不相关的int变量i,并发生分段错误.
我理解为什么会发生缓冲区溢出,但为什么在访问此整数时会出现分段错误?为什么我不简单地得到垃圾数据?
我正在上一门计算机安全课程,还有额外的学分,可以将可执行代码插入到缓冲区溢出中.我有我正在尝试操作的目标程序的c源代码,并且我已经达到了能够成功覆盖当前函数堆栈帧的eip的程度.但是,我总是遇到Segmentation故障,因为我提供的地址总是错误的.问题是当前函数在pthread内部,因此,堆栈的地址似乎总是在程序的不同运行之间发生变化.是否有任何方法可以在pthread中查找堆栈地址(或者用于估计pthread中的堆栈地址)?(注意:pthread_create的第二个参数为null,所以我们不是手动分配堆栈地址)
我正在尝试了解堆栈基础溢出并编写一个简单的代码来利用堆栈.但不知怎的,它根本不起作用,只显示我的机器上的Abort陷阱(mac os豹)
我猜Mac OS对待溢出的方式不同,它不允许我通过c代码覆盖内存.例如,
strcpy(buffer, input) // lets say char buffer[6] but input is 7 bytes
Run Code Online (Sandbox Code Playgroud)
在Linux机器上,此代码成功覆盖下一个堆栈,但在mac os上被阻止(Abort trap)
任何人都知道如何在mac机器上执行简单的堆栈溢出?
根据维基百科(http://en.wikipedia.org/wiki/Buffer_overflow)
通常与缓冲区溢出相关的编程语言包括C和C++,它们不提供内置保护以防止访问或覆盖内存的任何部分中的数据,也不会自动检查写入数组的数据(内置缓冲区类型)是否在该数组的边界.边界检查可以防止缓冲区溢出.
那么,为什么'Bounds Checking'没有在C和C++等语言中实现呢?
我正在尝试使用缓冲区溢出进行一些实验以获得乐趣.我正在这个论坛上阅读这个主题,并试着编写我自己的小代码.
所以我所做的是一个小的"C"程序,它接受字符参数并运行直到分段错误.
所以我提供参数,直到我收到一条消息,我用"A"覆盖了返回地址,这是41.我的缓冲区字符长度,我复制输入字符串是[5].
这是我在gdb中所做的.
run $(perl -e 'print "A"x32 ; ')
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400516 in main (argc=Cannot access memory at address 0x414141414141412d
Run Code Online (Sandbox Code Playgroud)
然后我发现需要16'A'才能覆盖.
run $(perl -e 'print "A"x16 . "C"x8 . "B"x32 ; ')
0x0000000000400516 in main (argc=Cannot access memory at address 0x434343434343432f
)
Run Code Online (Sandbox Code Playgroud)
这告诉我们8"C"正在覆盖返回地址.
根据在线教程,如果我提供有效的地址而不是8"C".我可以跳到某个地方并执行代码.所以我在最初的16"A"之后重载了内存.
下一步是执行
run $(perl -e 'print "A"x16 . "C"x8 . "B"x200 ; ')
rax 0x0 0
rbx 0x3a0001bbc0 249108216768
rcx 0x3a00552780 249113683840
rdx 0x3a00553980 249113688448
rsi 0x42 66
rdi 0x2af9e57710e0 47252785008864 …Run Code Online (Sandbox Code Playgroud) Fortify在下面的代码中报告了一个缓冲区溢出漏洞,理由如下:
在这种情况下,我们主要关注案例"取决于在代码的直接范围之外强制执行的数据的属性".,因为我们无法验证abc.cpp中memcpy()执行的操作的安全性
void create_dir(const char *sys_tmp_dir, const char *base_name,
size_t base_name_len)
{
char *tmp_dir;
size_t sys_tmp_dir_len;
sys_tmp_dir_len = strlen(sys_tmp_dir);
tmp_dir = (char*) malloc(sys_tmp_dir_len + 1 + base_name_len + 1);
if(NULL == tmp_dir)
return;
memcpy(tmp_dir, sys_tmp_dir, sys_tmp_dir_len);
tmp_dir[sys_tmp_dir_len] = FN_LIBCHAR;
memcpy(tmp_dir + sys_tmp_dir_len + 1, base_name, base_name_len);
tmp_dir[sys_tmp_dir_len + base_name_len + 1] = '\0';
..........
..........
}
Run Code Online (Sandbox Code Playgroud)
在我看来这是一个误报,因为我们首先得到数据的大小,分配大量的空间,然后调用memcpy大小来复制.但我正在寻找有充分理由说服其他开发人员摆脱当前的实现,而不是使用c ++字符串.这个问题已经分配给他了.他只是认为这是一个误报,所以不想改变任何东西.
编辑我看到对当前代码的快速,有效的批评.希望我现在能够说服他.否则,我会拿着接力棒.:)
strncpy州的手册页:
char*strncpy(char*dest,const char*src,size_t n);
strcpy()和strncpy()函数返回指向目标字符串dest的指针.
如果可能strncpy(buff, "something", 9) == 0是真的char buff[100]吗?
UPDATE
我也认为它不是很可能,但它是我应该对缓冲区溢出的程序的一部分,这种情况仍然在我实现这一目标的路上.
我正在尝试使用 Ubuntu 16.04 在我的机器中重新创建缓冲区溢出攻击。但无论我尝试什么,我总是收到错误“分段错误(核心转储)”
我已经使用以下方法禁用了内存随机化:
sysctl kernel.randomize_va_space=0
Run Code Online (Sandbox Code Playgroud)
我在编译我的程序时也尝试过这些标志:
-fno-stack-protector
-z execstack
-D_FORTIFY_SOURCE=0
Run Code Online (Sandbox Code Playgroud)
添加所有这些标志,我最终编译了以下内容:
gcc -z execstack -g -fno-stack-protector -mpreferred-stack-boundary=2 -D_FORTIFY_SOURCE=0 -o code code.c
Run Code Online (Sandbox Code Playgroud)
但似乎没有任何效果。为了成功重新创建缓冲区溢出,是否需要禁用任何其他保护?
我正在解决一个关于 Leetcode(捕获雨水)的问题,我写了我的解决方案,该解决方案已经在我的本地机器以及 GeeksForGeeks 上通过了所有 TC 的测试。代码是:
int trap(vector<int>& height) {
int size = height.size();
int i,units;
vector<int> l(size),r(size);
l[0] = height[0];
r[size-1] = height[size-1];
for(i=1; i<size; i++){
l[i] = max(height[i-1],l[i-1]);
}
for(i=size-1; i>=0; i--){
r[i-1] = max(r[i],height[i]);
}
for(i=0; i<size; i++){
if((min(l[i],r[i]) == 0) || (min(l[i],r[i])-height[i]<0))
continue;
else{
units +=min(l[i],r[i])-height[i];
}
}
return units;
}
Run Code Online (Sandbox Code Playgroud)
这是我唯一需要编辑的部分。在运行它时,我收到以下错误
Line 928: Char 34: runtime error: addition of unsigned offset to 0x6040000000d0 overflowed to 0x6040000000cc (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:34
Run Code Online (Sandbox Code Playgroud)
我需要一些帮助来找到我遇到缓冲区溢出的地方。提前加油。
这是源代码。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
Run Code Online (Sandbox Code Playgroud)
main 的汇编代码
0x0000000000400604 <+0>: stp x29, x30, [sp, #-96]!
0x0000000000400608 <+4>: mov x29, sp
0x000000000040060c <+8>: str w0, [sp, #28]
0x0000000000400610 <+12>: str x1, [sp, #16]
0x0000000000400614 <+16>: add x0, sp, #0x20
0x0000000000400618 <+20>: bl 0x4004d0 <gets@plt>
0x000000000040061c <+24>: mov w0, #0x0 // #0
0x0000000000400620 <+28>: ldp x29, x30, [sp], #96
0x0000000000400624 <+32>: …Run Code Online (Sandbox Code Playgroud)