我在CentOS 6.4 32位上,并试图在程序中导致缓冲区溢出.在GDB中它可以工作.这是输出:
[root@localhost bufferoverflow]# gdb stack
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/bufferoverflow/stack...done.
(gdb) r …Run Code Online (Sandbox Code Playgroud) 我有一个家庭作业,要求我使用缓冲区溢出调用函数而不显式调用它.代码基本上是这样的:
#include <stdio.h>
#include <stdlib.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然我不知道该怎么办.我想改变程序计数器的返回地址,以便它直接进入g()的地址,但我不知道如何访问它.无论如何,提示将是伟大的.
我听说过缓冲区溢出,我想知道如何导致缓冲区溢出.
有人能告诉我一个小缓冲区溢出的例子吗?新的(它们用于什么?)
我试图通过Smashing the Stack for Fun和Profit在C中做一个例子,但我有点卡在一点,以下是代码(我有一个64位机器与Ubuntu 64位):
int main()
{
int x;
x = 0;
func(1,2,3);
x = 1;
printf("x is : %d\n", x);
}
void func(int a, int b, int c)
{
char buffer[1];
int *ret;
ret = buffer + 17;
(*ret) += 7;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,并且在返回x=1行时没有执行,但我无法理解背后的逻辑ret = buffer + 17;,不应该是ret = buffer + 16;8字节用于缓冲区,8用于保存的栈指针上的指针.
其次,我的理解是char buffer[1]占用8个字节(由于64位拱)并且如果我增加这个缓冲区来说buffer[2],仍然相同的代码应该工作正常,但这不会发生并且它开始给出seg错误.
此致,努曼
我写了一段C代码,我已经拆解了它,并阅读了寄存器以了解程序在汇编中的工作原理.
int test(char *this){
char sum_buf[6];
strncpy(sum_buf,this,32);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我一直在研究的代码是测试功能.当我反汇编输出我的测试功能时,我得到...
0x00000000004005c0 <+12>: mov %fs:0x28,%rax
=> 0x00000000004005c9 <+21>: mov %rax,-0x8(%rbp)
... stuff ..
0x00000000004005f0 <+60>: xor %fs:0x28,%rdx
0x00000000004005f9 <+69>: je 0x400600 <test+76>
0x00000000004005fb <+71>: callq 0x4004a0 <__stack_chk_fail@plt>
0x0000000000400600 <+76>: leaveq
0x0000000000400601 <+77>: retq
Run Code Online (Sandbox Code Playgroud)
我想知道的mov %fs:0x28,%rax是真正在做什么?
我读了一本关于缓冲区溢出的书,它建议下一步处理:
使堆栈(和堆)不可执行可以为现有程序提供高度保护,防止多种类型的缓冲区溢出攻击.
但我不明白我们怎么做 - 执行会发生在哪里,如果不在堆上或堆栈上?
我按顺序继承了一个控件,所以我可以添加一些我需要的字段,但现在当我在运行时创建它时,我得到一个Access Violation.不幸的是,这种访问冲突不会发生在我正在创建控件的地方,甚至那些我在启用所有调试选项的情况下构建的(包括"使用调试DCU构建")堆栈跟踪根本无法帮助我!
在我尝试重现错误时,我尝试创建一个控制台应用程序,但显然这个错误只出现在Forms应用程序中,并且只有当我的控件实际显示在表单上时!
以下是重现错误的步骤.创建一个新的VCL Forms应用程序,单击一个按钮,双击以创建OnClick处理程序并写入:
type TWinControl<T,K,W> = class(TWinControl);
procedure TForm3.Button1Click(Sender: TObject);
begin
with TWinControl<TWinControl, TWinControl, TWinControl>.Create(Self) do
begin
Parent := Self;
end;
end;
Run Code Online (Sandbox Code Playgroud)
每次我尝试时,这都会连续生成访问冲突.仅在Delphi 2010上测试过,因为这是我在这台计算机上唯一的版本.
问题是:
以下是质量控制报告的链接:http://qc.embarcadero.com/wc/qcmain.aspx?d = 112101
我被要求维护一个充满内存泄漏的大型C++代码库.在探索时,我发现我们有很多缓冲区溢出导致泄漏(它如何变坏,我不想知道).
我决定先删除缓冲区溢出.为了使我的bug更容易找到,可以使用哪些工具来检查缓冲区溢出?
所以在这里我相信我在查看其他人的代码时发现了一个小的缓冲区溢出问题.它立刻让我觉得不正确,而且有潜在危险,但不可否认,我无法解释这个"错误"的实际后果,如果有的话.
我写了一个测试应用程序来演示错误,但发现(令我沮丧的是)无论溢出如何,它似乎都能正常运行.我想相信这只是偶然的,但是需要一些反馈来确定我的想法是否错误,或者是否真的存在问题,而不是在我的测试应用程序中显示出来.
问题代码(我认为无论如何):
char* buffer = new char[strlen("This string is 27 char long" + 1)];
sprintf(buffer, "This string is 27 char long");
Run Code Online (Sandbox Code Playgroud)
现在,这对我来说很突出,我想把它标记为可能的缓冲区溢出是因为第一个strlen.由于指针运算,"错误"放置+ 1将导致strlen返回26而不是27(取"他的字符串的长度为27个字符长").sprintf我相信,然后将27个字符打印到缓冲区并导致缓冲区溢出.
这是正确的评估吗?
我编写了一个测试应用程序来为我正在查看的代码演示这个,并发现即使在调试器中字符串也会正确打印.我还尝试在此代码之前和之后将其他变量放在堆栈和堆上,以查看是否可以影响邻近的内存区域,但仍然收到正确的输出.我意识到我新分配的堆内存可能不相邻,这可以解释缺乏有用的溢出,但我真的想确认其他人的意见,如果这实际上是一个问题.
由于这是一个非常简单的"问题",如果你能通过某种参考来支持你的答案,那就太好了.虽然我重视并欢迎您的意见,但我不会接受"是的"作为最终答案.提前谢谢你.
更新:许多有很多额外见解的好答案.不幸的是,我无法接受所有这些.感谢您分享您的知识并成为我的"第二意见".我很感激帮助.
如何进行堆溢出攻击?
在stackoverflow攻击的情况下,攻击者用他的地址替换函数返回地址.
这是如何在堆溢出攻击中完成的?此外,是否可以从堆运行代码?
buffer-overflow ×10
c ×7
c++ ×3
security ×3
delphi ×1
delphi-2010 ×1
disassembly ×1
gcc ×1
pointers ×1
printf ×1
shellcode ×1
stack-trace ×1
x86-64 ×1