C缓冲区溢出-输入多少字节
我制作了一个简单的C程序来尝试理解缓冲区溢出。我试图使输入缓冲区溢出,使标志变为true,程序输出“got here”。程序在这里(假设您的password.txt中有hey:C缓冲区溢出-输入多少字节,c,security,buffer,overflow,C,Security,Buffer,Overflow,我制作了一个简单的C程序来尝试理解缓冲区溢出。我试图使输入缓冲区溢出,使标志变为true,程序输出“got here”。程序在这里(假设您的password.txt中有hey: 所以我想我只需要给程序17个字节来覆盖flag变量。所以我给了它aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
所以我想我只需要给程序17个字节来覆盖flag变量。所以我给了它aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。我必须给它a23次,所以是23个字节。为什么17个字节不够?尝试此操作时可能会遇到多个问题
- 堆栈上局部变量的顺序不一定与代码中的顺序相同。编译器可以随意重新排列它们
- 编译器通常将数据与边界对齐,以便更快地执行。这意味着不同的局部变量之间的空间可能比你想象的要大得多。堆栈变量在8或16字节边界上对齐并不少见,即使其内容要小得多
您可以使用
objdump-D
反汇编程序,也可以使用gdb
调试程序。这将使您更好地了解程序中的堆栈对齐方式。免责声明:我在gcc版本4.8.4中使用了Ubuntu 14.04,并遵守了您的
代码因此gcc-m32-g-ansi-pedantic-Wall temp.c-o temp
。不同的
编译器或gcc的不同选项很可能会
不同的结果
我还稍微修改了你的代码,让你更容易找到东西
int flag=0x4141代码>
if(flag==1){
(gdb) print &pwd
$3 = (char (*)[5]) 0xffffd132
(gdb) print &flag
$4 = (int *) 0xffffd128
(gdb) print &input
$5 = (char (*)[5]) 0xffffd137
(gdb) print &f
$6 = (FILE **) 0xffffd12c
从这里我们可以推断出我们的堆栈布局
在运行过程序读取命令行的位置后拍摄
参数,该参数是字符串BBB(回想一下,B的ASCII代码是0x42,因此很容易看到0x42字节的序列)
还要注意的是,如果我将命令行参数设置为bbbbbb,我们就有了
对于堆栈框架的内容
(gdb) x/56xb $esp
0xffffd110: 0x37 0xd1 0xff 0xff 0xbc 0xd3 0xff 0xff
0xffffd118: 0x32 0xd1 0xff 0xff 0xe4 0xd1 0xff 0xff
0xffffd120: 0x02 0x00 0x00 0x00 0xe4 0xd1 0xff 0xff
0xffffd128: 0x41 0x41 0x41 0x41 0x08 0xb0 0x04 0x08
0xffffd130: 0xc4 0xf3 0x68 0x65 0x79 0x00 0xff 0x42
0xffffd138: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x00
0xffffd140: 0x60 0x86 0x04 0x08 0x00 0x00 0x00 0x00
请注意,flag变量的内容保持不变,但现在溢出的输入缓冲区的内容移向堆栈顶部。回想一下,在x86中,堆栈向下增长(较低的内存地址)。此外,由于缓冲区向上增长,因此我们可以使用缓冲区溢出来覆盖堆栈上存储的EIP
因此,在我的系统中,我不认为可以用用户输入覆盖标志
变量。您的系统可能会在堆栈上以不同的方式进行布局(您需要进行类似的练习来验证这一点)
另外,请注意,变量在堆栈上的位置与它们在源文件中声明的顺序不相关。C语言中没有堆栈。要求其他人解释未定义的行为也没有用。我建议分解可执行文件,看看堆栈是如何使用的。另外,您可以查看e内存以查看东西放置的位置。另外,不要忘记说明“f”也存储在堆栈上,它应该占用4(如果您在64位机器上,则为8)的空间。不要在此处询问,不要猜测;找出!使用调试器、反汇编、打印。您正在尝试(当然是出于教育目的)要创建恶意软件,路径不会被清晰地标示出来。实际上,一些现代编译器会积极地阻止你…理解缓冲区溢出很容易-不要溢出缓冲区。如果你不溢出缓冲区,UB的特定原因将不再是一个问题。你的解释帮助我解决了我的问题,谢谢你U
(gdb) disass
Dump of assembler code for function main:
0x0804857d <+0>: push ebp
0x0804857e <+1>: mov ebp,esp
0x08048580 <+3>: and esp,0xfffffff0
0x08048583 <+6>: sub esp,0x30
0x08048586 <+9>: mov eax,DWORD PTR [ebp+0xc]
0x08048589 <+12>: mov DWORD PTR [esp+0xc],eax
=> 0x0804858d <+16>: mov eax,gs:0x14
0x08048593 <+22>: mov DWORD PTR [esp+0x2c],eax
0x08048597 <+26>: xor eax,eax
0x08048599 <+28>: mov DWORD PTR [esp+0x18],0x41414141
(gdb) info registers esp
esp 0xffffd110 0xffffd110
(gdb) info registers ebp
ebp 0xffffd148 0xffffd148
(gdb) print &pwd
$3 = (char (*)[5]) 0xffffd132
(gdb) print &flag
$4 = (int *) 0xffffd128
(gdb) print &input
$5 = (char (*)[5]) 0xffffd137
(gdb) print &f
$6 = (FILE **) 0xffffd12c
(gdb) x/56xb $esp
0xffffd110: 0x37 0xd1 0xff 0xff
0xffffd114: 0xbf 0xd3 0xff 0xff
0xffffd118: 0x32 0xd1 0xff 0xff
0xffffd11c: 0xe4 0xd1 0xff 0xff
0xffffd120: 0x02 0x00 0x00 0x00
0xffffd124: 0xe4 0xd1 0xff 0xff
0xffffd128: 0x41 0x41 0x41 0x41 (flag)
0xffffd12c: 0x08 0xb0 0x04 0x08 (f)
0xffffd130: 0xc4 0xf3
0xffffd132: 0x68 0x65 0x79 0x00 0xff (pwd buffer)
0xffffd137: 0x42 0x42 0x42 0x42 0x42 (input buffer)
0xffffd13c: 0x00 0xd5 0x61 0x5d
0xffffd140: 0x60 0x86 0x04 0x08
0xffffd144: 0x00 0x00 0x00 0x00
(gdb) x/56xb $esp
0xffffd110: 0x37 0xd1 0xff 0xff 0xbc 0xd3 0xff 0xff
0xffffd118: 0x32 0xd1 0xff 0xff 0xe4 0xd1 0xff 0xff
0xffffd120: 0x02 0x00 0x00 0x00 0xe4 0xd1 0xff 0xff
0xffffd128: 0x41 0x41 0x41 0x41 0x08 0xb0 0x04 0x08
0xffffd130: 0xc4 0xf3 0x68 0x65 0x79 0x00 0xff 0x42
0xffffd138: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x00
0xffffd140: 0x60 0x86 0x04 0x08 0x00 0x00 0x00 0x00