缓冲区溢出后的函数调用
Function call after buffer overflow
我看过一个视频:https://www.youtube.com/watch?v=AXQefYKWjz4
我不明白两件事:
- 我看不到函数调用,但确实如此。
- 他如何得到一个特定的数字,并将其写入文件。
他正在尝试写入特定值(可能是函数地址到堆栈中的某个位置)。为什么可能?我怎样才能重复这个?
缓冲区溢出是一种'problem',它让程序有可能覆盖自己的内存堆栈。
这有两件事:
- 用普通值覆盖 IP(指令指针)return 地址
- (覆盖)在堆栈中写入数据,用作函数参数。
当前函数退出时,指令指针变为栈中地址。如果该地址是恶意代码的地址,则该代码将被执行,就好像它是程序的地址一样。
如果在使用此类权限的程序中完成,这可能允许使用 root 权限执行代码。
首先,这里发生的是他将函数 foo() 的硬编码地址存储在他读入变量 'x' 的 'file' 中。他将其存储为“134513853”,当转换为十六进制时变为:0x80484bd 必须是 地址 函数 foo()。
所以,按照执行顺序,
程序从文件中读取 foo() 的 地址并将其复制到 x 中。然后它覆盖这个地址的缓冲区,这样在它溢出缓冲区之后,它覆盖return地址.
例如:
如果这就是函数堆栈的样子,
Buffer----------------->
EBP ----------------->
Return address --------> some 0x value <--- EIP
Post 溢出看起来像这样:
Buffer-----------------> 0x80484bd
EBP--------------------> 0x80484bd
Return Address---------> 0x80484bd <----EIP
我们暂时不用理会小尾数法。因此,当函数 main() 结束时,执行将从存储在 'Return address' 的地址恢复,从而将执行转移到函数 foo() 并打印字符串 "Welcome to my...".
关于你的第二个问题,我认为制作视频的人禁用了 ASLR 和 Stack Cookies。
ASLR 或地址 Space 布局随机化 随机化可执行文件的关键部分,以便在每个新实例的不同地址存在一个函数。
堆栈 Cookie/Canary 是一个随机运行时生成值,它位于局部变量和 return 地址之间,这样任何溢出都必须首先覆盖 cookie 值。在函数结束之前检查此 cookie 值,如果存在不匹配,函数将退出,从而不会让执行流转移到攻击者控制的 return 地址。
为了重复这个,你将不得不在你的系统上禁用 ASLR,在 Ubuntu 这可以通过在你的终端中输入以下内容来实现,例如 Bash:
回显 0 |须藤三通 /proc/sys/kernel/randomize_va_space
然后,您必须按以下方式在没有堆栈 cookie 的情况下编译您的程序:
gcc -fno-stack-protector -z execstack -o test test.c
更多信息:
美国单反:http://en.wikipedia.org/wiki/Address_space_layout_randomization
http://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries
希望对您有所帮助。
我看过一个视频:https://www.youtube.com/watch?v=AXQefYKWjz4
我不明白两件事:
- 我看不到函数调用,但确实如此。
- 他如何得到一个特定的数字,并将其写入文件。
他正在尝试写入特定值(可能是函数地址到堆栈中的某个位置)。为什么可能?我怎样才能重复这个?
缓冲区溢出是一种'problem',它让程序有可能覆盖自己的内存堆栈。
这有两件事:
- 用普通值覆盖 IP(指令指针)return 地址
- (覆盖)在堆栈中写入数据,用作函数参数。
当前函数退出时,指令指针变为栈中地址。如果该地址是恶意代码的地址,则该代码将被执行,就好像它是程序的地址一样。
如果在使用此类权限的程序中完成,这可能允许使用 root 权限执行代码。
首先,这里发生的是他将函数 foo() 的硬编码地址存储在他读入变量 'x' 的 'file' 中。他将其存储为“134513853”,当转换为十六进制时变为:0x80484bd 必须是 地址 函数 foo()。 所以,按照执行顺序, 程序从文件中读取 foo() 的 地址并将其复制到 x 中。然后它覆盖这个地址的缓冲区,这样在它溢出缓冲区之后,它覆盖return地址.
例如:
如果这就是函数堆栈的样子,
Buffer----------------->
EBP ----------------->
Return address --------> some 0x value <--- EIP
Post 溢出看起来像这样:
Buffer-----------------> 0x80484bd
EBP--------------------> 0x80484bd
Return Address---------> 0x80484bd <----EIP
我们暂时不用理会小尾数法。因此,当函数 main() 结束时,执行将从存储在 'Return address' 的地址恢复,从而将执行转移到函数 foo() 并打印字符串 "Welcome to my...".
关于你的第二个问题,我认为制作视频的人禁用了 ASLR 和 Stack Cookies。
ASLR 或地址 Space 布局随机化 随机化可执行文件的关键部分,以便在每个新实例的不同地址存在一个函数。
堆栈 Cookie/Canary 是一个随机运行时生成值,它位于局部变量和 return 地址之间,这样任何溢出都必须首先覆盖 cookie 值。在函数结束之前检查此 cookie 值,如果存在不匹配,函数将退出,从而不会让执行流转移到攻击者控制的 return 地址。
为了重复这个,你将不得不在你的系统上禁用 ASLR,在 Ubuntu 这可以通过在你的终端中输入以下内容来实现,例如 Bash:
回显 0 |须藤三通 /proc/sys/kernel/randomize_va_space
然后,您必须按以下方式在没有堆栈 cookie 的情况下编译您的程序:
gcc -fno-stack-protector -z execstack -o test test.c
更多信息: 美国单反:http://en.wikipedia.org/wiki/Address_space_layout_randomization http://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries
希望对您有所帮助。